频道澳门葡京手机版网址
登录注册
澳门葡京手机版网址 > 澳门葡京手机版网址 > 移动开发 > 其他 > 正文
RecyclerView详细先容(二)
2016-11-11 10:52:09      个评论    来源:sammy的专栏  
收藏   我要投稿

1. 前言

RecyclerView 没有提供类似ListView的setOnItemClickListener方法,所以只有大家自己为RecyclerView添加点击事件, 本篇文章主要先容如何添加点击事件,进行Item增加和删除,并且解决RecycleView Adapter使用notifyItemRemoved和notifyItemInserted造成Position混乱的问题。

2.添加点击事件

1)在Adapter中创建一个实现点击接口:

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

2)在Adapter中添加接口设置方法:

private OnItemClickLitener mOnItemClickListener = null;

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

3)触发itemClick回调代码:

@Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.mTextView.setText(data.get(position));
        holder.mTextView.setTag(holder.getLayoutPosition());
        holder.mTextView.setOnClickListener(this);
    }
@Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.item_text:
                mOnItemClickListener.onItemClick(v, (int) v.getTag());
                break;
        }
    }

4)activity中注册接口到Adapter中:

public class ItemClickListViewActivity extends AppCompatActivity {

    /**
     * view
     */
    private RecyclerView recyclerView;

    /**
     * 用来确定每一个item如何进行排列摆放,何时展示和隐藏
     */
    private LinearLayoutManager layoutManager;

    /**
     * 适配器
     */
    private MyItemClickAdapter mAdapter;

    private ArrayList data = new ArrayList();

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

