Android App手势冲突处理中上下左右滑动的处理以及侧滑边缘菜单的讲解及实战(附源码 可直接使用)

简介: Android App手势冲突处理中上下左右滑动的处理以及侧滑边缘菜单的讲解及实战(附源码 可直接使用)

运行有问题或需要源码请 点赞关注收藏后评论区留言~~~

一、上下滚动与左右滑动的冲突处理

Android控件繁多,允许滚动或滑动操作的视图也不少,如果开发者要自己接管手势处理,那么这个页面的滑动就存在冲突的情况,如果系统响应了A视图的滑动事件,就顾不上B视图的滑动事件

解决这种冲突,关键在于提供某种方式通知滚动视图,告诉他什么时候可以上下滚动,什么时候不能上下滚动,这个通知方式主要有两种,一种是父视图主动向下查询,即由滚动视图判断滚动规则并决定是否拦截手势,另一种是子视图向上反映,即由子视图告诉滚动视图是否拦截手势,下面分别介绍

1:由滚动视图判断滚动规则

自定义一个滚动视图 判断手势的横纵坐标关系

2:子视图告诉滚动视图能否拦截手势

实战效果如下

代码如下

Java类

package com.example.event;
import android.annotation.SuppressLint;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.widget.TextView;
import android.widget.LinearLayout.LayoutParams;
import com.example.event.constant.ImageList;
import com.example.event.util.Utils;
import com.example.event.widget.BannerPager;
@SuppressLint("DefaultLocale")
public class CustomScrollActivity extends AppCompatActivity {
    private static final String TAG = "CustomScrollActivity";
    private TextView tv_flipper; // 声明一个文本视图对象
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_custom_scroll);
        tv_flipper = findViewById(R.id.tv_flipper);
        BannerPager banner = findViewById(R.id.banner_pager);
        LayoutParams params = (LayoutParams) banner.getLayoutParams();
        params.height = (int) (Utils.getScreenWidth(this) * 250f / 640f);
        banner.setLayoutParams(params); // 设置广告轮播条的布局参数
        banner.setImage(ImageList.getDefault()); // 设置广告轮播条的图片列表
        // 设置广告轮播条的横幅点击监听器
        banner.setOnBannerListener(position -> {
            String desc = String.format("您点击了第%d张图片", position + 1);
            tv_flipper.setText(desc);
        });
    }
}

XML文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <com.example.event.widget.CustomScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >
            <View
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:background="#9999ff" />
            <com.example.event.widget.BannerPager
                android:id="@+id/banner_pager"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
            <TextView
                android:id="@+id/tv_flipper"
                android:layout_width="match_parent"
                android:layout_height="300dp"
                android:background="#eeffee"
                android:gravity="top|center"
                android:paddingTop="20dp"
                android:text="请左右滑动或者上下拉动广告图片"
                android:textColor="@color/black"
                android:textSize="17sp" />
            <View
                android:layout_width="match_parent"
                android:layout_height="1000dp"
                android:background="#9999ff" />
        </LinearLayout>
    </com.example.event.widget.CustomScrollView>
</LinearLayout>

二、边缘侧滑菜单

可以借鉴抽屉布局DrawerLayout,该布局运行左右滑动,在滑动时会拉出侧面的抽屉面板,常用于实现侧滑菜单

举个实际例子的应用,微信的聊天窗口是上下滚动的,在主窗口的大部分区域触摸都是上下滚动窗口,若在窗口左侧边缘按下再右拉,就会看到左边拉出了消息关注页面,限定某块区域接管特定的手势,这是一种处理滑动冲突行之有效的方法

抽屉布局不仅可以拉出左侧抽屉面板,还可以拉出右侧抽屉面板 效果如下

代码如下

Java类

