【问题标题】:Remove Tab Fragment from ViewPager and TabLayout Android从 ViewPager 和 TabLayout Android 中删除选项卡片段
【发布时间】:2018-06-14 23:09:23
【问题描述】:

我有一个使用 viewpager 和片段托管 tablayout 的活动。我已经成功地使用来自本地数据库的用户填充值设置了 tablayout 和 viewpager,如下面的代码(尽量简短,这里只显示一个选项卡)-

public void setUpTabs() {
   setUpViewPager(viewPager);
   tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
   tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
   tabLayout.setupWithViewPager(viewPager);
}

private void setUpViewPager(ViewPager viewPager) {

  Customize customize = new Select()  
          .from(Customize.class)
          .where("tabName = ? ", Constants.NATURE)
          .executeSingle();
  if (customize != null) {
      String nature = customize.tabName;
      Log.d(TAG, "Nature Tab Name:\t" + nature);
  }

  pagerAdapter = new TabsPagerAdapter(getSupportFragmentManager());
  pagerAdapter.addTab(new Top30Fragment(), Constants.Top30); // default tab

  if (nature != null) {
      pagerAdapter.addTab(new NatureFragment(), Constants.NATURE); // dynamic tab from db
  }

  pagerAdapter.addTabAtLastPosition(new PrefsFragment(), Constants.PREFS);

  viewPager.setAdapter(pagerAdapter); 
  }

Customize 是模型类,我使用 ActiveAndroid 库进行持久化。这是我的 tabsadapter 类代码:

public class TabsPagerAdapter extends FragmentPagerAdapter {

private static final String TAG = TabsPagerAdapter.class.getSimpleName();
private List<Fragment> fragmentList = new ArrayList<>();
private List<String> titlesList = new ArrayList<>();

private ViewPager viewPager;
private TabLayout tabLayout;

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

@Override
public Fragment getItem(int position) {
    return fragmentList.get(position);
}

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

public void addTab(Fragment fragment, String name){
     fragmentList.add(fragment);
     titlesList.add(name);
}

public void addTabAtLastPosition(Fragment fragment, String name){
     fragmentList.add(fragmentList.size(), fragment);
     titlesList.add(name);
}

public void removeTab(Fragment fragment, String name){ //Not working
     for (int i = 0; i < fragmentList.size(); i++){
         if (fragmentList.get(i).equals(fragment)){ // never enters/returns from this loop
              Log.d(TAG, "Fragment at position:\t" + i);
              fragmentList.remove(fragment);
              titlesList.remove(name);
           }
      }
 }

 @Nullable
 @Override
 public CharSequence getPageTitle(int position) {
     return titlesList.get(position);
 } 
 }

在我的首选项片段(也是 tablayout 的一部分)中,我有一个带有复选框的 recyclerview,case1:如果选中,则在 db 中选中该选项卡,如果还没有,则仅添加到 tablayout。 case2:否则如果不勾选,则表示tab在layout和db中,必须从两者中移除。

我已经开始处理案例 2,但我只能从 db 中删除值,要删除的选项卡仍然存在于 tablayout 中。这是我删除标签的recyclerview适配器代码:

public class PrefsAdapter extends RecyclerView.Adapter<PrefsCustomizeViewHolder> {

private static final String TAG = PrefsAdapter.class.getSimpleName();

private final Context context;
private List<Customize> itemsList;

private long id_nature, id_space, id_seasons, id_art, id_scifi, id_misc;
private Customize cust; // Model class for saving and retrieving tabs

private TabsPagerAdapter pagerAdapter;
private String nature, space, seasons, art, scifi, misc;
private String tabNature, tabSpace, tabSeasons, tabArt, tabScifi, tabMisc;

public PrefsAdapter(Context context, List<Customize> itemsList) {
    this.context = context;
    this.itemsList = itemsList;
    pagerAdapter = new TabsPagerAdapter(((AppCompatActivity)context).getSupportFragmentManager());
}

@Override
public PrefsCustomizeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.prefs_customize_items_layout, parent, false);
    return new PrefsCustomizeViewHolder(view);
}

