标题翻译
How to update ViewPager dynamically when removing fragment
问题
I'm sorry a question that has already been answered in this web, but I can't find same case with mine.
I call lists of multiple columns from `RoomDatabase` for `SetText` in a `ViewPager`, and my question is how to dynamically update `ViewPager` when I delete record. In other questions I've checked, there was a single `TextView` in a `ViewPager`. But in my case, I assign arrays, that I received through bundle, into each `TextView` in `ArrayListFragment` class.
It's so frustrating after searching for what to do after `myAdapter.notifyDataSetChanged()` in delete button.
I will really appreciate your help.
public class FragmentStateLibraryPagerSupport extends Fragment {
MyAdapter myAdapter;
ViewPager mPager;
public List<String> head_array;
public List<String> desc_array;
TodoDatabase db;
@Nullable
@Override
public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
final View root = inflater.inflate(R.layout.fragment_pager, null);
Button btn_delete = root.findViewById(R.id.btn_delete);
btn_delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ArrayListFragment arrayListFragment = new ArrayListFragment();
String head_array_text = head_array.get(arrayListFragment.return_mNum());
Log.e("head_array_text ::", head_array.get(arrayListFragment.return_mNum()));
TodoDatabase db = Room.databaseBuilder(getContext(), TodoDatabase.class, "todo-db").allowMainThreadQueries().build();
db.todoDao().deleteRecord(head_array_text);
myAdapter.notifyDataSetChanged();
}
});
return root;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
db = Room.databaseBuilder(getContext(), TodoDatabase.class, "todo-db").allowMainThreadQueries().build();
head_array = db.todoDao().getAllHead();
desc_array = db.todoDao().getAllDesc();
myAdapter = new MyAdapter(getChildFragmentManager());
mPager = (ViewPager) view.findViewById(R.id.pager);
mPager.setAdapter(myAdapter);
}
private class MyAdapter extends FragmentStatePagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
@NonNull
@Override
public Fragment getItem(int position) {
return ArrayListFragment.newInstance(position, head_array, desc_array);
}
@Override
public int getCount() {
return head_array.size();
}
@Override
public int getItemPosition(@NonNull Object object) {
return POSITION_NONE;
}
}
public static class ArrayListFragment extends ListFragment {
int mNum;
ArrayList<String> head_array, desc_array;
Button btn_save;
public int return_mNum(){
return mNum;
}
static ArrayListFragment newInstance(int num, List<String> head_array, List<String> desc_array) {
ArrayListFragment arrayListFragment = new ArrayListFragment();
Bundle bundle = new Bundle();
bundle.putInt("num", num);
bundle.putStringArrayList("head_array", (ArrayList<String>) head_array);
bundle.putStringArrayList("desc_array", (ArrayList<String>) desc_array);
arrayListFragment.setArguments(bundle);
return arrayListFragment;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNum = getArguments() != null ? getArguments().getInt("num") : 1;
head_array = getArguments().getStringArrayList("head_array");
desc_array = getArguments().getStringArrayList("desc_array");
}
@Nullable
@Override
public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_pager_list, container, false);
btn_save = v.findViewById(R.id.btn_save);
final View head_tv = v.findViewById(R.id.head_tv);
final View desc_tv = v.findViewById(R.id.desc_tv);
if (head_array.size() == 0) {
((TextView) head_tv).setText(R.string.when_no_data_in_DB);
((TextView) desc_tv ).setText("");
btn_save.setVisibility(View.INVISIBLE);
} else {
((TextView) head_tv).setText(head_array.get(mNum));
((TextView) desc_tv ).setText(getString(Integer.parseInt(desc_array.get(mNum))));
}
return v;
}
}
}
英文翻译
I'm sorry a question that has already been answered in this web, but I can't find same case with mine.
I call lists of multiple columns from RoomDatabase
for SetText
in a ViewPager
, and my question is how to dynamically update ViewPager
when I delete record. In other questions I've checked, there was a single TextView
in a ViewPager
. But in my case, I assign arrays, that I received through bundle, into each TextView
in ArrayListFragment
class.
It's so frustrating after searching for what to do after 'myAdapter.notifyDataSetChanged()' in delete button.
I will really appreciate your help.
public class FragmentStateLibraryPagerSupport extends Fragment {
MyAdapter myAdapter;
ViewPager mPager;
public List<String> head_array;
public List<String> desc_array;
TodoDatabase db;
@Nullable
@Override
public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
final View root = inflater.inflate( R.layout.fragment_pager, null );
Button btn_delete = root.findViewById( R.id.btn_delete );
btn_delete.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
ArrayListFragment arrayListFragment = new ArrayListFragment();
String head_array_text = head_array.get( arrayListFragment.return_mNum() );
Log.e( "head_array_text ::" , head_array.get( arrayListFragment.return_mNum() ));
TodoDatabase db = Room.databaseBuilder( getContext(), TodoDatabase.class, "todo-db" ).allowMainThreadQueries().build();
db.todoDao().deleteRecord( head_array_text );
myAdapter.notifyDataSetChanged();
}
} );
return root;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated( view, savedInstanceState );
db = Room.databaseBuilder( getContext(), TodoDatabase.class, "todo-db" ).allowMainThreadQueries().build();
head_array = db.todoDao().getAllHead();
desc_array = db.todoDao().getAllDesc();
myAdapter = new MyAdapter( getChildFragmentManager() );
mPager = (ViewPager) view.findViewById( R.id.pager );
mPager.setAdapter( myAdapter );
}
private class MyAdapter extends FragmentStatePagerAdapter {
public MyAdapter(FragmentManager fm) {
super( fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT );
}
@NonNull
@Override
public Fragment getItem(int position) {
return ArrayListFragment.newInstance( position, head_array, desc_array );
}
@Override
public int getCount() {
return head_array.size();
}
@Override
public int getItemPosition(@NonNull Object object) {
return POSITION_NONE;
}
}
public static class ArrayListFragment extends ListFragment {
int mNum;
ArrayList<String> head_array, desc_array;
Button btn_save;
public int return_mNum(){
return mNum;
}
static ArrayListFragment newInstance(int num, List<String> head_array, List<String> desc_array) {
ArrayListFragment arrayListFragment = new ArrayListFragment();
Bundle bundle = new Bundle();
bundle.putInt( "num", num );
bundle.putStringArrayList( "head_array", (ArrayList<String>) head_array );
bundle.putStringArrayList( "desc_array", (ArrayList<String>) desc_array );
arrayListFragment.setArguments( bundle );
return arrayListFragment;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
mNum = getArguments() != null ? getArguments().getInt( "num" ) : 1;
head_array = getArguments().getStringArrayList( "head_array" );
desc_array = getArguments().getStringArrayList( "desc_array" );
}
@Nullable
@Override
public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate( R.layout.fragment_pager_list, container, false );
btn_save = v.findViewById( R.id.btn_save );
final View head_tv = v.findViewById( R.id.head_tv );
final View desc_tv = v.findViewById( R.id.desc_tv );
if (head_array.size() == 0) {
((TextView) head_tv).setText( R.string.when_no_data_in_DB );
((TextView) desc_tv ).setText( "" );
btn_save.setVisibility( View.INVISIBLE );
} else {
((TextView) head_tv).setText( head_array.get( mNum ) );
((TextView) desc_tv ).setText( getString( Integer.parseInt( desc_array.get( mNum ) ) ) );
}
return v;
}
}
}
答案1
得分: 0
public class DynamicFragmentPagerAdapter extends PagerAdapter {
private static final String TAG = "DynamicFragmentPagerAdapter";
private final FragmentManager fragmentManager;
public static abstract class FragmentIdentifier implements Parcelable {
private final String fragmentTag;
private final Bundle args;
public FragmentIdentifier(@NonNull String fragmentTag, @Nullable Bundle args) {
this.fragmentTag = fragmentTag;
this.args = args;
}
protected FragmentIdentifier(Parcel in) {
fragmentTag = in.readString();
args = in.readBundle(getClass().getClassLoader());
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(fragmentTag);
dest.writeBundle(args);
}
protected final Fragment newFragment() {
Fragment fragment = createFragment();
Bundle oldArgs = fragment.getArguments();
Bundle newArgs = new Bundle();
if (oldArgs != null) {
newArgs.putAll(oldArgs);
}
if (args != null) {
newArgs.putAll(args);
}
fragment.setArguments(newArgs);
return fragment;
}
protected abstract Fragment createFragment();
}
private ArrayList<FragmentIdentifier> fragmentIdentifiers = new ArrayList<>();
private FragmentTransaction currentTransaction = null;
private Fragment currentPrimaryItem = null;
public DynamicFragmentPagerAdapter(FragmentManager fragmentManager) {
this.fragmentManager = fragmentManager;
}
private int findIndexIfAdded(FragmentIdentifier fragmentIdentifier) {
for (int i = 0, size = fragmentIdentifiers.size(); i < size; i++) {
FragmentIdentifier identifier = fragmentIdentifiers.get(i);
if (identifier.fragmentTag.equals(fragmentIdentifier.fragmentTag)) {
return i;
}
}
return -1;
}
public void addFragment(FragmentIdentifier fragmentIdentifier) {
if (findIndexIfAdded(fragmentIdentifier) < 0) {
fragmentIdentifiers.add(fragmentIdentifier);
notifyDataSetChanged();
}
}
public void removeFragment(FragmentIdentifier fragmentIdentifier) {
int index = findIndexIfAdded(fragmentIdentifier);
if (index >= 0) {
fragmentIdentifiers.remove(index);
notifyDataSetChanged();
}
}
@Override
public int getCount() {
return fragmentIdentifiers.size();
}
@Override
public void startUpdate(@NonNull ViewGroup container) {
if (container.getId() == View.NO_ID) {
throw new IllegalStateException("ViewPager with adapter " + this
+ " requires a view id");
}
}
@SuppressWarnings("ReferenceEquality")
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
if (currentTransaction == null) {
currentTransaction = fragmentManager.beginTransaction();
}
final FragmentIdentifier fragmentIdentifier = fragmentIdentifiers.get(position);
// Do we already have this fragment?
final String name = fragmentIdentifier.fragmentTag;
Fragment fragment = fragmentManager.findFragmentByTag(name);
if (fragment != null) {
currentTransaction.attach(fragment);
} else {
fragment = fragmentIdentifier.newFragment();
currentTransaction.add(container.getId(), fragment, fragmentIdentifier.fragmentTag);
}
if (fragment != currentPrimaryItem) {
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
}
return fragment;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
if (currentTransaction == null) {
currentTransaction = fragmentManager.beginTransaction();
}
currentTransaction.detach((Fragment) object);
}
@SuppressWarnings("ReferenceEquality")
@Override
public void setPrimaryItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
Fragment fragment = (Fragment) object;
if (fragment != currentPrimaryItem) {
if (currentPrimaryItem != null) {
currentPrimaryItem.setMenuVisibility(false);
currentPrimaryItem.setUserVisibleHint(false);
}
fragment.setMenuVisibility(true);
fragment.setUserVisibleHint(true);
currentPrimaryItem = fragment;
}
}
@Override
public void finishUpdate(@NonNull ViewGroup container) {
if (currentTransaction != null) {
currentTransaction.commitNowAllowingStateLoss();
currentTransaction = null;
}
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return ((Fragment) object).getView() == view;
}
@Override
public Parcelable saveState() {
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("fragmentIdentifiers", fragmentIdentifiers);
return bundle;
}
@Override
public void restoreState(Parcelable state, ClassLoader loader) {
Bundle bundle = ((Bundle) state);
bundle.setClassLoader(loader);
fragmentIdentifiers = bundle.getParcelableArrayList("fragmentIdentifiers");
}
}
英文翻译
FragmentPagerAdapter is not really intended to support the ability of removing items (dynamic fragment item count).
For that you should use the following code, that tracks identifiers instead of Fragments by position.
public class DynamicFragmentPagerAdapter extends PagerAdapter {
private static final String TAG = "DynamicFragmentPagerAdapter";
private final FragmentManager fragmentManager;
public static abstract class FragmentIdentifier implements Parcelable {
private final String fragmentTag;
private final Bundle args;
public FragmentIdentifier(@NonNull String fragmentTag, @Nullable Bundle args) {
this.fragmentTag = fragmentTag;
this.args = args;
}
protected FragmentIdentifier(Parcel in) {
fragmentTag = in.readString();
args = in.readBundle(getClass().getClassLoader());
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(fragmentTag);
dest.writeBundle(args);
}
protected final Fragment newFragment() {
Fragment fragment = createFragment();
Bundle oldArgs = fragment.getArguments();
Bundle newArgs = new Bundle();
if(oldArgs != null) {
newArgs.putAll(oldArgs);
}
if(args != null) {
newArgs.putAll(args);
}
fragment.setArguments(newArgs);
return fragment;
}
protected abstract Fragment createFragment();
}
private ArrayList<FragmentIdentifier> fragmentIdentifiers = new ArrayList<>();
private FragmentTransaction currentTransaction = null;
private Fragment currentPrimaryItem = null;
public DynamicFragmentPagerAdapter(FragmentManager fragmentManager) {
this.fragmentManager = fragmentManager;
}
private int findIndexIfAdded(FragmentIdentifier fragmentIdentifier) {
for (int i = 0, size = fragmentIdentifiers.size(); i < size; i++) {
FragmentIdentifier identifier = fragmentIdentifiers.get(i);
if (identifier.fragmentTag.equals(fragmentIdentifier.fragmentTag)) {
return i;
}
}
return -1;
}
public void addFragment(FragmentIdentifier fragmentIdentifier) {
if (findIndexIfAdded(fragmentIdentifier) < 0) {
fragmentIdentifiers.add(fragmentIdentifier);
notifyDataSetChanged();
}
}
public void removeFragment(FragmentIdentifier fragmentIdentifier) {
int index = findIndexIfAdded(fragmentIdentifier);
if (index >= 0) {
fragmentIdentifiers.remove(index);
notifyDataSetChanged();
}
}
@Override
public int getCount() {
return fragmentIdentifiers.size();
}
@Override
public void startUpdate(@NonNull ViewGroup container) {
if (container.getId() == View.NO_ID) {
throw new IllegalStateException("ViewPager with adapter " + this
+ " requires a view id");
}
}
@SuppressWarnings("ReferenceEquality")
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
if (currentTransaction == null) {
currentTransaction = fragmentManager.beginTransaction();
}
final FragmentIdentifier fragmentIdentifier = fragmentIdentifiers.get(position);
// Do we already have this fragment?
final String name = fragmentIdentifier.fragmentTag;
Fragment fragment = fragmentManager.findFragmentByTag(name);
if (fragment != null) {
currentTransaction.attach(fragment);
} else {
fragment = fragmentIdentifier.newFragment();
currentTransaction.add(container.getId(), fragment, fragmentIdentifier.fragmentTag);
}
if (fragment != currentPrimaryItem) {
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
}
return fragment;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
if (currentTransaction == null) {
currentTransaction = fragmentManager.beginTransaction();
}
currentTransaction.detach((Fragment) object);
}
@SuppressWarnings("ReferenceEquality")
@Override
public void setPrimaryItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
Fragment fragment = (Fragment) object;
if (fragment != currentPrimaryItem) {
if (currentPrimaryItem != null) {
currentPrimaryItem.setMenuVisibility(false);
currentPrimaryItem.setUserVisibleHint(false);
}
fragment.setMenuVisibility(true);
fragment.setUserVisibleHint(true);
currentPrimaryItem = fragment;
}
}
@Override
public void finishUpdate(@NonNull ViewGroup container) {
if (currentTransaction != null) {
currentTransaction.commitNowAllowingStateLoss();
currentTransaction = null;
}
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return ((Fragment) object).getView() == view;
}
@Override
public Parcelable saveState() {
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("fragmentIdentifiers", fragmentIdentifiers);
return bundle;
}
@Override
public void restoreState(Parcelable state, ClassLoader loader) {
Bundle bundle = ((Bundle)state);
bundle.setClassLoader(loader);
fragmentIdentifiers = bundle.getParcelableArrayList("fragmentIdentifiers");
}
}
专注分享java语言的经验与见解,让所有开发者获益!
评论