package com.example.event;
import android.annotation.SuppressLint;
import android.os.Bundle;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.drawerlayout.widget.DrawerLayout.DrawerListener;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
@SuppressLint("SetTextI18n")
public class DrawerLayoutActivity extends AppCompatActivity {
    private final static String TAG = "DrawerLayoutActivity";
    private DrawerLayout dl_layout; // 声明一个抽屉布局对象
    private Button btn_drawer_left; // 声明一个按钮对象
    private Button btn_drawer_right; // 声明一个按钮对象
    private TextView tv_drawer_center; // 声明一个文本视图对象
    private ListView lv_drawer_left; // 声明左侧菜单的列表视图对象
    private ListView lv_drawer_right; // 声明右侧菜单的列表视图对象
    private String[] titleArray = {"首页", "新闻", "娱乐", "博客", "论坛"}; // 左侧菜单项的标题数组
    private String[] settingArray = {"我的", "设置", "关于"}; // 右侧菜单项的标题数组
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_drawer_layout);
        dl_layout = findViewById(R.id.dl_layout);
        dl_layout.addDrawerListener(new SlidingListener()); // 设置侧滑监听器
        btn_drawer_left = findViewById(R.id.btn_drawer_left);
        btn_drawer_right = findViewById(R.id.btn_drawer_right);
        tv_drawer_center = findViewById(R.id.tv_drawer_center);
        btn_drawer_left.setOnClickListener(v -> {
            if (dl_layout.isDrawerOpen(lv_drawer_left)) { // 左侧菜单已打开
                dl_layout.closeDrawer(lv_drawer_left); // 关闭左侧抽屉
            } else { // 左侧菜单未打开
                dl_layout.openDrawer(lv_drawer_left); // 打开左侧抽屉
            }
        });
        btn_drawer_right.setOnClickListener(v -> {
            if (dl_layout.isDrawerOpen(lv_drawer_right)) { // 右侧菜单已打开
                dl_layout.closeDrawer(lv_drawer_right); // 关闭右侧抽屉
            } else { // 右侧菜单未打开
                dl_layout.openDrawer(lv_drawer_right); // 打开右侧抽屉
            }
        });
        initListDrawer(); // 初始化侧滑的菜单列表
    }
    // 初始化侧滑的菜单列表
    private void initListDrawer() {
        // 下面初始化左侧菜单的列表视图
        lv_drawer_left = findViewById(R.id.lv_drawer_left);
        ArrayAdapter<String> left_adapter = new ArrayAdapter<>(this,
                R.layout.item_select, titleArray);
        lv_drawer_left.setAdapter(left_adapter);
        lv_drawer_left.setOnItemClickListener((parent, view, position, id) -> {
            String text = titleArray[position];
            tv_drawer_center.setText("这里是" + text + "页面");
            dl_layout.closeDrawers(); // 关闭所有抽屉
        });
        // 下面初始化右侧菜单的列表视图
        lv_drawer_right = findViewById(R.id.lv_drawer_right);
        ArrayAdapter<String> right_adapter = new ArrayAdapter<>(this,
                R.layout.item_select, settingArray);
        lv_drawer_right.setAdapter(right_adapter);
        lv_drawer_right.setOnItemClickListener((parent, view, position, id) -> {
            String text = settingArray[position];
            tv_drawer_center.setText("这里是" + text + "页面");
            dl_layout.closeDrawers(); // 关闭所有抽屉
        });
    }
    // 定义一个抽屉布局的侧滑监听器
    private class SlidingListener implements DrawerListener {
        // 在拉出抽屉的过程中触发
        @Override
        public void onDrawerSlide(View drawerView, float slideOffset) {}
        // 在侧滑抽屉打开后触发
        @Override
        public void onDrawerOpened(View drawerView) {
            if (drawerView.getId() == R.id.lv_drawer_left) {
                btn_drawer_left.setText("关闭左边侧滑");
            } else {
                btn_drawer_right.setText("关闭右边侧滑");
            }
        }
        // 在侧滑抽屉关闭后触发
        @Override
        public void onDrawerClosed(View drawerView) {
            if (drawerView.getId() == R.id.lv_drawer_left) {
                btn_drawer_left.setText("打开左边侧滑");
            } else {
                btn_drawer_right.setText("打开右边侧滑");
            }
        }
        // 在侧滑状态变更时触发
        @Override
        public void onDrawerStateChanged(int paramInt) {}
    }
}

XML文件

<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/dl_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >
            <Button
                android:id="@+id/btn_drawer_left"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:text="打开左边侧滑"
                android:textColor="@color/black"
                android:textSize="17sp" />
            <Button
                android:id="@+id/btn_drawer_right"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:text="打开右边侧滑"
                android:textColor="@color/black"
                android:textSize="17sp" />
        </LinearLayout>
        <TextView
            android:id="@+id/tv_drawer_center"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:gravity="top|center"
            android:paddingTop="30dp"
            android:text="这里是首页"
            android:textColor="@color/black"
            android:textSize="17sp" />
    </LinearLayout>
    <!-- 抽屉布局左边的侧滑列表视图,layout_gravity属性设定了它的对齐方式 -->
    <ListView
        android:id="@+id/lv_drawer_left"
        android:layout_width="150dp"
        android:layout_height="match_parent"
        android:layout_gravity="left"
        android:background="#ffdd99" />
    <!-- 抽屉布局右边的侧滑列表视图,layout_gravity属性设定了它的对齐方式 -->
    <ListView
        android:id="@+id/lv_drawer_right"
        android:layout_width="150dp"
        android:layout_height="match_parent"
        android:layout_gravity="right"
        android:background="#99ffdd" />
