使用ViewPager的Master-Detail视图

时间:2016-12-03 22:51:52

标签: java android android-fragments android-viewpager master-detail

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

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

  1. 我的适配器有什么问题导致EditText从一个片段复制到另一个片段?
  2. 这是我的第一次拍摄,它可能远非最佳实施。但我发现这是一个常见的用例,我几乎觉得它会有一个现成的框架。这可以更容易实现吗?
  3. 寻呼机适配器:

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

1 个答案:

答案 0 :(得分: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());
    }
}