ViewPager 内的 TabLayout 禁止滑动
TabLayout inside ViewPager prohibits swiping
我有以下 ViewPager
的 FINANCIAL 片段页面。
它是根据以下神话建造的
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个组成部分
- 按钮
- TextView
- inner TabLayout(1D、1W、1M、3M、...的栏)
如果我触摸以下任何组件并向右滑动,它会按预期工作。
- 按钮
- TextView
- 片段的任何空白区域
但是,如果我的触摸区域在内部 TabLayout
,滑动将不起作用。 TabLayout
似乎有 "eaten" 我的滑动事件。
知道如何在 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 后,您可以在 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);
}
}
}
你的布局应该是这样的:
<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>
TabLayout
是 HorizontalScrollView
的子类,后者又是 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;
}
}
输出:
我认为以下作品:
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);
}
}
我有以下 ViewPager
的 FINANCIAL 片段页面。
它是根据以下神话建造的
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个组成部分
- 按钮
- TextView
- inner TabLayout(1D、1W、1M、3M、...的栏)
如果我触摸以下任何组件并向右滑动,它会按预期工作。
- 按钮
- TextView
- 片段的任何空白区域
但是,如果我的触摸区域在内部 TabLayout
,滑动将不起作用。 TabLayout
似乎有 "eaten" 我的滑动事件。
知道如何在 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 后,您可以在 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);
}
}
}
你的布局应该是这样的:
<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>
TabLayout
是 HorizontalScrollView
的子类,后者又是 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;
}
}
输出:
我认为以下作品:
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);
}
}