移動開發筆記(六)聊天室和Kotlin

1.聊天框

創建activity_chat.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="match_parent"
    tools:context=".Chat"
    android:orientation="vertical">
    <androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:id="@+id/chatRecyclerView"
        ></androidx.recyclerview.widget.RecyclerView>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
        <EditText
            android:id="@+id/inputText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            ></EditText>
        <Button
            android:id="@+id/send"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="發送"
            tools:ignore="InvalidId"></Button>
    </LinearLayout>
</LinearLayout>

編寫chat Activity

class Chat : 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_chat)
        initMsg()
        val layoutManager=LinearLayoutManager(this)
        chatRecyclerView.layoutManager=layoutManager
        adapter= MsgAdapter(msgList)
        chatRecyclerView.adapter=adapter
        send.setOnClickListener(this)
    }

    private fun initMsg(){
        val msg1=Msg("在嗎?",Msg.TYPE_RECEIVED)
        msgList.add(msg1)
        val msg2=Msg("在",Msg.TYRE_SENT)
        msgList.add(msg2)
        val msg3=Msg("上號!!",Msg.TYPE_RECEIVED)
        msgList.add(msg3)
    }

    override fun onClick(v: View?) {
        when(v){
            send -> {
                val content = inputText.text.toString()
                if(content.isNotEmpty()){
                    val msg=Msg(content,Msg.TYRE_SENT)
                    msgList.add(msg)
                    adapter?.notifyItemInserted(msgList.size - 1)//當有新消息時,刷新RecyclerView中的顯示
                    chatRecyclerView.scrollToPosition(msgList.size-1)//定位到最後一行
                    inputText.setText("")
                }
            }
        }
    }


}




創建實體類Msg

class Msg(val content:String,val type:Int) {
    companion object{
        const val TYPE_RECEIVED=0
        const val TYRE_SENT=1
    }
}

創建MsgAdapter

class MsgAdapter (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)=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 {
        return msgList.size
    }
}

創建兩個xml
1msg_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"
    android:orientation="vertical"
    >
    <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"
            ></TextView>
    </LinearLayout>
</FrameLayout>
2.msg_right_item
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:orientation="vertical"
    >
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/message_right"
        android:layout_gravity="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"
            ></TextView>
    </LinearLayout>
</FrameLayout>

2.Kotlin增強

2.1對變量延遲初始化
關鍵字lateinit

class Chat : AppCompatActivity(), View.OnClickListener {
    private val msgList =ArrayList<Msg>()
   // private var adapter:MsgAdapter?=null
    private lateinit var adapter : MsgAdapter
 val content = inputText.text.toString()
                if(content.isNotEmpty()){
                    val msg=Msg(content,Msg.TYRE_SENT)
                    msgList.add(msg)
                   // adapter?.notifyItemInserted(msgList.size - 1)//當有新消息時,刷新RecyclerView中的顯示
                    adapter.notifyItemInserted(msgList.size - 1)
                    chatRecyclerView.scrollToPosition(msgList.size-1)//定位到最後一行
                    inputText.setText("")

它可以告訴Kotlin編譯器,我們會延遲初始化的
判斷全局變量是否完成初始化

if(!::adapter.isInitialized){
            adapter= MsgAdapter(msgList)      
        }
2.2使用密封優化代碼
關鍵字 sealed class
創建一個Kotlin文件    Result.kt
sealed class  Result
class Success(val msg:String ) : Result()
class Failure (val error:Exception) : Result()

fun getResultMsg(result: Result)=when(result){
    is Success ->result.msg
    is Failure ->result.error.message
}

當When語句傳入一個密封類變量作爲條件時,kotlin編譯器會自動檢查該密封類有哪些子類,並強制要求你將每一個子類對應的條件全部處理。這樣幫助及時沒有編寫else條件也不肯出現漏寫的情況。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章