第四章 UI
注:因为和第一行代码第二版高度重合,所以我就记了一些我不太熟的地方和不一样的地方
4.2常用控件
4.2.2Button
android:textAllCaps="false"//取消默认大写字体
设计点击事件:
- 匿名内部类式
button.setOnClickListener{
}
- 实现接口式
class MainActivity : AppCompatActivity() , View.OnClickListener{
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button.setOnClickListener(this)
}
override fun onClick(p0: View?) {
when(p0?.id){
R.id.button ->{
}
}
}
}
补充:kotlin 的set/get方法的语法糖,一般直接写带有它们的格式然后利用代码提示tab来获取简便用法
4.2.4 ImageView
imageView.setImageResource(R.drawable.img_2)
4.2.5 ProgressBar
4.2.6 AlertDialog
AlertDialog.Builder(this).apply {
setTitle("This is a Title")
setMessage("This is a Message")
setCancelable(false)
setPositiveButton("OK"){
dialog,which ->
}
setNegativeButton("Cancel"){
dialog,which ->
}
show()
}
4.3 布局
4.3.1 线性布局
4.3.2 相对布局
- 相对父布局位置
<RelativeLayout 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=".MainActivity">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="button1"
/>
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="button2"
/>
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="button3"
/>
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:text="button4"
/>
<Button
android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:text="button5"
/>
</RelativeLayout>
- 相对其他控件位置
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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=".MainActivity">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/button3"
android:layout_toLeftOf="@id/button3"
android:text="button1"
/>
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/button3"
android:layout_toRightOf="@id/button3"
android:text="button2"
/>
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="button3"
/>
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/button3"
android:layout_toLeftOf="@id/button3"
android:text="button4"
/>
<Button
android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/button3"
android:layout_toRightOf="@id/button3"
android:text="button5"
/>
</RelativeLayout>
- 边缘对齐
- android:layout_alignLeft 表示一个控件和另一个控件左边缘对齐
- 右边,底部和顶部类似
4.3.3 FrameLayout
控件默认摆放在左上角,xml中放在下面的控件压在上层,用layout_gravity定位
4.4 创建自定义控件
4.4.1 引入布局
- 写布局文件
- 利用 引入
补充:supportActioinBar?.hide( )隐藏标题栏
4.4.3 创建自定义控件
- 自定义控件布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="wrap_content">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/titleBack"
android:layout_gravity="center"
android:layout_margin="5dp"
android:text="Back"
android:textColor="#fff"
></Button>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/titleText"
android:layout_weight="1"
android:gravity="center"
android:text="Title Text"
android:textColor="#fff"
android:textSize="24sp"
></TextView>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/titleEdit"
android:layout_gravity="center"
android:layout_margin="5dp"
android:text="Edit"
android:textColor="#fff"
></Button>
</LinearLayout>
- 编写自定义控件代码
class TitleLayout(context: Context, attrs: AttributeSet):LinearLayout(context,attrs) {
init{
LayoutInflater.from(context).inflate(R.layout.title,this)
titleBack.setOnClickListener {
val activity = context as Activity
activity.finish()
}
titleEdit.setOnClickListener {
Toast.makeText(context,"You clicked Edit button",Toast.LENGTH_LONG).show()
}
}
}
- 引入控件
<android.bignerdranch.uilayouttest.TitleLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"></android.bignerdranch.uilayouttest.TitleLayout>
##4.5 ListView
4.5.1 简单用法
- 布局放入listview
- 代码
private val data = listOf("苹果","梨子","香蕉","西瓜","凤梨","火龙果","龙眼","枸杞","水蜜桃","樱桃")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val adapter = ArrayAdapter<String>(this, androidx.appcompat.R.layout.support_simple_spinner_dropdown_item,data)
listView.adapter = adapter
}
4.5.2 定制 ListView 的界面
- 准备一组图片,放下android-xxhdpi下
- 定义实体类
class Fruit(val name:String,val imageId:Int) {
}
- 定义子项布局 fruit_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="60dp">
<ImageView
android:id="@+id/fruitImage"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"/>
<TextView
android:id="@+id/fruitName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp" />
</LinearLayout>
- 自定义适配器
class FruitAdapter(activity: Activity, val resourceId: Int,data:List<Fruit>) : ArrayAdapter<Fruit>(activity,resourceId,data){
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val view = LayoutInflater.from(context).inflate(resourceId,parent,false)
val fruitImage : ImageView = view.findViewById(R.id.fruitImage)
val fruitName : TextView = view.findViewById(R.id.fruitName)
val fruit = getItem(position)
if (fruit != null) {
fruitImage.setImageResource(fruit.imageId)
fruitName.text = fruit.name
}
return view
}
}
- 编写代码
class MainActivity : AppCompatActivity() {
private val fruitList = ArrayList<Fruit>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initFruits()
val adapter = FruitAdapter(this, R.layout.fruit_item,fruitList)
listView.adapter = adapter
}
private fun initFruits(){
repeat(2){
fruitList.add(Fruit("Apple",R.drawable.apple_pic))
fruitList.add(Fruit("Banana",R.drawable.banana_pic))
fruitList.add(Fruit("Orange",R.drawable.orange_pic))
fruitList.add(Fruit("Watermelon",R.drawable.watermelon_pic))
fruitList.add(Fruit("Pear",R.drawable.pear_pic))
fruitList.add(Fruit("Grape",R.drawable.grape_pic))
fruitList.add(Fruit("Pineapple",R.drawable.pineapple_pic))
fruitList.add(Fruit("Strawberry",R.drawable.strawberry_pic))
fruitList.add(Fruit("Cherry",R.drawable.cherry_pic))
fruitList.add(Fruit("Mango",R.drawable.mango_pic))
}
}
}
4.5.3 提升 ListView 的运行效率
class FruitAdapter(activity: Activity, val resourceId: Int,data:List<Fruit>) : ArrayAdapter<Fruit>(activity,resourceId,data){
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val view:View
val viewHolder: ViewHolder
if (convertView == null) {
view = LayoutInflater.from(context).inflate(resourceId,parent,false)
val fruitImage : ImageView = view.findViewById(R.id.fruitImage)
val fruitName : TextView = view.findViewById(R.id.fruitName)
viewHolder = ViewHolder(fruitImage,fruitName)
view.tag = viewHolder
}else{
view = convertView
viewHolder = view.tag as ViewHolder
}
val fruit = getItem(position)
if (fruit != null) {
viewHolder.fruitImage.setImageResource(fruit.imageId)
viewHolder.fruitName.text = fruit.name
}
return view
}
inner class ViewHolder(val fruitImage: ImageView, val fruitName: TextView)
}
4.5.4 点击事件
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initFruits()
val adapter = FruitAdapter(this, R.layout.fruit_item,fruitList)
listView.adapter = adapter
listView.setOnItemClickListener { _, _, position, _ ->
val fruit = fruitList[position]
Toast.makeText(this,fruit.name,Toast.LENGTH_LONG).show()
}
}
补充
- 如果需要知道传入什么参数可以点进去看源码
- kotlin中可以将没使用的参数用下划线替代
4.6 RecycleView
- 准备一组图片,子项视图,水果类,放置RecycleView
- 编写适配器
class FruitAdapter(val fruitList:List<Fruit>): RecyclerView.Adapter<FruitAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FruitAdapter.ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.fruit_item, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: FruitAdapter.ViewHolder, position: Int) {
val fruit = fruitList[position]
holder.fruitImage.setImageResource(fruit.imageId)
holder.fruitName.text = fruit.name
}
override fun getItemCount() = fruitList.size
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val fruitImage: ImageView = view.findViewById(R.id.fruitImage)
val fruitName : TextView = view.findViewById(R.id.fruitName)
}
}
- 编写代码
class MainActivity : AppCompatActivity() {
private val fruitList = ArrayList<Fruit>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initFruits()
val layoutManager = LinearLayoutManager(this)
recycleView.layoutManager = layoutManager
val adapter = FruitAdapter(fruitList)
recycleView.adapter = adapter
}
private fun initFruits(){
repeat(2){
fruitList.add(Fruit("Apple",R.drawable.apple_pic))
fruitList.add(Fruit("Banana",R.drawable.banana_pic))
fruitList.add(Fruit("Orange",R.drawable.orange_pic))
fruitList.add(Fruit("Watermelon",R.drawable.watermelon_pic))
fruitList.add(Fruit("Pear",R.drawable.pear_pic))
fruitList.add(Fruit("Grape",R.drawable.grape_pic))
fruitList.add(Fruit("Pineapple",R.drawable.pineapple_pic))
fruitList.add(Fruit("Strawberry",R.drawable.strawberry_pic))
fruitList.add(Fruit("Cherry",R.drawable.cherry_pic))
fruitList.add(Fruit("Mango",R.drawable.mango_pic))
}
}
}
4.6.2 横向滚动和瀑布流布局
- 横向布局
//布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="80dp"
android:orientation="vertical"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/fruitImage"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"/>
<TextView
android:id="@+id/fruitName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp" />
</LinearLayout>
- 代码
layoutManager.orientation = LinearLayoutManager.HORIZONTAL
- 布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_margin="5dp"
android:orientation="vertical"
android:layout_height="wrap_content">
<--宽度由布局的列数自动适配,而不是固定值,所以宽度设为填充父布局-->
<ImageView
android:id="@+id/fruitImage"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"/>
<TextView
android:id="@+id/fruitName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_marginTop="10dp" />
</LinearLayout>
- 代码
class MainActivity : AppCompatActivity() {
private val fruitList = ArrayList<Fruit>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initFruits()
val layoutManager = StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL)
recycleView.layoutManager = layoutManager
val adapter = FruitAdapter(fruitList)
recycleView.adapter = adapter
}
private fun initFruits(){
repeat(2){
fruitList.add(Fruit(getRandomLengthString("Apple"),R.drawable.apple_pic))
fruitList.add(Fruit(getRandomLengthString("Banana"),R.drawable.banana_pic))
fruitList.add(Fruit(getRandomLengthString("Orange"),R.drawable.orange_pic))
fruitList.add(Fruit(getRandomLengthString("Watermelon"),R.drawable.watermelon_pic))
fruitList.add(Fruit(getRandomLengthString("Pear"),R.drawable.pear_pic))
fruitList.add(Fruit(getRandomLengthString("Grape"),R.drawable.grape_pic))
fruitList.add(Fruit(getRandomLengthString("Pineapple"),R.drawable.pineapple_pic))
fruitList.add(Fruit(getRandomLengthString("Strawberry"),R.drawable.strawberry_pic))
fruitList.add(Fruit(getRandomLengthString("Cherry"),R.drawable.cherry_pic))
fruitList.add(Fruit(getRandomLengthString("Mango"),R.drawable.mango_pic))
}
}
private fun getRandomLengthString(str:String):String{
val n = (1..20).random()
val builder = StringBuilder()
repeat(n){
builder.append(str)
}
return builder.toString()
}
}
4.6.3 点击事件
viewHolder.itemView.setOnClickListener{
val position = viewHolder.adapterPosition
val fruit = fruitList[position]
Toast.makeText(parent.context,"you clicked view ${fruit.name}",Toast.LENGTH_SHORT).show()
}
viewHolder.fruitImage.setOnClickListener{
val position = viewHolder.adapterPosition
val fruit = fruitList[position]
Toast.makeText(parent.context,"you clicked view ${fruit.imageId}",Toast.LENGTH_SHORT).show()
}
补充:dp是一种和屏幕密度无关的尺寸单位,可以保证在不同手机上显示效果尽可能的一致。
4.7 编写界面的实践
4.7.1 制作 9-Patch 图片
- 获得原始图片
[外链图片转存中…(img-5KFLVQC2-1660655504008)]
- 右击图片 Create 9 - Patch file
- 给四个边框绘制小黑点,左边框和上边框为设置需要拉伸就拉伸的区域。另外两个是放置内容的区域。shift擦除
- 删除原来的图片
4.7.2 编写精美的聊天界面
- 主界面
<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:orientation="vertical"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:background="#d8e0e8">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/recycleView"
></androidx.recyclerview.widget.RecyclerView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/inputText"
android:layout_weight="1"
android:hint="Type something here"
android:maxLines="2"
></EditText>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send"
android:id="@+id/send"
></Button>
</LinearLayout>
</LinearLayout>
- 定义实体类Msg
class Msg(val content:String,val type:Int) {
companion object{
const val TYPE_RECEIVED = 0
const val TYPE_SEND = 1
}
}
- 编写子项布局 msg_left.xml
<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_original"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/leftMsg"
android:layout_gravity="center"
android:layout_margin="10dp"
android:textColor="#fff"
></TextView>
</LinearLayout>
</FrameLayout>
4.编写子项布局 msg_right.xml 。图片资源为第一行代码配套资源
<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="right"
android:background="@drawable/message_right"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/rightMsg"
android:layout_gravity="center"
android:layout_margin="10dp"
android:textColor="#000"
></TextView>
</LinearLayout>
</FrameLayout>
- 编写适配器
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 IllegalAccessException()
}
}
override fun getItemCount() = msgList.size
}
- 编写代码
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)
recycleView.layoutManager = layoutManager
adapter = MsgAdapter(msgList)
recycleView.adapter = adapter
send.setOnClickListener(this)
}
private fun initMsg() {
val msg1 = Msg("Hello guy.", Msg.TYPE_RECEIVED)
msgList.add(msg1)
val msg2 = Msg("Hello. Who is that?",Msg.TYPE_SEND)
msgList.add(msg2)
val msg3 = Msg("This is Tom.Nice talking to you.",Msg.TYPE_RECEIVED)
msgList.add(msg3)
}
override fun onClick(p0: View?) {
when(p0){
send ->{
val content = inputText.text.toString()
if (content.isNotEmpty()) {
val msg = Msg(content, Msg.TYPE_SEND)
msgList.add(msg)
adapter?.notifyItemInserted(msgList.size-1)
recycleView.scrollToPosition(msgList.size-1)
inputText.setText("")
}
}
}
}
}
4.8 Kotlin:延迟初始化和密封类
4.8.1 对变量延迟初始化
对上面的代码进行优化,利用 lateinit 延迟初始化关键字
class MainActivity : AppCompatActivity() , View.OnClickListener{
private val msgList = ArrayList<Msg>()
private lateinit var adapter:MsgAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initMsg()
val layoutManager = LinearLayoutManager(this)
recycleView.layoutManager = layoutManager
if (!::adapter.isInitialized) {
adapter = MsgAdapter(msgList)
}
recycleView.adapter = adapter
send.setOnClickListener(this)
}
private fun initMsg() {
val msg1 = Msg("Hello guy.", Msg.TYPE_RECEIVED)
msgList.add(msg1)
val msg2 = Msg("Hello. Who is that?",Msg.TYPE_SEND)
msgList.add(msg2)
val msg3 = Msg("This is Tom.Nice talking to you.",Msg.TYPE_RECEIVED)
msgList.add(msg3)
}
override fun onClick(p0: View?) {
when(p0){
send ->{
val content = inputText.text.toString()
if (content.isNotEmpty()) {
val msg = Msg(content, Msg.TYPE_SEND)
msgList.add(msg)
adapter.notifyItemInserted(msgList.size-1)
recycleView.scrollToPosition(msgList.size-1)
inputText.setText("")
}
}
}
}
}
4.8.2 密封类
interface 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
//不得不编写,否则会认为缺少条件分支,无法编译通过。这里的代码永远不会走到,只是为了满足编译检查。并且如果Result增加一个实现接口,并且没在这里添加分支,程序就会崩溃
else -> throw IllegalArgumentException()
}
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 -> "Error is ${result.error.toString()}"
}
- 新建一个 MsgViewHolder.kt 代码
sealed class MsgViewHolder(view: View):RecyclerView.ViewHolder(view)
class LeftViewHolder(view: View) : MsgViewHolder(view) {
val leftMsg: TextView = view.findViewById(R.id.leftMsg)
}
class RightViewHolder(view: View) : MsgViewHolder(view) {
val rightMsg: TextView = view.findViewById(R.id.rightMsg)
}
- 修改适配器中的语句
class MsgAdapter(val msgList:List<Msg>) : RecyclerView.Adapter<MsgViewHolder>() {
...
override fun onBindViewHolder(holder:MsgViewHolder, position: Int) {
val msg = msgList[position]
when (holder) {
is LeftViewHolder -> holder.leftMsg.text = msg.content
is RightViewHolder -> holder.rightMsg.text = msg.content
}
}
...
}
|