您的当前位置:首页正文

RecyclerView更新数据时焦点丢失(android bu

来源:华拓网

先看下效果:


device-2018-03-07-154357.gif

做车机项目时,需要动态更新WIFI信息,WIFI列表增加焦点控制

开发中遇到两个问题

  • RecyclerView抢占了item的焦点,导致不显示红色框框
  • RecyclerView刷新数据时焦点丢失
    (刷新前焦点位置比刷新后大于刷新后的数据大小,这样系统就会去找layout中可以获取的焦点的控件,可能不会是recyclerview,这时焦点就会消失掉;反之,则会在recyclerview的第一个位置)

先解决第一个问题:

第一步

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.yftech.myapplication.MainActivity"
    android:background="#000"
    android:orientation="vertical">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recy"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        ##表示当子控件不需要focus的时候,recyclerview才会去获取focus
        android:descendantFocusability="afterDescendants"
        />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:text="刷新数据"/>

</LinearLayout>

第二步

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    android:id="@+id/item"
    ##必须设置
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/list_selector">
    <TextView
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="@dimen/text_item_height"
        android:textColor="@android:color/white"
        android:gravity="left|center_vertical"
        android:textSize="@dimen/item_text_size"
        android:height="65dp"
        android:paddingLeft="30dp"
        ##指的是当前控件是否跟随父控件的(点击、焦点等)状态
        android:duplicateParentState="true"
        />
</LinearLayout>

搞定第一个问题!!!

重点解决第二个问题

1.adapter的setHasStableIds设置成true

adapter.setHasStableIds(true);

解释:设置item是否可以有一个id(具体意思可以百度)
2.重写adapter的getItemId方法

    @Override
    public long getItemId(int position) {
        return position;
    }

解释:给item生成一个id,用于定位焦点的
3.这两步已经可以保存recyclerview的焦点了,但是使用notify系列方法仍然会出现focus丢失的问题,现在官方已经承认这是一个bug,可以暂时使用禁用notifyDataSetChanged动画的方法来规避:

mRecyclerView.setItemAnimator(null);

搞定