Android学习之RecyclerView的使用

今年用了Android Studio后才认识到RecyclerView......略菜.....编写完成后现在去看又感觉不太懂了....所以今天想要总结下,让自己以后回顾的时候可以快一点...
PS:recyclerView网上有很多大神的资料写的很屌,菜如我只取了一瓢

  • 先上个效果图吧:
无标题22.png

以上的图标请自找。。。

  • 列出下程序的目录(黑框框中的都是,其它的请自动忽略)
无标题.png
  • 如上图所示:

  • MyItemClickListener : 列表行点击事件的接口,实现后用于响应列表点击事件

  • MyItemLongClickListener:列表行长按事件的接口,实现后用于响应列表长按事件

  • ContentViewHolder:列表行视图容器,对应的section_item.xml中控件都绑定在此,实现一个容器的显示,也就是列表的一行

  • FootViewHolder:列表尾视图容器,对应的section_footer.xml中控件都绑定在此,实现一行列表尾的显示

  • HeadViewHolder:列表头视图容器,对应的section_header.xml中控件都绑定在此,实现一行列表头的显示

  • MainActivity:实现activity_main.xml中recyclerView的绑定和显示

  • 其中:

    • 每个ViewHolder对应一个xml(如ContentViewHolder对应section_item)
    • 每个ViewHolder都会在MyRecycViewAdapter中初始化,并实现控件的赋值
    • 生成列表只需要以下几步:
      • 1、在activity_main.xml中创建一个RecyclerView的控件,并在MainAcitivity中绑定
      • 2、创建一个MyRecyclerVIewAdapter的对象,并且把你需要显示的数据传递给它
      • 3、使用RecyclerView.setAdapter(MyRecyclerVIewAdapter对象)实现列表的显示
      • 4、若需要更新,使用MyRecyclerVIewAdapter对象.notifyDataSetChanged()
  • 下面就附上代码

MyItemClickListener 列表行点击事件接口

public interface MyItemClickListener {  
  public void MyItemClick(View view, int position);
}

MyItemLongClickListener 列表行长按事件接口

public interface MyItemLongClickListener {    
  public void MyItemLongClick(View view, int position);、
}

ContentViewHolder 继承自RecyclerView.ViewHolder,section_item.xml中的控件都绑定于此,我们可以通过ContentViewHolder对象来获取其中的控件,进而赋值(如:ContentViewHolder对象.tv.setText( "xxxx");)

public class ContentViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {   
 //xml中的控件,由于要在会在MyRecyclerViewAdapter中调用,所以不能为私有
    TextView tv;    
    View cutLine;    
    ImageView icon;   
   //点击事件和长按事件   
    private MyItemClickListener mItemClickListener;    
    private MyItemLongClickListener mItemLongClickListener;    
    //这个是ContentViewHolder的构造函数,会在MyRecyclerViewAdapter中调用,生成ContentViewHolder一个对象    
     public ContentViewHolder(View itemView,MyItemClickListener mItemClickListener,MyItemLongClickListener mItemLongClickListener) {  
        super(itemView);       
         tv = (TextView)itemView.findViewById(R.id.tv);        
        cutLine = (View)itemView.findViewById(R.id.cutLine);       
        icon = (ImageView)itemView.findViewById(R.id.icon);     
        this.mItemClickListener = mItemClickListener;    
        this.mItemLongClickListener = mItemLongClickListener; 
       itemView.setOnClickListener(this);     
       itemView.setOnLongClickListener(this);  
  }  

 //短按 
@Override    
  public void onClick(View v) {       
      if(mItemClickListener != null){ 
           mItemClickListener.MyItemClick(v,getPosition());  //若不为空则调用MyItemClickListener的MyItemClick方法    
       }  
    }    

//长按   
@Override    
public boolean onLongClick(View v) {      
    if(mItemLongClickListener != null){ 
        mItemLongClickListener.MyItemLongClick(v,getPosition());   //若不为空则调用MyItemLongClickListener的MyItemLongClick方法      
        }  
       return true;   
     }
}

section_item.xml 包涵一个图标,文字和一条分割线

<?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"
    android:orientation="vertical">

    <RelativeLayout
        android:id="@+id/column"
        android:layout_width="match_parent"
        android:layout_height="50dp">

        <ImageView
            android:id="@+id/icon"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_marginLeft="5dp"
            android:layout_marginTop="5dp"
            />

        <TextView
            android:id="@+id/tv"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:layout_toRightOf="@+id/icon"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:text="mxy"
            android:gravity="center_vertical"
            />
    </RelativeLayout>

    <View
        android:id="@+id/cutLine"
        android:layout_width="match_parent"
        android:layout_height="0.3dp"
        android:background="@color/black"/>



</LinearLayout>

FootViewHolder 列表尾viewholder,列表尾也可以像ContentViewHolder一样放入很多控件,我只放了一个TextView

