RecyclerView的item的selected、click以及按键响应操作的简单demo

本文提供RecyclerView的item的selected、click以及按键响应操作的简单demo。介绍了在布局文件中定义RecyclerView,还提到HorizontalGridView特点;说明了定义RecyclerView适配器的相关代码,包括item点击、选中、按键事件接口;最后提及接口的实现。

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

                    RecyclerView的item的selected、click以及按键响应操作的简单demo

1、在布局文件中定义 RecyclerView。

<android.support.v17.leanback.widget.HorizontalGridView
    android:id="@+id/horizontal_gridView_channel_group"
    android:layout_width="match_parent"
    android:layout_height="160dp"
    android:layout_below="@+id/recyclerView_title"
    android:layout_marginStart="10dp"
    android:layout_marginTop="10dp">
</android.support.v17.leanback.widget.HorizontalGridView>

     HorizontalGridView是一个非常实用的水平方向的RecyclerView,它最大的特点就是焦点项始终是显示在正中间的位置。如下图中的Movies项。

2、定义RecyclerView的适配器

package com.amlogic.dvb_adapter;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.amlogic.DVBPlayer.R;
import com.amlogic.dvb_entity.GroupInfo;
import com.amlogic.dvb_interface.OnRecycleViewItemClickListener;
import com.amlogic.dvb_interface.OnRecycleViewItemSelectListener;
import com.amlogic.dvb_interface.OnRecyclerViewItemKeyListener;
import com.amlogic.dvb_util.ContactsUtil;
import com.amlogic.dvb_util.CornerUtil;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;

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

import static com.amlogic.DVBPlayer.AndroidNineMainMenu.CHANNEL_GROUP_RECYCLERVIEW_TAG;
import static com.amlogic.DVBPlayer.AndroidNineMainMenu.SETTINGS_HELP;
import static com.amlogic.DVBPlayer.AndroidNineMainMenu.SETTINGS_MYLIBRARY;
import static com.amlogic.DVBPlayer.AndroidNineMainMenu.SETTINGS_SYSTEM_ONLY;
import static com.amlogic.DVBPlayer.AndroidNineMainMenu.SETTINGS_USER_SETUP;
import static com.amlogic.DVBPlayer.AndroidNineMainMenu.TITLE_SETTINGS_ITEM;

public class ChannelGroupHorizontalGridViewAdapter extends RecyclerView.Adapter<ChannelGroupHorizontalGridViewHolder> {
    private OnRecycleViewItemSelectListener mOnItemSelectLister;
    private OnRecycleViewItemClickListener mOnItemClickLister;
    private OnRecyclerViewItemKeyListener mOnKeyListener;

    private List<GroupInfo> mGropuInfos;
    private Context mContext;
    private int current_title_index;

    private int[] textViewDefault = {R.drawable.txt_default_blue, R.drawable.txt_default_orange, R.drawable.txt_default_purple, R.drawable.txt_default_red, R.drawable.txt_default_yellow};
    private int[] imgViewDefault  = {R.drawable.img_default_blue, R.drawable.img_default_orange, R.drawable.img_default_purple, R.drawable.img_default_red, R.drawable.img_default_yellow};

    public ChannelGroupHorizontalGridViewAdapter(Context context, List<GroupInfo> groupInfos, int title_index) {
        if (mGropuInfos == null) {
            mGropuInfos = new ArrayList<>();
        }
        mGropuInfos.clear();
        mGropuInfos.addAll(groupInfos);

        current_title_index = title_index;
        mContext = context;
    }

