制作9-Patch图片以及设计聊天界面

普通图片会被均匀拉伸,如下:

 会被均匀拉伸成

使用效果非常差,可以使用9-patch图片来进行改善。、

在Android Studio中,我们可以将任何png类型的图片制作成9-Patch图片。

步骤如下:

首先对着   message_left.png  图片右击  → Create 9-Patch file,会出现如下图片: 

上边框和左边框绘制的部分表示当图片需要拉伸时就拉伸黑点标记的区域

下边框和右边框绘制的部分表示内容允许被放置的区域

需要删掉原来的图片,因为Android项目中不允许同一文件夹下有两张相同名称的图片!!!!

设计聊天界面:

新建两个子布局 msg_left_item.xml 和 msg_right_item.xml

msg_left_item代码如下:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="10dp">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="left"
        android:background="@drawable/message_left" >

        <TextView
            android:id="@+id/leftMsg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_margin="10dp"
            android:textColor="#fff" />

    </LinearLayout>

</FrameLayout>

msg_right_item代码如下:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="10dp">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:background="@drawable/message_right">

        <TextView
            android:id="@+id/rightMsg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_margin="10dp"
            android:textColor="#000" />

    </LinearLayout>

</FrameLayout>

分别用两个设计好的9-patch图作为背景。

然后创建RecyclerView的适配器,新建类MsgAdapter,代码如下:

class MsgAdapter(private val msgList: List<Msg>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
    inner class LeftViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val leftMsg: TextView = view.findViewById(R.id.leftMsg)
    }

    inner class RightViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val rightMsg: TextView = view.findViewById(R.id.rightMsg)
    }

    override fun getItemViewType(position: Int): Int {
        val msg = msgList[position]
        return msg.type
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder =
        if (viewType == Msg.TYPE_RECEIVED) {
            val view =
                LayoutInflater.from(parent.context).inflate(R.layout.msg_left_item, parent, false)
            LeftViewHolder(view)
        } else {
            val view =
                LayoutInflater.from(parent.context).inflate(R.layout.msg_right_item, parent, false)
            RightViewHolder(view)
        }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val msg = msgList[position]
        when (holder) {
            is LeftViewHolder -> holder.leftMsg.text = msg.content
            is RightViewHolder -> holder.rightMsg.text = msg.content
            else -> throw IllegalArgumentException()
        }
    }

    override fun getItemCount(): Int = msgList.size
}

根据不同的viewType创建不同的界面。

定义两个viewHolder,LeftViewHolder和RightViewHolder,分别缓存msg_left_item.xml和msg_right_item.xml布局中的控件。然后重写getItemViewType()方法,并在这个方法中返回当前position对应的消息类型。

然后重写三个函数,均按照不同的viewHolder类型来进行创建

在onCreateViewHolder()方法中根据不同的viewType来加载不同的布局并创建不同的ViewHolder。然后在onBindViewHolder()方法中判断ViewHolder的类型:如果是LeftViewHolder,就将内容显示到左边的消息布局;如果是RightViewHolder,就将内容显示到右边的消息布局。

最后在MainActivity中些如下代码:

class MainActivity : AppCompatActivity(), View.OnClickListener {
    private val msgList = ArrayList<Msg>()
    private var adapter:MsgAdapter? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initMsg()
        val layoutManager = LinearLayoutManager(this)
        val recyclerView: RecyclerView = findViewById(R.id.recyclerView)
        recyclerView.layoutManager = layoutManager
        adapter = MsgAdapter(msgList)
        recyclerView.adapter = adapter
        val send: Button = findViewById(send)
        send.setOnClickListener(this)
    }

    override fun onClick(p0: View?) {
        if (p0 != null) {
            when (p0.id) {
                send ->{
                    val inputText:TextView = findViewById(R.id.inputText)
                    val recyclerView:RecyclerView = findViewById(R.id.recyclerView)
                    val content = inputText.text.toString()
                    if (content.isNotEmpty()) {
                        val msg = Msg(content, Msg.TYPE_SEND)
                        msgList.add(msg)
                        adapter?.notifyItemInserted(msgList.size - 1)
                        recyclerView.scrollToPosition(msgList.size-1)
                        inputText.text = ""
                    }
                }
            }
        }
    }

    private fun initMsg(){
        msgList.add(Msg("Hello guys!", Msg.TYPE_RECEIVED))
        msgList.add(Msg("Hello,who are you?", Msg.TYPE_SEND))
        msgList.add(Msg("This is mmm,i love you!", Msg.TYPE_RECEIVED))
    }
}

主要是定义了主界面send按钮的点击事件,获得EditText中的文本内容,然后通过Send 按钮发送,并当发送的消息不为空时,调用适配器的notifyItemInserted()方法,通知列表有新的消息插入,从而完成显示。

或者可以使用notifyDataSetChanged()方法,它会将RecyclerView中所有可见的元素全部刷新,这样不管是新增、删除、还是修改元素,界面上都会显示最新的数据,但缺点是效率会相对差一些。

接着调用RecyclerView的scrollToPosition()方法,定位到最后一行,完成显示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值