You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android横竖滑页面开发求助:为EmptyFragment添加上下滑页面

实现四向滑动(左右+EmptyFragment上下)的方案

嘿,我来帮你搞定这个四向滑动的需求!核心思路是让EmptyFragment单独承载VerticalViewPager,而不是在MainActivity里放全局的VerticalViewPager(这样会和横向ViewPager的滑动冲突)。下面是具体步骤:

1. 先创建上下滑动的两个Fragment(对应你准备的布局)

先把你准备的两个上下页面封装成独立Fragment,方便VerticalViewPager调用:

// TopFragment(对应白色背景的布局)
public class TopFragment extends Fragment {
    public static TopFragment create() {
        return new TopFragment();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_top, container, false);
    }
}

// BottomFragment(对应黄色背景的布局)
public class BottomFragment extends Fragment {
    public static BottomFragment create() {
        return new BottomFragment();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_bottom, container, false);
    }
}

2. 为VerticalViewPager创建适配器

和你的HorizontalViewPager逻辑一致,写一个适配上下页面的适配器:

public class VerticalPagerAdapter extends FragmentPagerAdapter {
    public VerticalPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0: return TopFragment.create();
            case 1: return EmptyContentFragment.create(); // 这里放你原来EmptyFragment要展示的内容
            case 2: return BottomFragment.create();
        }
        return null;
    }

    @Override
    public int getCount() {
        return 3; // 上页面、原Empty内容、下页面,共3个
    }
}

3. 重构EmptyFragment,让它成为VerticalViewPager的容器

原来的EmptyFragment是空的,现在要改成能承载VerticalViewPager的容器,这样只有这个页面能触发上下滑动:
首先创建EmptyFragment的布局文件fragment_empty.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <me.kaelaela.verticalviewpager.VerticalViewPager
        android:id="@+id/evp_empty_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

然后修改EmptyFragment的代码:

public class EmptyFragment extends Fragment {
    public static EmptyFragment create(){
        return new EmptyFragment();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_empty, container, false);
        // 初始化内部的VerticalViewPager
        me.kaelaela.verticalviewpager.VerticalViewPager verticalViewPager = rootView.findViewById(R.id.evp_empty_container);
        VerticalPagerAdapter verticalAdapter = new VerticalPagerAdapter(getChildFragmentManager());
        verticalViewPager.setAdapter(verticalAdapter);
        verticalViewPager.setPageTransformer(false, new DefaultTransformer());
        // 默认显示中间的原Empty内容页面
        verticalViewPager.setCurrentItem(1);
        
        // 处理滑动冲突:判断手势方向,避免和横向ViewPager冲突
        verticalViewPager.setOnTouchListener(new View.OnTouchListener() {
            private float startX, startY;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        startX = event.getX();
                        startY = event.getY();
                        v.getParent().requestDisallowInterceptTouchEvent(true);
                        break;
                    case MotionEvent.ACTION_MOVE:
                        float dx = Math.abs(event.getX() - startX);
                        float dy = Math.abs(event.getY() - startY);
                        // 横向滑动交给父ViewPager(左右切换),纵向滑动自己处理
                        v.getParent().requestDisallowInterceptTouchEvent(dy > dx);
                        break;
                    case MotionEvent.ACTION_UP:
                    case MotionEvent.ACTION_CANCEL:
                        v.getParent().requestDisallowInterceptTouchEvent(false);
                        break;
                }
                return false;
            }
        });
        
        return rootView;
    }
}

注意这里要用getChildFragmentManager(),因为是Fragment嵌套Fragment的场景。

4. 调整MainActivity和主布局,移除全局VerticalViewPager

原来MainActivity里的全局VerticalViewPager会覆盖在横向ViewPager上,导致滑动冲突,所以要删掉这部分:

修改主布局activity_main.xml

只保留背景和横向ViewPager:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="c.kristofer.jax2.MainActivity">

    <View
        android:id="@+id/am_background_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/green"/>

    <android.support.v4.view.ViewPager
        android:id="@+id/am_view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</RelativeLayout>

修改MainActivity代码

删掉VerticalViewPager相关逻辑,保留横向ViewPager的原有功能:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // HorizontalViewPager 逻辑保留
        View background = findViewById(R.id.am_background_view);
        ViewPager viewPager = findViewById(R.id.am_view_pager);
        HorizontalViewPager adapter = new HorizontalViewPager(getSupportFragmentManager());
        viewPager.setAdapter(adapter);
        viewPager.setCurrentItem(1); // 默认显示中间的EmptyFragment
    }
}

这样调整后,你就能实现:

  • 左右滑动自由切换ChatFragment ↔ EmptyFragment ↔ StoryFragment
  • 在EmptyFragment内,上下滑动切换TopFragment ↔ 原Empty内容 ↔ BottomFragment

内容的提问来源于stack exchange,提问作者KristoferH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:41:21