android RecyclerView实现加载多种item的样式布局

在实际的应用中列表经常是图文并茂的形式展示,这也就需要在一个RecyclerView中加载不一样的模板文件。

 首先准备需要加载的模板文件,这里准备了2个模板文件

item_multi_one.xml 文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <TextView
        android:id="@+id/title"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:text="我的标题"
        />
</LinearLayout>

item_multi_third.xml 文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#DF0303"
    >

    <ImageView
        android:id="@+id/photo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"
        android:layout_gravity="center_horizontal"
        />

    <TextView
        android:id="@+id/title"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:text="图文并排"
        />
</LinearLayout>

 

activity_main.xml 文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:orientation="vertical"
    >

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </androidx.recyclerview.widget.RecyclerView>

</LinearLayout>

 

到这里基本的XML文件就准备齐全了

接下来看 自定义的 RvAdapter文件

package jz.app.myapplication.adapter;



import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;


import jz.app.myapplication.R;

public class RvAdapter extends RecyclerView.Adapter {

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

    private Context mContext;
    private ArrayList<Bean> mlist;

    public OnItemClickListener mOnItemClickListener;


    private static int VIEW_TYPE_1=1;
    private static int VIEW_TYPE_2=2;

    public RvAdapter(Context mContext,ArrayList mlist){
        this.mContext=mContext;
        this.mlist = mlist;
    }

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

    @Override
    public int getItemViewType(int position) {

        if(mlist.get(position).getType()==VIEW_TYPE_1){
            return VIEW_TYPE_1;
        }
        return VIEW_TYPE_2;

    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        if(viewType == VIEW_TYPE_1){
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_multi_one,parent,false);
            return new Holder1(view);
        } else{
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_multi_third,parent,false);
            return new Holder2(view);
        }


    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

        if(holder instanceof Holder1){
            Holder1 holder1 = (Holder1) holder;
            holder1.Tvtitle.setText(mlist.get(position).getTitle());
        }else{
            Holder2 holder2 = (Holder2) holder;
            holder2.Tvtitle.setText(mlist.get(position).getTitle());
        }

        if(mOnItemClickListener != null){
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    //Toast.makeText(mContext,position + "",Toast.LENGTH_LONG).show();
                    int pos = holder.getLayoutPosition();
                    mOnItemClickListener.onItemClick(holder.itemView,pos);
                }
            });

//            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
//                @Override
//                public boolean onLongClick(View view) {
//                    int pos = holder.getLayoutPosition();
//                    mOnItemClickListener.onItemLongClick(holder.itemView,pos);
//                    return false;
//                }
//            });
        }



    }

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

    public class Holder1 extends RecyclerView.ViewHolder{

        private TextView Tvtitle;

        public Holder1(@NonNull View itemView) {
            super(itemView);
            Tvtitle = (TextView) itemView.findViewById(R.id.title);

        }
    }

    public class Holder2 extends RecyclerView.ViewHolder{

        private TextView Tvtitle;


        public Holder2(@NonNull View itemView) {
            super(itemView);
            Tvtitle =(TextView)itemView.findViewById(R.id.title);
        }
    }




}

 

这里定义两个常量 VIEW_TYPE_1跟VIEW_TYPE_2 这两个是用来区分加载哪一个模板文件的。

在这里还需要实现一个方法

    @Override
    public int getItemViewType(int position) {

        if(mlist.get(position).getType()==VIEW_TYPE_1){
            return VIEW_TYPE_1;
        }
        return VIEW_TYPE_2;

    }

在传过来的数据里面定义好模板文件参数,在这个函数里面进行比较。

在 OnCreateViewHolder 这个函数进行模板加载

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        if(viewType == VIEW_TYPE_1){
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_multi_one,parent,false);
            return new Holder1(view);
        } else{
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_multi_third,parent,false);
            return new Holder2(view);
        }


    }

这里需要分别创建 Holder1 跟 Holder2分别继承自 RecyclerView.ViewHolder。

在 OnBindViewHolder函数里面 通过 instanceof 方法对不同的模板进行数据绑定。

        if(holder instanceof Holder1){
            Holder1 holder1 = (Holder1) holder;
            holder1.Tvtitle.setText(mlist.get(position).getTitle());
        }else{
            Holder2 holder2 = (Holder2) holder;
            holder2.Tvtitle.setText(mlist.get(position).getTitle());
        }

 

另外 在上面的实例里面还是实现了 OnItemClickLinster 接口,这里实现了 onItemClick 方法。

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

 

现在来看 mainActivity.java 文件,一下文件包含了测试数据,拷贝可以直接运行效果。

package jz.app.myapplication;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

import java.util.ArrayList;

import jz.app.myapplication.adapter.Bean;
import jz.app.myapplication.adapter.RvAdapter;

public class MainActivity extends AppCompatActivity {

    private RecyclerView rv;

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

        rv = (RecyclerView) findViewById(R.id.rv);

        ArrayList<Bean> list = new ArrayList<>();
        Bean a = new Bean();
        a.setType(1);
        a.setTitle("标题1");
        list.add(a);

        Bean b = new Bean();
        b.setType(1);
        b.setTitle("模板1");
        list.add(b);

        Bean c = new Bean();
        c.setType(2);
        c.setTitle("模板2");
        list.add(c);

        Bean e = new Bean();
        e.setType(1);
        e.setTitle("加载了模板1");
        list.add(e);

        Bean f = new Bean();
        f.setType(1);
        f.setTitle("加载第一个模板 one");
        list.add(f);

        Bean d = new Bean();
        d.setType(2);
        d.setTitle("加载模板2");
        list.add(d);

        Bean g = new Bean();
        g.setType(1);
        g.setTitle("加载模板1");
        list.add(g);

        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        rv.setLayoutManager(linearLayoutManager);

        RvAdapter myAdapter = new RvAdapter(this,list);
        myAdapter.setmOnItemClickListener(new RvAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                Toast.makeText(MainActivity.this,"点击了位置:"+position ,Toast.LENGTH_LONG).show();
            }

//            @Override
//            public void onItemLongClick(View view, int position) {
//
//                Toast.makeText(MainActivity.this,"长按了"+position+",触了提示",Toast.LENGTH_LONG).show();
//            }
        });
        rv.setAdapter(myAdapter);


    }
}

 

posted @ 2022-07-03 11:55  星锋  阅读(892)  评论(0编辑  收藏  举报