开发简单Android聊天软件(5)

绘制消息页面

在 “开发简单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作为判断条件。

三、总结

初始的聊天功能就这样完成了。能够实现聊天发送,界面加载聊天数据渲染显示,能区分左右消息分开显示,我们甚至还把图片消息的布局也准备好了。
但是距离可用还是有不少差距,比如聊天数据发送支持显示了,那接受到的消息其实还没能加载。下期我们介绍如何接受消息并实时显示,还有保存消息。

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值