使用com.android.support:design:28.0.0的setOnTabSelectedListener崩溃

时间:2018-10-19 19:02:56

标签: android android-tablayout androiddesignsupport

我正在使用带有扩展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库是否存在问题,或者我只是在构建中做错了什么。在早期版本中似乎可以正常工作。任何建议表示赞赏。

3 个答案:

答案 0 :(得分:2)

我从两个版本的27.1.128.0.0下载了AAR文件:

从这两个包中反编译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'

Doc of old onTabSelectedListener(未实现BaseOnTabSelectedListener

Doc of new onTabSelectedListener(实现BaseOnTabSelectedListener)。

对不起,但由于无法立即进行进一步介绍,因此我没有直接显示如何解决它。但这是我猜到的根本原因。

答案 1 :(得分:0)

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

在API级别26.1.0中是depreciated,也许这就是您收到此错误的原因。

要解决此问题,请使用addOnTabSelectedListener代替 setOnTabSelectedListener

引用to this answer

示例代码:

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

请注意,请勿使用折旧方法。

答案 2 :(得分:0)

您应该使用新的材料成分依赖关系。有了这一功能,一切正常,您只需要在Gradle中添加一行即可导入所有设计组件。

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

有了这一行依赖性,RecyclerView,CardView,TabLayout和所有视图组件均可用。您还将拥有Chips,CardView,RecyclerView等。

请记住:

  

您不应使用com.android.support和   同时在您的应用中添加com.google.android.material依赖项

在此处检查有关设置的方法:https://medium.com/nyc-design/material-design-components-setup-on-android-studio-3-2-8b3194d9bebf