У меня есть фрагмент с viewpager
с удлинителем адаптера FragmentStatePagerAdapter
с тремя скользящими фрагментами внутри. основной фрагмент имеет список данных static
и три ссылки на суб-фрагменты и показывает тот же список (не спрашивайте, почему). Элемент списка можно удалить кнопкой внутри макета строки или щелчком по кнопке «Очистить все» после списка в каждом из этих трех фрагментов.Random Out Of Bounds после удаления элемента из списка statc, используемого несколькими фрагментами
Моя проблема заключается в том, что после удаления одного или всех элементов с помощью кнопок иногда я получаю мгновенный index out of bounds exception
(код приложения в трассировке стека, чтобы найти, откуда исходит исключение) или случайным образом удаляя работу, но фрагменты рядом отобразите старые данные с дополнительным элементом, и, щелкнув, чтобы удалить его, вызывается out of bounds exception
, потому что после некоторой отладки я вижу, что размер списка, переданного адаптеру для воссоздания близлежащего фрагмента, ниже на один (удаление выполнено успешно), поэтому я считаю, что список не уведомлен/недействителен правильно. Любая помощь, поскольку stacktrace не может помочь?
Btw Я использую FragmentStatePagerAdapter.POSITION_NONE
воссоздать фрагменты с новыми данными по каждой салфетке, notifyDataSetChanged
уведомить адаптер измененных данных, и invalidate()
элемента управления ListView в onViewCreated()
, но они не помогают.
соответствующий код:
Главная Фрагмент
public class MainFragment extends BaseFragment<CategoryTreeItem> {
public static List<Map.Entry<EventTreeItem, String>> betList = new ArrayList<>();
...
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ViewPager mViewPager = (ViewPager) view.findViewById(R.id.viewpager);
mViewPager.setAdapter(new MyPagerAdapter(getChildFragmentManager()));
SlidingTabLayout mSlidingTabLayout = (SlidingTabLayout) view.findViewById(R.id.sliding_tabs);
mSlidingTabLayout.setViewPager(mViewPager);
}
}
class MyPagerAdapter extends FragmentStatePagerAdapter {
private List<String> items;
public MyPagerAdapter(FragmentManager fm) {
super(fm);
items = getResources().getStringArray(R.array.three_categories);
}
@Override
public Fragment getItem(int i) {
Fragment fragment;
switch (i) {
case 0:
fragment = new FirstFragment();
return fragment;
case 1:
fragment = new SecondFragment();
return fragment;
case 2:
fragment = new ThirdFragment();
return fragment;
default:
return null;
}
}
...
@Override
public int getItemPosition(Object object) {
return FragmentStatePagerAdapter.POSITION_NONE;
}
}
Три фрагмента (они необходимы, так как расположение и функциональность немного отличается)
public class First/Second/ThirdFragment extends BaseListFragment<ArrayList<EventTreeItem>> {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_main, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
MyListAdapter adapter = new MyListdapter(getActivity(), R.layout.item_first/second/thirdfragment, MainFragment.betList);
getListView().setItemsCanFocus(true);
View footerView = getLayoutInflater(savedInstanceState).inflate(R.layout.include_first/second/third_footer, getListView(), false);
getListView().addFooterView(footerView);
adapter.notifyDataSetChanged();
setListAdapter(adapter);
getListView().invalidate();
//handles REMOVE ALL button for all fragments footer button
Helper.setUpClearOption(footerView, adapter);
}
}
MyListAdapter
@CompileStatic
public class MyListAdapter extends ArrayAdapter<Map.Entry<EventTreeItem,String>> {
private int mResourceId;
private List<Map.Entry<EventTreeItem,String>> mObjects;
public MyListAdapter(Context context, int resource, List<Map.Entry<EventTreeItem,String>> objects) {
super(context, resource, objects);
mResourceId = resource;
mObjects = objects;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
view = LayoutInflater.from(getContext()).inflate(mResourceId, parent, false);
}
//------setting a lot of text for textViews
// .....
//------
ImageView ivRemove = (ImageView) view.findViewById(R.id.ivRemove);
ivRemove.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Tried removing directly from adapter, not helping
// MyListAdapter.this.remove(mObjects.get(position));
MainFragment.betList.remove(position);
MyListAdapter.this.notifyDataSetChanged();
}
});
return view;
}
}
Удалить все вспомогательный метод (также возвращение мгновенного OOB
или не уведомляя соседних фрагментов)
public static void setUpClearOption(View view, final ArrayAdapter adapter) {
ImageView ivRemoveAll = (ImageView) view.findViewById(R.id.ivRemoveAll);
ivRemoveAll.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
adapter.clear();
adapter.notifyDataSetChanged();
}
});
}
Таким образом, любая помощь очень ценится!