搬砖搬砖。笔记迁移,笔记迁移,继续把有道云笔记的东西搬到CSDN。

作为一个小白程序员,虽然知道RecyclerView功能比较强大,可以说RecyclerView 是一个增强版的ListView,但是总是懒得把ListView和GridView换成RecyclerView。趁着码博客,哦不,复制粘贴!重新梳理一下RecyclerView的使用。

1.导包。

android recyclerview 中间大 recyclerview addview_android


2.简单使用

既然踩过坑,我们第一步先看下RecyclerView的Adapter。这里最大的改进就是对ViewHolder进行了封装,我们只需要自定义一个ViewHolder继承RecyclerView.ViewHolder就可以。并且Adapter继承RecyclerView.Adapter。加载条目布局在onCreatViewHolder,在onBindViewHolder中将视图与数据进行绑定。

上代码。

/**
 * 作 者:黑马小杰
 * 时 间:2017/6/18
 * 邮 箱:598214297@qq.com
 */
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {
    private List<String> mlist;

    public RecyclerAdapter(List<String> mlist) {
        this.mlist = mlist;
    }

    /**
     * 删除子项目并刷新
     *
     * @param position 删除数据的位置
     */
    private void removeData(int position) {
        mlist.remove(position);
        notifyItemChanged(position);
    }


    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycler_sensor, parent, false);
        MyViewHolder holder = new MyViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.tv_item_sensor.setText(mlist.get(position));
    }


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

    class MyViewHolder extends RecyclerView.ViewHolder {
        TextView tv_item_sensor;

        public MyViewHolder(View itemView) {
            super(itemView);
            tv_item_sensor = itemView.findViewById(R.id.tv_item_sensor);
        }
    }
}

我们在HomeAdapter的onCreatViewHolder方法中加载了自定义的样式文件itm_recycler_sensor,其中放入了一个TextView——id为tv_item_sensor

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
<TextView
    android:id="@+id/tv_item_sensor"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />
</LinearLayout>



另外我们发现,在adapter中有了ViewHolder的新概念,不引入Context,避免因为页面状态切换,使context为空,所引起的内存泄露,赞!

然后看一下主界面。

private void setRecycle() {
        list.add("1");
        list.add("2");
        list.add("3");
        //设置布局管理器 LinearLayoutManager表示线性排列
        recycler_sensor_list.setLayoutManager(new LinearLayoutManager(HwApplication.getContext()));
        //设置item和删除时的动画
        recycler_sensor_list.setItemAnimator(new DefaultItemAnimator());
        recycler_sensor_list.setAdapter(new RecyclerAdapter(list));
    }

LinearManager表示RecyclerView为线性布局,那么究竟是垂直还是水平呢?我们点进去看看。

android recyclerview 中间大 recyclerview addview_ViewHolder_02

从源码中可以看出,默认的线性布局为竖直,那么我们也可以改成水平布局。

LinearLayoutManager layoutManager= new LinearLayoutManager(HwApplication.getContext());
        layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        //设置布局管理器 LinearLayoutManager表示线性排列
        recycler_sensor_list.setLayoutManager(layoutManager);

OK,这样就改为水平布局了,完成~

因为我们的子布局仅仅需要展示一个TextView,所以这次只传入一个泛型为String的List,如果item需要更为复杂的展示效果,建议传入一个实体bean,这样会更加合理跟清晰。

3.子布局点击事件

 恩,有点麻烦,item点击事件需要自己定义。老套路,回调接口。首先在adapter定义回调接口。定义俩个点击事件——长/短按。

OnItemClickListener mOnItemClickListener;

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

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

item中定义点击事件监听,开启回调函数。

@Override
    public void onBindViewHolder(final MyViewHolder holder, int position) {
        holder.tv_item_sensor.setText(mlist.get(position).getmName());
        if (mOnItemClickListener != null)
        {
            holder.tv_item_sensor.setOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View v)
                {
                    int pos = holder.getLayoutPosition();
                    mOnItemClickListener.onItemClick(holder.tv_item_sensor,pos);
                }
            });
            holder.tv_item_sensor.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View view) {
                    int pos = holder.getLayoutPosition();
                    mOnItemClickListener.onItemLongClick(holder.tv_item_sensor,pos);
                    return false;
                }
            });
        }
    }

在主布局中应用也很简单。

recyclerSensorAdapter.setOnItemClickListener(new RecyclerSensorAdapter.OnItemClickListener() {
    @Override
    public void onItemClick(View view, int position) {
        Toast.makeText(getInstance().getActivity(), "点击第" + (position + 1) + "条", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onItemLongClick(View view, final int position) {
        new AlertDialog.Builder(getInstance().getActivity())
                .setTitle("留恋么?")
                .setNegativeButton("取消", null)
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        recyclerSensorAdapter.removeData(position);
                    }
                })
                .show();
    }
});

就是这么简单,搞定。

3.Gridview的实现如何?

我们现在不满足与简单的线性布局了,跟ListView一样没有新意。加上GridView试试看吧。

// LinearLayoutManager layoutManager = new LinearLayoutManager(HwApplication.getContext());
        StaggeredGridLayoutManager gridLayoutManager=new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL);
        //设置为水平
        //  layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        //设置布局管理器 LinearLayoutManager表示线性排列
        recycler_sensor_list.setLayoutManager(gridLayoutManager);

这样一完成了N行4列的布局。