public class FootViewHolder extends RecyclerView.ViewHolder {

    TextView footer_tv;
    public FootViewHolder(View itemView) {
        super(itemView);
        footer_tv = (TextView)itemView.findViewById(R.id.footer_tv);
    }
}

section_footer.xml 列表尾xml


<?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/footer_tv"
        android:layout_width="match_parent"
        android:layout_height="20dp"
        android:text="footer_tv"
        android:gravity="center"
        android:background="#30696969"
        />

</LinearLayout>

HeadViewHolder列表头viewholder

public class HeadViewHolder extends RecyclerView.ViewHolder {

    TextView header_tv;
    public HeadViewHolder(View itemView) {
        super(itemView);
        header_tv = (TextView)itemView.findViewById(R.id.header_tv);
    }
}

section_header.xml 列表头xml

<?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/header_tv"
       android:layout_width="match_parent"
       android:layout_height="20dp"
       android:text="header_tv"
       android:gravity="center"
       android:background="#30696969"
       />

</LinearLayout>

MyRecyclerViewAdapter 这个是核心,看上去很长,但其实层次感很强,主要分为以下4部分

  • 1 ViewHolder的Create
  • 2 ViewHolder的赋值
  • 3 列表的行数
  • 4 其他部分
    • 4.1 因为我有三个ViewHolder分别表示content,head,foot所以我需要在getItemViewType中判断
    • 4.2 因为我有点击事件,所以需要点击方法
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {


    private static final int TYPE_HEADER = 0;  //表格头
    private static final int TYPE_CONTENT = 1; //表格内容
    private static final int TYPE_FOOTER = 2;  //表格尾


    private LayoutInflater inflater;
    private List<String> slist;    //标识,标识是头还是尾,还是内容
    private List<contentData> cList; //头或尾或内容的数据


    MyItemClickListener mItemClickListener;
    MyItemLongClickListener mItemLongClickListener;

    public MyRecyclerViewAdapter(Context context,List<allData> list){
        this.slist = list.get(0).getSlist();
        this.cList =list.get(0).getMlist();
        inflater=LayoutInflater. from(context);

    }
  /************************************此处区分viewholder类型***************************************/
    //这里判断viewType类型,到底是header还是footer还是content
    @Override
    public int getItemViewType(int postion){

        if(slist.get(postion).equals("head")){return TYPE_HEADER;}
        else if (slist.get(postion).equals("foot")){return TYPE_FOOTER;}
        else{return TYPE_CONTENT;}

//       if(postion == 0){return TYPE_HEADER;}  //header
//       else if(postion == getItemCount()-1){return TYPE_FOOTER;} //footer
//       else{return TYPE_CONTENT;}  //content

    }
    /************************************点击事件的方法***************************************/
    //表格行点击方法
    public void setOnItemClickListener(MyItemClickListener listener){
        this.mItemClickListener = listener;
    }
    //表格行长按方法
    public void setOnItemLongClickListener(MyItemLongClickListener listener){
        //listener为MainAcitivity传递进来的listener
        this.mItemLongClickListener = listener;
    }

    /************************************create部分***************************************/
    //此函数中根据xml生成View对象,并传递进入对应的ViewHolder构造函数,生成对应的Viewholder对象,并返回
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if(viewType == TYPE_CONTENT){ //表格内容
            View view = inflater.inflate(R.layout.section_item,parent, false); //根据xml生成View对象
            ContentViewHolder viewholder = new ContentViewHolder(view,mItemClickListener,mItemLongClickListener);
            return viewholder;
        }else if(viewType == TYPE_HEADER){//表格头
            View view = inflater.inflate(R.layout.section_header,parent, false);
            HeadViewHolder headholder = new HeadViewHolder(view);
            return headholder;
        }else{//表格尾
            View view = inflater.inflate(R.layout.section_footer,parent, false);
            FootViewHolder footholder = new FootViewHolder(view);
            return footholder;
        }

    }

    /************************************为ViewHolder中的控件赋值部分***************************************/
    //此函数中holder即为onCreateViewHolder返回的的holder,根据这些holder获取对应的控件,进行赋值
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if(holder instanceof ContentViewHolder){ // content 表格内容
            ContentViewHolder contentholder = (ContentViewHolder) holder;
            contentholder.tv.setText(cList.get(position).getDescrib());
            contentholder.icon.setImageResource(cList.get(position).getIconID());
        }else if(holder instanceof HeadViewHolder){  //header 表格头
            HeadViewHolder headholder = (HeadViewHolder) holder;
            headholder.header_tv.setText(cList.get(position).getDescrib());
        }else{ //footer 表格尾
            FootViewHolder footholder = (FootViewHolder) holder;
            footholder.footer_tv.setText(cList.get(position).getDescrib());
        }
    }
     /************************************列表行数***************************************/
    //此处返回表格的行数,也就是数据的size
    @Override
    public int getItemCount() {
        return slist.size();
    }
}