    @NonNull
    @Override
    public ChannelGroupHorizontalGridViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.channel_recycleview_item, viewGroup, false);
        view.setTag(CHANNEL_GROUP_RECYCLERVIEW_TAG);
        ChannelGroupHorizontalGridViewHolder holder = new ChannelGroupHorizontalGridViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull ChannelGroupHorizontalGridViewHolder viewHolder, final int position) {
        ChannelGroupHorizontalGridViewHolder ViewHolder = (ChannelGroupHorizontalGridViewHolder) viewHolder;
        TextView textView = (TextView) ViewHolder.item_name;
        ImageView imageView = (ImageView) ViewHolder.item_background;

        textView.setText(mGropuInfos.get(position).getName());
        ContactsUtil.Set_TextView_Typeface(ContactsUtil.contextTypeFace, textView);

        if (mOnItemSelectLister != null) {
            viewHolder.itemView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
                @Override
                public void onFocusChange(View view, boolean hasFocus) {
                    mOnItemSelectLister.onItemSelected(view, position, hasFocus);
                }
            });
        }

        if (mOnItemClickLister != null) {
            viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    mOnItemClickLister.onItemClick(view, position);
                }
            });
        }

        if (mOnKeyListener != null) {
            viewHolder.itemView.setOnKeyListener(new View.OnKeyListener() {
                @Override
                public boolean onKey(View v, int keyCode, KeyEvent event) {
                    return mOnKeyListener.recyclerViewItemOnKey(v, keyCode, event, position);
                }
            });
        }

        Log.d("wujiang", "ChannelGroupHorizontalGridViewAdapter: current_title_index = " + current_title_index);

        if (current_title_index == TITLE_SETTINGS_ITEM) {
            textView.setBackgroundResource(R.drawable.translucent_background);
            switch (position) {
                case SETTINGS_HELP:
                    Glide.with(mContext).load(R.drawable.ic_help).placeholder(R.drawable.ic_help).into(imageView);
                    break;

                case SETTINGS_MYLIBRARY:
                    Glide.with(mContext).load(R.drawable.ic_my_library).placeholder(R.drawable.ic_my_library).into(imageView);
                    break;

                case SETTINGS_USER_SETUP:
                    Glide.with(mContext).load(R.drawable.ic_user_setup).placeholder(R.drawable.ic_user_setup).into(imageView);
                    break;

                case SETTINGS_SYSTEM_ONLY:
                    Glide.with(mContext).load(R.drawable.ic_settings).placeholder(R.drawable.ic_settings).into(imageView);
                    break;
            }
        } else {
            int index;
            if (position == 0) {
                index = 0;
            } else {
                index = position % textViewDefault.length;
            }

            Glide.with(imageView.getContext()).load(imgViewDefault[index]).placeholder(imgViewDefault[index]).into(imageView);
            textView.setBackgroundResource(textViewDefault[index]);
        }
    }

    @Override
    public void onViewRecycled(ChannelGroupHorizontalGridViewHolder holder) {
        if (holder != null) {
            Glide.clear(holder.item_background);
        }
        super.onViewRecycled(holder);
    }

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

    @Override
    public int getItemViewType(int position) {
        return 0;
    }

    public void setOnItemSelectListener(OnRecycleViewItemSelectListener listener) {
        mOnItemSelectLister = listener;
    }

    public void setOnItemClickLister(OnRecycleViewItemClickListener listener) {
        mOnItemClickLister = listener;
    }

    public void setOnKeyListener(OnRecyclerViewItemKeyListener listener) {
        mOnKeyListener = listener;
    }

    public void setGroupInfors(List<GroupInfo> groupInfors, int title_index) {
        if (mGropuInfos == null) {
            mGropuInfos = new ArrayList<>();
        }
        mGropuInfos.clear();
        mGropuInfos.addAll(groupInfors);
        current_title_index = title_index;

        notifyDataSetChanged();
    }
}

  channel_recycleview_item.xml代码

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="230dp"
    android:layout_height="140dp"
    android:clipChildren="false"
    android:clipToPadding="false"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:gravity="center"
    android:paddingLeft="10dp"
    android:paddingTop="10dp">

    <RelativeLayout
        android:id="@+id/rl_item"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/transparent_yellow_view_selector"
        android:duplicateParentState="true"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/image"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="1.3dp"
            android:duplicateParentState="true"
            android:scaleType="fitXY" />

        <TextView
            android:id="@+id/textview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:duplicateParentState="true"
            android:gravity="bottom|center_horizontal"
            android:layout_margin="1.3dp"
            android:paddingBottom="6dp"
            android:textColor="@drawable/nine_listview_textcolor_selector_02"
            android:textSize="20dp" />
    </RelativeLayout>
</RelativeLayout>

       要让最外层的RelativeLayout拥有获取焦点的权利,于是给它加上android:focusable="true"属性。子控件如果想保持和父控件一样的状态(焦点状态时子控件不是真正获取了焦点),加上android:duplicateParentState="true"属性即可。例如上面id为textview的TextView,它的textColor是一个drawable,它里面定义了有焦点状态和无焦点状态时字体的颜色:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:color="@color/yellow" android:state_selected="true" />

    <item android:color="@color/yellow" android:state_focused="true" />

    <item android:color="@color/white" android:state_focused="false" />

    <item android:color="@color/white" />
