简体   繁体   中英

FragmentStateAdapter removing last tab instead of current ViewPager2

ViewPager2 is removing last tab instead of current tab, same problem was occurring when i was using viewpager.
Also when selected tab is last one it removes last tab correctly
dependency

implementation "androidx.viewpager2:viewpager2:1.0.0"

This is main activity code
MainActivity.java

 public class MainActivity extends AppCompatActivity { TabLayout tabLayout; ViewPager2 viewPager; ViewPagerAdapter adapter; Button btnAddTab,btnRemoveCurrentTab; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); viewPager = findViewById(R.id.view_pager); tabLayout = findViewById(R.id.tabs); btnAddTab=findViewById(R.id.btn_add); btnRemoveCurrentTab=findViewById(R.id.btn_remove); adapter=new ViewPagerAdapter(this); viewPager.setAdapter(adapter); new TabLayoutMediator(tabLayout, viewPager, new TabLayoutMediator.TabConfigurationStrategy() { @Override public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) { tab.setText("Store " + (position + 1)); } }).attach(); btnRemoveCurrentTab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { adapter.removeFrag(tabLayout.getSelectedTabPosition()); } }); btnAddTab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { DynamicFragment fView = new DynamicFragment(); adapter.addFrag(fView,"Store "+(adapter.getmFragmentIdList().contains(adapter.getItemCount()+1)?adapter.getItemCount()+2:adapter.getItemCount()+1),(adapter.getmFragmentIdList().contains(adapter.getItemCount()+1)?adapter.getItemCount()+2:adapter.getItemCount()+1)); } }); } }

ViewPagerAdapter
This is FragentStateAdapter

 public class ViewPagerAdapter extends FragmentStateAdapter { private final List<DynamicFragment> mFragmentList = new ArrayList<>(); private final List<Integer> mFragmentIdList = new ArrayList<>(); public ViewPagerAdapter(@NonNull FragmentActivity fragmentActivity) { super(fragmentActivity); } @NonNull @Override public Fragment createFragment(int position) { return DynamicFragment.newInstance(String.valueOf(position),mFragmentIdList.get(position)); } public void addFrag(DynamicFragment fragment, String title, int id) { mFragmentList.add(fragment); Log.e("fragment id " ,""+id); Log.e("fragment array " ,title+ mFragmentList.size()); mFragmentIdList.add(id); notifyDataSetChanged(); } public void removeFrag(int pos) { Log.e("deleted frag",mFragmentIdList.get(pos)+" "+pos); mFragmentList.remove(pos); mFragmentIdList.remove(pos); notifyDataSetChanged(); } public List<Integer> getmFragmentIdList() { return mFragmentIdList; } @Override public long getItemId(int position) { return super.getItemId(position); } @Override public int getItemCount() { return mFragmentList.size(); } }


Fragment
This is my dynamic fragment which i want to add and remove

public class DynamicFragment extends Fragment { private static final String ARG_SECTION_NUMBER = "section_number"; private static final String ARG_ID = "id"; private String sectionNumber; int id; TextView textView; EditText editText1,editText2; public DynamicFragment() { // Required empty public constructor } public static DynamicFragment newInstance(String sectionNumber, int id) { DynamicFragment fragment = new DynamicFragment(); Bundle args = new Bundle(); args.putString(ARG_SECTION_NUMBER, sectionNumber); args.putInt(ARG_ID, id); fragment.setArguments(args); Log.e("StoreDynamic","dynamic new instance"); return fragment; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View rootView= inflater.inflate(R.layout.fragment_dynamic, container, false); textView=rootView.findViewById(R.id.textView); editText1=rootView.findViewById(R.id.et1); editText2=rootView.findViewById(R.id.et2); sectionNumber = getArguments().getString(ARG_SECTION_NUMBER); id=getArguments().getInt(ARG_ID); editText1.setText(id+" "+sectionNumber); textView.setText(id+" "+sectionNumber); return rootView; } }

I ran into the same problem and the solution to this question: remove fragment in viewPager2 use FragmentStateAdapter, but still display worked for me. Mostly the part about overriding the getItemId function to return something other than the position to identify the item because the item's position changes when adding and removing fragments.

You need to overwrite the methods getItemId() and containsItemId() as shown in this post: https://stackoverflow.com/a/57944197/870242

items variable holds your fragment (mFragmentList )

private val pageIds= items.map { it.hashCode().toLong() }

override fun getItemId(position: Int): Long {
    return items[position].hashCode().toLong() // make sure notifyDataSetChanged() works
}

override fun containsItem(itemId: Long): Boolean {
    return pageIds.contains(itemId)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM