Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SlidingTabLayout之动态添加删除tab #129

Closed
guominfang opened this issue Mar 8, 2017 · 11 comments
Closed

SlidingTabLayout之动态添加删除tab #129

guominfang opened this issue Mar 8, 2017 · 11 comments

Comments

@guominfang
Copy link

动态添加tab时,并且滑动到新添加的tab页demo会报错

Process: com.flyco.tablayoutsamples, PID: 5173
 java.lang.NullPointerException: Attempt to invoke virtual method 'int android.view.View.getWidth()' on a null object reference
at com.flyco.tablayout.SlidingTabLayout.scrollToCurrentTab(SlidingTabLayout.java:343)
at com.flyco.tablayout.SlidingTabLayout.onPageScrolled(SlidingTabLayout.java:324)
@guominfang
Copy link
Author

这是我在demo,新加的代码进行测试 动态添加删除的

XML

...........

<android.support.v4.view.ViewPager
            android:id="@+id/vp"
            android:layout_width="match_parent"
            android:layout_height="84dp"/>

        <TextView
            android:id="@+id/btn1"
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:background="@color/colorAccent"
            android:padding="8dp"
            android:text="add"/>

        <TextView
            android:id="@+id/btn2"
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:background="@color/colorPrimary"
            android:padding="8dp"
            android:text="update"/>

        <TextView
            android:id="@+id/btn3"
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:background="@color/colorPrimaryDark"
            android:padding="8dp"
            android:text="del"/>

JAVA

数据源修改

mTitles = new ArrayList<>();
        mTitles.add("哈哈");
        mTitles.add("呵呵");
        mTitles.add("嘎嘎");
        for (String title : mTitles) {
            mFragments.add(SimpleCardFragment.getInstance(title));
        }

监听

findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mFragments.add(SimpleCardFragment.getInstance("添加"));
                mAdapter.notifyDataSetChanged();
                tabLayout_1.notifyDataSetChanged();
            }
        });
        findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mFragments.remove(1);
                mFragments.add(1, SimpleCardFragment.getInstance("修改"));
                mAdapter.notifyDataSetChanged();
                tabLayout_1.notifyDataSetChanged();
            }
        });

        findViewById(R.id.btn3).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mFragments.remove(2);
                mAdapter.notifyDataSetChanged();
                tabLayout_1.notifyDataSetChanged();
            }
        });

adapter

private class MyPagerAdapter extends FragmentStatePagerAdapter {

        public MyPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public int getCount() {
            return mFragments.size();
        }

        @Override
        public CharSequence getPageTitle(int position) {
            SimpleCardFragment fragment = (SimpleCardFragment) mFragments.get(position);
            return fragment.getTitle();
        }

        @Override
        public Fragment getItem(int position) {
            return mFragments.get(position);
        }
       
      // 必须重写此方法,不然,数据源改变,fragment数据不刷新
        @Override
        public int getItemPosition(Object object) {
            return POSITION_NONE;
        }
    }

SimpleCardFragment新增此方法

public String getTitle() {
        return mTitle;
    }

@liangjingkanji
Copy link

我也是, 添加删除直接报空指针异常

@1876505167
Copy link

这个问题解决了吗

@ContinueCoding
Copy link

各位解决上述问题了吗?我试了一下,添加或删除tab后重新设置以下可以暂时可用:
view_pager.setAdapter(adapter);
sliding_tabs.setViewPager(view_pager);
但还是没有解决根本问题,希望作者能尽快修复🙏!

@guominfang
Copy link
Author

@ContinueCoding
未解决呢!你的这个方法,我尝试过。
在新增一个tab时,滑动到新增的界面就报:

java.lang.NullPointerException: Attempt to invoke virtual method 'int android.view.View.getWidth()' on a null object reference
                                                                                at com.flyco.tablayout.SlidingTabLayout.scrollToCurrentTab(SlidingTabLayout.java:343)
                                                                                at com.flyco.tablayout.SlidingTabLayout.onPageScrolled(SlidingTabLayout.java:324)

@ContinueCoding
Copy link

default

如图中代码,在initData()中设置刚进入页面时的Tab;通过点击添加按钮执行添加一个Tab的逻辑,然后再次通过view_pager.setAdapter(adapter);sliding_tabs.setViewPager(view_pager);重新设置后,可以滑到新加的Tab,而且不崩溃的(如果用adapter.notifyDataSetChanged()时会报null指针)。此种方法删除一个Tab也是可以的。

