女朋友生气了怎么办???——编写一个道歉室

一、实践——编写一个聊天框

笔者昨天玩游戏把女朋友惹生气了,编写了一个道歉室哄女朋友,给女朋友真诚的表示错了。(生气的女朋友比过年的猪都难抓)
在这里插入图片描述

1、制作9-Patch图片

在Android stdio中点击图片右键,找到9-Patch然后一键生成,

在这里插入图片描述

然后使用鼠标将不需要变化的地方涂黑,这个目的是为了让图标更好的适配,只有涂黑的部分才会发生长宽的变化,类比一下QQ的聊天气泡,有多少文字就有多大的聊天气泡。

2、构建主页面activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/RecyclerView1"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <EditText
            android:id="@+id/text1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="2"
            android:hint="Type something here"
            android:maxLines="2"/>

        <Button
            android:id="@+id/Button1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Send"/>

    </LinearLayout>

</LinearLayout>

2.2 复习hint、maxLines

android:hint="Type something here"的作用是显示了一段提示性文本

android:maxLines="2"的作用是设置最大可见行数

效果如图:image-20230721155656604

3、构建实体类Msg

public class Msg {
    public static final int TYPE_RECEIVED = 0;  //收到的消息
    public static final int TYPE_SENT = 1;  //发送的消息

    private String content; //消息内

    private int type;   //消息类型

    public Msg(String content, int type) {
        this.content = content;
        this.type = type;
    }

    public String getContent() {
        return content;
    }

    public int getType() {
        return type;
    }
}

用来储存消息

4、编写RecycleView子项的布局

新建msg_item.xml

<?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="wrap_content"
    android:orientation="vertical"
    android:padding="10dp">

    <LinearLayout
        android:id="@+id/Left_chat"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="left"
        android:background="@drawable/chat_left"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/Left_Msg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="left"
            android:gravity="center|left"
            android:layout_margin="10dp" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/Right_chat"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:background="@drawable/chat_right"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/Right_Msg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:layout_margin="10dp"/>

    </LinearLayout>
</LinearLayout>

这里我们让收到的消息居左对齐,发出的消息居右对齐,你可能会有些疑虑,怎么能让收到的消息和发出的消息都放在同一个布局里呢?不用担心,还记得我们前面学过的可见属性吗?只要稍后在代码中根据消息的类型来决定隐藏和显示哪种消息就可以了。

5、创建RecycleView的适配器类——MsgAdaoter

如果忘记了,可以看看上一篇博客有关于RecycleView的使用

5.1 复习setVisibility隐藏与显示

所有的Android控件都具有这个属性。

visible表示控件是可见的,这个值是默认值,不指定android:visibility时,控件都是可见的。

invisbale 表示控件不可见,但是它仍然占据着原来的位置和大小,可以理解成控件变成透明状态了。

gone 则表示控件不仅不可见,而且不再占用任何屏幕空间。

public class MsgAdapter extends RecyclerView.Adapter<MsgAdapter.ViewHolder> {

    private List<Msg> mMsgList;

    public MsgAdapter(List<Msg> mMsgList) {
        this.mMsgList = mMsgList;
    }

    @NonNull
    @Override
    public MsgAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate
                (R.layout.msg_item,parent,false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull MsgAdapter.ViewHolder holder, int position) {
        Msg msg = mMsgList.get(position);
        if(msg.getType() == Msg.TYPE_RECEIVED){
            //如果收到消息则显示左布局,不显示右布局
            holder.binding.LeftChat.setVisibility(View.VISIBLE);
            holder.binding.RightChat.setVisibility(View.GONE);
            holder.binding.LeftMsg.setText(msg.getContent());
        } else if (msg.getType() == Msg.TYPE_SENT) {
            //如果发出消息则显示右布局,不显示左布局
            holder.binding.LeftChat.setVisibility(View.GONE);
            holder.binding.RightChat.setVisibility(View.VISIBLE);
            holder.binding.RightMsg.setText(msg.getContent());
        }
    }

    @Override
    public int getItemCount() {
        return mMsgList.size();
    }

    static class ViewHolder extends RecyclerView.ViewHolder {
        MsgItemBinding binding;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            binding = MsgItemBinding.bind(itemView);
        }
    }
}

6、修改MainActivity中的代码

public class MainActivity extends AppCompatActivity {

    private List<Msg> msgList = new ArrayList<>();  //保存消息

    private List<Msg> ListmsgList = new ArrayList<>();  //保存消息

    private MsgAdapter msgAdapter;

    private int LeftMsgNumber = 0;  //确定左边回复哪一条消息

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initMsgs();//初始化所有消息
        LeftinitMsgs();//初始化左侧消息

        ActivityMainBinding activityMainBinding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(activityMainBinding.getRoot());
        //制作布局方式
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        //设置布局方式
        activityMainBinding.RecyclerView1.setLayoutManager(linearLayoutManager);
        //制作适配器并传递数据
        msgAdapter = new MsgAdapter(msgList);

        activityMainBinding.RecyclerView1.setAdapter(msgAdapter);


        activityMainBinding.Button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                String text = activityMainBinding.text1.getText().toString();
                Log.d("TAg",text+("".equals(text)));
                if(!"".equals(text)){
                    Msg msg = new Msg(text,Msg.TYPE_SENT);
                    msgList.add(msg);

                    //清空输入框内容
                    activityMainBinding.text1.setText("");

                    //左边回的消息
                    msgList.add(ListmsgList.get(LeftMsgNumber++));
                    //如果预定的消息数回复完了,从头开始
                    if(LeftMsgNumber == ListmsgList.size()) LeftMsgNumber = 0;;

                    //当有新的消息时刷新在RecycleView中的显示
                    msgAdapter.notifyItemInserted(msgList.size()-1);

                    //RecycleView定位到最后一行
                    activityMainBinding.RecyclerView1.scrollToPosition(msgList.size()-1);
                }
            }
        });

    }

    private void initMsgs(){
        Msg msg1 = new Msg("XXXXXXXXXXXXXXXXXXXXXXXXXXXXX",Msg.TYPE_RECEIVED);
        msgList.add(msg1);
    }

    private void LeftinitMsgs(){
        Msg msg1 = new Msg("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",Msg.TYPE_RECEIVED);
        ListmsgList.add(msg1);
        ListmsgList.add(msg18);
    }
}

解释一下这两行代码:

//当有新的消息时刷新在RecycleView中的显示
msgAdapter.notifyItemInserted(msgList.size()-1);

//RecycleView定位到最后一行
activityMainBinding.RecyclerView1.scrollToPosition(msgList.size()-1);

msgAdapter.notifyItemInserted(msgList.size()-1);

  • 通知适配器msgAdapter有一个新的消息被插入到了列表中,以便更新RecyclerView的显示。在这里,msgList.size()-1表示最后一条消息的位置索引。这意味着当有新的消息加入到msgList列表中时,RecyclerView会刷新并显示新的消息。

activityMainBinding.RecyclerView1.scrollToPosition(msgList.size()-1);

  • 这行代码通过RecyclerView的scrollToPosition方法将RecyclerView定位到指定位置。在这里,msgList.size()-1表示最后一条消息的位置索引,所以这行代码的作用是将RecyclerView滚动到最后一条消息,确保用户能够直接看到最新的消息。

注: 笔者在这里也附带上打包好的APK文件

baidu网盘下载地址:点击即可下载。
「下载地址」

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

摸鱼小小虫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值