ViewPager 中的 TabLayout 禁止滑动。

3
我有以下 ViewPager财务 片段页面。

enter image description here

它是使用以下方法构建的。
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;
        }
    }
}

财务页面上,有3个组件:
  1. 按钮
  2. 文本视图
  3. 内部TabLayout(带有1D、1W、1M、3M等的栏)
如果我点击以下任何一个组件,并向右滑动,则按预期工作。
  1. 按钮
  2. 文本视图
  3. 片段的任何空白区域

enter image description here


然而,如果我的触摸区域在内部的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 的代码吗? - romtsn
3个回答

2

TabLayoutHorizontalScrollView的子类,而HorizontalScrollView则是ScrollView的子类。如果您禁用水平滚动,那么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; }
}

输出:

enter image description here


嗨,@azizbekian, 您在 ACTION_DOWN 事件中禁用了选项卡的滚动,这也会禁用选项卡布局的垂直滚动。 - Amit Bhati
@AmitBhati,“TabLayout”没有垂直滚动,也不需要在他的使用情况下。 - azizbekian
TabLayout 可能包含任何滚动视图的子片段。 - Amit Bhati
@Amit Bhati,我不确定这是可能的。根据文档TabLayout只接受TabItem。然而,如果您采用此方法,那么根据TabView#onMeasure()源代码heightMeasureSpec没有任何限制,滚动视图应该完全布局。 - azizbekian
我认为我的解决方案考虑到了这些情况,应该被接受。 - Antonis Lat

0

我认为以下代码可以正常工作:

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

-1

在编程中,你可以在 FinancialFragment 中使用 Viewpager。在修改后,你的 FinancialFragment 应该像下面这样:

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

你的布局应该像这样:


<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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接