【问题标题】:TabLayout inside ViewPager prohibits swipingViewPager里面的TabLayout禁止滑动
【发布时间】:2017-09-29 20:34:50
【问题描述】:

我有以下ViewPagerFINANCIAL片段页面。

它是使用以下神话建造的

this.detailedStockFragmentPagerAdapter = new DetailedStockFragmentPagerAdapter(this.getSupportFragmentManager(), bundle);
viewPager.setAdapter(detailedStockFragmentPagerAdapter);
viewPager.setOffscreenPageLimit(Math.max(1, detailedStockFragmentPagerAdapter.getCount() - 1));
tabLayout.setupWithViewPager(viewPager);

private static class DetailedStockFragmentPagerAdapter extends FragmentPagerAdapter {
    public DetailedStockFragmentPagerAdapter(FragmentManager fm, Bundle bundle) {
        super(fm);
        this.bundle = bundle;
    }

    @Override
    public int getCount() {
        return 3;
    }

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
            {
                ...
            }
            case 1:
            {
                ...
            }
            case 2:
            {
                FinancialFragment financialFragment = FinancialFragment.newInstance();
                financialFragment.setArguments(bundle);
                return financialFragment;
            }
            default:
                assert(false);
        }
        return null;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        switch (position) {
            case 0:
                return JStockApplication.instance().getString(R.string.info);
            case 1:
                return JStockApplication.instance().getString(R.string.news);
            case 2:
                return JStockApplication.instance().getString(R.string.financial);
            default:
                return null;
        }
    }
}

FINANCIAL页面中,有3个组件

  1. 按钮
  2. 文本视图
  3. inner TabLayout(1D, 1W, 1M, 3M, ...的栏)

如果我触摸以下任何组件并向右滑动,它会按预期工作。

  1. 按钮
  2. 文本视图
  3. 片段的任何空白区域


但是,如果我的触摸区域在内部TabLayout,则滑动不起作用。 TabLayout 似乎“吃掉”了我的滑动事件。

知道如何在ViewPager 片段中有内部TabLayout,但不影响我的滑动事件吗?

我的ViewPager片段页面的XML如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:layout_marginBottom="20dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is button"
        android:textSize="18sp" />

    <TextView
        android:layout_marginBottom="20dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#ff000000"
        android:textSize="18sp"
        android:text="This fragment is not scrollable. How to make toolbar visible?"/>

    <LinearLayout
        android:id="@+id/period_tablayout_linear_layout"
        android:layout_width="match_parent"
        android:layout_height="38dp"
        android:orientation="vertical">

        <android.support.design.widget.TabLayout
            android:id="@+id/period_tab_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5dp"
            android:layout_marginRight="5dp"

            app:tabTextAppearance="@style/TradingChartPeriodTabTextAppearance"
            app:tabPaddingStart="0dp"
            app:tabPaddingEnd="0dp"
            app:tabIndicatorHeight="2dp"
            app:tabMode="fixed"
            app:tabGravity="fill"
            app:tabBackground="?attr/tradingHistorySummaryChartBackgroundColor"
            app:tabSelectedTextColor="?attr/primaryTextColor"
            app:tabIndicatorColor="?attr/primaryTextColor">

            <android.support.design.widget.TabItem
                android:id="@+id/tab_item_1d"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="@string/trading_day_1_short" />

            <android.support.design.widget.TabItem
                android:id="@+id/tab_item_1w"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="@string/trading_week_1_short" />

            <android.support.design.widget.TabItem
                android:id="@+id/tab_item_1m"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="@string/trading_month_1_short" />

            <android.support.design.widget.TabItem
                android:id="@+id/tab_item_3m"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="@string/trading_months_3_short" />

            <android.support.design.widget.TabItem
                android:id="@+id/tab_item_6m"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="@string/trading_months_6_short" />

            <android.support.design.widget.TabItem
                android:id="@+id/tab_item_1y"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="@string/trading_year_1_short" />

            <android.support.design.widget.TabItem
                android:id="@+id/tab_item_5y"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="@string/trading_years_5_short" />

            <android.support.design.widget.TabItem
                android:id="@+id/tab_item_10y"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="@string/trading_period_max" />

        </android.support.design.widget.TabLayout>

    </LinearLayout>

</LinearLayout>

【问题讨论】:

  • 你能把FinancialFragment的代码贴出来吗?

标签: android android-viewpager android-view android-scrollview android-tablayout


【解决方案1】:

TabLayoutHorizontalScrollView 的子类,而ScrollView 又是ScrollView 的子类。如果你disable horizontal scrolling,那么MotionEvent 不会被TabLayout 吞没,而是会被传递到视图层次结构的更高层——ViewPager

您可以继承TabLayout 执行以下更改:

public class MyTabLayout extends TabLayout { public MyTabLayout(Context context) { super(context); } public MyTabLayout(Context context, AttributeSet attrs) { super(context, attrs); } public MyTabLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: return false; default: return super.onTouchEvent(ev); } } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return false; } }

输出:

