ClassNotFoundException: Didn't find class "android.support.v7.internal.widget.TintManager

现象:在使用TabLayout的时候,实现ViewPager Indicator 的效果

代码:

NewsPagerAdapter adapter = new NewsPagerAdapter(getSupportFragmentManager(), fragmentList);

vpnewInfo = (ViewPager) findViewById(R.id.vp_newInfo);
indiactor = (TabLayout) findViewById(R.id.tl_indiactor);

vpnewInfo.setAdapter(adapter);

indiactor.setupWithViewPager(vpnewInfo);

但是运行的时候会报错:ClassNotFoundException: Didn't find class "android.support.v7.internal.widget.TintManager

就是这句代码:indiactor.setupWithViewPager(vpnewInfo);

在给TabLayout关联ViewPager的时候报错,

先说解决办法吧:

引入design包的时候,版本要和appcompat版本一致。


但是为什么呢?

今天有空,正好看一下TabLayout是怎么实现的?内部原理的是怎样的?为什么版本一致就能解决问题了呢?知其然,知其所以然。

TabLayout实现源码:

public void setupWithViewPager(@NonNull ViewPager viewPager) {
        final PagerAdapter adapter = viewPager.getAdapter();
        if (adapter == null) {
            throw new IllegalArgumentException("ViewPager does not have a PagerAdapter set");
        }

        // First we'll add Tabs, using the adapter's page titles
        setTabsFromPagerAdapter(adapter);

        // Now we'll add our page change listener to the ViewPager
        viewPager.addOnPageChangeListener(new TabLayoutOnPageChangeListener(this));

        // Now we'll add a tab selected listener to set ViewPager's current item
        setOnTabSelectedListener(new ViewPagerOnTabSelectedListener(viewPager));

        // Make sure we reflect the currently set ViewPager item
        if (adapter.getCount() > 0) {
            final int curItem = viewPager.getCurrentItem();
            if (getSelectedTabPosition() != curItem) {
                selectTab(getTabAt(curItem));
            }
        }
 }

可以看出来setupWithViewPager做了几件事:

1、判断一下,viewpager是否设置了适配器,如果没有,就抛异常(这就是为什么要先设置适配器,在关联TabLayout)。

2、拿到adpter,设置Tab(上边的title),把adpter传进去(具体下面详细谈)。

3、给Tab设置选择监听。

4、给Tab设置当前状态。

根据断点调试发现,setTabsFromPagerAdapter(adapter);这句代码出错,直接跟进去查看源码:

 public void setTabsFromPagerAdapter(@NonNull PagerAdapter adapter) {
        removeAllTabs();
        for (int i = 0, count = adapter.getCount(); i < count; i++) {
            addTab(newTab().setText(adapter.getPageTitle(i)));
        }
    }

通过adpter获取pager的个数,动态设置Tab的个数,而且title的值是通过getPageTitle(i)获取的。

如果继续跟下去,会发现它的调用栈是

addTab()

addTabView()

createTabView()

TabView()

这里,在实现TabView()的时候,发现TintManager报错,最终导致应用崩溃。

但是为什么呢?

TintManager是干嘛的呢?

为什么版本一致了,就能解决这个问题呢?

TintManager查看源码会发现,它是被@hide修饰的,而依赖的类库不一致,就会导致找不到TintManager这个类。

所以会报错。

另:@hide可以修饰的类、常量、函数。谷歌官方意思是:编译时这些API不对外开放,运行时,这些API就可以被访问了。

这就可以解释,为什么会报错 Didn't find class TintManager

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值