使用FragmentPagerAdapter

时间:2016-05-04 14:15:22

标签: android android-viewpager swipe fragmentpageradapter

我对Android编程很新,所以这[希望]可能是一个愚蠢的问题。

我正在复制底部有4个标签的iOS应用的行为。

最初,只有2个活跃的是第一个和最后一个。中心2仅在成功搜索后才会激活。

我喜欢Android的滑动改变行为(我可能会将其添加到iOS应用中)。

但是,我不确定跳过两个非活动中心的正确方法,因此从右到左滑动从第一个标签到最后一个标签(反之亦然)。

我在发布的API中看不到任何钩子。我想我可以搞砸getItem()中返回的项目(而不是发送其中一个,我直接进入最后一个),但我想知道这是不是正确的方法做到这一点。我担心,因为你在getItem()上实例化实例,所以这意味着它可能不是最好的地方。

对此有何反馈?我知道,对于Android,通常有十几种方法可以做某事,但通常只有一两种方法可以纠正"方式。

我想以正确的方式这样做。

1 个答案:

答案 0 :(得分:0)

行。我说我会报告我是如何解决的#34;问题。它不是100%完美,但它有效,我认为它基本上是做正确的事。

首先,我使用了the TabLayout system,您在其中创建了一个TabLayout对象,并为其指定了ViewPagerFragmentPagerAdapter

我发现Tab class是最终的。你不能将它子类化。这意味着我需要将Fragments用于状态(启用/禁用)。您可以为选项卡打开和关闭可点击,但我添加了一个"已启用"标记为Fragment子类。这是我用来查询选项卡状态的方法。

然后我在Adapter子类中创建了一个嵌入式类。我实施了ViewPager.OnPageChangeListener(它是一个界面):

private class MyTabPagerListener implements ViewPager.OnPageChangeListener

我将它作为监听器添加到TabLayout:

mViewPager.addOnPageChangeListener(new MyTabPagerListener(mTabLayout,this));

然后我实施了"跳过" onPageSelected()方法中的代码。我试着预测选择的去向,所以我可以跳转到相应的选项卡。整个想法是找出方向。如果禁用了下一个选定的选项卡,那么我们继续:

public void onPageSelected(int position) {
    AWrapperBaseFragment    fragment = (AWrapperBaseFragment)mAdapter.getItem(position);
    mSkipToPosition = -1; // This will inform the "wrap up" function that we need to skip to another tab.

    if ( !fragment.isEnabled() ) {
        Log.d(TAG, "Page " + position + " is disabled, selecting a different one.");
        int oldPosition = mTabLayout.getSelectedTabPosition();
        if ( position > oldPosition ) {
            Log.d(TAG, "Going up.");
            for ( int i = position + 1; i < mAdapter.getCount(); i++ ) {
                AWrapperBaseFragment    comp_fragment = (AWrapperBaseFragment)mAdapter.getItem(i);
                if ( comp_fragment.isEnabled() ) {
                    mSkipToPosition = i;
                    break;
                }
            }
        }

        if ( mSkipToPosition == -1 ) {
            Log.d(TAG, "Going down.");
            for ( int i = position - 1; i > -1; i-- ) {
                AWrapperBaseFragment    comp_fragment = (AWrapperBaseFragment)mAdapter.getItem(i);
                if ( comp_fragment.isEnabled() ) {
                    mSkipToPosition = i;
                    break;
                }
            }
        }
    }

    mSelectedPosition = position;

    if ( mSkipToPosition == -1 ) {
        mSkipToPosition = mSelectedPosition;
    }

    Log.d(TAG, "Page selection will " + ((mSelectedPosition != mSkipToPosition) ? ("change from " + mSelectedPosition + " to " + mSkipToPosition) : "not be changed." ));
}

此函数设置信号量,该信号量在状态更改回调中执行:

public void onPageScrollStateChanged(int state) {
    Log.d(TAG, "New Scroll State for page " + mSelectedPosition + ": " + state);
    if ( (state == 0) && (mSkipToPosition > -1) && (mSkipToPosition != mSelectedPosition) ) {
        Log.d(TAG, "This is a disabled page, so page selection will change from " + mSelectedPosition + " to " + mSkipToPosition + "." );
        mViewPager.setCurrentItem(mSkipToPosition, true);
    }
}
像我说的那样,它并不完美。有一个明显的犹豫,你仍然看到禁用的标签内容经过(所以不要在禁用标签中留下slop)。

它比iOS解决方案复杂得多,但我认为它会起作用。我还没有完成测试。