概述
第 5 章 碎片
5.2 碎片的使用方式
5.2.1 碎片的简单使用
- 编写 left_fragment.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Button"
/>
</LinearLayout>
- 编写 right_fragment.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="#00ff00"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textSize="24sp"
android:text="This is right fragment"
/>
</LinearLayout>
3.编写左侧碎片代码
class LeftFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.left_fragment,container,false)
}
}
- 编写右侧碎片代码
class RightFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.right_fragment,container,false)
}
}
- 编写主活动布局
<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="horizontal"
android:layout_height="match_parent"
tools:context=".MainActivity">
<fragment
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:id="@+id/leftFrag"
android:name="android.bignerdranch.fragmenttest.LeftFragment"
/>
<fragment
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:id="@+id/rightFrag"
android:name="android.bignerdranch.fragmenttest.RightFragment"
/>
</LinearLayout>
5.2.2 动态添加碎片
- 新建另一个右侧右侧布局 another_right_fragment.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="#ffff00"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textSize="24sp"
android:text="This is another right fragment"
/>
</LinearLayout>
- 新建另一个右侧碎片代码
class AnotherRightFragment:Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.another_right_fragment,container,false)
}
}
- 修改主布局
<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="horizontal"
android:layout_height="match_parent"
tools:context=".MainActivity">
<fragment
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:id="@+id/leftFrag"
android:name="android.bignerdranch.fragmenttest.LeftFragment"
/>
<FrameLayout
android:id="@+id/rightLayout"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
>
</FrameLayout>
</LinearLayout>
- 编写主布局代码动态添加碎片
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button.setOnClickListener{
replaceFragment(AnotherRightFragment())
}
replaceFragment(RightFragment())
}
private fun replaceFragment(fragment: Fragment) {
val fragmentManager = supportFragmentManager
val transaction = fragmentManager.beginTransaction()
transaction.replace(R.id.rightLayout, fragment)
transaction.commit()
}
}
5.2.3 碎片中实现返回栈
在提交事务之前调用
transaction.addToBackStack(null)
5.2.4 碎片和活动进行交互
- 活动中调用碎片的方法
//fFBI 用于在布局中获取碎片的实例,然后就能使用里面的方法了
val fragment = supportFragmentManager.findFragmentById(R.id.leftFrag) as LeftFragment
优化 :id ‘kotlin-android-extensions’ 插件允许我们直接使用布局文件中定义的碎片 Id 来自动获取碎片的实例
val fragment = leftFrag as LeftFragment
- 碎片中调用活动的方法
if (activity != null) {
val mainActivity = activity as MainActivity
}
补充:得到的Activity本身就是一个Context对象
- 碎片和碎片的通信
先在碎片中获取与它关联的活动,然后通过活动去获得另一个碎片
5.3 碎片的生命周期
5.3.1 碎片的状态和回调
- 状态
- 运行状态:当一个活动进入运行状态时,相关联的碎片也会进入运行状态
- 暂停状态:当一个活动进入暂停状态时,相关联的碎片也会进入暂停状态
- 停止状态:当一个活动进入停止状态时,相关联的碎片也会进入停止状态。通过调用了事务的remove和replace方法,但是事务提交前调用了addToBackStack方法,也会进入停止状态。这时候的碎片完全不可见有可能被收回
- 销毁状态:当一个活动进入销毁状态时,相关联的碎片也会进入销毁状态。通过调用了事务的remove和replace方法,但是事务提交前没有调用了addToBackStack方法,会进入销毁状态。
- 回调
- onAttach( ) :碎片和活动建立关联时调用
- onCreateView( ):碎片创建视图(加载布局)时调用
- onActivityCreated( ):确保和碎片相关联的活动创建完毕时调用
- onDestroyView( ):与碎片相关联的视图被移除时调用
- onDetach( ):碎片和活动解除关联时调用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WBTxnkR4-1660713951648)(第一行代码Kotlin.assets/image-20220816215031973.png)]
5.3.2 体验碎片的生命周期
class RightFragment : Fragment() {
//kotlin中定义常量都是在companion object、单例类、顶层作用域中使用
companion object {
const val TAG = "RightFragment"
}
override fun onAttach(context: Context) {
super.onAttach(context)
Log.d(TAG, "onAttach")
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d(TAG, "onCreate")
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
Log.d(TAG, "onCreateView")
return inflater.inflate(R.layout.right_fragment, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
Log.d(TAG, "onActivityCreated")
}
override fun onStart() {
super.onStart()
Log.d(TAG, "onStart")
}
override fun onResume() {
super.onResume()
Log.d(TAG, "onResume")
}
override fun onPause() {
super.onPause()
Log.d(TAG, "onPause")
}
override fun onStop() {
super.onStop()
Log.d(TAG, "onStop")
}
override fun onDestroyView() {
super.onDestroyView()
Log.d(TAG, "onDestroyView")
}
override fun onDestroy() {
super.onDestroy()
Log.d(TAG, "onDestroy")
}
override fun onDetach() {
super.onDetach()
Log.d(TAG, "onDetach")
}
}
- 刚进入 attach-create-createView-ActivityCreated-start-resume
- 点击左侧按钮 pause - stop - destroyView
- 如果没有加入返回栈 destroy - detach
- 按下back createView - activityCreated - start - resume//create没执行因为加入了返回栈,碎片没被销毁
- 再次按下back pause - stop - destroyView - destroy -Detach
5.4 动态添加布局的技巧
5.4.1 使用限定符
5.4.2 使用最小限定符
因为不常用到并且在第二版的时候实现过,就不再敲一遍,很简单,跟着书就能实现
5.5 简易版新闻应用 没实现
5.6 Kotlin 课堂:扩展函数和运算符重载
5.6.1 拓展函数
拓展函数:在不修改某个类的源码的情况下,仍然可以打开这个类,向该类新增新的函数
情景:统计字符串中的字母的数量
- 定义单例类,在单例类中写方法
object StringUtil {
fun letterCount(str: String): Int{
var count = 0
for (char in str) {
if (char.isLetter()) {
count++
}
}
return count
}
}
- 拓展函数的语法结构 类名.方法就表示将方法定义到类里面
fun ClassName.methodName(param1: Int,param2:Int): Int{
return 0
}
- 应用:向String 中定义一个拓展函数
建议:向哪个类中定义拓展函数,就定义一个同名的 Kotlin 文件。定义成顶层方法,能够拥有全局的访问域
fun String.lettersCount():Int{
//因为拥有了String的上下文所以就不需要传入字符串,直接遍历this,this就是字符串本身
var count = 0
for (char in this) {
if (char.isLetter()) {
count++
}
}
return count
}
调用
val count = "ABC123xyz!@#".lettersCount()
补充:String中有capitalize()实现首字母大写,reverse()字符串反转
5.6.2 运算符的重载
语法结构:在“指定函数”前加入operator关键字
class Obj{
operator fun plus(obj: Obj): Obj{
//处理相加的逻辑
}
}
- 调用
val obj1 = Obj()
val obj2 = Obj()
val obj3 = obj1 + obj2
//编译的时候就会转换成 obj1.plus(obj2)
- 应用:实现两个Money相加
class Money(val value:Int) {
operator fun plus(money:Money):Money{
val sum = value + money.value
return Money(sum)
}
//实现Money和数字的相加
operator fun plue(newValue:Int):Money{
val sum = value + newValue
return Money(sum)
}
}
//调用,在main函数中
val money1 = Money(5)
val money2 = Money(10)
val money3 = money1 + money2
val money4 = money3 + 20
println(money3.value)
println(money4.value)
语法糖表达式 | 实际调用函数 |
---|---|
a + b | a.plus(b) |
a - b | a.minus(b) |
a * b | a.times(b) |
a / b | a.div(b) |
a % b | a.rem(b) |
a++ | a.inc() |
a– | a.dec() |
+a | a.unaryPlus() |
-a | a.unaryMinus() |
!a | a.not() |
a == b | a.equals(b) |
a > ba < ba >= b****a <= b | a.compareTo(b) |
a…b | a.rangeTo(b) |
a[b] | a.get(b) |
a[b] = c | a.set(b, c) |
a in b | b.contains(a) |
对随机生成字符串的函数进行优化
operator fun String.times(n:Int):String{
val builder = StringBuilder()
repeat(n){
builder.append(this)
}
return builder.toString()
}
//调用
val str = "abc"*3
println(str)
//结果: abcabcabc
优化:Kotlin中的String已经拓展了一个重复字符串的方法
operator fun String.time(n:Int) = repeat(n)
最后
以上就是时尚时光为你收集整理的第一行代码 第三版 第五章 碎片第 5 章 碎片的全部内容,希望文章能够帮你解决第一行代码 第三版 第五章 碎片第 5 章 碎片所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复