有关语法
有关循环
在Kotlin中有十分熟悉的for-in循环,终于不和while功能重复了
可是Kotlin不像py那样直接用range生成range
比如下边这样能得到一个$0≤x≤10$的范围
val range = 0..10
还有这样能得到$0≤x<10$的范围
val range = 0 until 10
后面加个step就可以一次想加几次就加几次
val range = 0 until 10 step 2
如果想倒过来就可以像下面这样得到一个$[10, 1]$的区间
val range = 10 downTo 1
怎么说呢,挺好的,就是要适应
有关let
let
是个作用域函数……
一般用于给某个对象判空,如果为空就不做那些事了不然会崩,比如
obj?.let {
println(it.toString())
}
和其它作用域函数一样,it
在这个大括号里边表示对象本身
有关try
try
是用来看看一段代码在运行时会不会崩掉的,如果真的崩了也不会把整个程序带走
它的完整结构包含try
、catch
和finally
GPT总结得很好
try {
// 可能会引发异常的代码
} catch (e: ExceptionType) {
// 处理异常的代码
} finally {
// 可选的代码块,不管是否发生异常都会执行
}
一般的e: Exception
基本代表所有类型的异常
可以有很多个catch
来捕获各种各样的异常,然后做出各种各样的应对方案
有关列表
你可能需要:有关Lambda表达式
kt中初始化列表似乎和别的语言不太一样?
比如我要一个有20个元素的列表,其值均为5,可以这么写
val list = List(20) {5}
有点太神奇了说实话
对可变列表也是一样的
如果想要元素按一定规律变化,可以这么写
val mutableList = MutableList(20) { "Element $it" }
元素的值分别为"Element 0"
, "Element 1"
……
然后当然也可以
val mutableList = MutableList(20) { it * 3 }
这样它就是[0, 3, 6, ..., 57]
了
这就是21世纪的语言吗太强悍了
唯一的问题是,如果想像其他语言一样已知元素创建列表时不能像上面那样
list = [233, 555, 114] # 人家py多方便啊
kt要用listof
来创建
val list = listof(233, 555, 114)
这大抵是因为kt里{}的作用太多了罢
说的就是你,Lambda 表达式!
字符串处理
replace
接收两个参数,将字符串中的对应字符替换成你想要的,比如
val result = text.replace(Regex("[ /\\\\:*?\"<>|]+"), "_")
方括号中的所有字符都会被替换为下划线,+代表无论几个这些字符连在一起都通通变成一个下划线
如果变成这样,代表这些字符连在一起大于等于两个才会被替换
val result = text.replace(Regex("[ /\\\\:*?\"<>|]{2,}"), "_")
既然能调下限,那也一定能改上限
这种比较新的语言都是这样轮子特别多的吗
有关时间
可以用Java的TimeUnit
对时间进行方便的转换
获取现在时间只需要System.currentTimeMillis()
获取现在的毫秒时间
通过TimeUnit.原单位.to新单位(数值)
就可以方便地得到一个新的单位的时间辣
如果要处理日程之类的东西……说实话用Java的Calendar
会比较方便
其它语言特性
kt:孩子们,我也有三引号
有关控件
超多控件,芝士雪豹,并不深但是广
其实就是属性超多啦
如果某个属性拥有多个值,可以在不同的值之间加上|
,比如android:layout_gravity="end|bottom"
如果没有特别指定,那在xml中下面的控件会把上面的盖住
还有个东西大大简化了控件的使用,详见有关Binding
有关TextView
textStyle
可以决定文字是否加粗或者斜体
typeface
可以决定文字的类型(只有一些简单的属性
fontFamily
可以决定文字的字体——和上一个属性有些相似呢,不过基本什么字体都能支持
paintFlags
可以给文字设置下划线和删除线,但只能在代码里边赋值,为什么?
像这样就是给它加一条下划线
tipTextView.paintFlags = android.graphics.Paint.UNDERLINE_TEXT_FLAG
STRIKE_THRU_TEXT_FLAG
则是添加删除线可是似乎只能同时应用一个属性
我有预感这些属性在别的有文字的控件里边也可以用
类似语言,在不同的values文件夹里能设置它的字体颜色之类的属性,这样就能支持深色模式了
有关EditText
hint
是设置提示文本
android:background="@android:color/transparent"
可以让下划线滚蛋
有关Button
使用MaterialButton
,更现代化且更易配置!
可以轻松设置边框
有关ImageView
可以用scaleType
这个属性来控制图片的缩放方式
比如fitXY
是拉伸,centerCrop
是保持比例使图片越界填充整个ImageView
,centerInside则不会让图片越界,只会尽可能填满
有关SearchView
iconifiedByDefault="false"
表示默认情况下展开搜索框
如果想在菜单里面加上搜索,可以添加一个这样的item
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_search"
android:icon="@drawable/ic_search"
android:title="Search"
android:showAsAction="ifRoom|collapseActionView"
android:actionViewClass="androidx.appcompat.widget.SearchView" />
</menu>
在代码中可以用setOnQueryTextListener
来监听搜索输入,像下面一样
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
// 用户提交搜索时触发
if (query != null) {
performSearch(query) // 执行搜索逻辑
}
return true
}
override fun onQueryTextChange(newText: String?): Boolean {
// 用户每次输入变化时触发
if (newText != null) {
updateSearchResults(newText) // 实时更新搜索结果
}
return true
}
})
GPT总结得真好是吧
如果是在菜单里面,就要在 onCreateOptionsMenu
里边初始化了
这玩意还能和 RecyclerView
一起用,实现有趣的效果
有关RecyclerView
需要写适配器的神奇东西
有关Adapter
有关notifyItemChanged
它是Adapter
里面的一个方法,可以更新某个项的数据
notifyItemChanged(adapterPosition)
这行代码的意思是更新当前位置的项
执行了这行代码就会让这一项重新绑定一次ViewHolder
,从而防止一些奇奇怪怪的bug(比如很多个项共用一个变量)
这样做还能获赠动画效果
有关ViewPager
同样要写适配器的神奇东西,可以实现不同页面之间的滑动切换
现已全面升级为ViewPager2
有关Adapter
下面就是一个GPT写的有关Adapter
的示例
class ViewPagerAdapter(activity: FragmentActivity) : FragmentStateAdapter(activity) {
private val fragments = listOf(
HomepageFragment(),
StatsFragment(),
SettingsFragment()
)
override fun getItemCount() = fragments.size
override fun createFragment(position: Int): Fragment = fragments[position]
}
有关布局
在那些并不智能的布局里(也就是除了ConstraintLayout
)都要用一大串layout
来决定控件的位置
layout_gravity
是用来决定这个控件以哪条边为基准,比如
android:layout_gravity="end|bottom"
这样能让这个控件以右下角为原点
有关ConstraintLayout
这玩意简直是超级神器,太好使了
如果要使一个控件的尺寸随别的控件变化,只要把它的尺寸设为0dp
,然后设置这个方向上对其哪个控件(的两条边)就好
杂项
有关MediaPlayer
这玩意有个神奇的特性那就是即使所处的界面关闭了还会继续播放
所以比较方便的做法就是在界面关闭时把播放一起关了
如果播放操作是在ViewModel中写的,那就可以专门准备个MediaPlayer然后每次播放都重新初始化一次,界面关闭也别忘了释放资源
有关Bitmap
Bitmap
是个保存了图像信息的对象
可以通过很多方式创建
比如从资源文件
val bitmap = BitmapFactory.decodeResource(context.resources, R.drawable.image) // decode,意为解码
从文件
val file = File("/path/to/image.jpg")
val bitmap = BitmapFactory.decodeFile(file.absolutePath)
从输入流
val inputStream = FileInputStream("image.jpg")
val bitmap = BitmapFactory.decodeStream(inputStream)
还可以生成空白的来画画
Bitmap
可以用compress()
来把图像压缩成别的格式的文件
有关语言(平时说的那个
一般的语言文件夹格式是
values-zh-CN
这样,有language和region两部分
当然region省略也是可以的
如果是自定义语言,可以这样
values-b+zh+ME
有关attachBaseContext
这玩意是更新资源文件的一个方法,接收一个Context然后更新现在的页面
可以用来更新页面语言
有关ContextCompat
这玩意可以获取一个资源的示例,用法是ContextCompat.get啥啥啥(context, id)
这样就能在代码中一遍应用多种不同模式下的资源
不知道该放到哪里的东西
lifecycleScope.launch {
while (true) {
delay(10000)
lifecycleScope.launch(Dispatchers.Main) {
reloadFragment(this@HomepageFragment)
}
}
}
this
还能这么用?!
有关习惯
一定,一定要记得初始化啊!