MainAcitvity主要分为数据的生成,和设置recyclerView的适配

public class MainActivity extends AppCompatActivity implements MyItemClickListener, MyItemLongClickListener {

    private RecyclerView recyclerView;
    private MyRecyclerViewAdapter recycleAdapter;
    private List<String> slist =new ArrayList<String>();
    private List<contentData> clist = new ArrayList<contentData>();

    private List<allData> mylist = new ArrayList<allData>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

       initData();
        recyclerView = (RecyclerView)this.findViewById(R.id.recyclerView);
        recycleAdapter = new MyRecyclerViewAdapter(this,mylist);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        //设置为垂直布局,这也是默认的
        layoutManager.setOrientation(OrientationHelper.VERTICAL);
        //设置布局管理器
        recyclerView.setLayoutManager(layoutManager);
        //设置Adapter
        recyclerView.setAdapter(recycleAdapter);
        //设置增加或删除条目的动画
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        //分割线
        //  recyclerView.addItemDecoration(new RecyclerDivideLine(Main.this,LinearLayoutManager.VERTICAL));
//        recycleAdapter.setOnItemClickListener(this);
//        recycleAdapter.setOnItemLongClickListener(this);

        recycleAdapter.setOnItemClickListener(this);
        recycleAdapter.setOnItemLongClickListener(this);


    }
    //数据初始化,其中在slist中add的是标识符,head就说明这行是表格头,body说明这行是表格内容,
  //而clist中add的有两个一个是图片的ID,一个是文字的说明,而head和foot没有图片ID
    private void initData(){

         clist.add(new contentData(1,"this is head1"));slist.add("head");
         clist.add(new contentData(R.drawable.ins,"仪表说明"));slist.add("body");
         clist.add(new contentData(R.drawable.handle,"操作说明"));slist.add("body");

        clist.add(new contentData(1,"this is head2"));slist.add("head");
        clist.add(new contentData(R.drawable.vision,"版本说明"));slist.add("body");
        clist.add(new contentData(R.drawable.err,"报错指南"));slist.add("body");
        // clist.add(new contentData(5,"footer1"));slist.add("foot");

        clist.add(new contentData(1,"this is head3"));slist.add("head");
        clist.add(new contentData(R.drawable.buy,"业务咨询"));slist.add("body");
        clist.add(new contentData(R.drawable.fix,"售后返修"));slist.add("body");

        clist.add(new contentData(1,"this is head4"));slist.add("head");
        clist.add(new contentData(R.drawable.sms,"短信发送"));slist.add("body");
       clist.add(new contentData(5,"this is foot1"));slist.add("foot");



        mylist.add(new allData(clist,slist));


    }

    //列表行的点击在此响应
    @Override
    public void MyItemClick(View view, int position) {
        Toast.makeText(this, ""+position, Toast.LENGTH_SHORT).show();
    }
    //列表行的长按在此响应
    @Override
    public void MyItemLongClick(View view, int position) {
        Toast.makeText(this, ""+position, Toast.LENGTH_SHORT).show();
    }
}

acitivity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.myapplication.MainActivity">


   <android.support.v7.widget.RecyclerView
       android:id="@+id/recyclerView"
       android:layout_width="match_parent"
       android:layout_height="match_parent"

       android:layout_alignParentTop="true"
       android:layout_alignParentLeft="true"
       android:layout_alignParentStart="true">
   </android.support.v7.widget.RecyclerView>


</RelativeLayout>

contentData包括两个参数,一个是icon也就是图标的ID,一个是describe也就是文字说明

public class contentData {

    public int getIconID() {
        return iconID;
    }

    public void setIconID(int iconID) {
        this.iconID = iconID;
    }

    private int iconID;

    public String getDescrib() {
        return describ;
    }

    public void setDescrib(String describ) {
        this.describ = describ;
    }

    private String describ;

    public contentData(int iconID,String describ){
        this.iconID = iconID;
        this.describ =describ;
    }


}

allData 其中mlist为内容数据模型,slist为描述数据模型

public class allData {



    private List<contentData> mlist;
    private List<String> slist;

    public allData(List<contentData> mlist,List<String> slist){
        this.mlist = mlist;
        this.slist = slist;
    }


    public List<String> getSlist() {
        return slist;
    }

    public void setSlist(List<String> slist) {
        this.slist = slist;
    }

    public List<contentData> getMlist() {
        return mlist;
    }

    public void setMlist(List<contentData> mlist) {
        this.mlist = mlist;
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,911评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,014评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,129评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,283评论 1 264
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,159评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,161评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,565评论 3 382
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,251评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,531评论 1 292
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,619评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,383评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,255评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,624评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,916评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,199评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,553评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,756评论 2 335

推荐阅读更多精彩内容