运行有问题或需要源码请 点赞关注收藏后评论区留言~~~
一、上下滚动与左右滑动的冲突处理
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>
创作不易 觉得有帮助请点赞关注收藏~~~