        initView();
        initData();
    }

    /**
     * 初始化布局组件
     */
    private void initView() {
        recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        //创建默认的线性LayoutManager
        layoutManager = new LinearLayoutManager(this);
//        layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        recyclerView.setLayoutManager(layoutManager);
        //如果可以确定每个item的高度是固定的,设置这个选项可以提高性能
        recyclerView.setHasFixedSize(true);
    }

    /**
     * 初始化数据
     */
    private void initData() {
        for (int i = 0; i < 100; i++) {
            data.add(i + "--->click");
        }
        //创建并设置Adapter
        mAdapter = new MyItemClickAdapter(data);
        recyclerView.setAdapter(mAdapter);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        mAdapter.setOnItemClickListener(new MyItemClickAdapter.OnItemClickLitener() {
            @Override
            public void onItemClick(View view, int position) {
                if(position ==2){
                    mAdapter.addItem("add click", 4);
                    Toast.makeText(ItemClickListViewActivity.this, "增加数据" + position, Toast.LENGTH_SHORT).show();
                }else if(position ==3) {
                    mAdapter.removeItem(2);
                    Toast.makeText(ItemClickListViewActivity.this, "删除数据" + position, Toast.LENGTH_SHORT).show();
                }else{

                    Toast.makeText(ItemClickListViewActivity.this, "选中" + position, Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

以上代码就可以为RecyclerView添加item点击事件了。

3.Item增加和删除

在adpater中增加如下两个方法:
1)添加数据:

public void addItem(String content, int position) {
        data.add(position, content);
        notifyItemInserted(position);
    }

2)删除数据:

public void removeItem(int position) {
        data.remove(position);
        notifyItemRemoved(position);
    }

activity中调用上面两个方法,实现增加跟删除item

mAdapter.setOnItemClickListener(new MyItemClickAdapter.OnItemClickLitener() {
            @Override
            public void onItemClick(View view, int position) {
                if(position ==2){
                    mAdapter.addItem("add click", 4);
                    Toast.makeText(ItemClickListViewActivity.this, "增加数据" + position, Toast.LENGTH_SHORT).show();
                }else if(position ==3) {
                    mAdapter.removeItem(2);
                    Toast.makeText(ItemClickListViewActivity.this, "删除数据" + position, Toast.LENGTH_SHORT).show();
                }else{

                    Toast.makeText(ItemClickListViewActivity.this, "选中" + position, Toast.LENGTH_SHORT).show();
                }
            }
        });

4.解决增加或者删除position混乱的问题:

照谷歌文档描述在使用了notifyItemInserted时候原来位置的position会加1,但是事实证明数据的position位置毫无变化,暂且认为google工程师的错误吧,但是大家还是要继续使用。一般有两种解决办法:
1)保留删除跟添加动画效果:notifyItemRemoved(position);notifyItemInserted(position);从源码可以看出,他只是刷新当前插入或者删除的item,不会触发onBindViewHolder,所以插入或者删除的item的下方的item的postion会有混乱。所以大家手动来刷新,代码如下:

public void removeItem(int position) {
        data.remove(position);
        notifyItemRemoved(position);
        // 加入如下代码保证position的位置正确性
        if (position != data.size() - 1) {
            notifyItemRangeChanged(position, data.size() - position);
        }
    }

    public void addItem(String content, int position) {
        data.add(position, content);
        notifyItemInserted(position);
        // 加入如下代码保证position的位置正确性
        if (position != data.size() - 1) {
            notifyItemRangeChanged(position, data.size() - position);
        }
    }

2)去掉动画:直接使用notifyDataSetChanged();因为使用notifyDataSetChanged();后,动画则消失了。

public void removeItem(int position) {
        data.remove(position);
        notifyItemRemoved(position);
        notifyDataSetChanged();
    }

    public void addItem(String content, int position) {
        data.add(position, content);
        notifyItemInserted(position);
        notifyDataSetChanged();
    }

5.完整代码

activity代码:

package com.test.recyclerview.itemclick;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Toast;

import com.test.recyclerview.R;

import java.util.ArrayList;

public class ItemClickListViewActivity extends AppCompatActivity {

    /**
     * view
     */
    private RecyclerView recyclerView;

    /**
     * 用来确定每一个item如何进行排列摆放,何时展示和隐藏
     */
    private LinearLayoutManager layoutManager;

    /**
     * 适配器
     */
    private MyItemClickAdapter mAdapter;

    private ArrayList data = new ArrayList();

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

        initView();
        initData();
    }

    /**
     * 初始化布局组件
     */
    private void initView() {
        recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        //创建默认的线性LayoutManager
        layoutManager = new LinearLayoutManager(this);
//        layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        recyclerView.setLayoutManager(layoutManager);
        //如果可以确定每个item的高度是固定的,设置这个选项可以提高性能
        recyclerView.setHasFixedSize(true);
    }

    /**
     * 初始化数据
     */
    private void initData() {
        for (int i = 0; i < 100; i++) {
            data.add(i + "--->click");
        }
        //创建并设置Adapter
        mAdapter = new MyItemClickAdapter(data);
        recyclerView.setAdapter(mAdapter);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        mAdapter.setOnItemClickListener(new MyItemClickAdapter.OnItemClickLitener() {
            @Override
            public void onItemClick(View view, int position) {
                if(position ==2){
                    mAdapter.addItem("add click", 4);
                    Toast.makeText(ItemClickListViewActivity.this, "增加数据" + position, Toast.LENGTH_SHORT).show();
                }else if(position ==3) {
                    mAdapter.removeItem(2);
                    Toast.makeText(ItemClickListViewActivity.this, "删除数据" + position, Toast.LENGTH_SHORT).show();
                }else{

                    Toast.makeText(ItemClickListViewActivity.this, "选中" + position, Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

adapter代码:

package com.test.recyclerview.itemclick;

import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.test.recyclerview.R;

import java.util.ArrayList;


public class MyItemClickAdapter extends RecyclerView.Adapter implements View.OnClickListener {
    private OnItemClickLitener mOnItemClickListener = null;

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

    private ArrayList data;

    public MyItemClickAdapter(ArrayList data) {
        this.data = data;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.activity_item, viewGroup, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.mTextView.setText(data.get(position));
        holder.mTextView.setTag(holder.getLayoutPosition());
        holder.mTextView.setOnClickListener(this);
    }

    @Override
    public int getItemCount() {
        return data == null ? 0 : data.size();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.item_text:
                mOnItemClickListener.onItemClick(v, (int) v.getTag());
                break;
        }
    }

    //自定义的ViewHolder,持有每个Item的的所有界面元素
    public static class ViewHolder extends RecyclerView.ViewHolder {
        public TextView mTextView;

        public ViewHolder(View view) {
            super(view);
            mTextView = (TextView) view.findViewById(R.id.item_text);
        }
    }

    public void removeItem(int position) {
        data.remove(position);
        notifyItemRemoved(position);
        // 加入如下代码保证position的位置正确性
        if (position != data.size() - 1) {
            notifyItemRangeChanged(position, data.size() - position);
        }
    }

    public void addItem(String content, int position) {
        data.add(position, content);
        notifyItemInserted(position);
        // 加入如下代码保证position的位置正确性
        if (position != data.size() - 1) {
            notifyItemRangeChanged(position, data.size() - position);
        }
    }

    public interface OnItemClickLitener {
        void onItemClick(View view, int position);
    }
}
点击复制链接 与好友分享!回澳门葡京手机版网址澳门葡京手机版网址
相关TAG标签 RecyclerView
上一篇:Graphics2D实现动态效果
下一篇:Zxing扫描和生成二维码+butterknife8.0之后的引用
相关文章
图文推荐

关于大家 | 联系大家 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 澳门葡京手机版网址_澳门新莆京娱乐_www.88807.com - 点此进入--致力于做实用的IT技术学习网站

XML 地图 | Sitemap 地图