0

Я хотел бы изменить реализацию основной детали моего приложения для Android. В настоящее время пользователи могут выбирать элементы из ListView, открывая новое мероприятие. Чтобы выбрать другое действие, пользователь должен вернуться в список. Вместо этого pogo-sticking, я хотел бы, чтобы пользователь пропустил влево и вправо на страницу через документы, используя ViewPager. Может быть много документов, поэтому я бы хотел загрузить не более 3 страниц за раз - текущую страницу, предыдущую и следующую. Затем пейджинг назад и вперед должен добавлять и удалять страницы слева и справа. Я создал адаптер, реализующий FragmentStatePagerAdapter, который красиво обрабатывает статический контент (например, TextViews). Также удаление страниц, похоже, работает нормально (не включено здесь). Но когда я добавляю, например, содержимое EditText копируется с одной страницы на другую при пейджинге.Master-Detail View с помощью ViewPager

Ниже приведен код для адаптера и для деятельности. Есть два вопроса, у меня есть:

  1. Что случилось с моим адаптером, который вызывает нежелательное копирование EditText от одного фрагмента к другому?
  2. Это мой первый выстрел в этом, и это, вероятно, далеко не оптимальная реализация. Но я считаю, что это такой распространенный случай использования, что я почти чувствую, что для него будет готовая структура. Может ли это быть достигнуто намного проще?

Пейджер адаптер:

public class DetailPagerAdapter extends FragmentStatePagerAdapter { 

    private final List<Fragment> mFragments; 
    private final static String TAG = "DetailPagerAdapter"; 

    public DetailPagerAdapter(FragmentManager fm, List<Fragment> fragments) { 
     super(fm); 
     mFragments = fragments; 
    } 

    @Override 
    public int getCount() { 
     return mFragments.size(); 
    } 

    @Override 
    public int getItemPosition(Object object) { 
     return PagerAdapter.POSITION_NONE; 
    } 

    @Override 
    public Fragment getItem(int position) { 
     return mFragments.get(position); 
    } 

    public void addItem(Fragment fragment) { 
     mFragments.add(fragment); 
     notifyDataSetChanged(); 
    } 

    public void removeItem(int position) { 
     mFragments.remove(position); 
     notifyDataSetChanged(); 
    } 

    public void insertItem(int position, Fragment fragment) { 
     mFragments.add(position, fragment); 
     notifyDataSetChanged(); 
    } 
} 

PagingActivity Базовый класс:

