这几天我们已经从 API 取得资料到包装成物件,再来就是资料显示罗。
这两天的范例会以对话页面为主,也会用到之前设计的 Chat
物件。今天要介绍把对话资料显示到 RecyclerView 上面。
Activity 和 Adapter 在 MVVM 属於 View 的范畴,用来显示资料,不过他们负责的部分还是有点差别。Activiy 负责跟ViewModel 取得资料,把 List 的资料给 Adapter,还有所有点击的监听器。Adapter 只负责将接到的资料显示到 RecyclerView 上。
物件间的关系图,可以参考 [[Android APP] 01-架构介绍-MVVM]。
OptionClickCallback optionClickCallback = new OptionClickCallback() {
@Override
public void onOptionClick(Option option) {
mViewModel.sendOptionMessage(option, categoryId);
}
@Override
public void noneOfAbove(Option option) {
mViewModel.sendOptionMessage(option, categoryId);
}
};
ChatAdapter mChatAdapter = new ChatAdapter(ChatActivity.this, chatArrayList,
optionClickCallback);
mRecyclerView.setLayoutManager(new LinearLayoutManager(ChatActivity.this));
mRecyclerView.setAdapter(mChatAdapter);
mRecyclerView.scrollToPosition(mChatAdapter.getItemCount() - 1);
new ChatAdapter(ChatActivity.this, chatArrayList, optionClickCallback);
这行就是要将整包的资料设置给 Adapter,并且把「回馈按钮」的监听器也一起给 Adapter。
private final Context mContext;
private final ArrayList<Chat> mChatList;
private final OptionClickCallback mOptionClickCallback;
public ChatAdapter(Context context, ArrayList<Chat> chatList, OptionClickCallback optionClickCallback) {
this.mContext = context;
this.mChatList = chatList;
this.mOptionClickCallback = optionClickCallback;
}
一开始,我们需要一些变数和建构子(Constructor)储存资料。
private static class RecyclerViewViewHolder extends RecyclerView.ViewHolder {
ImageView icon;
TextView text, option_message;
ConstraintLayout constraintLayout;
LinearLayout optionsArea, options;
Button opt1, opt2, opt3;
public RecyclerViewViewHolder(@NonNull View itemView) {
super(itemView);
icon = itemView.findViewById(R.id.img);
text = itemView.findViewById(R.id.text);
option_message = itemView.findViewById(R.id.option_message);
constraintLayout = itemView.findViewById(R.id.constraint_layout);
optionsArea = itemView.findViewById(R.id.options_area);
options = itemView.findViewById(R.id.options);
opt1 = itemView.findViewById(R.id.option1);
opt2 = itemView.findViewById(R.id.option2);
opt3 = itemView.findViewById(R.id.option3);
}
}
还需要一个 ViewHoder 用来 bind RecyclerView item 里的物件。
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
Chat chat = mChatList.get(position);
RecyclerViewViewHolder viewHolder = (RecyclerViewViewHolder) holder;
viewHolder.icon.setImageResource(chat.getIcon());
viewHolder.text.setText(chat.getText());
// 奇数列,底色改灰色
if (position % 2 != 0) {
viewHolder.constraintLayout.setBackgroundColor(ContextCompat.getColor(mContext, R.color.list_background));
}
// 有选项的 Chat,才显示 Option 区块
if (mChatList.get(position).getOptions().size() < 1) {
viewHolder.optionsArea.setVisibility(View.GONE);
} else {
// 取得所有 Option
ArrayList<Option> options = mChatList.get(position).getOptions();
// 设置选项的文字
viewHolder.opt1.setText(options.get(0).getQuestion());
viewHolder.opt2.setText(options.get(1).getQuestion());
viewHolder.opt3.setText(options.get(2).getQuestion());
// 设置三个选项的监听器
viewHolder.opt1.setOnClickListener(v -> mOptionClickCallback.onOptionClick(options.get(0)));
viewHolder.opt2.setOnClickListener(v -> mOptionClickCallback.onOptionClick(options.get(1)));
viewHolder.opt3.setOnClickListener(v -> mOptionClickCallback.noneOfAbove(options.get(2)));
// 选项显示的开关,预设 Gone
viewHolder.option_message.setOnClickListener(v -> {
if (viewHolder.options.getVisibility() == View.GONE) {
viewHolder.options.setVisibility(View.VISIBLE);
} else {
viewHolder.options.setVisibility(View.GONE);
}
});
}
}
最後把对话讯息的文字、回馈按钮的内容都设置上去,今天就完工罗!!
>>: Day 27 - 3D绘图篇 - 2D图片上面的3D物件是怎麽产生的? I - 成为Canvas Ninja ~ 理解2D渲染的精髓
今天的内容属於设计模式的一种。 当我们从後端接到资料後,有时後资料格式往往不是如我们所想,所以会再加...
Golang Golang gin Middleware中间件 我第一次接触Middleware这个...
我们都要谈Django了,总不能连他是什麽都不知道吧? 那既然你都诚心诚意地发问了,那我就大发慈悲地...
今晚我想来点... 麻而不辣的 linker script [叮咚] 您的外送餐点到瞜, 已经依照您...
课程目标 了解系统分析实务、系统分析工具之应用、逻辑资料库设计技巧、系统分析产出文件、同仁审查等,以...