绘制消息页面
在 “开发简单Android聊天软件(4)” 中,完成了聊天界面的绘制,现在我们来完成对应的ChatActivity。
一、ChatActivity获取页面组件对象,监听点击事件
public class ChatActivity extends AppCompatActivity implements View.OnClickListener {
public static final String CHAT_TOUSER="chat_touser";
public static final String CHAT_MID="chat_mid";
public static final String CHAT_TOUSER_IMAGE="chat_touser_image";
private static String chat_toUser,chat_mid,chat_user,chat_toUserImage;
private static List<Im_msg_content> imMsgContentList=new ArrayList<>();
private EditText chatInputText;
private Button chatButton;
private static RecyclerView recyclerView;
private static LinearLayoutManager layoutManager;
public static ChatAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActionBar actionBar = getSupportActionBar();
actionBar.hide(); //隐藏actionBar
setContentView(R.layout.activity_chat);
recyclerView=(RecyclerView)findViewById(R.id.chat_recycview);
layoutManager=new LinearLayoutManager(this);
chat_activity_dialog=(LinearLayout)findViewById(R.id.chat_activity_dialog);
chatButton=(Button)findViewById(R.id.chat_send);
chatButton.setOnClickListener(this);
chatInputText=(EditText)findViewById(R.id.chat_inputText);
initMsg();
}
public static void initMsg(){
//初始化历史聊天数据
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.chat_send:
if(!chatInputText.getText().toString().trim().equals("")) {
send();
}
break;
}
}
private void send(){
try {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Im_msg_content sendIm= new Im_msg_content();
sendIm.setCid("c_"+chat_user+"_to_"+chat_toUser);
sendIm.setContent(chatInputText.getText().toString().trim()); //获取输入框文字
sendIm.setCreate_time(df.format(new Date()));
sendIm.setMsg_type(0);
sendIm.setRecipient_id(chat_toUser);
sendIm.setSender_id(chat_user);
JSONObject init = new JSONObject();
init.put("content", sendIm.getContent());
init.put("sender_id", sendIm.getSender_id());
init.put("recipient_id",sendIm.getRecipient_id());
init.put("msg_type", sendIm.getMsg_type());
init.put("cid",sendIm.getCid());
init.put("create_time", sendIm.getCreate_time());
sendMsg(init.toString()); //调用长连接消息发送接口。并封装方法sendMsg;
layoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(layoutManager); //将recyclerView列表滚动到最底部
imMsgContentList.add(sendIm); //将消息添加到消息list
adapter=new ChatAdapter(imMsgContentList); 更新消息list到recycler适配器
recyclerView.setAdapter(adapter);
chatInputText.setText("");
} catch (JSONException e) {
e.printStackTrace();
}
}
1、在ChatActivity中,获取到布局中的对象,调用本次消息recyclerView的适配器ChatAdapter,创建一个消息list:imMsgContentList,将其装载到ChatAdapter,完成数据加载。
2、然后给chatButton加入了监听事件,获取chatInputText中的消息文本,封装成消息对象后,一边调用长连接发送方法,一边将对象放入消息list。
二、ChatAdapter
public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ViewHolder> {
private List<Im_msg_content> mImMsgContentList;
private Context mContext;
private ViewHolder viewHolder1;
private File leftavaterfile,rightavaterfile;
private String user_id ="u_00001" //这里作为代码示例,将当前用户写死,实际上应该是全局获取
static class ViewHolder extends RecyclerView.ViewHolder {
LinearLayout leftLayout ,leftMessage; //左布局
LinearLayout rightLayout ,rightMessage; //右布局
TextView leftMsg; //左消息
TextView rightMsg; //右消息
ImageView rightSending; //左图片消息 本期不予实现
ImageView rightPhoto,leftPhoto; //右图片消息 本期不予实现
CircleImageView rightAvater,leftAvater; //左右头像 本期不予实现
//圆形头像组件来自于implementation 'de.hdodenhof:circleimageview:2.1.0'
public ViewHolder(View view) {
super(view);
leftAvater=(CircleImageView)view.findViewById(R.id.left_avater);
rightAvater=(CircleImageView)view.findViewById(R.id.right_avater);
leftLayout = (LinearLayout) view.findViewById(R.id.left_layout);
rightLayout = (LinearLayout) view.findViewById(R.id.right_layout);
leftMessage= (LinearLayout) view.findViewById(R.id.message_left);
rightMessage= (LinearLayout) view.findViewById(R.id.message_right);
leftMsg = (TextView) view.findViewById(R.id.chat_left_msg);
rightMsg = (TextView) view.findViewById(R.id.chat_right_msg);
leftPhoto = (ImageView) view.findViewById(R.id.chat_left_photo);
rightPhoto = (ImageView) view.findViewById(R.id.chat_right_photo);
rightSending=(ImageView)view.findViewById(R.id.chat_right_sending);
}
}
public ChatAdapter(List<Im_msg_content> im_msg_content) {
mImMsgContentList = im_msg_content; //获取activity传入的消息list
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//initAvater();初始化头像,本期不予实现
if (mContext == null) {
mContext = parent.getContext(); //获取上下文
}
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_chat_msg, parent, false); //获取卡片对象
final ChatAdapter.ViewHolder holder = new ChatAdapter.ViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
final Im_msg_content imMsgContent = mImMsgContentList.get(position); //recyclerView对应每行对象,position对应位置坐标
if (imMsgContent.getSender_id().equals(user_id)) { //显示己方右侧卡片
holder.leftLayout.setVisibility(View.GONE); //左侧layout隐藏
holder.rightLayout.setVisibility(View.VISIBLE); //右侧layout显示
if (imMsgContent.getMsg_type() == 0) { //等于1是图片消息,0是文字消息
holder.rightPhoto.setVisibility(View.GONE);
holder.rightMessage.setVisibility(View.VISIBLE);
holder.rightMsg.setText(imMsgContent.getContent());
}
} else {
//完成加载图片逻辑
holder.rightPhoto.setVisibility(View.VISIBLE);
holder.rightMessage.setVisibility(View.GONE);
}
} else if (imMsgContent.getIshost().equals("0")) { //显示对方左侧卡片
holder.rightLayout.setVisibility(View.GONE);
holder.leftLayout.setVisibility(View.VISIBLE);
if (imMsgContent.getMsg_type() == 0) { //等于1是图片消息,0是文字消息
holder.leftPhoto.setVisibility(View.GONE);
holder.leftMessage.setVisibility(View.VISIBLE);
holder.leftMsg.setText(imMsgContent.getContent());
}
} else {
//完成加载图片逻辑
holder.leftPhoto.setVisibility(View.VISIBLE);
holder.leftMessage.setVisibility(View.GONE);
}
}
}
@Override
public int getItemCount() {
return mImMsgContentList.size(); //反馈list总数
}
private void initAvater(){
//加载头像
}
public Context getmContext(){
return mContext;
}
}
1、在这个adapter中,我们需要同时给左右两个layout做显示隐藏处理。因为我们的card_chat_msg为了保证显示效果,是同时绘制了左右两侧布局的,而一条消息必然只会显示在左侧或者右侧,所以要时刻保持GONE和VISIBLE的切换。
2、每一条消息是分为发送方send和接收方recipient的。但是并不是消息体中sender_id的一方一定显示在右侧。比如你和张三聊天,张三作为send发的消息一定显示在界面上的左侧,你的消息显示在右侧。所以我们在渲染左右两侧布局的时候,以sender_id等于当前用户user_id作为判断条件。
三、总结
初始的聊天功能就这样完成了。能够实现聊天发送,界面加载聊天数据渲染显示,能区分左右消息分开显示,我们甚至还把图片消息的布局也准备好了。
但是距离可用还是有不少差距,比如聊天数据发送支持显示了,那接受到的消息其实还没能加载。下期我们介绍如何接受消息并实时显示,还有保存消息。