public abstract class PagingActivity 
     extends AppCompatActivity 
     implements ViewPager.OnPageChangeListener { 

    protected ViewPager mViewPager; 
    DetailPagerAdapter mViewPagerAdapter; 
    protected ArrayList<String> mAllItemIds; 
    private String mPreviousItemId; 
    private String mCurrentItemId; 
    private String mNextItemId; 

    private boolean mMuteOnPageSelected = false; 


    protected abstract Fragment getNewPageFragment(String id); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     List<Fragment> initialFragments = new ArrayList<>(); 

     int currentItemIndex = mAllItemIds.indexOf(mCurrentItemId); 
     int pageSelection = 1; 
     // Add previous view. 
     if (currentItemIndex > 0) { 
      mPreviousItemId = mAllItemIds.get(mAllItemIds.indexOf(mCurrentItemId) - 1); 
      initialFragments.add(getNewPageFragment(mPreviousItemId)); 
     } else { 
      pageSelection = 0; 
      mPreviousItemId = null; 
     } 
     // Add current view. 
     initialFragments.add(getNewPageFragment(mCurrentItemId)); 
     // Add next view. 
     if (currentItemIndex < mAllItemIds.size() - 1) { 
      mNextItemId = mAllItemIds.get(mAllItemIds.indexOf(mCurrentItemId) + 1); 
      initialFragments.add(getNewPageFragment(mNextItemId)); 
     } else { 
      mNextItemId = null; 
     } 

     mViewPagerAdapter = new DetailPagerAdapter(getSupportFragmentManager(), initialFragments); 
     mViewPager.setAdapter(mViewPagerAdapter); 
     mViewPager.setCurrentItem(pageSelection); 

     mViewPager.addOnPageChangeListener(this); 
    } 

    @Override 
    public void onPageSelected(int position) { 

     if (!mMuteOnPageSelected) { 
      mCurrentItemId = ((PagingFragment) (mViewPagerAdapter.getItem(mViewPager.getCurrentItem()))).getItemId(); 
      int currentItemIndex = mAllItemIds.indexOf(mCurrentItemId); 

      // Navigated to the right. 
      if (position == mViewPagerAdapter.getCount() - 1) { 
       // Add next if not already pointing at the last available item. 
       if (currentItemIndex < mAllItemIds.size() - 1) { 
        mNextItemId = mAllItemIds.get(mAllItemIds.indexOf(mCurrentItemId) + 1); 
        mViewPagerAdapter.addItem(getNewPageFragment(mNextItemId)); 
       } else { 
        mNextItemId = null; 
       } 
       // If it succeeds remove first item. 
       int itemCount = mViewPagerAdapter.getCount(); 
       if ((itemCount > 3) || ((itemCount == 3) && (currentItemIndex == mAllItemIds.size() - 1))) { 
        mMuteOnPageSelected = true; 
        mViewPagerAdapter.removeItem(0); 
        mViewPager.setCurrentItem(1); 
        mMuteOnPageSelected = false; 
       } 
      } 

      // Navigated to the left. 
      else if (position == 0) { 
       // Add item on the left if not already pointing at the first available item. 
       if (currentItemIndex > 0) { 
        mPreviousItemId = mAllItemIds.get(mAllItemIds.indexOf(mCurrentItemId) - 1); 
        mViewPagerAdapter.insertItem(0, getNewPageFragment(mPreviousItemId)); 
       } else { 
        mPreviousItemId = null; 
       } 
       // Check if last item needs to be removed and selection updated. 
       int itemCount = mViewPagerAdapter.getCount(); 
       if (itemCount == 3) { 
        if (currentItemIndex == 0) { 
         // Points to the first of two items. 
         // -> do not change selection 
         // -> remove rightmost item. 
         mViewPagerAdapter.removeItem(itemCount - 1); 
        } else if (currentItemIndex == mAllItemIds.size() - 2) { 
         // Will point to the middle of 3 items. 
         // -> nothing to remove 
         // -> select middle page. 
         mMuteOnPageSelected = true; 
         mViewPager.setCurrentItem(1); 
         mMuteOnPageSelected = false; 
        } 
       } else if (itemCount > 3) { 
        // Pager contains 4 items, first item selected. 
        // -> remove rightmost item 
        // -> select middle page. 
        mMuteOnPageSelected = true; 
        mViewPagerAdapter.removeItem(itemCount - 1); 
        mViewPager.setCurrentItem(1); 
        mMuteOnPageSelected = false; 
       } 
      } 

      mViewPagerAdapter.notifyDataSetChanged(); 
     } 
    } 
} 

ответ

0

Второй вопрос был ключевым: Да, по крайней мере, текущее состояние может быть достигнуто гораздо проще позволяя адаптеру обрабатывать полный массив элементов. FragmentStatePagerAdapter загружает столько фрагментов за раз, сколько необходимо, поэтому он может обрабатывать всю ручную работу, которую я сделал в своей деятельности.

Пейджер адаптер

public class MyPagerAdapter extends FragmentStatePagerAdapter { 

    private List<String> mAllItemIds; 

    public MyPagerAdapter(Context context, FragmentManager fm) { 
     super(fm); 
     mAllItemIds = ... 
    } 

    @Override 
    public int getCount() { 
     return mAllItemIds.size(); 
    } 

    @Override 
    public int getItemPosition(Object object) { 
     return PagerAdapter.POSITION_NONE; 
    } 

    @Override 
    public Fragment getItem(int position) { 
     return MyFragment.newInstance(mAllItemIds.get(position)); 
    } 

    public void removeItem(int position) { 

     // add needed code here to remove item also from source 
     // ... 

     mAllItemIds.remove(position); 
     notifyDataSetChanged(); 
    } 
} 

активность

public abstract class PagingActivity extends AppCompatActivity { 

    protected ViewPager mViewPager; 
    MyPagerAdapter mViewPagerAdapter; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     mViewPager = (ViewPager)findViewById(R.id.viewPager); 
     mViewPagerAdapter = new MyPagerAdapter(this, getSupportFragmentManager()); 
     mViewPager.setAdapter(mViewPagerAdapter); 
    } 

    private void deleteItem() { 
     mViewPagerAdapter.removeItem(mViewPager.getCurrentItem()); 
    } 
} 
Смежные вопросы