RecyclerView使用

  1. 添加库
    搜索 recyclerview
    在这里插入图片描述
  2. 重写 RecyclerView ,记录焦点移出recyclerview的位置。
    文件 FocusKeepRecyclerView
package com.app.changhong.syssetting.home.lables;

import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;


import java.util.ArrayList;

class FocusKeepRecyclerView extends RecyclerView {

    private static final String TAG = FocusKeepRecyclerView.class.getSimpleName();
    //是否可以纵向移出
    private boolean mCanFocusOutVertical = true;
    //是否可以横向移出
    private boolean mCanFocusOutHorizontal = true;
    //焦点移出recyclerview的事件监听
    private FocusLostListener mFocusLostListener;
    //焦点移入recyclerview的事件监听
    private FocusGainListener mFocusGainListener;
    //默认第一次选中第一个位置
    private int mCurrentFocusPosition = 0;

    public FocusKeepRecyclerView(Context context) {
        this(context, null);
    }

    public FocusKeepRecyclerView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FocusKeepRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
        setChildrenDrawingOrderEnabled(true);
        setItemAnimator(null);
        this.setFocusable(true);
    }


    public boolean isCanFocusOutVertical() {
        return mCanFocusOutVertical;
    }

    public void setCanFocusOutVertical(boolean canFocusOutVertical) {
        mCanFocusOutVertical = canFocusOutVertical;
    }

    public boolean isCanFocusOutHorizontal() {
        return mCanFocusOutHorizontal;
    }

    public void setCanFocusOutHorizontal(boolean canFocusOutHorizontal) {
        mCanFocusOutHorizontal = canFocusOutHorizontal;
    }

    @Override
    public View focusSearch(int direction) {
        return super.focusSearch(direction);
    }

    //覆写focusSearch寻焦策略
    @Override
    public View focusSearch(View focused, int direction) {
        Log.i(TAG, "focusSearch " + focused + ",direction= " + direction);
        View view = super.focusSearch(focused, direction);
        if (focused == null) {
            return view;
        }

        if (view != null) {
            //该方法返回焦点view所在的父view,如果是在recyclerview之外,就会是null.所以根据是否是null,来判断是否是移出了recyclerview
            View nextFocusItemView = findContainingItemView(view);
            if (nextFocusItemView == null) {
                if (!mCanFocusOutVertical && (direction == View.FOCUS_DOWN || direction == View.FOCUS_UP)) {
                    //屏蔽--焦点纵向移出recyclerview,直接返回当前焦点
                    return focused;
                }
                if (!mCanFocusOutHorizontal && (direction == View.FOCUS_LEFT || direction == View.FOCUS_RIGHT)) {
                    //屏蔽--焦点横向移出recyclerview,直接返回当前焦点
                    return focused;
                }
                //调用移出的监听
                if (mFocusLostListener != null) {
                    mFocusLostListener.onFocusLost(focused, direction);
                }
                return view;
            }
        }
        return view;
    }

    public void setFocusLostListener(FocusLostListener focusLostListener) {
        this.mFocusLostListener = focusLostListener;
    }

    public interface FocusLostListener {
        void onFocusLost(View lastFocusChild, int direction);
    }

    public void setGainFocusListener(FocusGainListener focusListener) {
        this.mFocusGainListener = focusListener;
    }


    public interface FocusGainListener {
        void onFocusGain(View child, View focued);
    }

    @Override
    public void requestChildFocus(View child, View focused) {
        Log.i(TAG, "nextchild= " + child + ",focused = " + focused);
        if (!hasFocus()) {
            //recyclerview 子view 重新获取焦点,调用移入焦点的事件监听
            if (mFocusGainListener != null) {
                mFocusGainListener.onFocusGain(child, focused);
            }
        }
        super.requestChildFocus(child, focused);//执行过super.requestChildFocus之后hasFocus会变成true
        mCurrentFocusPosition = getChildViewHolder(child).getAdapterPosition();
        Log.i(TAG,"focusPos = "+mCurrentFocusPosition);
    }

    //实现焦点记忆的关键代码
    @Override
    public void addFocusables(ArrayList<View> views, int direction, int focusableMode) {
        View view = null;
        if (this.hasFocus() || mCurrentFocusPosition < 0 || (view = getLayoutManager().findViewByPosition(mCurrentFocusPosition)) == null) {
            super.addFocusables(views,direction,focusableMode);
        }else if(view.isFocusable()){
            //将当前的view放到Focusable views列表中,再次移入焦点时会取到该view,实现焦点记忆功能
            views.add(view);
        }else{
            super.addFocusables(views,direction,focusableMode);
        }
    }


    /**
     * 控制当前焦点最后绘制,防止焦点放大后被遮挡
     * 原顺序123456789,当4是focus时,绘制顺序变为123567894
     * @param childCount
     * @param i
     * @return
     */
    @Override
    protected int getChildDrawingOrder(int childCount, int i) {
        View focusedChild = getFocusedChild();
        Log.i(TAG,"focusedChild ="+focusedChild);
        if(focusedChild== null){
            return super.getChildDrawingOrder(childCount, i);
        }else{
            int index = indexOfChild(focusedChild);
            Log.i(TAG, " index = " + index + ",i=" + i + ",count=" + childCount);
            if(i == childCount-1){
                return index;
            }
            if(i<index){
                return i;
            }
            return i+1;
        }
    }
}

  1. adapter 文件 HomeLablesAdapterView
