23

Tôi có một TabLayout và bên trong mà tôi có ViewPager. Tôi cần phải tự động thêm và xóa tab trong tablayout (material design). Tôi có thể thêm các tab động nhưng trong khi xóa tab, tab sẽ xóa chính xác. Nhưng mục cuối cùng của người xem sẽ bị xóa. Vì vậy, tab không hiển thị đoạn cụ thể. FYI tôi đã sử dụng FragmentPagerAdapter.Tự động thêm và xóa các tab trong TabLayout (thiết kế material design) android

Tôi đã theo hướng dẫn này để thực hiện

https://androidbelieve.com/navigation-drawer-with-swipe-tabs-using-design-support-library

public class TabFragment extends Fragment { 

    public static TabLayout tabLayout; 
    public static ViewPager viewPager; 
    public static int int_items = 2; 
    private MyNewsFragment mMyNewsFragment; 
    private ArrayList<TabFragmentModelClass> mFragmentArrayList; 
    private TabLayoutAdapter mTabLayoutAdapter; 

    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 

     mMyNewsFragment = new MyNewsFragment(); 
     /** 
     *Inflate tab_layout and setup Views.i;;a 
     */ 
     View x = inflater.inflate(R.layout.tab_layout, null); 
     tabLayout = (TabLayout) x.findViewById(R.id.tabs); 
     tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE); // scorllable tab 
     tabLayout.setTabGravity(TabLayout.GRAVITY_FILL); // tab name fill parent 
     viewPager = (ViewPager) x.findViewById(R.id.viewpager); 
     mFragmentArrayList = new ArrayList<>(); 
     mFragmentArrayList.add(new TabFragmentModelClass(new MyNewsSelectionFragment(), "", "")); 
     mFragmentArrayList.add(new TabFragmentModelClass(mMyNewsFragment, "", getResources().getString(R.string.mynews))); 
     mFragmentArrayList.add(new TabFragmentModelClass(new BreakingNewsFragment(), "", getResources().getString(R.string.breakingnews))); 

     // Selected news from shared preference 
     ArrayList<MyNewsSharedPreferenceModelClass> tempSharedPreferenceModelClass = new MyNewsSharedPreferenceClass().loadFavorites(getActivity()); 
     for (int i = 0; i < tempSharedPreferenceModelClass.size(); i++) { 
      mFragmentArrayList.add(new TabFragmentModelClass(new CategoreyNewsFragment(tempSharedPreferenceModelClass.get(i).getmCatID()), tempSharedPreferenceModelClass.get(i).getmCatID(), 
        tempSharedPreferenceModelClass.get(i).getmCatName())); 
     } 


} 


     /** 
     *Set an Apater for the View Pager 
     */ 
     mTabLayoutAdapter = new TabLayoutAdapter(getChildFragmentManager(), mFragmentArrayList); 
     viewPager.setAdapter(mTabLayoutAdapter); 
     viewPager.setOffscreenPageLimit(mFragmentArrayList.size()); 
     tabLayout.setupWithViewPager(viewPager); 


     viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 
      @Override 
      public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 
      } 

      @Override 
      public void onPageSelected(int position) { 
       tabLayout.getTabAt(position); 
      } 

      @Override 
      public void onPageScrollStateChanged(int state) { 
       if (state == 1) { 
        updateMyNewsFragment(); 
       } 
      } 
     }); 

     /** 
     * Now , this is a workaround , 
     * The setupWithViewPager dose't works without the runnable . 
     * Maybe a Support Library Bug . 
     */ 

     tabLayout.post(new Runnable() { 
      @Override 
      public void run() { 

       tabLayout.getTabAt(0).setIcon(R.mipmap.mynewselection); 

       tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { 
        @Override 
        public void onTabSelected(TabLayout.Tab tab) { 
         viewPager.setCurrentItem(tab.getPosition()); 
         switch (tab.getPosition()) { 
          case 1: 

           System.out.println("000000000000000000000 "); 
           updateMyNewsFragment(); 
           break; 
         } 
        } 

        @Override 
        public void onTabUnselected(TabLayout.Tab tab) { 
        } 


        @Override 
        public void onTabReselected(TabLayout.Tab tab) { 
        } 
       }); 

      } 
     }); 
     return x; 
    } 

    /** 
    * update the mynews selection 
    * this method trigger from the MainNewsActivity 
    */ 
    public void updateMyNewsFragment() { 
     if (ApplicationController.getInstance().getBoolPref(CommonVariableInterFace.isNewsSelected)) { 
      mMyNewsFragment.sendMyNewsRequest(); 
      ApplicationController.getInstance().setBoolPref(CommonVariableInterFace.isNewsSelected, false); 
     } 
    } 

    /** 
    * update the tab values 
    * this method trigger from the MainNewsActivity 
    * if value is zero need to add in tab 
    * if value is one need to remove in tab 
    */ 
    public void updateTabvalue(String catId, String catName, int value) { 

      if (value == 0) { // add the value in tab 

       mFragmentArrayList.add(new TabFragmentModelClass(new CategoreyNewsFragment(catId), catId, 
         catName)); 
      } else {  // Removing the tab 
       for (int i = 0; i < mFragmentArrayList.size(); i++) { 
        if (mFragmentArrayList.get(i).getmCatID().equalsIgnoreCase(catId)) { 

         Log.i("-----same id ", catId); 
         mFragmentArrayList.remove(i); 
         mTabLayoutAdapter = new TabLayoutAdapter(getChildFragmentManager(), mFragmentArrayList); 
         viewPager.setAdapter(mTabLayoutAdapter); 
        } 
       } 
      } 

      mTabLayoutAdapter.notifyDataSetChanged(); 
      viewPager.setOffscreenPageLimit(mFragmentArrayList.size()); 
      tabLayout.getTabAt(0).setIcon(R.mipmap.mynewselection); 
      tabLayout.setupWithViewPager(viewPager); 


      tabLayout.post(new Runnable() { 
       @Override 
       public void run() { 

        tabLayout.getTabAt(0).setIcon(R.mipmap.mynewselection); 

        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { 
         @Override 
         public void onTabSelected(TabLayout.Tab tab) { 
          viewPager.setCurrentItem(tab.getPosition()); 
          switch (tab.getPosition()) { 
           case 1: 
            updateMyNewsFragment(); 
            break; 
          } 
         } 

         @Override 
         public void onTabUnselected(TabLayout.Tab tab) { 
         } 


         @Override 
         public void onTabReselected(TabLayout.Tab tab) { 
         } 
        }); 

       } 
      }); 
    } 

    public void openSpecificTab() { 

//  tabLayout.settab 
//  tabLayout.se 
    } 
} 

