解决RecyclerView嵌套RecyclerView位移问题

博客详细描述了在Android开发中,如何解决RecyclerView嵌套使用时遇到的位移问题,包括垂直方向的首次加载位移和水平方向滑动后位置还原。通过设置焦点和监听滑动事件,结合LinearLayoutManager的方法,成功修复了这两个问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、概述
  最近项目中用到了两个RecyclerView嵌套的布局,即RecyclerView的item也是RecyclerView,其中遇到了两个比较典型的问题:1、当item的方向是垂直方向时,父RecyclerView首次加载会出现位移;2、当item的方向是水平方向时,父RecyclerView上下滑动之后,子RecyclerView位置会还原,本文主要解决以上两个问题。我们先来瞄一眼这两个问题的效果图:

修复前.gif

  可以明显的看到当item的Recyclerview是垂直方向时,打开页面时“title1”不见了;当item的Recyclerview是水平方向时,我们把 Inner Title1-x和 Inner Title2-x滑动一定距离之后,上下滑动父Recyclerview,Inner Title1-x和 Inner Title2-x的位置又还原了。

二、解决
  2.1 首先解决垂直嵌套问题,这个比较简单,主要是子Recyclerview抢占焦点导致,我们只需要让其父布局获取焦点即可解决,完整代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:gravity="center_vertical"
              android:orientation="vertical"
              android:paddingLeft="14dp"
              android:paddingRight="14dp"
              android:focusableInTouchMode="true"
              android:focusable="true"
    >

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="20dp"
        android:paddingBottom="20dp"
        android:layout_gravity="center_vertical"
        android:layout_marginRight="30dp"
        android:gravity="center"
        
### 解决RecyclerView无法响应按键事件 为了使`RecyclerView`能够正确处理按键事件,特别是当其中包含可交互组件(如`EditText`)时,可以采用以下几种方法: #### 方法一:自定义`FocusRecyclerView` 创建继承于`RecyclerView`的类,在该类中重写触摸监听器逻辑来增强其功能。这种方法允许更细粒度地控制子视图的行为。 ```java public class FocusRecyclerView extends RecyclerView { public FocusRecyclerView(Context context) { super(context); init(); } public FocusRecyclerView(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { addOnItemTouchListener(new OnItemTouchListener() { @Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { // 自定义拦截逻辑 return false; } @Override public void onTouchEvent(RecyclerView rv, MotionEvent e) {} @Override public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {} }); } } ``` 此方式使得可以通过`OnItemTouchListener`接口更好地管理触控流[^1][^2]。 #### 方法二:设置焦点变化监听器 对于特定场景下发生的键盘操作问题,比如点击回车键触发多次提交的情况,可以在`EditText`上注册一个特殊的监听器来进行过滤或调整行为模式。 ```java editText.setOnKeyListener((v, keyCode, event) -> { if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN){ // 防止重复触发 v.clearFocus(); InputMethodManager imm = (InputMethodManager)v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); // 执行单次提交动作... return true; // 表明已经消费掉这个事件 }else{ return false; } }); ``` 这段代码展示了如何阻止连续按下Enter键造成的多重反应,并隐藏软键盘[^3][^5]。 #### 方法三:优化UI刷新机制 有时由于快速更新界面而导致意外滚动现象发生,这可能是因为每次获得焦点都会尝试让列表移动到可见区域所致。为了避免这种情况,应该谨慎设计数据绑定过程中的通知策略以及布局参数配置。 ```xml <androidx.recyclerview.widget.RecyclerView ... android:nestedScrollingEnabled="false" /> ``` 禁用嵌套滚动可以帮助减少不必要的位移效果;另外也可以考虑延迟执行某些可能导致重新排列的操作直到用户完成编辑为止[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值