❤️ Author: 老九
☕️ 个人博客:老九的CSDN博客
🙏 个人名言:不可控之事 乐观面对
😍 系列专栏:
<?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="match_parent"
android:orientation="vertical">
<!--layout_width指明宽度,layout_height指明高度。三个值可供选择:match_parent(当前控件大小与父布局相同)、
wrap_content(刚好包住)和固定值dp(与屏幕密度无关,不同分辨率下尽可能一致)-->
<!--android:gravity指明文字对齐方式,可选值有top、bottom、top等。可以用|来同时指定多个值。譬如center等价于center_vertical|center_horizontal-->
<!--android:textColor指明了文字颜色,android:textSize文字大小,文字大小以sp为单位-->
<TextView
android:id="@+id/text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#00ff00"
android:textSize="24sp"
android:text="Hello World!" />
</LinearLayout>
<?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="match_parent"
android:orientation="vertical">
.....
<!--Android默认将英文字母转换成大写,android:textAllCaps设置为false保留指定原始文件内容-->
<Button
android:id="@+id/btn_click01"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:text="Button" />
</LinearLayout>
package com.example.myapplication
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity(), View.OnClickListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//第一种调用方法:匿名内部类,利用Java单抽象方法接口特性,使用函数式API来写监听事件。
// btn_click01.setOnClickListener{
// //在此添加处理逻辑
// }
//第二种调用方法:实现接口方法进行注册。让MainActivity实现了View.OnClickListener接口,并重写onClick方法
//setOnClickListener将MainActivity实例传了进去
btn_click01.setOnClickListener(this)
}
//重写的方法,很简单。
override fun onClick(v: View?) {
when (v?.id) {
R.id.btn_click01 -> {
//在此添加逻辑
}
}
}
}
<?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="match_parent"
.....
<!--android:hint指定提示性的文本-->
<!--android:maxLines指明最大行数为2行,若超过,文本向上滚动,EditText不会再拉伸。-->
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/edit_text01"
android:maxLines="2"
android:hint="type sth please"/>
</LinearLayout>
//重写的方法,很简单。
override fun onClick(v: View?) {
when (v?.id) {
R.id.btn_click01 -> {
//点击按钮完成显式EditText文本内容的功能
//edit_text01.text通过语法糖调用了getText方法,编写代码直接调用实际方法即可,getText可以自动转换为text。
val inputText = edit_text01.text.toString()
Toast.makeText(this, inputText, Toast.LENGTH_SHORT).show()
}
}
}
<!--android:src为ImageView指定了一张图片,由于宽高未知,因此使用两个wrap_content使得其能显示出来-->
<ImageView
android:id="@+id/image_view01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/image_1" />
//通过代码动态更改ImageView图片
R.id.btn_click02 ->{
image_view01.setImageResource(R.drawable.image_2)
}
<!-- 默认是圆形样式,通过style属性将其变为水平进度条,修改其中的代码-->
<!--android:max给进度条设置一个最大值,在代码中动态的更改进度条进度。-->
<ProgressBar
android:id="@+id/progress_bar01"
style="?android:attr/progressBarStyleHorizontal"
android:max="100"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
//android:visibility有三个可选值:visiable(控件可见,默认)、invisible(空间不可见,仍占据原来未知)
// 和gone(控件不仅不可见,也不再占用之前的屏幕),在使用setVisibility使用View.可选值
R.id.btn_click03 -> {
//使用getVisibility判断prograssBar是否可见,如果可见隐藏,否则显示
if (progress_bar01.visibility == View.VISIBLE) {
//调用了setVisibility
progress_bar01.visibility = View.GONE
} else {
progress_bar01.visibility = View.VISIBLE
}
}
//进度条增加
R.id.btn_click04 -> {
progress_bar01.progress += 10
}
R.id.btn_click05 -> {
//构建一个对话框并使用apply函数
AlertDialog.Builder(this).apply {
//消息标题
setTitle("This is Dialog")
//消息内容
setMessage("Sth important")
//是否可以使用back键返回对话框
setCancelable(false)
//确定按钮点击事件
setPositiveButton("OK") { dialog, which -> "删除吧" }
//取消按钮点击事件
setNegativeButton("Cancel") { dialog, which -> "保留吧" }
//对话框显示出来
show()
}
}
<?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="match_parent"
android:orientation="vertical">
<!--vertical竖直方向上布局,horiziontal水平布局,默认是水平布局。wrap_content刚好包含文字。-->
<!--介绍一下android:gravity和android:layout_gravity,前者是文字在控件中的对齐方式,后者是指定控件在布局中的对齐方式-->
<!--两者可选值差不多,但horizontal时,只有垂直方向上的对齐方式可以改变,换之亦然。每添加一个控件,水平上的长度会改变。-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="9"
android:orientation="horizontal">
<Button
android:id="@+id/btn_01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:text="Button 01" />
<Button
android:id="@+id/btn_02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="Button 03" />
<Button
android:id="@+id/btn_03"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="Button 03" />
</LinearLayout>
<!--可能有人说为什么layout_width是0dp呢?这是因为使用android:layout_weight,0dp是比较规范的写法-->
<!--android:layout_weight先将layout_weight所有值相加,再按照比例进行划分。-->
<!--如果将后者的layout_width设置为wrap_content。前者layout_weight等于1,那么后面刚好包着,前面是屏幕剩余的所有空间-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_gravity="bottom"
android:orientation="horizontal">
<EditText
android:id="@+id/edit_text01"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="4"
android:hint="Type sth please" />
<Button
android:id="@+id/btn_send"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Send" />
</LinearLayout>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--Button 1与父布局左上角对齐,layout_alignParentLeft和layout_alignParentTop指定-->
<Button
android:id="@+id/btn_click_01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="Button 1" />
<!--Button 2与父布局右上角对齐-->
<Button
android:id="@+id/btn_click_02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:text="Button 2" />
<!--Button 3居中显示-->
<Button
android:id="@+id/btn_click_03"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Button 3" />
<!--相对于控件进行定位,控件左上,需要注意的是:若一个控件引用另一个控件的id,那么该控件一定要定义在引用控件的后面-->
<Button
android:id="@+id/btn_click_06"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/btn_click_03"
android:layout_toLeftOf="@id/btn_click_03"
android:text="Button 6" />
<!--相对于控件进行定位,控件右上-->
<Button
android:id="@+id/btn_click_07"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/btn_click_03"
android:layout_toRightOf="@id/btn_click_03"
android:text="Button 7" />
<!--相对于控件进行定位,控件左下-->
<Button
android:id="@+id/btn_click_08"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/btn_click_03"
android:layout_toLeftOf="@id/btn_click_03"
android:text="Button 8" />
<!--相对于控件进行定位,控件右下-->
<Button
android:id="@+id/btn_click_09"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/btn_click_03"
android:layout_toRightOf="@id/btn_click_03"
android:text="Button 9" />
<!--Button 4与父布局左下角对齐-->
<Button
android:id="@+id/btn_click_04"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:text="Button 4" />
<!--Button 5与父布局右下角对齐-->
<Button
android:id="@+id/btn_click_05"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:text="Button 5" />
</RelativeLayout>

