RecyclerView真的是太强大太强大的,没听过这个view 的可以自行google一下;
本文将介绍RecyclerView的多布局;
多布局的实现
布局
多布局是指一个不同的item用不同的layout显示。
我们的主页面里面就放RecyclerView
<android.support.v7.widget.RecyclerView
android:id="@+id/recylerview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
既然是要实现多布局,那么我们就写两个布局吧,一个item_normal
,值包含一个 TextView
<?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="?listPreferredItemHeight"
android:background="?selectableItemBackground"
android:clickable="true"
android:gravity="center"
android:orientation="vertical"
android:id="@+id/root_view"
android:padding="10dp">
<TextView
android:id="@+id/tv_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp" />
</LinearLayout>
另外一个布局,放一个TextView
和一个CheckBox
;
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root_view"
android:layout_width="match_parent"
android:layout_height="?listPreferredItemHeight"
android:background="?selectableItemBackground"
android:clickable="true"
android:gravity="center"
android:orientation="horizontal"
android:padding="10dp">
<TextView
android:id="@+id/tv_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="hunao"
android:textSize="18sp" />
<CheckBox
android:id="@+id/cb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true" />
</LinearLayout>
Adapter
布局和item有了,那就要写Adapter了;
自定义Adapter
继承RecyclerView.Adapter<RecyclerView.ViewHolder>
,复写需要复写的方法,我们来看一个这个方法,传进来的一个int
类型的参数viewType
,其实这个就相当于不同item的标记吧,我们可以根据这个值,给item
选择不同的标记;
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
}
那这个标记是从哪里来的呢?这个好办,RecyclerView.Adapter
有一个方法getItemViewType()
,返回值是int
类;这个方法就是返回item布局类型标记的方法。
private static final int NORMAL_TYPE = 0;
private static final int CHECK_TYPE = 1;
@Override
public int getItemViewType(int position) {
if (position % 4 == 0) {
return CHECK_TYPE;
}
return NORMAL_TYPE;
}
如果position%4==0
就返回NORMAL_TYPE
,否则就返回CHECK_TYPE
;然后我们就可以根据比较选择不同的布局了;
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == NORMAL_TYPE) {
return new NormalHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_normal, parent, false));
} else
return new CheckHoldr(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_check, parent, false));
}
然后我们创建来数据就好了;
给MyAdapter一个构造方法,传进来数据
private List<String> datas;
public MyAdapter(List<String> datas) {
this.datas = datas;
}
每一个布局都要写一个ViewHolder
class NormalHolder extends RecyclerView.ViewHolder {
TextView tv_name;
LinearLayout rootView;
public NormalHolder(View itemView) {
super(itemView);
tv_name = (TextView) itemView.findViewById(R.id.tv_name);
rootView = (LinearLayout) itemView.findViewById(R.id.root_view);
}
class CheckHoldr extends NormalHolder {
public CheckHoldr(View itemView) {
super(itemView);
}
}
这样,就可以给RecyclerView设置Adapter了
private void initData() {
datas = new ArrayList<>();
for (int i = 0; i < 20; i++) {
datas.add("hunao " + i);
}
}
private void initView() {
recylerView = (RecyclerView) findViewById(R.id.recylerview);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recylerView.setLayoutManager(layoutManager);
MyAdapter adapter = new MyAdapter(datas);
recylerView.setAdapter(adapter);
}
Paste_Image.png
Item点击事件
RecyclerView
并没有给我们封装item点击事件,那我们就自己动手吧
我们需要在Adapter里面暴露出去一个借口,这样的,定义了一个OnItemClickListener
借口,并且给了set
方法,然后我们只要处理回调就可以了
private OnItemClickListener clickListener;
public void setClickListener(OnItemClickListener clickListener) {
this.clickListener = clickListener;
}
public static interface OnItemClickListener {
void onClick(View view, int position);
}
给我们的ViewHolder
实现View.OnClickListener
,然后重写onClick()
方法,当OnItemClickListener
监听器不为空的时候,就回调出去
class NormalHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView tv_name;
LinearLayout rootView;
public NormalHolder(View itemView) {
super(itemView);
tv_name = (TextView) itemView.findViewById(R.id.tv_name);
rootView = (LinearLayout) itemView.findViewById(R.id.root_view);
rootView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (clickListener != null) {
clickListener.onClick(itemView, getAdapterPosition());
}
}
}
class CheckHoldr extends NormalHolder {
public CheckHoldr(View itemView) {
super(itemView);
}
}
最后只要在Adapter上设置我们的监听器就可以了
adapter.setClickListener(new MyAdapter.OnItemClickListener() {
boolean flag = false;
@Override
public void onClick(View view, int position) {
TextView tvName = (TextView) view.findViewById(R.id.tv_name);
String name = flag ? "hunao" : "china";
tvName.setText(name + position);
flag = !flag;
}
});
完整代码
Activity
package com.hugo.recylerviewdemo;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private RecyclerView recylerView;
private List<String> datas;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
initView();
}
private void initData() {
datas = new ArrayList<>();
for (int i = 0; i < 20; i++) {
datas.add("hunao " + i);
}
}
private void initView() {
recylerView = (RecyclerView) findViewById(R.id.recylerview);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recylerView.setLayoutManager(layoutManager);
MyAdapter adapter = new MyAdapter(datas);
recylerView.setAdapter(adapter);
adapter.setClickListener(new MyAdapter.OnItemClickListener() {
boolean flag = false;
@Override
public void onClick(View view, int position) {
TextView tvName = (TextView) view.findViewById(R.id.tv_name);
String name = flag ? "hunao" : "china";
tvName.setText(name + position);
flag = !flag;
}
});
}
}
MyAdapter
package com.hugo.recylerviewdemo;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.List;
/**
* @auther Hugo
* Created on 2016/5/12 20:29.
*/
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int NORMAL_TYPE = 0;
private static final int CHECK_TYPE = 1;
@Override
public int getItemViewType(int position) {
if (position % 4 == 0) {
return CHECK_TYPE;
}
return NORMAL_TYPE;
}
private List<String> datas;
public MyAdapter(List<String> datas) {
this.datas = datas;
}
private OnItemClickListener clickListener;
public void setClickListener(OnItemClickListener clickListener) {
this.clickListener = clickListener;
}
public static interface OnItemClickListener {
void onClick(View view, int position);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == NORMAL_TYPE) {
return new NormalHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_normal, parent, false));
} else
return new CheckHoldr(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_check, parent, false));
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof NormalHolder) {
((NormalHolder) holder).tv_name.setText(datas.get(position));
} else {
((CheckHoldr) holder).tv_name.setText(datas.get(position));
}
}
@Override
public int getItemCount() {
return datas.size();
}
class NormalHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView tv_name;
LinearLayout rootView;
public NormalHolder(View itemView) {
super(itemView);
tv_name = (TextView) itemView.findViewById(R.id.tv_name);
rootView = (LinearLayout) itemView.findViewById(R.id.root_view);
rootView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (clickListener != null) {
clickListener.onClick(itemView, getAdapterPosition());
}
}
}
class CheckHoldr extends NormalHolder {
public CheckHoldr(View itemView) {
super(itemView);
}
}
}
网友评论
Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at com.ouman.sia.adapters.Main2RecyclerViewAdapter.onBindViewHolder(Main2RecyclerViewAdapter.java:66)
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == NORMAL_TYPE) {
return new NormalHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item_icon, parent, false));
} else
return new CheckHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item_icon_bages, parent, false));
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof NormalHolder) {
((NormalHolder) holder).tv_name.setText(data.get(position).getSection());
((NormalHolder) holder).iv_icon.setImageResource(data.get(position).getIconId());
} else {
((CheckHolder) holder).tv_name.setText(data.get(position).getSection());
((CheckHolder) holder).iv_icon.setImageResource(data.get(position).getIconId());
}
}