@guominfang
Copy link
Author

@ContinueCoding
是的,你这个方法可以。
我当时不可以,可能是直接在原先的demo界面上修改。一个界面有七八个tab控件。
现在新建一个界面来单独使用,是可以的,

    public void addNewTab() {
        mFragments.add(SimpleCardFragment.getInstance("新增"));
        mAdapter.notifyDataSetChanged();
        tabLayout_1.setViewPager(vp);
    }

    public void upCurrentTab() {
        mFragments.remove(currentIndex);
        mFragments.add(currentIndex, SimpleCardFragment.getInstance("改变"));
        mAdapter.notifyDataSetChanged();
        tabLayout_1.setViewPager(vp);
    }

    public void delCurrentTab() {
        mFragments.remove(currentIndex);
        mAdapter.notifyDataSetChanged();
        tabLayout_1.setViewPager(vp);
    }

@kailaisi
Copy link

kailaisi commented Jun 6, 2017

@guominfang 这个问题好纠结啊,我按照新的方法也不行呢

@magic-zagan
Copy link

magic-zagan commented Jun 12, 2017

1.作者默认的PagerAdapter继承了FragmentPagerAdapter,自己写一个PageAdapter继承FragmentStatePagerAdapter。
然后初始化的时候使用这种方式:

if (null == mAttentionListPagerAdapter) {
                                mAttentionListPagerAdapter = new AttentionListPagerAdapter(getFragmentManager(), mAttentionListFragments, mTitles);
                                vViewPager.setAdapter(mAttentionListPagerAdapter);
                                vSecondTabLayout.setViewPager(vViewPager);
                            } else {
                                mAttentionListPagerAdapter.notifyDataSetChanged();
                                vSecondTabLayout.notifyDataSetChanged();
                            }

即可解决。

FragmentPagerAdapter FragmentPagerAdapter拥有自己的缓存策略,当和ViewPager配合使用的时候,会缓存当前Fragment以及左边一个、右边一个,一共三个Fragment对象。
FragmentStatePagerAdapter 当Fragment对用户不可见的时候,整个Fragment会被销毁
Fragment销毁重建才能被刷新。

另外CommonTabLayout如果想动态刷新,通过反射将mIsFirstDraw设为true,然后set数据即可:

vSecondTabLayout.setIndicatorAnimEnable(false);
            vSecondTabLayout.setCurrentTab(0);
            vSecondTabLayout.setIndicatorAnimEnable(true);
            try {
                Class clazz = vSecondTabLayout.getClass();
                Field field = clazz.getDeclaredField("mIsFirstDraw");
                field.setAccessible(true);
                field.setBoolean(vSecondTabLayout, true);
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            vSecondTabLayout.setTabData(new ArrayList<CustomTabEntity>(mMsgBeens.get(position).getSmlclasslst()));
            vSecondTabLayout.setCurrentTab(mMsgBeens.get(position).getLastIndex());

@guominfang
Copy link
Author

@kailaisi 你的解决不了?
我这边按上面的步骤是可以的

  1. 更新fragment集合
  2. 更新adapter
  3. 重现设置viewpage

@LiWeiQiangAndroid
Copy link

LiWeiQiangAndroid commented Jul 5, 2020

1、更新fragment集合
2、更新adapter
3、重新设置viewpager
4、继承FragmentStatePagerAdapter

SlidingTabActivity 动态更新所有数据源
`public void upAllTab() {
mFragments.clear();
String[] mTitless = {
"Web", "Java", "Android"
, "ReactNative", "IOS"
};

    for (String title : mTitless) {
        mFragments.add(SimpleCardFragment.getInstance(title));
    }
   
   //重新为vp设置adapter
    vp.setAdapter(mAdapter);
   //更新fragment adapter
    mAdapter.notifyDataSetChanged();
    tabLayout_7.setViewPager(vp, mTitless);
}`

修改
private class MyPagerAdapter extends FragmentPagerAdapter
to
private class MyPagerAdapter extends FragmentStatePagerAdapter

这样就可以动态更新所有数据源,不知道存在其他问题没有

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants