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

news2025/8/11 16:30:52

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

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

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>

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/15396.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

贴花、射线、动画通知——足迹01

案例实现效果&#xff1a; 人物跑步留下脚印&#xff08;其他运动留下脚印也是同理&#xff09;。 重点&#xff1a; 贴花的创建、射线、动画通知。射线碰撞决定贴花生成位置&#xff0c;动画通知决定贴花生成时间。 一、贴花 1、贴花纹理图 在网络上找素材&#xff08…

JavaSE之动态代理

目录动态代理动态代理的好处Proxy重写invoke方法实例最后动态代理 动态代理需要确定要代理的对象&#xff0c;所以需要先new一个要代理的对象 动态代理的好处 可以在不改变方法源码的情况下&#xff0c;实现对方法功能的增强。 简化了代码。 提高了软件系统的可扩展性。 P…

【TensorRT】神经网络中的量化

文章目录一、TensorRT 为什么需要量化二、基础内容三、神经网络的量化过程一、TensorRT 为什么需要量化 量化是什么&#xff1a;量化在数字信号处理领域&#xff0c;是指将信号的连续取值&#xff08;或者大量可能的离散取值&#xff09;近似为有限多个&#xff08;或较少的&a…

七彩动态|棱镜七彩获“北京国家金融科技认证中心”颁发的「金融开源技术服务商能力评估证书」

11月13日&#xff0c;由北京金融科技产业联盟举办的第二届会员大会第四次会议在北京召开。 聚焦开源应用与安全&#xff0c;棱镜七彩通过北京国家金融科技认证中心“金融业开源评估”—金融开源技术服务商能力评估&#xff0c;并获得由北京国家金融科技认证中心颁发的“金融开…

对梯度回传的理解

参考 对梯度回传的理解 - 云社区 - 腾讯云 神经网络的每一层可以看做是使用一个函数对变量的一次计算。在微分中链式法则用于计算复合函数的导数。反向传播时一种计算链式法则的算法&#xff0c;使用高效的特定运算顺序。 设x是实数&#xff0c;f和g是从实数映射到实数的函数。…

分享一个单片机GUI库,简洁,使用

1-介绍一下 先来几张图&#xff1a; 看着是不是还不错。这个是一个国外的爱好者开发的&#xff0c;笔者有次逛网站&#xff0c;搜GUI看到的没感觉还不错&#xff0c;今天特意给大家分享一下。 这个GUI是一个用于嵌入式系统的免费开源图形库。平台独立的&#xff0c;也就是说可…

OVN 流表基础 -- 基于 kubeOVN (二)

文章目录功能流表加 Pod加子网跨子网 pod 互访访问外部网络DHCP静态路由策略路由安全组DNATLBFullNAT LBService 扩展Src-ip LB功能流表 基于此模型配置功能&#xff0c;来查看流表变化&#xff0c;探讨功能实现方式。 加 Pod 流表添加&#xff1a; Datapath: "ovn-cl…

《Eolink 征文活动- -RESTful接口全解测试-全方位了解Eolink》

目录 Eolink平台首页 Eolink平台下载地址 一、自带环境示例【GET】|【POST】 示例项目&#xff1a; 完成Get请求示例&#xff1a; 完整POST请求示例&#xff1a; 二、自建接口测试【PUT】|【DELETE】 RESTful协议/方法 创建PUT&DELETE的API接口&#xff1a; PUT协…

【linux】虚拟化

linux虚拟化 文章目录linux虚拟化实验环境安装虚拟化服务安装虚拟机遇到报错效果虚拟机管理命令移植虚拟机虚拟机快照由快照创建虚拟机实验环境 1号虚拟机配置局域网镜像仓库&#xff0c;httpd服务2号虚拟机保证可以使用dnf搜索到1号的镜像仓库 安装虚拟化服务 查看是否支持v…

代码随想录刷题|动态规划理论基础 LeetCode 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯

目录 动态规划理论基础 509. 斐波那契数 思路 斐波那契数 递归思路 动态规划 动态规划(优化数组) 70. 爬楼梯 思路 爬楼梯 动态规划(优化数组) 动态规划(变量替代数组) 746. 使用最小花费爬楼梯 思路 使用最小花费爬楼梯 动态规划(使用数组) 动态规划(使用变量) 动态规划理论基…

顺风车用户最爱“送花”城市Top30 出炉,来看有没有你的家乡?

11月18日&#xff0c;嘀嗒小红花迎来“一周岁生日”&#xff0c;嘀嗒出行也于当日正式发布《嘀嗒小红花一周年出行人文报告》。《报告》显示&#xff0c;自2021年11月18日&#xff0c;嘀嗒出行“送你一朵小红花”产品功能上线至今&#xff0c;嘀嗒顺风车乘客已向车主送出239万朵…

商品720vr全景环物制作便捷推送到全世界

720vr全景的应用范围也得到了扩大和普及。VR全景作为新一代信息技术&#xff0c;相较于传统的图文视频等展现方式而言&#xff0c;VR全景不仅能够帮助用户随时随地身临其境的进行沉浸式体验&#xff0c;也可以帮助商家有效降低宣传推广成本。 720VR全景制作拍摄VR全景需要用到相…

德国药品数据库查询系统(含网址)

德国曾经有被誉为世界’医药基地’的称号。在2020年时德国药品出口额有近千亿美元&#xff0c;占世界药品出口总额的近七分之一&#xff0c;连续18年为居世界第一位&#xff0c;不仅仅是销量&#xff0c;德国生物医药行业在心脏、血液循环、糖尿病、癌症等疾病的研究、预防、基…

用Python计算点估计预测评价指标(误差指标RMSE、MSE、MAE、MAPE) ,画图展示

机器学习的回归问题常用RMSE&#xff0c;MSE, MAE,MAPE等评价指标&#xff0c;还有拟合优度R2。由于每次预测出来的预测值再去和原始数据进行误差评价指标的计算很麻烦&#xff0c;所以这里就直接给出他们五个指标的计算函数。把每次预测出来的值和真实值输入这个函数就可以得到…

对话钱江机器人丨国产化破风,谁动了工业机器人厂商的“奶酪”?

工业机器人的研发、制造和应用是衡量一国科技创新和高端制造水平的重要标志&#xff0c;是“制造业皇冠顶端的明珠”&#xff0c;亦是硬科技技术行列中的“课代表”。 《中国机器人产业发展报告&#xff08;2022年&#xff09;》预计&#xff0c;2022年全球机器人市场规模将达…

抗心血管疾病、内分泌信号通路等小分子化合物库介绍

心血管疾病 不少人认为经常熬夜&#xff0c;工作压力大是猝死的主要原因&#xff0c;其实猝死的根本原因是心血管突发病。 心血管疾病是心脏和血管疾病的统称&#xff0c;主要包括冠心病&#xff0c;脑血管疾病&#xff0c;周围末梢动脉血管疾病&#xff0c;先天性心脏病及深…

快速排序图文详细教程

文章目录 文章目录文章目录[toc]一、快排思路二、相关代码小细节改进版本一版本二一、快排思路 还记得之前的荷兰国旗问题吗&#xff08;快排的前身&#xff1a;详解荷兰国旗问题&#xff09;&#xff0c;快排其实就是借助这种思路&#xff0c;在每次遍历中以第一个数作为目标…

[模型部署]:深度学习模型部署(已更Pytorch篇)

模型部署一、Pytorch 模型部署1. 模型保存1.1. 使用torch.save()保存1.2. 使用[torch.jit.save()](https://pytorch.org/docs/stable/generated/torch.jit.save.html)保存2. 模型部署 or 模型编译2.1. TorchScript部署2.2. TensorRT部署2.3. TVM部署2.4. Laser部署模型部署 一…

STM32 GD32 标准库移植SFUD

本次移植是在官方源码的基础上进行移植的 本次介绍的两个软件包SFUD/FAL都与FLASH有关&#xff0c;并且都可以独立使用或者结合在一起使用&#xff0c;两个软件包都对操作系统无依赖&#xff0c;可以使用裸机移植&#xff0c;也很方便移植到各种系统。 这两个软件包的作者都是…

Java JDK安装与配置

Java JDK安装与配置 JDK下载 下载地址&#xff1a;JDK下载 最上方是JDK最新版&#xff0c;往下滑将看到最常用的稳定版本&#xff1a;JDK8 选择版本 勾上选框&#xff0c;点击下载 登录Oracle账号&#xff1a; 没有账号可注册或网上寻找账号&#xff0c;建议自行注册登录成功…