使用ViewPager的Master-Detail视图



我想更改我的Android手机应用程序的主详细信息。当前,用户可以从ListView中选择项目,打开新活动。要选择其他活动,用户必须返回列表。我希望用户使用ViewPager通过文档向左和向右滑动,而不是使用这种pogo刺。可能有很多文档,所以我想一次最多加载3页 - 当前页面,上一个和下一个页面。然后来回分页,然后添加并左右删除页面。我已经创建了一个实现FragmentStatePagerAdapter的适配器,该适配器很好地处理静态内容(例如文本视图)。另外,删除页面似乎可以正常工作(此处不包括)。但是当我添加时,分页时从一个页面到下一页复制EditText内容。

以下是适配器和活动的代码。我有两个问题:

  1. 我的适配器有什么问题,它导致EditText从一个片段到下一个片段不需要复制?
  2. 这是我对此的第一张照片,这可能远非最佳实现。但是我发现这是一种常见的用例,我几乎觉得会有一个现成的框架。这可以容易得多吗?

Pager适配器:

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 base类:

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

第二个问题是关键:是的,至少可以通过让适配器处理完整的项目来实现当前状态。FragmentStatePagerAdapter一次仅加载尽可能多的片段,因此它可以处理我在活动中所做的所有手动工作。

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

活动

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

最新更新