0

Ich möchte die Master-Detail-Implementierung meiner Android Phone App ändern. Derzeit können Benutzer Elemente aus einer ListView auswählen und eine neue Aktivität öffnen. Um eine andere Aktivität auszuwählen, muss der Benutzer zur Liste zurückkehren. Anstatt dieses Pogo-Sticks möchte ich, dass der Benutzer nach links und rechts wischt, um die Dokumente mit einem ViewPager zu durchsuchen. Es kann viele Dokumente geben, also möchte ich höchstens 3 Seiten gleichzeitig laden - die aktuelle Seite, die vorherige und die nächste. Paging vor und zurück sollte dann Seiten hinzufügen und entfernen links und rechts. Ich habe einen Adapter erstellt, der FragmentStatePagerAdapter implementiert, der statischen Inhalt (z. B. TextViews) behandelt. Auch das Löschen von Seiten scheint OK zu sein (hier nicht enthalten). Aber wenn ich z.B. Ein EditText Inhalt wird beim Paging von einer Seite auf die nächste kopiert.Master-Detailansicht mit ViewPager

Unten ist der Code für den Adapter und für die Aktivität. Es gibt zwei Fragen, die ich habe:

  1. Was ist falsch mit meinem Adapter, der das unerwünschte Kopieren von EditText von einem Fragment zum nächsten verursacht?
  2. Dies ist meine erste Aufnahme, und es ist wahrscheinlich weit von einer optimalen Implementierung. Aber ich halte das für einen so häufigen Anwendungsfall, dass ich fast das Gefühl habe, dass es einen vorgefertigten Rahmen dafür geben würde. Konnte das viel einfacher erreicht werden?

Pager-Adapter:

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 Basisklasse:

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(); 
     } 
    } 
} 

Antwort

0

Die zweite Frage der Schlüssel wurde: Ja, zumindest kann der aktuelle Zustand viel leichter erreicht werden indem der Adapter das gesamte Array von Elementen behandelt. FragmentStatePagerAdapter lädt nur so viele Fragmente wie nötig, so dass es die gesamte manuelle Arbeit, die ich in der Aktivität ausgeführt habe, bewältigen kann.

Pager Adapter

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(); 
    } 
} 

Aktivität

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()); 
    } 
}