đang Adaptor này:

public class TabLayoutAdapter extends FragmentPagerAdapter { 

    private long baseId = 0; 
    ArrayList<TabFragmentModelClass> fragmentAdapterArrayList; 

    public TabLayoutAdapter(FragmentManager fm, ArrayList<TabFragmentModelClass> fragmentArrayList) { 
     super(fm); 
     fragmentAdapterArrayList = fragmentArrayList; 
    } 

    @Override 
    public Fragment getItem(int position) { 

     if (position == 0) 
      return fragmentAdapterArrayList.get(position).getmFragment(); 
     if (position == 1) 
      return fragmentAdapterArrayList.get(position).getmFragment(); 
     if (position == 2) 
      return fragmentAdapterArrayList.get(position).getmFragment(); 

     return new CategoreyNewsFragment().newInstance(fragmentAdapterArrayList.get(position).getmCatID()); 
    } 

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


    //this is called when notifyDataSetChanged() is called 
    @Override 
    public int getItemPosition(Object object) { 
     // refresh all fragments when data set changed 
     return TabLayoutAdapter.POSITION_NONE; 
    } 


    @Override 
    public long getItemId(int position) { 
     // give an ID different from position when position has been changed 
     return baseId + position; 
    } 

    /** 
    * Notify that the position of a fragment has been changed. 
    * Create a new ID for each position to force recreation of the fragment 
    * 
    * @param n number of items which have been changed 
    */ 
    public void notifyChangeInPosition(int n) { 
     // shift the ID returned by getItemId outside the range of all previous fragments 
     baseId += getCount() + n; 
    } 

    /** 
    * //  * This method returns the title of the tab according to the position. 
    * // 
    */ 

    @Override 
    public CharSequence getPageTitle(int position) { 
     return fragmentAdapterArrayList.get(position).getmCatName(); 
    } 
} 

Trả lời

22

Remove tab từ TabLayout

... 
public void removeTab(int position) { 
    if (mTabLayout.getTabCount() >= 1 && position<mTabLayout.getTabCount()) { 
      mTabLayout.removeTabAt(position); 
      mPagerAdapter.removeTabPage(position); 
    } 
} 
... 

Thêm một phương pháp removeTabPage để bạn PagerAdapter

... 
public void removeTabPage(int position) { 
    if (!tabItems.isEmpty() && position<tabItems.size()) { 
      tabItems.remove(position); 
      notifyDataSetChanged(); 
    } 
} 
... 

Thêm một Tab

... 
private void addTab(String title) { 
     mTabLayout.addTab(mTabLayout.newTab().setText(title)); 
     mPagerAdapter.addTabPage(title); 
} 
... 

Thêm một phương pháp addTabPage để bạn PagerAdapter

... 
public void addTabPage(String title) { 
     tabItems.add(title); 
     notifyDataSetChanged(); 
} 
... 

Kiểm tra mẫu mã này cho một đầy đủ ví dụ: ...samples/SupportDesignDemos/src/com/example/android/support/design/widget/TabLayoutUsage.java

+0

Cảm ơn anh chàng đó là hữu ích – Ruban

+1

tôi đã cố gắng ở trên nhưng nó không làm việc cho tôi. Sau khi gọi removeTab (2) trên một viewpager với 5 đoạn tôi nhận được lỗi java.lang.NullPointerException: Cố gắng gọi phương thức ảo 'int android.view.View.getLeft()' trên tham chiếu đối tượng null @Ruban – Zvi

+1

@Zvi lỗi này có vẻ như bạn đang cố gắng gọi View.getLeft() trên Chế độ xem không có ở đó, hãy thử và tìm hiểu lý do tại sao? đã thực hiện cuộc gọi để removeTab (2) xóa tham chiếu đến chế độ xem này? – TouchBoarder

10

Với thư viện hỗ trợ mới (tôi đang sử dụng 23.2.1), bạn chỉ nên thêm vào Viewpager chứ không phải TabLayout (nếu không bạn kết thúc bằng tab kép và hành vi sôi nổi khác). Vì vậy, để cập nhật TouchBoarder's answer:

Thêm một phương pháp removeTabPage để PagerAdapter bạn

public void removeTabPage(int position) { 
    if (!tabItems.isEmpty() && position<tabItems.size()) { 
      tabItems.remove(position); 
      notifyDataSetChanged(); 
    } 
} 

Thêm một phương pháp addTabPage để PagerAdapter bạn

public void addTabPage(String title) { 
     tabItems.add(title); 
     notifyDataSetChanged(); 
} 
+0

Cảm ơn Midas ... – Ruban

+0

nếu tôi không có bộ điều hợp trang và chỉ có ta b bố cục? –

Các vấn đề liên quan