0

У меня есть фрагмент с 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(); 
     } 
    }); 
} 

Таким образом, любая помощь очень ценится!

ответ

0

мне удалось исправить мою проблему, создав три listadapters для каждого из моих фрагментов (статические адаптеры instantiaiting с null значения) и в onClick я проверить каждый из этих трех адаптеров, если они не являются null (поскольку адаптеры null только после onViewCreated , и он вызывается только тогда, когда текущий фрагмент является соседом). Все три адаптера используют одни и те же данные.