</selector>

  ChannelGroupHorizontalGridViewHolder.java代码

package com.amlogic.dvb_adapter;

import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import com.amlogic.DVBPlayer.R;
import com.amlogic.dvb_util.CornerUtil;

public class ChannelGroupHorizontalGridViewHolder extends RecyclerView.ViewHolder {
    public TextView item_name;
    public ImageView item_background;

    public ChannelGroupHorizontalGridViewHolder(View view) {
        super(view);
        item_name = (TextView) view.findViewById(R.id.textview);
        item_background = (ImageView) view.findViewById(R.id.image);

        //切圆角(在我博客可以找到这个工具类)
        CornerUtil.clipViewCornerByDp(item_name, 8);
        CornerUtil.clipViewCornerByDp(item_background, 8);
    }
}

  OnRecycleViewItemClickListener.java代码,item点击事件接口。

package com.amlogic.dvb_interface;

import android.view.View;

public interface OnRecycleViewItemClickListener {
    void onItemClick(View view,int position);
}

  OnRecycleViewItemSelectListener.java代码,item选中事件接口。

package com.amlogic.dvb_interface;

import android.view.View;

public interface OnRecycleViewItemSelectListener {
    void onItemSelected(View view, int position, boolean hasFocus);
}

  OnRecyclerViewItemKeyListener.java代码,item按键事件接口。

package com.amlogic.dvb_interface;

import android.view.KeyEvent;
import android.view.View;

//这里特意带上了position,可以做一些位置的判断
public interface OnRecyclerViewItemKeyListener {
    boolean recyclerViewItemOnKey(View view, int keyCode, KeyEvent event, int position);
}

3、接口的实现。

     上面的代码是我自己项目里的,我们只需要关注焦点选中、点击、按键事件的相关代码。

mChannelGroupHorizontalGridView = getView().findViewById(R.id.horizontal_gridView_channel_group);
mChannelGroupHorizontalGridViewAdapter = new ChannelGroupHorizontalGridViewAdapter(mDVBPlayer, mChannelGroupInfoList, TITLE_MAIN_ITEM);
initChannelGroupHorizontalGridViewListener();
mChannelGroupHorizontalGridView.setAdapter(mChannelGroupHorizontalGridViewAdapter);

  initChannelGroupHorizontalGridViewListener中实现了选中、click、按键接口。

private void initChannelGroupHorizontalGridViewListener() {
        //item选中事件
        mChannelGroupHorizontalGridViewAdapter.setOnItemSelectListener(new OnRecycleViewItemSelectListener() {
            @Override
            public void onItemSelected(View view, int position, boolean hasFocus) {
                mSettingsTitleRecyclerViewCurrentPosition = position;

                ObjectAnimator animator1;
                ObjectAnimator animator2;
                if(hasFocus == true) {
                    Log.d("wujiang", "initChannelGroupHorizontalGridViewListener onItemSelected: 1 position = " + position);

                    animator1 = ObjectAnimator.ofFloat(view, "scaleX", 1f, 1.05f);
                    animator2 = ObjectAnimator.ofFloat(view, "scaleY", 1f, 1.05f);
                } else {
                    Log.d("wujiang", "initChannelGroupHorizontalGridViewListener onItemSelected: 2 position = " + position);
                    animator1 = ObjectAnimator.ofFloat(view, "scaleX", 1.05f, 1f);
                    animator2 = ObjectAnimator.ofFloat(view, "scaleY", 1.05f, 1f);
                }

                AnimatorSet animSet = new AnimatorSet();
                animSet.setDuration(200);
                animSet.playTogether(animator1, animator2);
                animSet.start();
            }
        });

        //按键事件
        mChannelGroupHorizontalGridViewAdapter.setOnKeyListener(new OnRecyclerViewItemKeyListener() {
            @Override
            public boolean recyclerViewItemOnKey(View view, int keyCode, KeyEvent event, int position) {
                if (event.getAction() == KeyEvent.ACTION_UP) {
                    return false;
                }

                switch (keyCode) {
                    case KeyEvent.KEYCODE_DPAD_DOWN:
                            return true;
                        }
                        return false;
                }
                return false;
            }
        });

        //item click事件
        mChannelGroupHorizontalGridViewAdapter.setOnItemClickLister(new OnRecycleViewItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                Log.d("wujiang", "initChannelGroupHorizontalGridViewListener onItemClick: position = " + position);
            }
        });
    }

  如果觉得可以,给个赞吧!

                                                                                            THE  END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值