compile ‘me.drakeet.multitype:multitype:3.1.0‘
compile ‘me.drakeet.multitype:multitype:3.1.0‘
dependencies {
compile(‘me.drakeet.multitype:multitype:3.1.0‘, {
exclude group: ‘com.android.support‘
})
compile ‘com.android.support:recyclerview-v7:你选择的版本‘
}
public class SimpleImage extends ContentModel {
public int resId;
public SimpleImage(int resId) {
super(ContentModel.TYPE_SIMPLE_IMAGE);
this.resId = resId;
}
}
public class SimpleImageViewBinder extends ItemViewBinder<SimpleImage, SimpleImageViewBinder.ViewHolder> {
@NonNull
@Override
protected ViewHolder onCreateViewHolder(@NonNull LayoutInflater inflater, @NonNull ViewGroup parent) {
View contentView = inflater.inflate(R.layout.item_weibo_simple_image, parent, false);
return new ViewHolder(contentView);
}
@Override
protected void onBindViewHolder(@NonNull ViewHolder holder, @NonNull SimpleImage item) {
holder.simpleImage.setImageResource(item.resId);
}
static class ViewHolder extends RecyclerView.ViewHolder {
private ImageView simpleImage;
ViewHolder(View itemView) {
super(itemView);
simpleImage = (ImageView) itemView.findViewById(R.id.simple_image);
}
}
}
MultiTypeAdapter adapter = new MultiTypeAdapter();
adapter.register(SimpleImage.class, new SimpleImageViewBinder());
adapter.register(SimpleText.class, new SimpleTextViewBinder());
recyclerView.setAdapter(adapter);
List<Simple_Content> items = new ArrayList<>();
adapter.setItems(items);
adapter.register(Data.class).to(
new DataType1ViewBinder(),
new DataType2ViewBinder()
).withClassLinker(new ClassLinker<Data>() {
@NonNull @Override
public Class<? extends ItemViewBinder<Data, ?>> index(@NonNull Data data) {
if (data.type == Data.TYPE_2)
return DataType2ViewBinder.class;else
return DataType1ViewBinder.class;}
});
adapter.register(Data.class).to(
new DataType1ViewBinder(),
new DataType2ViewBinder()
).withLinker(new Linker<Data>() {
@Override
public int index(@NonNull Data data) {
if (data.type == Data.TYPE_2) return 1;
else return 0;
}
});
assertHasTheSameAdapter(recyclerView, adapter);//断言 recyclerView 使用的是正确的 adapter,必须在setAdapter(adapter) 之后调用
assertAllRegistered(adapter, items);//断言所有使用的类型都已注册,需要在加载或更新数据之后调用
public class ChatActivity extends Activity {
private static final String TEXT = "不懂左右逢源,不喜趋炎附势,不会随波逐流,不狡辩,不恭维,不把妹";
private static final String PATH1 = "http://img.mmjpg.com/2015/74/33.jpg";
private static final String PATH2 = "http://img.mmjpg.com/2015/74/35.jpg";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RecyclerView recyclerView = new RecyclerView(this);
MultiTypeAdapter adapter = new MultiTypeAdapter();
//一对多,都有相同的父框架结构(头像、昵称、时间……等)
adapter.register(ContentModel.class).to(
new SimpleTextViewBinder(ContentModel.SEND_TYPE_OTHERS),//左边的布局(别人发的消息)
new SimpleTextViewBinder(ContentModel.SEND_TYPE_YOURSELF),//右边的布局(自己发的消息)
new SimpleImageViewBinder(ContentModel.SEND_TYPE_OTHERS),
new SimpleImageViewBinder(ContentModel.SEND_TYPE_YOURSELF),
new SimpleVoiceViewBinder(ContentModel.SEND_TYPE_OTHERS),
new SimpleVoiceViewBinder(ContentModel.SEND_TYPE_YOURSELF)
).withLinker(model -> {
if (model.msgType == ContentModel.MSG_TYPE_SIMPLE_TEXT
&& model.sendType == ContentModel.SEND_TYPE_OTHERS) return 0;//左边的布局(别人发的消息)
else if (model.msgType == ContentModel.MSG_TYPE_SIMPLE_TEXT
&& model.sendType == ContentModel.SEND_TYPE_YOURSELF) return 1;//右边的布局(自己发的消息)
else if (model.msgType == ContentModel.MSG_TYPE_SIMPLE_IMAGE
&& model.sendType == ContentModel.SEND_TYPE_OTHERS) return 2;
else if (model.msgType == ContentModel.MSG_TYPE_SIMPLE_IMAGE
&& model.sendType == ContentModel.SEND_TYPE_YOURSELF) return 3;
else if (model.msgType == ContentModel.MSG_TYPE_SIMPLE_VOICE
&& model.sendType == ContentModel.SEND_TYPE_OTHERS) return 4;
else if (model.msgType == ContentModel.MSG_TYPE_SIMPLE_VOICE
&& model.sendType == ContentModel.SEND_TYPE_YOURSELF) return 5;
return 0;
});
//一个独立的结构,没有父框架结构
adapter.register(BigImage.class, new BigImageViewBinder());
recyclerView.setLayoutManager(new LinearLayoutManager(this));//new GridLayoutManager(this,2)
recyclerView.setAdapter(adapter);
assertHasTheSameAdapter(recyclerView, adapter);//断言 recyclerView 使用的是正确的 adapter,可选择性使用
User other = new User("other", PATH1);
User yourself = new User("包青天", PATH2);
List<ContentModel> items = new ArrayList<>();
for (int i = 0; i < 50; i++) {
int sendType = new Random().nextBoolean() ? ContentModel.SEND_TYPE_OTHERS : ContentModel.SEND_TYPE_YOURSELF;
User user = sendType == ContentModel.SEND_TYPE_OTHERS ? other : yourself;
String path = sendType == ContentModel.SEND_TYPE_OTHERS ? PATH1 : PATH2;
int random = new Random().nextInt(4);
if (random == 0) items.add(new SimpleText(user, sendType, i + "、" + TEXT));
else if (random == 1) items.add(new SimpleImage(user, sendType, path));
else items.add(new SimpleVoice(user, sendType, path, new Random().nextInt(60)));
}
items.add(new BigImage(other, ContentModel.SEND_TYPE_OTHERS, PATH1));
items.add(new BigImage(yourself, ContentModel.SEND_TYPE_YOURSELF, PATH2));
adapter.setItems(items);
adapter.notifyDataSetChanged();
assertAllRegistered(adapter, items);//断言所有使用的类型都已注册,需要在加载或更新数据之后调用,可选择性使用
setContentView(recyclerView);
}
}
/**
* 各种消息类型的基类
*/
public abstract class ContentModel {
//消息类型
public static final int MSG_TYPE_SIMPLE_TEXT = 0;
public static final int MSG_TYPE_SIMPLE_IMAGE = 1;
public static final int MSG_TYPE_SIMPLE_VOICE = 2;
public static final int MSG_TYPE_BIG_IMAGE = 3;
//消息是谁发的
public static final int SEND_TYPE_OTHERS = 0;
public static final int SEND_TYPE_YOURSELF = 1;
public static final int SEND_TYPE_YSTEM = 2;
public int msgType;
public int sendType;
public String createTime;
/**
* 所有信息都可以封装到user中
*/
public User user;
protected ContentModel(User user, int msgType, int sendType) {
this.user = user;
this.msgType = msgType;
this.sendType = sendType;
this.createTime = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss SSS E", Locale.getDefault()).format(new Date());
}
}
public class ContentHolder {
public ChatFrameBinder.FrameHolder frameHolder;
public final View itemView;
public ContentHolder(final View itemView) {
this.itemView = itemView;
}
public ChatFrameBinder.FrameHolder getParent() {
return frameHolder;
}
public final int getAdapterPosition() {
return getParent().getAdapterPosition();
}
public final int getLayoutPosition() {
return getParent().getLayoutPosition();
}
public final int getOldPosition() {
return getParent().getOldPosition();
}
public final boolean isRecyclable() {
return getParent().isRecyclable();
}
public final void setIsRecyclable(boolean recyclable) {
getParent().setIsRecyclable(recyclable);
}
}
/**
* 此种方式非常适合聊天页面。
* 对于聊天页面,left和right的元素基本是完全相同的,唯一(会最大)的不同就是元素放置的位置不同
*/
public abstract class ChatFrameBinder<T extends ContentModel, H extends ContentHolder>
extends ItemViewBinder<ContentModel, ChatFrameBinder.FrameHolder> {
protected int sendType;
public ChatFrameBinder(int sendType) {
super();
this.sendType = sendType;
}
protected abstract ContentHolder onCreateContentViewHolder(LayoutInflater inflater, ViewGroup parent);
protected abstract void onBindContentViewHolder(H holder, T content);
@NonNull
@Override
protected FrameHolder onCreateViewHolder(@NonNull LayoutInflater inflater, @NonNull ViewGroup parent) {
View root;
if (sendType == ContentModel.SEND_TYPE_OTHERS) root = inflater.inflate(R.layout.item_frame_left, parent, false);
else root = inflater.inflate(R.layout.item_frame_right, parent, false);
ContentHolder subViewHolder = onCreateContentViewHolder(inflater, parent);
return new FrameHolder(root, subViewHolder);
}
@Override
@SuppressWarnings("unchecked")
protected void onBindViewHolder(@NonNull FrameHolder holder, @NonNull ContentModel model) {
Glide.with(holder.avatar.getContext()).load(model.user.avatar).into(holder.avatar);
holder.username.setText(model.user.name);
holder.createTime.setText(model.createTime);
onBindContentViewHolder((H) holder.subViewHolder, (T) model);
}
public static class FrameHolder extends RecyclerView.ViewHolder {
private ImageView avatar;
private TextView username;
private FrameLayout container;
private TextView createTime;
private ContentHolder subViewHolder;
FrameHolder(View itemView, final ContentHolder subViewHolder) {
super(itemView);
avatar = (ImageView) itemView.findViewById(R.id.avatar);
username = (TextView) itemView.findViewById(R.id.username);
container = (FrameLayout) itemView.findViewById(R.id.container);
createTime = (TextView) itemView.findViewById(R.id.create_time);
container.addView(subViewHolder.itemView);
this.subViewHolder = subViewHolder;
this.subViewHolder.frameHolder = this;
itemView.setOnClickListener(v -> Toast.makeText(v.getContext(), "Position=" + getAdapterPosition(), LENGTH_SHORT).show());
}
}
}
public class SimpleImage extends ContentModel {
public String imagePath;
public SimpleImage(User user, int sendType, String imagePath) {
super(user, ContentModel.MSG_TYPE_SIMPLE_IMAGE, sendType);
this.imagePath = imagePath;
}
}
public class SimpleImageViewBinder extends ChatFrameBinder<SimpleImage, SimpleImageViewBinder.ViewHolder> {
public SimpleImageViewBinder(int sendType) {
super(sendType);
}
@Override
protected ContentHolder onCreateContentViewHolder(LayoutInflater inflater, ViewGroup parent) {
View root;
if (sendType == ContentModel.SEND_TYPE_OTHERS) root = inflater.inflate(R.layout.item_simple_image_left, parent, false);
else root = inflater.inflate(R.layout.item_simple_image_right, parent, false);
return new SimpleImageViewBinder.ViewHolder(root);
}
@Override
protected void onBindContentViewHolder(ViewHolder holder, SimpleImage simpleImage) {
Glide.with(holder.simpleImage.getContext()).load(simpleImage.imagePath).into(holder.simpleImage);
}
static class ViewHolder extends ContentHolder {
private ImageView simpleImage;
ViewHolder(View itemView) {
super(itemView);
simpleImage = (ImageView) itemView.findViewById(R.id.simple_image);
}
}
}
public class BigImage extends ContentModel {
public String imagePath;
public BigImage(User user, int sendType, String imagePath) {
super(user, ContentModel.MSG_TYPE_BIG_IMAGE, sendType);
this.imagePath = imagePath;
}
}
public class BigImageViewBinder extends ItemViewBinder<BigImage, BigImageViewBinder.ViewHolder> {
@NonNull
@Override
protected ViewHolder onCreateViewHolder(@NonNull LayoutInflater inflater, @NonNull ViewGroup parent) {
View root = inflater.inflate(R.layout.item_big_image, parent, false);
return new ViewHolder(root);
}
@Override
protected void onBindViewHolder(@NonNull ViewHolder holder, @NonNull BigImage bigImage) {
Glide.with(holder.iv_pic.getContext()).load(bigImage.imagePath).into(holder.iv_pic);
holder.tv_path.setText(bigImage.imagePath);
}
static class ViewHolder extends RecyclerView.ViewHolder {
private ImageView iv_pic;
private TextView tv_path;
ViewHolder(View itemView) {
super(itemView);
iv_pic = (ImageView) itemView.findViewById(R.id.iv_pic);
tv_path = (TextView) itemView.findViewById(R.id.tv_path);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
style="@style/Weibo.Frame"
tools:ignore="UnusedAttribute, RtlHardcoded, ContentDescription">
<ImageView
android:id="@+id/avatar"
style="@style/Weibo.Avatar"
android:layout_marginRight="16dp"
android:src="@drawable/icon"/>
<TextView
android:id="@+id/username"
style="@style/Weibo.Username"
android:layout_alignTop="@id/avatar"
android:layout_toRightOf="@id/avatar"
tools:text="drakeet"/>
<FrameLayout
android:id="@+id/container"
style="@style/Weibo.SubView"
android:layout_alignLeft="@id/username"
android:layout_below="@id/username"
tools:background="@android:color/darker_gray"
tools:layout_height="72dp"/>
<TextView
android:id="@+id/create_time"
style="@style/Weibo.CreateTime"
android:layout_alignLeft="@id/username"
android:layout_below="@id/container"
tools:text="2017-7-18 11:53:59 星期二"/>
</RelativeLayout>
<?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="wrap_content">
<ImageView
android:id="@+id/simple_image"
style="@style/WeiboContent.SimpleImage"
tools:src="@drawable/icon"/>
</RelativeLayout>
原文:http://www.cnblogs.com/baiqiantao/p/7202134.html