</androidx.drawerlayout.widget.DrawerLayout>

创作不易 觉得有帮助请点赞关注收藏~~~

相关文章
|
2天前
|
PHP
全新uniapp小说漫画APP小说源码/会员阅读/月票功能
价值980的uniapp小说漫画APP小说源码/会员阅读/月票功能
31 20
|
1天前
|
JSON 缓存 前端开发
HarmonyOS NEXT 5.0鸿蒙开发一套影院APP(附带源码)
本项目基于HarmonyOS NEXT 5.0开发了一款影院应用程序,主要实现了电影和影院信息的展示功能。应用包括首页、电影列表、影院列表等模块。首页包含轮播图与正在热映及即将上映的电影切换显示;电影列表模块通过API获取电影数据并以网格形式展示,用户可以查看电影详情;影院列表则允许用户选择城市后查看对应影院信息,并支持城市选择弹窗。此外,项目中还集成了Axios用于网络请求,并进行了二次封装以简化接口调用流程,同时添加了请求和响应拦截器来处理通用逻辑。整体代码结构清晰,使用了组件化开发方式,便于维护和扩展。 该简介概括了提供的内容,但请注意实际开发中还需考虑UI优化、性能提升等方面的工作。
31 11
|
5天前
|
机器学习/深度学习 前端开发 算法
婚恋交友系统平台 相亲交友平台系统 婚恋交友系统APP 婚恋系统源码 婚恋交友平台开发流程 婚恋交友系统架构设计 婚恋交友系统前端/后端开发 婚恋交友系统匹配推荐算法优化
婚恋交友系统平台通过线上互动帮助单身男女找到合适伴侣,提供用户注册、个人资料填写、匹配推荐、实时聊天、社区互动等功能。开发流程包括需求分析、技术选型、系统架构设计、功能实现、测试优化和上线运维。匹配推荐算法优化是核心,通过用户行为数据分析和机器学习提高匹配准确性。
28 3
|
29天前
|
移动开发 小程序
仿青藤之恋社交交友软件系统源码 即时通讯 聊天 微信小程序 App H5三端通用
仿青藤之恋社交交友软件系统源码 即时通讯 聊天 微信小程序 App H5三端通用
56 3
|
1月前
|
JSON JavaScript 前端开发
harmony-chatroom 自研纯血鸿蒙OS Next 5.0聊天APP实战案例
HarmonyOS-Chat是一个基于纯血鸿蒙OS Next5.0 API12实战开发的聊天应用程序。这个项目使用了ArkUI和ArkTS技术栈,实现了类似微信的消息UI布局、输入框光标处插入文字、emoji表情图片/GIF动图、图片预览、红包、语音/位置UI、长按语音面板等功能。
73 2
|
1月前
|
监控 安全 开发者
山东布谷科技:关于直播源码|语音源码|一对一直播源码提交App Store的流程及重构经验
分享提交直播源码,一对一直播源码,语音源码到Appstore的重构经验!
|
1月前
|
NoSQL 应用服务中间件 PHP
布谷一对一直播源码服务器环境配置及app功能
一对一直播源码阿里云服务器环境配置及要求
|
2月前
|
缓存 前端开发 Android开发
Android实战之如何截取Activity或者Fragment的内容?
本文首发于公众号“AntDream”,介绍了如何在Android中截取Activity或Fragment的屏幕内容并保存为图片。包括截取整个Activity、特定控件或区域的方法,以及处理包含RecyclerView的复杂情况。
27 3
|
1月前
|
机器人
布谷直播App系统源码开发之后台管理功能详解
直播系统开发搭建管理后台功能详解!
|
2月前
|
NoSQL PHP Redis
布谷语音app源码服务器环境配置及技术开发语言
布谷语音app源码服务器环境配置及技术语言研发。。