<?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="match_parent">
<TextView
android:id="@+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:text="This is TextView" />
<Button
android:id="@+id/btn_001"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="Button" />
</FrameLayout>
<?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="60dp"
android:background="#ff00ff">
<!--android:background表示用图片或者颜色填充背景-->
<!--android:layout_margin用于指定控件在上下左右方向上的举例,当然也可以通过android:layout_marginLeft等指定-->
<Button
android:id="@+id/titleBack"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="left|center_vertical"
android:layout_margin="5dp"
android:background="#00ff00"
android:text="Back"
android:textColor="#fff" />
<TextView
android:id="@+id/title_text"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="Title text"
android:textColor="#fff"
android:textSize="24sp" />
<Button
android:id="@+id/titleEdit"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="right|center_vertical"
android:layout_margin="5dp"
android:background="#00ff00"
android:text="Edit"
android:textColor="#fff" />
</LinearLayout>
<?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="match_parent">
<include layout="@layout/title" />
</LinearLayout>
package com.example.myapplication
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//通过语法糖调用getSupportActionBar来获得ActionBar的实例,然后调用hide方法将标题隐藏
//由于ActionBar可能为空,因此使用了?.操作符,目的是隐藏原始标题栏
supportActionBar?.hide()
}
}
package com.example.myapplication
import android.app.Activity
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.LinearLayout
import android.widget.Toast
import kotlinx.android.synthetic.main.title.view.*
//继承自LinearLayout使其成为我们的自定义控件。声明两个参数,在init结构体中对标题栏布局进行动态加载
class TitleLayout(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
init {
//LayoutInflater的from方法可以构建出一个LayoutInflater对象,然后inflate方法动态加载一个布局文件
//inflate加载两个参数,一个是布局文件ID,一个是给加载好的布局再添加一个父布局,在这里指定为TitleLayout,直接传入this。
LayoutInflater.from(context).inflate(R.layout.title, this)
titleBack.setOnClickListener {
//context参数实际上是Activity实例,首先将其抓换为Activity类型,然后再行销毁。
// Kotlin的强制类型转换用as
val activity = context as Activity
activity.finish()
}
titleEdit.setOnClickListener {
Toast.makeText(context, "You clicked the edit", Toast.LENGTH_SHORT).show()
}
}
}
<?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="match_parent">
<!-- <include layout="@layout/title" />-->
<com.example.myapplication.TitleLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<?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="match_parent">
<ListView
android:id = "@+id/listView_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
package com.example.myapplication
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.ArrayAdapter
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
//提供待展示数据,使用listOf初始化集合
private val data = listOf(
"Apple", "Banana", "Orange", "WaterMelon", "Pear", "Grape", "Cherry","Mango", "Apple", "Banana", "Orange", "WaterMelon", "Pear", "Grape", "Cherry", "Mango"
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//集合数据无法直接传递,需要借助适配器。比较好用的是ArrayAdapter,泛型指定为String
//在构造方法中分别传入Activity实例、ListView子项布局的id以及数据源
//simple_list_item_1为子项布局id,Android内置布局文件,里面只有TextView用于显示一段文本
val adapter = ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, data)
//最后利用setAdapter方法将构建好的适配器传递进去,这样ListView和数据之间的关联算是搞定了
listView_main.adapter = adapter
}
}
package com.example.myapplication
//Fruit类有两个字段,一个是水果名,一个是水果对应图片资源的ID
class Fruit(val name: String, val imageid: Int)
<?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="60dp">
<!--让两个玩意在垂直方向上居中显示-->
<ImageView
android:id="@+id/fruit_image"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp" />
<TextView
android:id="@+id/fruit_Name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp" />
</LinearLayout>
package com.example.myapplication
import android.app.Activity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.TextView
//定义一个主构造函数来将Activity实例、ListView子项布局id和数据源传递进来
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 {
//首先使用LayoutInflater子项加载我们的布局,三个参数。
// 最后一个false的意思是父布局声明的layout生效,不会为该View增加父布局。保准写法
val view = LayoutInflater.from(context).inflate(resourceId, parent, false)
//获取到ImageView和TextView的实例
val fruitImage: ImageView = view.findViewById(R.id.fruit_image)
val fruitName: TextView = view.findViewById(R.id.fruit_Name)
//得到当前项的Fruit实例
val fruit = getItem(position)
//设置图片和文字
if (fruit != null) {
fruitImage.setImageResource(fruit.imageid)
fruitName.text = fruit.name
}
//将布局返回
return view
}
}
package com.example.myapplication
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.ArrayAdapter
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
private val fruit_list = ArrayList<Fruit>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initFruits()//初始化水果数据
//创建Adapter对象,并将其作为适配器传递给ListView
val adapter = FruitAdapter(this, R.layout.fruit_item, fruit_list)
listView.adapter = adapter
}
fun initFruits() {
//repeat函数将水果数据重复两遍
repeat(2) {
//构造方法中将水果名字和水果id传入,将创建好的对象添加到水果列表中。
fruit_list.add(Fruit("Apple", R.drawable.apple_pic))
fruit_list.add(Fruit("Banana", R.drawable.banana_pic))
fruit_list.add(Fruit("Orange", R.drawable.orange_pic))
fruit_list.add(Fruit("WaterMelon", R.drawable.watermelon_pic))
fruit_list.add(Fruit("Pear", R.drawable.pear_pic))
fruit_list.add(Fruit("PineApple", R.drawable.pineapple_pic))
fruit_list.add(Fruit("StrawBerry", R.drawable.strawberry_pic))
fruit_list.add(Fruit("Cherry", R.drawable.cherry_pic))
}
}
}
package com.example.myapplication
import android.app.Activity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.TextView
//定义一个主构造函数来将Activity实例、ListView子项布局id和数据源传递进来
class FruitAdapter(activity: Activity, val resourceId: Int, data: List<Fruit>) :
ArrayAdapter<Fruit>(activity, resourceId, data) {
//innerclass来定义内部类
inner class ViewHolder(val fruitImage: ImageView, val fruitName: TextView)
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
//首先使用LayoutInflater子项加载我们的布局,三个参数。
// 最后一个false的意思是父布局声明的layout生效,不会为该View增加父布局。保准写法
val view: View
val viewHolder: ViewHolder
if (convertView == null) {
view = LayoutInflater.from(context).inflate(resourceId, parent, false)
//用于对ImageView和TextView的控件实例进行缓存
val fruitImage: ImageView = view.findViewById(R.id.fruit_image)
val fruitName: TextView = view.findViewById(R.id.fruit_Name)
//创建ViewHolder对象并将控件实例放在ViewHolder里
viewHolder = ViewHolder(fruitImage, fruitName)
//使用View的setTag方法将ViewHolder存储在View中。
view.tag = viewHolder
} else {
view = convertView
//缓存对象不为空时,使用View的getTag方法将ViewHolder重新取出,这样所有控件的实例都存储于ViewHolder中了
viewHolder = view.tag as ViewHolder
}
//得到当前项的Fruit实例
val fruit = getItem(position)
//设置图片和文字
if (fruit != null) {
viewHolder.fruitImage.setImageResource(fruit.imageid)
viewHolder.fruitName.text = fruit.name
}
//将布局返回
return view
}
}
// listView_main.setOnItemClickListener { parent, view, position, id ->
// val fruit = fruit_list[position]
// Toast.makeText(this, fruit.name, Toast.LENGTH_SHORT).show()
// }
//没用到的参数可以用_来代替。因为是Java单抽象方法接口,所以可用函数式API的写法。onItemClick中接收四个参数。
listView_main.setOnItemClickListener { _, _, position, _ ->
val fruit = fruit_list[position]
Toast.makeText(this, fruit.name, Toast.LENGTH_SHORT).show()
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/recyclerView"/>
</LinearLayout>
package com.example.listview
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView
class FruitAdapte(val fruitList : List<Fruit>,var onItemCLick : (view : View,position : Int)->Unit ) :
RecyclerView.Adapter<FruitAdapte.ViewHolder>() {
//viewHolder用来定义item实例
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val fruitImage: ImageView = view.findViewById(R.id.fruitImage)
val fruitName: TextView = view.findViewById(R.id.fruitName)
}
// todo:
// interface OnItemClickListener{
// fun onItemClick(view: View,position: Int)
// }
// private var mOnItemClickListener : OnItemClickListener? = null
// fun setOnItemClickListener(listener : OnItemClickListener?){
// mOnItemClickListener = listener
// }
//首先定义一个函数类型,使用lambda语法,返回值是一个Unit,用一个变量进行接收
// lateinit var onItemClick : (view : View,position : Int) -> Unit
//创建viewholder
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
//加载xml文件,转换成view
val view = LayoutInflater.from(parent.context).inflate(R.layout.fruit_item, parent, false)
val viewHolder = ViewHolder(view)
// viewHolder.fruitName.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 image ${fruit.name}",Toast.LENGTH_SHORT).show()
}
return viewHolder
}
//渲染数据
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
//滚动到的数据加载进来,然后进行赋值
val fruit = fruitList[position]
holder.fruitImage.setImageResource(fruit.imgaeId)
holder.fruitName.text = fruit.name
//todo:
// holder.fruitName.setOnClickListener {
// mOnItemClickListener?.onItemClick(it,position)
// }
holder.fruitName.setOnClickListener {
onItemCLick(it,position)
}
}
//返回列表长度
override fun getItemCount(): Int
{
return fruitList.size
}
}
package com.example.listview
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.*
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import java.lang.StringBuilder
import androidx.recyclerview.widget.RecyclerView.LayoutManager as LayoutManager1
class MainActivity : AppCompatActivity() {
private var fruitList = ArrayList<Fruit>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initFruits()
val layoutManager = LinearLayoutManager(this)
val recyclerView : RecyclerView= findViewById(R.id.recyclerView)
recyclerView.layoutManager = layoutManager
val adapter = FruitAdapte(fruitList){view,position ->
val fruit = fruitList[position]
Toast.makeText(this@MainActivity,fruit.name,Toast.LENGTH_SHORT).show()
}
//todo:
// adapter.setOnItemClickListener(object : FruitAdapte.OnItemClickListener{
// override fun onItemClick(view : View, position: Int) {
// val fruitname : TextView = view.findViewById(R.id.fruitName)
// val fruit = fruitList[position]
// Toast.makeText(this@MainActivity,fruit.name,Toast.LENGTH_SHORT).show()
// }
// })
// adapter.onItemClick = {view,position ->
// val fruit = fruitList[position]
// Toast.makeText(this@MainActivity,fruit.name,Toast.LENGTH_SHORT).show()
// }
recyclerView.adapter = adapter
}
private fun initFruits(){
repeat(5){
fruitList.add(Fruit(getRandomLengthString("1"),R.drawable.ic_launcher_background))
fruitList.add(Fruit(getRandomLengthString("2"),R.drawable.ic_launcher_background))
fruitList.add(Fruit(getRandomLengthString("3"),R.drawable.ic_launcher_background))
fruitList.add(Fruit(getRandomLengthString("4"),R.drawable.ic_launcher_background))
fruitList.add(Fruit(getRandomLengthString("5"),R.drawable.ic_launcher_background))
}
}
private fun getRandomLengthString(str : String) : String{
val n = (1..20).random()
val builder = StringBuilder()
repeat(n){
builder.append(str)
}
return builder.toString()
}
}
layoutmanager.orientation = LinearLayoutManager.HORIZONTAL
<?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:layout_margin="5dp"
android:orientation="vertical">
<ImageView
android:id="@+id/fruit_image"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp" />
<!-- layout_gravity使得文字左对齐-->
<TextView
android:id="@+id/fruit_Name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_marginTop="10dp" />
</LinearLayout>
package com.example.myapplication
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import kotlinx.android.synthetic.main.activity_main.*
import java.lang.StringBuilder
class MainActivity : AppCompatActivity() {
private val fruit_list = ArrayList<Fruit>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initFruits()
//两个参数,第一个是几列;第二个是布局的排列方向,我们选择垂直
val layoutmanager = StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL)
recycler_view.layoutManager = layoutmanager
//创建FruitAdapter实例并将水果数据传入FruitAdapter构造函数中
val adapter = FruitAdapter(fruit_list)
//最后调用setAdapter来完成适配器设置,从而完成RecyclerView与数据的关联
recycler_view.adapter = adapter
}
private fun initFruits() {
//repeat函数将水果数据重复两遍
repeat(2) {
//构造方法中将水果名字和水果id传入,将创建好的对象添加到水果列表中。
fruit_list.add(Fruit(getRandomLengthString("Apple"), R.drawable.apple_pic))
fruit_list.add(Fruit(getRandomLengthString("Banana"), R.drawable.banana_pic))
fruit_list.add(Fruit(getRandomLengthString("Orange"), R.drawable.orange_pic))
fruit_list.add(Fruit(getRandomLengthString("WaterMelon"), R.drawable.watermelon_pic))
fruit_list.add(Fruit(getRandomLengthString("Pear"), R.drawable.pear_pic))
fruit_list.add(Fruit(getRandomLengthString("PineApple"), R.drawable.pineapple_pic))
fruit_list.add(Fruit(getRandomLengthString("StrawBerry"), R.drawable.strawberry_pic))
fruit_list.add(Fruit(getRandomLengthString("Cherry"), R.drawable.cherry_pic))
}
}
private fun getRandomLengthString(str:String):String{
val n = (1..20).random()
val builder = StringBuilder()
repeat(n){
builder.append(str)
}
return builder.toString()
}
}
//用于创建ViewHolder实例,将fruit_item加载进来,然后创建ViewHolder实例,最后将布局传入构造函数当中
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FruitAdapter.ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.fruit_item, parent, false)
val viewholder = ViewHolder(view)
//为最外层的布局和ImageView都注册了点击事件,先获取用户点击的position,然后通过position获取相应的Fruit实例,最后Toast
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 image ${fruit.name}", Toast.LENGTH_SHORT)
.show()
}
return viewholder
}
class MainActivity : AppCompatActivity(), View.OnClickListener {
//因为初始化是在onCreate方法中进行,因此不得不将adapter赋值为null,同时将他的类型声明改成 MsgAdapter?
private var adapter: MsgAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
...
adapter = MsgAdapter(msgList)
}
override fun onClick(p0: View?) {
.....
//肯定要进行判空处理,否则编译无法进行
adapter?.notifyItemInserted(msgList.size - 1)
....
}
}
class MainActivity : AppCompatActivity(), View.OnClickListener {
private lateinit var adapter: MsgAdapter
override fun onCreate(savedInstanceState: Bundle?) {
...
//判断变量是否进行初始化,如果初始化,则不用重复对变量初始化,否则初始化
if(!::adapter.isInitialized) {
adapter = MsgAdapter(msgList)
}
}
override fun onClick(p0: View?) {
.....
adapter.notifyItemInserted(msgList.size - 1)
....
}
}
package com.example.myapplication
import java.lang.IllegalArgumentException
//定义一个接口,表示某个操作的执行结果
interface Result
//Success类用于表示成功时的结果
class Success(val msg: String) : Result
//Failure类用于表示失败时的结果
class Failure(val error: String) : Result
//接受一个Result参数,通过判断result类型返回不同的结果
fun getResultMsg(result: Result) = when (result) {
is Success -> result.msg
is Failure -> result.error
//else这块是完全执行不到的,但缺少的话代码将无法编译过。
//如果新增一个UnKnown类并实现了Result接口,用于表示未知的执行结果,但忘记写分支,将会抛出异常使程序崩溃
else -> throw IllegalArgumentException()
}
package com.example.myapplication
import java.lang.IllegalArgumentException
//密封类
sealed class Result
//继承类需要后面加上一对括号
class Success(val msg: String) : Result()
class Failure(val error: String) : Result()
//class unkonwn(val time: String) : Result()
//else条件已经没有了?为什么呢?
//when传入密封类时,Kotlin会自动检查该密封类有哪些子类,并强制要求你对每一个都需要处理(若不处理,编译不会通过)。即使没有else,也不会出现遗漏分支
fun getResultMsg(result: Result) = when (result) {
is Success -> result.msg
is Failure -> result.error
}
————————————————————————
♥♥♥码字不易,大家的支持就是我坚持下去的动力♥♥♥
版权声明:本文为CSDN博主「亚太地区百大最帅面孔第101名」的原创文章