package com.app.changhong.sysseting.home.lables;

import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v7.widget.RecyclerView;
import android.util.ArrayMap;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.app.changhong.sysseting.R;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class HomeLablesAdapterView extends RecyclerView.Adapter<HomeLablesAdapterView.VH> {
    private final static String TAG = HomeLablesAdapterView.class.getSimpleName();
    public final static String HOME_LABLE_NAME = "HOME_LABLE_NAME_title";
    public final static String HOME_LABLE_FRAGMENT = "HOME_LABLE_NAME_fragment";
    List<Map<String, Object>> homeLableMapList = new ArrayList<>();

    public void addHomeLable(String homeLable, Fragment fragment) {
        Map<String ,Object> map = new ArrayMap<>();
        map.put(HomeLablesAdapterView.HOME_LABLE_NAME, homeLable);
        map.put(HomeLablesAdapterView.HOME_LABLE_FRAGMENT, fragment);
        homeLableMapList.add(map);
    }

    @NonNull
    @Override
    public VH onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.layout_home_lable_recyclerview_item, viewGroup, false);
        view.getLayoutParams().width = viewGroup.getWidth()/getItemCount();  //一行平分宽度
//        view.getLayoutParams().height= viewGroup.getHeight();
//        Log.e(TAG, ""+viewGroup.getHeight()+"  "+viewGroup.getWidth());
        return new VH(view);
    }

    @Override
    public void onBindViewHolder(@NonNull VH vh, int i) {
        vh.textView.setText((String) homeLableMapList.get(i).get(HOME_LABLE_NAME));
    }

    @Override
    public int getItemCount() {
        return homeLableMapList.size();
    }

    public class VH extends RecyclerView.ViewHolder {
        TextView textView;
        public VH(@NonNull View itemView) {
            super(itemView);
            textView = itemView.findViewById(R.id.text);
            itemView.setFocusable(true);
        }
    }
}

  1. activity 文件 MainActivity
package com.app.changhong.sysseting;

import android.app.Activity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.widget.LinearLayout;

import com.app.changhong.sysseting.home.lables.FocusKeepRecyclerView;
import com.app.changhong.sysseting.home.lables.HomeLablesAdapterView;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class MainActivity extends Activity {
    private final static String TAG = MainActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FocusKeepRecyclerView focusKeepRecyclerView = findViewById(R.id.home_lables_recycler_view);

        HomeLablesAdapterView homeLablesAdapterView  = new HomeLablesAdapterView();
        homeLablesAdapterView.addHomeLable("test0", null);
        homeLablesAdapterView.addHomeLable("test1", null);
        homeLablesAdapterView.addHomeLable("test2", null);

        focusKeepRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
        focusKeepRecyclerView.setAdapter(homeLablesAdapterView);
    }
}
  1. activity 布局文件 activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">

    <com.app.changhong.sysseting.home.lables.FocusKeepRecyclerView
        android:id="@+id/home_lables_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="50dp">
    </com.app.changhong.sysseting.home.lables.FocusKeepRecyclerView>

    <FrameLayout
        android:id="@+id/frame_layout_fragment_home"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#4e4545">
    </FrameLayout>
</LinearLayout>
  1. item 布局文件 layout_home_lable_recyclerview_item.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/text"
    android:background="@drawable/maker_btn_home_lable"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:gravity="center">
</TextView>

猜你喜欢

转载自blog.csdn.net/liuyj_vv/article/details/88634534