Сбой в setOnTabSelectedListener с com.android.support:design:28.0.0

Я использую библиотеку с классом, расширяющим TabLayout. Я пытаюсь собрать последние библиотеки поддержки:

implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support:preference-v14:28.0.0'
implementation 'com.android.support:support-v13:28.0.0'

Это приводит к сбою:

java.lang.NoSuchMethodError: No virtual method setOnTabSelectedListener(Landroid/support/design/widget/TabLayout$OnTabSelectedListener;)

Это исходный код из декомпилированного файла TabLayout.class (похоже, у него нет исходного файла jar, как в других версиях):

/** @deprecated */
@Deprecated
public void setOnTabSelectedListener(@Nullable TabLayout.BaseOnTabSelectedListener listener) { ... }

public interface OnTabSelectedListener extends TabLayout.BaseOnTabSelectedListener<TabLayout.Tab> {
}

public interface BaseOnTabSelectedListener<T extends TabLayout.Tab> { ... }

Он работает с 27.1.1 и более ранними версиями, где исходный код выглядит так:

/**
 * @deprecated Use {@link #addOnTabSelectedListener(OnTabSelectedListener)} and
 * {@link #removeOnTabSelectedListener(OnTabSelectedListener)}.
 */
@Deprecated
public void setOnTabSelectedListener(@Nullable OnTabSelectedListener listener) { ... }

/**
 * Callback interface invoked when a tab's selection state changes.
 */
public interface OnTabSelectedListener { ... }

Я работаю в Genymotion с Samsung Galaxy S8 - API 26 - 1440x2960.

Я не уверен, есть ли проблема с библиотекой design:28.0.0 или, может быть, я просто делаю что-то неправильно в сборке. Кажется, с более ранними версиями все работает нормально. Любые советы приветствуются.


person John    schedule 19.10.2018    source источник
comment
Попробуйте использовать addOnTabSelectedListener(OnTabSelectedListener) вместо setOnTabSelectedListener(...)   -  person Ümañg ßürmån    schedule 19.10.2018
comment
Спасибо, но вызов не в моем коде. Это в структуре, которую я использую - ResearchStack.   -  person John    schedule 19.10.2018
comment
Странный. Док не упомянул, что он был удален. Я декомпилировал класс из mvnrepository.com/artifact/com.android.support /design/28.0.0 (AAR), и этот метод все еще там... Он устарел... не удален.   -  person W0rmH0le    schedule 19.10.2018


Ответы (3)


Я скачал файл AAR из обеих версий: 27.1.1 и 28.0.0:

Декомпилировав TabLayout.class из обоих пакетов, я увидел, что его подпись изменилась с:

27.1.1

@Deprecated
public void setOnTabSelectedListener(@Nullable TabLayout.BaseOnTabSelectedListener listener)
}

28.0.0

@Deprecated
public void setOnTabSelectedListener(@Nullable TabLayout.OnTabSelectedListener listener) {
}

Итак, теперь этот метод ожидает BaseOnTabSelectedListener, а не OnTabSelectedListener

Старый onTabSelectedListener не реализует новый BaseOnTabSelectedListener

Итак, вероятно, придется также импортировать компонент материала, который имеет новую реализацию OnTabSelectedListener:

implementation 'com.google.android.material:material:1.0.0'

старый документ onTabSelectedListener (не реализует BaseOnTabSelectedListener

новый документ onTabSelectedListener (реализует BaseOnTabSelectedListener) .

Извините, но я не показал прямо, как это исправить, потому что я не могу идти дальше прямо сейчас. Но это первопричина, я думаю.

person W0rmH0le    schedule 19.10.2018
comment
Спасибо. Я думаю, что это решение, а также использование addOnTabSelectedListener сработало бы, если бы я писал класс; однако я использую класс, реализованный фреймворком: открытый класс IconTabLayout расширяет android.support.design.widget.TabLayout, а material:1.0.0 предоставляет com.google.android.material.tabs.TabLayout, который не собирается чтобы помочь мне, если я не запутался. - person John; 22.10.2018

/**
 * @deprecated Use {@link #addOnTabSelectedListener(OnTabSelectedListener)} and
 * {@link #removeOnTabSelectedListener(OnTabSelectedListener)}.
 */

Это было устарел на уровне API 26.1.0, возможно, поэтому вы получаете эту ошибку.

Чтобы это исправить, используйте addOnTabSelectedListener вместо setOnTabSelectedListener

См. этот ответ.

Пример кода:

tablayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager));
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tablayout));

В качестве примечания: не используйте устаревшие методы.

person ʍѳђઽ૯ท    schedule 19.10.2018

Вы должны использовать новые зависимости Material Components. С этим все работает нормально, и вам просто нужно добавить одну строку в Gradle, чтобы импортировать все компоненты дизайна.

implementation 'com.google.android.material:material:1.0.0'

Благодаря этой однострочной зависимости становятся доступными RecyclerView, CardView, TabLayout и все компоненты представления. Также у вас будут чипы, CardView, RecyclerView, т.д.

Помните, что:

Вы не должны использовать зависимости com.android.support и com.google.android.material в своем приложении одновременно.

Узнайте здесь, как настроить: https://medium.com/nyc-design/material-design-components-setup-on-android-studio-3-2-8b3194d9bebf

person Pedro Massango    schedule 19.10.2018
comment
На самом деле это не отвечает на главный вопрос. - person ʍѳђઽ૯ท; 19.10.2018