【讨论】:

  • 嗨 @azizbekian,您在 ACTION_DOWN 事件中禁用了选项卡的滚动,这也将禁用选项卡布局的垂直滚动。
  • @AmitBhati, TabLayout 没有垂直滚动,OP 在他的用例中也不需要它。
  • TabLayout 可能包含可能包含任何滚动视图的子片段
  • @Amit Bhati,我不确定这是否可行。从docs 判断,TabLayout 只需要TabItem。不过,如果你应用this的方法,那么从sources of TabView#onMeasure()来看,heightMeasureSpec没有没有约束,滚动视图应该是完全布局的。
  • 我认为我的解决方案可以处理这些情况,应该被接受
【解决方案2】:

我认为以下工作:

public class CustomTabLayout extends TabLayout {
    private PointF touchStartPoint;
    private int mTouchSlop;
    private boolean mIsScrolling;

    public CustomTabLayout(Context context) {
        super(context);
        config();

    }

    public CustomTabLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        config();
    }

    public CustomTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        config();

    }

    private void config() {
        ViewConfiguration vc = ViewConfiguration.get(getContext());
        mTouchSlop = vc.getScaledTouchSlop();
    }


    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        final int action = ev.getAction();

        if (action == MotionEvent.ACTION_DOWN) {
            touchStartPoint = new PointF(ev.getX(), ev.getY());

            return super.onInterceptTouchEvent(ev);
        }

        if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {

            mIsScrolling = false;
            return false;
        }

        switch (action) {
            case MotionEvent.ACTION_MOVE: {
                if (mIsScrolling) {
                    return false;
                }
                final int xDiff = calculateDistanceX(ev);
                if (xDiff > mTouchSlop) {
                    mIsScrolling = true;
                    return true;
                }
                break;
            }
        }
        return super.onInterceptTouchEvent(ev);
    }

    private int calculateDistanceX(MotionEvent ev) {
        return (int) Math.abs(ev.getX() - touchStartPoint.x);
    }
}

【讨论】:

    【解决方案3】:

    您可以在更改 FinancialFragment 后在您的 FinantialFragment 中使用 Viewpager,如下所示:

    public class FinancialFragment extends Fragment {
    
        private ViewPager viewPager;
        private View rootView;
        private TabLayout tabLayout;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            // Inflate the layout for this fragment
    
            rootView = inflater.inflate(R.layout.fragment_three, container, false);
            viewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
            tabLayout = (TabLayout) rootView.findViewById(R.id.period_tab_layout);
    
            return rootView;
        }
    
        @Override
        public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
    
    
            setupViewPager(viewPager);
    
            tabLayout.setupWithViewPager(viewPager);
    
        }
    
        private void setupViewPager(ViewPager viewPager) {
            ViewPagerAdapters adapter = new ViewPagerAdapters(getChildFragmentManager() );
            adapter.addFragment(new OneDayFragment(), "1D");
            adapter.addFragment(new OneWeekFragment(), "1W");
            adapter.addFragment(new OneMonthFragment(), "1M");
            adapter.addFragment(new ThreeMonthFragment(), "3M");
            adapter.addFragment(new SixMonthFragment(), "6M");
            adapter.addFragment(new OneYearFragment(), "1Y");
            adapter.addFragment(new FiveYearFragment(), "5Y");
            viewPager.setAdapter(adapter);
            viewPager.setOffscreenPageLimit(Math.max(1, adapter.getCount() - 1));
        }
    
        class ViewPagerAdapters extends FragmentPagerAdapter {
            private final List<Fragment> mFragmentList = new ArrayList<>();
            private final List<String> mFragmentTitleList = new ArrayList<>();
    
            public ViewPagerAdapters(FragmentManager fm) {
                super(fm);
            }
    
            @Override
            public Fragment getItem(int position) {
                return mFragmentList.get(position);
            }
    
            @Override
            public int getCount() {
                return mFragmentList.size();
            }
    
            public void addFragment(Fragment fragment, String title) {
                mFragmentList.add(fragment);
                mFragmentTitleList.add(title);
            }
    
            @Override
            public CharSequence getPageTitle(int position) {
                return mFragmentTitleList.get(position);
            }
        }
    }
    

    Yout 布局应该是这样的:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <Button
            android:layout_marginBottom="20dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="This is button"
            android:textSize="18sp" />
    
        <TextView
            android:layout_marginBottom="20dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#ff000000"
            android:textSize="18sp"
            android:text="This fragment is not scrollable. How to make toolbar visible?"/>
    
        <LinearLayout
            android:id="@+id/period_tablayout_linear_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
    
            <android.support.design.widget.TabLayout
                android:id="@+id/period_tab_layout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="5dp"
                android:layout_marginRight="5dp"
                app:tabPaddingStart="0dp"
                app:tabPaddingEnd="0dp"
                app:tabIndicatorHeight="2dp"
                app:tabMode="fixed"
                app:tabGravity="fill">
    
            </android.support.design.widget.TabLayout>
    
            <android.support.v4.view.ViewPager
                android:id="@+id/viewpager"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_behavior="@string/appbar_scrolling_view_behavior"  />
    
        </LinearLayout>
    
    </LinearLayout>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-05
      • 2015-04-14
      • 1970-01-01
      • 2017-06-02
      • 1970-01-01
      相关资源
      最近更新 更多