1. 程式人生 > >RecyclerView 選擇多個item的實現

RecyclerView 選擇多個item的實現

模仿網易新聞客戶端閱讀偏好的頻道選擇,先看實現的頁面:
這裡寫圖片描述
直接上程式碼:

import android.content.res.Resources;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
import
android.support.v7.widget.RecyclerView; import android.support.v7.widget.helper.ItemTouchHelper; import android.util.Log; import android.util.SparseBooleanArray; import android.view.View; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class RecyclerViewActivity
extends AppCompatActivity {
private RecyclerView recycler; private RecyclerAdapter mAdapter; private List<PreferCustomizableChannel> channels = new ArrayList<>(); private List<PreferCustomizableChannel> channelsSelected; @Override protected void onCreate(Bundle savedInstanceState) { super
.onCreate(savedInstanceState); setContentView(R.layout.activity_recycler_view_acitivity); initData(); initUI(); findViewById(R.id.resultBTN).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int lens = channelsSelected.size(); for (int i =0 ; i < lens; i++) { PreferCustomizableChannel customizableChannel = channelsSelected.get(i); if (customizableChannel.isSelected()) { Log.i("RecyclerViewActivity", "onClick: "+customizableChannel.toString()); } } } }); } private void initData() { Resources resources = getResources(); TypedArray array = resources.obtainTypedArray(R.array.prefer_channel_icon); int len = array.length(); String[] name = resources.getStringArray(R.array.prefer_channel_name); for (int i = 0; i < len; i++) { PreferCustomizableChannel customizableChannel = new PreferCustomizableChannel(); customizableChannel.setChannel(name[i]); customizableChannel.setResId(array.getResourceId(i, 0)); customizableChannel.setSelected(false); customizableChannel.setId(i * 100); channels.add(customizableChannel); } array.recycle(); channelsSelected = channels; } private void initUI() { recycler = (RecyclerView) findViewById(R.id.recycler); final GridLayoutManager manager = new GridLayoutManager(this, 3); recycler.setLayoutManager(manager); recycler.setHasFixedSize(true); recycler.setItemAnimator(new DefaultItemAnimator()); mAdapter = new RecyclerAdapter(RecyclerViewActivity.this, channels); recycler.setAdapter(mAdapter); mAdapter.setClickListener(new OnRecyclerViewItemClickListener() { @Override public void onItemClick(View view, int position) { SparseBooleanArray selecteds = mAdapter.getSelectedItem(); int len = channels.size(); for (int i = 0; i < len; i++) { if (selecteds.get(i)) { channelsSelected.get(position).setSelected(true); } } } }); } }

佈局檔案RecyclerView橫豎都是“match_parent”,否則在點選的時候gridView會自動上滑一段距離。

介面卡的實現:

import android.support.v7.widget.RecyclerView;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.entity.PreferCustomizableChannel;
import com.listener.OnRecyclerItemClickListener;

import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;

public class PreferChannelAdapter extends RecyclerView.Adapter<PreferChannelAdapter.PreferChannelHolder>{
    private List<PreferCustomizableChannel> lists;
    private OnRecyclerItemClickListener listener;
    private SparseBooleanArray selectLists = new SparseBooleanArray();

    public PreferChannelAdapter() {
    }

    public void setDatas(List<PreferCustomizableChannel> lists) {
        this.lists = lists;
        notifyDataSetChanged();
    }

    public void setOnItemClickListener(OnRecyclerItemClickListener listener) {
        this.listener = listener;
    }

    @Override
    public PreferChannelHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.prefer_channel_item, null);
        return new PreferChannelHolder(view);
    }

    @Override
    public void onBindViewHolder(final PreferChannelHolder holder, final int position) {
        PreferCustomizableChannel channelItem = lists.get(position);
        holder.channelItemTV.setText(channelItem.getChannel());
        holder.channelItemImg.setImageResource(channelItem.getResId());
        if (!selectLists.get(position)) {
            holder.selectedMarkImg.setVisibility(View.GONE);
        } else {
            holder.selectedMarkImg.setVisibility(View.VISIBLE);
        }
        holder.preferChannelItemLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (holder.selectedMarkImg.getVisibility() == View.GONE) {
                    holder.selectedMarkImg.setVisibility(View.VISIBLE);
                    selectLists.put(position, true);
                } else if (holder.selectedMarkImg.getVisibility() == View.VISIBLE){
                    holder.selectedMarkImg.setVisibility(View.GONE);
                    selectLists.put(position, false);
                }
                listener.onRecyclerClick(position);
            }
        });
    }

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

    public class PreferChannelHolder extends RecyclerView.ViewHolder {
        @BindView(R.id.preferChannelItemLayout)
        RelativeLayout preferChannelItemLayout;
        @BindView(R.id.channelItemTV)
        TextView channelItemTV;
        @BindView(R.id.channelItemImg)
        ImageView channelItemImg;
        @BindView(R.id.selectedMarkImg)
        ImageView selectedMarkImg;

        public PreferChannelHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }
    }

    public SparseBooleanArray getSelectedItem() {
        return selectLists;
    }
}

順便把item的佈局也貼出來吧:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/preferChannelItemLayout"
    android:gravity="center"
    android:layout_gravity="center"
    android:layout_marginTop="10dp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <!--android:gravity="center"
    android:layout_gravity="center"-->
    <ImageView
        android:id="@+id/channelItemImg"
        android:scaleType="centerInside"
        android:layout_width="68dp"
        android:layout_height="wrap_content"/>
    <TextView
        android:id="@+id/channelItemTV"
        android:gravity="center"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginBottom="20dp"
        android:layout_marginTop="8dp"
        android:layout_below="@id/channelItemImg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <ImageView
        android:id="@+id/selectedMarkImg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:visibility="gone"
        android:layout_alignRight="@id/channelItemImg"
        android:src="@mipmap/prefer_selected"/>
</RelativeLayout>

其他注意的地方:
SpareBooleanArrary.size()返回的是已經設定為true的長度,比如選擇了一個則返回1,選擇了10則返回10,但在選擇了10後去掉一個的時候,size()返回的並不是9,而依然是10,這點注意,所以在遍歷的時候並沒有使用使用size()取長度。