@Override
public void onBindViewHolder(final PrefsCustomizeViewHolder viewholder, final int position) {
  final Customize customize = itemsList.get(position);

  Picasso.with(context)
          .load(customize.getIcon())
          .fit()
          .into(viewholder.prefsSelImg);

         // search db to find if checkbox is checked, i.e tab is present or not and update recyclerview
  switch (position) {
      case 0:
          cust = new Select()
                  .from(Customize.class)
                  .where("tabName = ? ", Constants.SPACE)
                  .executeSingle();
          if (cust != null) {
              space = cust.tabName;
              Log.d(TAG, "Space Tab From DB:\t" + space);
              id_space = cust.getId();
              Log.d(TAG, "Space Tab Id from DB:\t" + id_space);
              viewholder.prefsCheckBox.setChecked(true);
           } else {
              viewholder.prefsCheckBox.setVisibility(View.INVISIBLE);
              viewholder.prefsCheckBox.setChecked(false);
           }
           break;
   }

   viewholder.prefsSelImg.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View view) {
          switch (position) {
              case 0:
                  if (viewholder.prefsCheckBox.isChecked()){
                      viewholder.prefsCheckBox.setChecked(false);

                      Customize.delete(Customize.class, id_space);
                      Log.d(TAG, "Deleted Space id:\t" + id_space); // prints right log detail
                      pagerAdapter.removeTab(new SpaceFragment(), Constants.SPACE);

                   } else {
                      viewholder.prefsCheckBox.setChecked(true);

                      customize.setTabId(UUID.randomUUID().toString());
                      customize.setTabName(Constants.NATURE);
                      customize.save();

                      pagerAdapter.addTab(new SpaceFragment(), Constants.SPACE);

                      viewholder.prefsCheckBox.setVisibility(View.VISIBLE);
                   }
                  break;
           }

        }
    });

}

@Override
public int getItemCount() {
    if (itemsList == null) {
       return 0;
    }
     return itemsList.size();
 }

}

tabspagerAdapter.removeTab() 永远不会被调用,即使我已经在下面的构造函数中对其进行了初始化:

public PrefsAdapter(Context context, List<Customize> itemsList) {
this.context = context;
this.itemsList = itemsList;
pagerAdapter = new TabsPagerAdapter(((AppCompatActivity)context).getSupportFragmentManager());
} 

有人可以帮我删除片段,以及为什么永远不会调用 pagerAdapter.removeTab(fragment, title) 方法以及如何更新选项卡布局。谢谢。

【问题讨论】:

    标签: android android-fragments android-viewpager android-recyclerview android-tablayout


    【解决方案1】:

    我已使用以下代码成功更改了选项卡的数量(添加和删除)。我发现我必须从寻呼机适配器和选项卡布局中删除它们。

    int cnp = mPagerAdapter.getCount();
    
    // remove all tabs (or just the ones you need to remove) 
    // from both the pager adapter and the tab layout
    for(int i = cnp-1; i >= 0; --i) {
        mPagerAdapter.destroyItem(mViewPager, i, mPagerAdapter.getItem(i));
        mTabLayout.removeTabAt(i);
    }
    
    // add back in whatever tabs you need and update the pager adapter to be consistent
    mTabLayout.addTab(mTabLayout.newTab().setText("Tab 0"),0);
    mTabLayout.addTab(mTabLayout.newTab().setText("Tab 1"),1);
    mPagerAdapter.setConfiguration(2); // my custom method to tell it which pages to show
    
    mTabLayout.invalidate();
    mPagerAdapter.notifyDataSetChanged();
    

    相关班级成员:

    ViewPager mViewPager;
    TabLayout mTabLayout;
    MyPagerAdapter mPagerAdapter; // extends FragmentPagerAdapter
    

    【讨论】:

    • 您添加和删除选项卡的方法与我的不同。我不明白你的回答。你能稍微修改一下以适应我的代码风格吗?谢谢
    • 您是否为 SpaceFragment 提供了自定义的 equals 方法?否则fragmentList.get(i).equals(fragment) 只会在它们是同一个实例时返回 true,因为您正在与新的 SpaceFragment 进行比较,所以这永远不会是 true。我建议完全按位置或使用instanceof 进行删除/添加。
    • 标签由用户选择随机添加。考虑到我没有添加 tabLayout.addTab() 之类的选项卡,如何从选项卡布局中获取选项卡的位置?
    • 您可以尝试存储地图或数组以跟踪添加选项卡时放置的位置。例如,有一个 HashMap&lt;String,Integer&gt; 并按名称存储位置(假设名称是唯一的),您在 addTabaddTabAtLastPosition 函数中填充 (myMap.put(name, fragmentList.size());)
    • 或者,我刚刚注意到您还存储了名称。您可以在 removeTab 中将 fragmentList.get(i).equals(fragment) 替换为 titlesList.get(i).equals(name)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多