RecyclerView 的介紹以及多佈局的實例

 RecyclerView 的使用以及多佈局的實例java

  RecyclerView 是在Android5.0以後推出的,是一個比ListView更加靈活更加高效的適配器類型控件。可是RecyclerView不一樣於其餘類型的適配器,它還須要一個LayoutManager進行頁面控制展現。RecyclerView提供了三種佈局管理器:
  一、LinearLayoutManager:線性佈局管理器,支持水平和垂直效果。
  二、GridLayoutManager:網格佈局管理器,支持水平和垂直效果。
  三、StaggeredGridLayoutManager:分佈型管理器,瀑布流效果

RecyclerView的使用:
  一、引入RecyclerView依賴包,V7下的,兼容到API17.
  二、在xml佈局中聲明,在Java代碼中初始化。
  三、設置佈局管理器
  四、建立適配器,設置數據源,綁定適配器
    具體建立適配器:①建立一個類,繼承RecyclerView.Adapter<ViewHolder>.
            ②建立一個類ViewHolder,繼承RecyclerView。VIewHolder,該類須要建立一個匹配父類的構造。
            ③重寫適配器中的方法:getItemCount():獲取數據源的個數(item的數量);onCreateViewHolder():該方法中導入佈局,實例化VIewHolder;onBindViewHolder():綁定VIewHolder,加載數據。
注意一點:RecyclerView的LinearLayoutManager不一樣於通常的適配器的佈局,RecyclerView的item最外層的佈局參數是有效的,如高度寬度等,因此在使用的時候,第一種方法是在導入View的時候指定沒有parent(不推薦使用),第二種方法是在item佈局的最外層指定具體的參數。
RecyclerView 爲開發者提供了強大的複用機制,可是全部的點擊事件都丟了,沒有提供默認的點擊事件,因此須要咱們本身爲RecyclerView手動實現點擊。
看一個簡單的例子,後面講解下多佈局的RecyclerView。效果圖以下(不要吐槽,我知道很醜,能達到效果就好^_^):

第一步:建立佈局,須要導入依賴包:android.support.v7.widget.RecyclerViewandroid

activity_main.xmlgit

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    tools:context="com.zcl.day40_recyleview01.MainActivity">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/teach_recycler"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

item.xmlgithub

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:background="@drawable/backgroud_shap"
    android:layout_height="match_parent">
    <ImageView
        android:src="@mipmap/ic_launcher"
        android:layout_width="80dp"
        android:layout_height="80dp" />
    <TextView
        android:id="@+id/teach_item_name"
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="80dp" />
</LinearLayout>

Model.java網絡

public class Model {
    private String name;
    private int height;

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

MainActivity.javaapp

public class MainActivity extends AppCompatActivity implements RecyclerAdapter.OnItemClickListener {
    private static final String TAG = MainActivity.class.getSimpleName();
    private RecyclerView mRecyclerView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }
    private void initView() {
        mRecyclerView = (RecyclerView) findViewById(R.id.teach_recycler);
        //設置佈局管理器
        //一、第一種LinearLayoutManager
//        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        //二、第二種 GridLayoutManager
//        GridLayoutManager layoutManager=new GridLayoutManager(this,3);
        //三、第三種
        StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
//        //設置佈局的排版方向
//        layoutManager.setOrientation(GridLayoutManager.HORIZONTAL);
        mRecyclerView.setLayoutManager(layoutManager);
        //綁定適配器
        RecyclerAdapter adapter = new RecyclerAdapter(this, getData());
        mRecyclerView.setAdapter(adapter);
        adapter.setOnItemClickListener(this);//將接口傳遞到數據產生的地方
    }

    /**
     * 獲取數據源
     *
     * @return
     */
    public List<Model> getData() {
        List<Model> data = new ArrayList<>();
        for (int i = 0; i < 30; i++) {
            Model model = new Model();
            model.setName("猴子請來的都比---" + i);
            model.setHeight(((int) (Math.random() * 100 + 200)));
            data.add(model);
        }
        return data;
    }

    @Override
    public void onItemClick(int position, Model model) {
        Log.e(TAG, "onItemClick: " + position);
    }
}

