[Android]关于RecyclerView控件的使用

来源:互联网 发布:java连接url账号密码 编辑:程序博客网 时间:2024/05/02 03:06

最近在研究android中瀑布流视图的实现方法,我第一次看到这种视图是在一款视频App上,名叫bilibili手机客户端,非常喜欢这款App,它的界面十分漂亮,与用户的交互性很高。以下就是这款App瀑布流视图的截图

 

 

查阅相关资料,我了解到了这种瀑布流效果可以借助一款新的android控件来实现,这款控件在android-support-v7包中,大名就叫做RecyclerView。可以说,RecyclerView的确是款挺强大的控件,它不仅可以取代ListView,完成数据列表形式的展示,还能做到像瀑布流或表格这样的布局风格,巧妙的是,这些布局风格的切换仅仅需要一行代码就能实现,方便快捷。

与传统的ListView相比,RecyclerView增加了ViewHolder特性,这对于列表视图优化的实现便捷了许多。传统ListView实现优化一般是采用自己编写ViewHolder的形式,通过可复用视图(convertView)的setTag()getTag()方法传递ViewHolder,当adapter每次创建item视图( getView() )的时候直接修改ViewHolder中已经定义好的控件的属性,避免了每次在创建item视图( getView() )时都调用findViewById(),从而达到优化的效果。而RecyclerView则自带了ViewHolder,设置起来也十分简单,所以在代码优化的方面比起ListView便捷了不少。

      话不多说,以下就展示这款强大控件的使用吧!

首先是引包,因为我使用的是Android Studio,所以导包的方式为:

File-->Project Structure打开项目结构面板,然后按照下方截图所示即可导入RecyclerView包:

       


 

 

导好包后下面就进行代码的编写,以下是数据和RecyclerView的初始化:

  private void initData() {        this.mData = new ArrayList<>();        mAdapter = new ContentViewAdapter(this.mData,getApplicationContext());        for(int i = 'A';i<'z';i++)        {            Map<String,String> map = new HashMap<>();            map.put("name",(char)i+"");            map.put("intro",i+"");            this.mData.add(map);        }    }    private void initView(RecyclerView.LayoutManager manager) {        this.contentView = (RecyclerView) this.findViewById(R.id.id_content_view);                /*设置Adapter*/        this.contentView.setAdapter(this.mAdapter);        /*设置recyclerView中item增减的动画效果*/        this.contentView.setItemAnimator(new DefaultItemAnimator());        /*设置布局*/        this.contentView.setLayoutManager(manager);          //manager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL)    }


上方有涉及到RecyclerView中LayoutManager的设置问题,在这里可传三种LayoutManager:



    其中,若使用第一个manager,则可以把此RecyclerView布局变成ListView的列表形式,若使用第二个,则是瀑布流布局,而第三个则是表格布局,每个布局都有方向可设置,水平或垂直。





下面就是创建RecyclerView的Adapter类。


/** * My View Adapter */public class ContentViewAdapter extends RecyclerView.Adapter<ContentViewAdapter.ContentViewHolder> {    private List<Map<String,String>> data;    private LayoutInflater inflater;    private ItemClickListener mListener;    public ContentViewAdapter(List<Map<String,String>> data,Context context)    {        this.inflater = LayoutInflater.from(context);        this.data = data;    }    public void setItemClickListener(ItemClickListener listener)    {        this.mListener = listener;    }    @Override    public ContentViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {        return new ContentViewHolder(this.inflater.inflate(R.layout.layout_item,viewGroup,false));    }    @Override    public int getItemCount() {        return this.data.size();    }        /**     * 方法中获取item位置我用的是 contentViewHolder.getLayoutPosition()     * 为什么不用参数中提供的position?     * 原因是当增加或删除一个item时,使用到     * notifyItemRemoved()或notifyItemInserted()方法     * position值不会随之改变,但是getLayoutPosition()返回的是真实的item位置     *      * */    @Override    public void onBindViewHolder(final ContentViewHolder contentViewHolder, int position) {        Map<String,String> sth = this.data.get(contentViewHolder.getAdapterPosition());        contentViewHolder.setName(sth.get("name"));        contentViewHolder.setIntro(sth.get("intro"));        if(mListener!=null)        {            contentViewHolder.getItemView().setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    ContentViewAdapter.this.mListener.onItemClick(v, contentViewHolder.getLayoutPosition());                }            });            contentViewHolder.getItemView().setOnLongClickListener(new View.OnLongClickListener() {                @Override                public boolean onLongClick(View v) {                    ContentViewAdapter.this.mListener.onItemLongClick(v, contentViewHolder.getLayoutPosition());                    return false;                }            });        }        /*随意设置item的高度,目的为了达到瀑布流的效果*/        ViewGroup.LayoutParams params = contentViewHolder.getItemView().getLayoutParams();        params.height = (int) (300 + Math.random()*(500-300+1));    }    public void insertItem()    {        Map<String,String> oneDate = new HashMap<>();        oneDate.put("name","Tom");        oneDate.put("intro", "I am tom!");        this.data.add(0, oneDate);        //记住是用这个方法而不是notifyDataSetChanged(),不然会没有动画效果        this.notifyItemInserted(0);    }    public void deleteItem(int pos)    {        this.data.remove(pos);        //规则同上        this.notifyItemRemoved(pos);    }    /**     * My View Holder     */    class ContentViewHolder extends RecyclerView.ViewHolder {        private TextView name;        private TextView intro;        private View itemView;        public ContentViewHolder(View itemView) {            super(itemView);            this.itemView = itemView;            this.name = (TextView) itemView.findViewById(R.id.id_name);            this.intro = (TextView) itemView.findViewById(R.id.id_intro);        }        public void setName(String name) {            this.name.setText(name);        }        public void setIntro(String intro) {            this.intro.setText(intro);        }        public View getItemView()        {            return this.itemView;        }    }    /**     * 监听item点击/长点击事件     * 因为RecyclerView中没有帮我们定义item被点击后的事件监听     * 所以这需要我们自己去定义     */    public interface ItemClickListener    {        void onItemClick(View view,int which);        void onItemLongClick(View view,int which);    }

以上就是实现RecyclerView的基本代码,下面是运行时的截图:





0 0
原创粉丝点击