【问题标题】:Master-Detail View using ViewPager使用 ViewPager 的主从视图
【发布时间】:2017-04-18 14:44:21
【问题描述】:

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

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

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

【问题讨论】:

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


    【解决方案1】:

    第二个问题是关键:是的,至少当前状态可以通过让适配器处理整个项目数组来更容易地实现。 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());
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-04-08
      • 2020-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多