如何解决如何使用viewpager2和fragmentstateadapter动态添加和删除片段?
所以几个月以来,我一直在尝试从应用程序中动态添加和删除片段。我最近迁移到了viewpager2和fragmentstateadapter,但无济于事。我的目标是完全删除特定位置的片段,但是能够将新片段添加到列表的末尾,而没有以前的数据。但是,当我执行此操作时,应用程序将复制片段。这是我的适配器代码:
package com.dc.shark_reel_t5.ui.main;
import android.content.Intent;
import android.content.Context;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.Lifecycle;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import com.dc.shark_reel_t5.R;
import java.util.ArrayList;
/**
* A [FragmentPagerAdapter] that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentStateAdapter {
private FragmentManager mFragmentManager;
private FragmentTransaction currTransaction = null;
private int count = 0;
private ArrayList<String> mTitles = new ArrayList<String>();
private ArrayList<Fragment> mFragments = new ArrayList<Fragment>();
private ArrayList<Integer> mFragmentIDs = new ArrayList<Integer>();
public SectionsPagerAdapter(FragmentManager fm,Lifecycle lc) {
super(fm,lc);
mFragmentManager = fm;
}
@NonNull
@Override
public Fragment createFragment(int position) {
return mFragments.get(position);
}
@Nullable
public CharSequence getPageTitle(int position) { return (CharSequence) mTitles.get(position); }
public String getTitle(int position) {
return mTitles.get(position);
}
//Dynamic(runtime) methods:
//On call: adds a hook to the end of the list in UI(DOES NOT CHANGE BACK END VARIABLES YET)
public void addHookFrag(){
mTitles.add("Hook " + (mFragments.size() + 1));
PlaceholderFragment currFrag = PlaceholderFragment.newInstance(mFragments.size() + 1);
mFragmentIDs.add(currFrag.getId());
mFragments.add(currFrag);
notifyItemInserted(mFragments.size()-1);
}
public void delHookFrag(int position){
mFragments.remove(position);
mFragmentIDs.remove(position);
notifyDataSetChanged();
}
@Override
public int getItemCount() {
return mFragments.size();
}
@Override
public long getItemId(int position){
if(position >= getItemCount() || position < 0)
return RecyclerView.NO_ID;
return mFragmentIDs.get(position);
}
@Override
public boolean containsItem(long itemId){
return mFragmentIDs.contains((int)itemId);
}
}
谢谢。
解决方法
我开发了一个解决方案。事实证明,传递给containsItem的ID来自getItemID,因此整个系统都依赖于程序员提供一种创建唯一ID的方法。我使用了一个计数器,因为唯一可以区分片段的是时间顺序,在这种情况下,顺序线性增加。以下是对我有帮助的适配器的相关属性:
public class SectionsPagerAdapter extends FragmentStateAdapter {
...
private int idGen = 0;
@Override
public long getItemId(int position) {
return (long)mFragmentIDs.get(position);
}
@Override
public boolean containsItem(long itemId) {
return mFragmentIDs.contains((int)itemId);
}
...
}
我没有在这里显示它,但是我管理一个片段ID列表。添加新片段时,我增加idGen并将增加的值添加到列表中。删除时,我将ID和片段从它们各自的列表中删除,并更新所有受影响片段的节号(使用片段类中的setter方法轻松完成)。祝大家好运,花了我足够长的时间!
,下面的代码具有FragmentStateAdapter。 Viewpager2使用回收站视图重用视图。您可以将新页面添加到数据列表中,并使用notifyDataSetChanged或notifyItemInserted方法将新页面添加到viewpager中。同样,notifyItemRemoved可用于从该位置动态删除页面并调整viewpager
class StoriesPagerAdapter(fragment: Fragment,var dataList:MutableList<Content> = mutableListOf()) : FragmentStateAdapter(fragment) {
override fun getItemCount(): Int {
return dataList.size
}
override fun createFragment(position: Int): Fragment {
return StoryViewFragment.newInstance(dataList[position],position)
}
companion object {
var currentItem = 0
get() = field
set(value) {
field = value
}
}}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。