適配器dom

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> implements View.OnClickListener {
    private static final String TAG = RecyclerAdapter.class.getSimpleName();
    private List<Model> data;
    private LayoutInflater inflater;
    private RecyclerView mRecyclerView;//用來計算Child位置
    private OnItemClickListener onItemClickListener;
    //對外提供接口初始化方法
    public void setOnItemClickListener(OnItemClickListener onItemClickListener){
        this.onItemClickListener=onItemClickListener;
    }

    public RecyclerAdapter(Context context,List<Model> data) {
        this.data = data;
        inflater= (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    public static class ViewHolder extends RecyclerView.ViewHolder{
        TextView name;

        public ViewHolder(View itemView) {
            super(itemView);
            name= (TextView) itemView.findViewById(R.id.teach_item_name);
        }
    }

    /**
     * 建立VIewHolder,導入佈局,實例化itemView
     * @param parent
     * @param viewType
     * @return
     */
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = inflater.inflate(R.layout.item, parent, false);
        //導入itemView,爲itemView設置點擊事件
        itemView.setOnClickListener(this);
        return new ViewHolder(itemView);
    }

    /**
     * 綁定VIewHolder,加載數據
     * @param holder
     * @param position
     */
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.name.setText(data.get(position).getName());//加載數據
        ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
        layoutParams.height=data.get(position).getHeight();
        holder.itemView.setLayoutParams(layoutParams);
    }

    /**
     * 數據源的數量,item的個數
     * @return
     */
    @Override
    public int getItemCount() {
        return data!=null?data.size():0;
    }

    /**
     * 適配器綁定到RecyclerView 的時候,回將綁定適配器的RecyclerView 傳遞過來
     * @param recyclerView
     */
    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        mRecyclerView=recyclerView;
    }

    /**
     *
     * @param v 點擊的View
     */
    @Override
    public void onClick(View v) {
        //RecyclerView能夠計算出這是第幾個Child
        int childAdapterPosition = mRecyclerView.getChildAdapterPosition(v);
        Log.e(TAG, "onClick: "+childAdapterPosition );
        if (onItemClickListener!=null) {
            onItemClickListener.onItemClick(childAdapterPosition,data.get(childAdapterPosition));
        }
    }

    /**
     * 接口回調
     * 一、定義接口,定義接口中的方法
     * 二、在數據產生的地方持有接口,並提供初始化方法,在數據產生的時候調用接口的方法
     * 三、在須要處理數據的地方實現接口,實現接口中的方法,並將接口傳遞到數據產生的地方
     */
    public interface OnItemClickListener{
        void onItemClick(int position,Model model);
    }
}

多佈局的RecyclerView ---------------------------------------------------------------ide

先看下效果圖:佈局

這是this

分析下該頁面佈局,三種佈局,第一種是標題文字+內容簡介文字佔一個item,第二種是圖片+標題佔一個item,第三種是標題+內容,而且一個item中有兩個這樣的佈局。那麼能夠用網格佈局,分爲兩列,第一種跟第二種佈局各自佔兩列,第三種佈局佔一列。那麼怎麼設置item能夠橫跨兩列呢,就要用到gridLayoutManager.setSpanSizeLookup來設置,具體看代碼:

activity_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"
    tools:context="com.zcl.day40_task2.MainActivity">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</RelativeLayout>

item1.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
    android:layout_height="200dp">
    <ImageView
        android:id="@+id/iv_item1"
        android:src="@mipmap/ic_launcher"
        android:layout_width="match_parent"
        android:layout_height="200dp" />
    <TextView
        android:id="@+id/tv_item1"
        android:text="title"
        android:textColor="#e5ffffff"
        android:textSize="20sp"
        android:textStyle="bold"
        android:layout_marginLeft="15dp"
        android:layout_marginTop="20dp"
        android:layout_marginRight="15dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</RelativeLayout>

item2.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="200dp">
    <TextView
        android:id="@+id/tv_item2_title"
        android:textSize="20sp"
        android:textStyle="bold"
        android:text="title"
        android:layout_marginLeft="15dp"
        android:layout_marginTop="20dp"
        android:layout_marginRight="15dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/tv_item2_content"
        android:layout_marginLeft="15dp"
        android:layout_marginTop="10dp"
        android:text="content"
        android:layout_marginBottom="10dp"
        android:layout_marginRight="15dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

item3.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="200dp">
    <TextView
        android:id="@+id/tv_item3_title"
        android:textSize="20sp"
        android:lines="2"
        android:ellipsize="end"
        android:text="title"
        android:layout_marginLeft="15dp"
        android:layout_marginTop="10dp"
        android:layout_marginRight="15dp"
        android:layout_width="match_parent"
        android:layout_height="60dp" />
    <TextView
        android:id="@+id/tv_item3_content"
        android:lines="2"
        android:ellipsize="end"
        android:text="content"
        android:layout_marginLeft="15dp"
        android:layout_marginTop="10dp"
        android:layout_marginRight="15dp"
        android:layout_width="match_parent"
        android:layout_height="60dp" />

</LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity implements MyAdapter.OnItemClickLietener{

    private static final String TAG = MainActivity.class.getSimpleName();
    private RecyclerView mRecyclerView;
    private MyAdapter adapter;
    private List<Model> data;
    public static final String URL_PATH="http://dxy.com/app/i/feed/index/list?hardName=Google%20Nexus%205%20-%205.1.0%20-%20API%2022%20-%201080x1920&u=&bv=2015&ac=d5424fa6-adff-4b0a-8917-4264daf4a348&vc=5.1.9&vs=5.1&mc=00000000600ba4e6ffffffff99d603a9";

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

    private void initView() {
        ImageLoader.init(this);
        mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        //設置佈局管理器
        GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2);
        Log.e(TAG, "initView:----1 " );
        gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                int spansize=1;
                switch (adapter.getItemViewType(position)) {
                    case 1:
                        spansize=2;
                        break;
                    case 2:
                        spansize=2;
                        break;
                }
                return spansize;
            }
        });
        Log.e(TAG, "initView: -----2" );
        mRecyclerView.setLayoutManager(gridLayoutManager);


        adapter = new MyAdapter(this, getData());
        mRecyclerView.setAdapter(adapter);
        adapter.setClickLietener(this);
        Log.e(TAG, "initView: 4" );
    }

    public List<Model> getData() {
        Log.e(TAG, "getData: 3" );
        HttpUtil.getStringAsync(URL_PATH, new HttpUtil.RequestCallBack() {
            @Override
            public void onFailure() {
                Log.e(TAG, "onFailure: " );
            }

            @Override
            public void onSuccess(String result) {
                Gson gson = new Gson();
                ModelData modelData = gson.fromJson(result, ModelData.class);
                List<Model> data =modelData.getData().getItems();
                Log.e(TAG, "onSuccess: "+data );
               adapter.addRes(data);
            }

            @Override
            public void onFinish() {
                Log.e(TAG, "onFinish: " );
            }
        });

        return data;
    }

    @Override
    public void setItemClickListener(int position) {
        Log.e(TAG, "setItemClickListener: "+position );
    }
}
MyAdapter.java

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> implements View.OnClickListener { private List<Model> data; private LayoutInflater inflater; private RecyclerView mRecyclerView; private OnItemClickLietener clickLietener; public void setClickLietener(OnItemClickLietener clickLietener){ this.clickLietener=clickLietener; } public MyAdapter(Context context, List<Model> data) { this.data = data; inflater = LayoutInflater.from(context); } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = null; switch (viewType) { case 1: itemView = inflater.inflate(R.layout.item1, parent, false); break; case 2: itemView = inflater.inflate(R.layout.item2, parent, false); break; case 8: itemView = inflater.inflate(R.layout.item3, parent, false); break; //設置監聽
 } itemView.setOnClickListener(this); return new ViewHolder(itemView); } @Override public void onBindViewHolder(ViewHolder holder, int position) { switch (getItemViewType(position)) { case 1: ImageView imageView = (ImageView) holder.getView(R.id.iv_item1); TextView textView = (TextView) holder.getView(R.id.tv_item1); textView.setText(data.get(position).getTitle()); String picPath = data.get(position).getCover(); ImageLoader.display(imageView, picPath); break; case 2: TextView item2Title = (TextView) holder.getView(R.id.tv_item2_title); TextView item2Content = (TextView) holder.getView(R.id.tv_item2_content); item2Title.setText(data.get(position).getTitle()); item2Content.setText(data.get(position).getContent()); break; case 8: TextView item3Title = (TextView) holder.getView(R.id.tv_item3_title); TextView item3Content = (TextView) holder.getView(R.id.tv_item3_content); item3Title.setText(data.get(position).getTitle()); item3Content.setText(data.get(position).getContent()); break; } } @Override public int getItemCount() { return data != null ? data.size() : 0; } @Override public int getItemViewType(int position) { return data.get(position).getShow_type(); } @Override public void onAttachedToRecyclerView(RecyclerView recyclerView) { super.onAttachedToRecyclerView(recyclerView); mRecyclerView=recyclerView; } public void addRes(List<Model> data) { if (data != null) { this.data = data; notifyDataSetChanged(); } } @Override public void onClick(View v) { int childAdapterPosition = mRecyclerView.getChildAdapterPosition(v); if (clickLietener!=null) { clickLietener.setItemClickListener(childAdapterPosition); } } public static class ViewHolder extends RecyclerView.ViewHolder { private Map<Integer, View> mCacheView; public ViewHolder(View itemView) { super(itemView); mCacheView = new HashMap<>(); } public View getView(int resId) { View view; if (mCacheView.containsKey(resId)) { view = mCacheView.get(resId); } else { view = itemView.findViewById(resId); mCacheView.put(resId, view); } return view; } } public interface OnItemClickLietener{ void setItemClickListener(int position); } }

代碼中使用的網絡數據的請求以及圖片的加載是本身封裝的類庫,你們能夠忽略,用本身的代碼填充,能理解RecyclerView就好,另外數據的實體類太簡單,也沒有貼上代碼。最後不要忘了配置網絡權限哦。

個人github:https://github.com/SiberiaDante

相關文章
相關標籤/搜索