Android开发-kotlin基本使用(二)

一、Android四大组件

1、 Android四大组件介绍

  • Activity: 负责用户界面的展示和用户交互,学习Activity就要学习Fragment,虽然它不是四大组件之一,但是它在我们的开发工作中也是频频被使用到,且必须和Activity一块使用,常用于分模块开发,比如慕课首页的几个tab,每个tab都是对应着一个Fragment.

  • Service服务:不需要和用户交互,负责后台任务,比如播放音乐,socket长连接

  • BroadcastReceiver广播接收者: 负责页面间通信,系统和APP通信,APP和APP通信,比如监听网络连接状态变化,就是通过BroadcastReceiver广播接收者来实现的

  • ContentProvider内容提供者: 负责数据存取,常用于APP进数据共享,跨进程数据存取等....比如读取相册,读取联系人,都是ContentProvider来实现的

2 、Activity

新建SecondActivity.kt文件:

package com.dbc.bckotlinall

import android.os.Bundle
import android.view.Gravity
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity

class SecondActivity : AppCompatActivity(){
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val textview = TextView(this)
        textview.text = "SecondActivity"
        textview.gravity = Gravity.CENTER
        setContentView(textview)
    }
}
//四大组件都需要在AndroidManifest文件中配置否则无法使用, 类似Activity无法启动

在AndroidManifest.xml中配置SecondActivity.kt:

        <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:usesCleartextTraffic="true"
        android:theme="@style/Theme.BCKotlinAll">
        ...

        <activity
            android:name=".SecondActivity"
            android:label="@string/app_name">
            <!-- 使用隐式意图去启动SecondActivity-->
            <intent-filter>
                <!--默认包名+类名-->
                <action android:name="com.dbc.bckotlinall.SECONDACTION"></action>
                <category android:name="android.intent.category.DEFAULT"></category>
            </intent-filter>
        </activity>
    </application>

在Android中我们可以通过下面两种方式来启动一个新的Activity,注意这里是怎么启动,分为显示启动和隐式启动!

显示启动 --- A->B页面跳转传参:
在MainActivity.kt中跳转:
class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val textview = TextView(this)
        textview.text = "MainActivity"
        textview.gravity = Gravity.CENTER
        setContentView(textview)
        textview.setOnClickListener{
          /// 页面跳转到 SecondActivity
            val intent = Intent(MainActivity@this, SecondActivity::class.java)
            //携带参数跳转启动新Activity
            intent.putExtra("extra_data", "extra_data")
                        intent.putExtra("extra_int_data", 100)
            startActivity(intent)
        }
    }
}


在SecondActivity.kt中, 获得参数:
class SecondActivity : AppCompatActivity(){
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val stringExtra = intent.getStringExtra("extra_data")
        val intExtra = intent.getIntExtra("extra_int_data",0)

        val textview = TextView(this)
        textview.text = "SecondActivity ${stringExtra}---${intExtra}"
        textview.gravity = Gravity.CENTER
        setContentView(textview)
    }
}

/*跳转生命周期流程:
 M:: onCreate --> M:: onStart --> M:: onResume --> M:: onPause --> S:: onCreate --> S:: onStart --> S:: onResume --> M:: onStop 
*/
显示启动 --- B页面返回A页面时传参:
///在MainActivity.kt中: -------

class MainActivity : AppCompatActivity() {

    private lateinit var textview: TextView // lateinit 延迟初始化
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        textview = TextView(this)
        textview.text = "MainActivity"
        textview.gravity = Gravity.CENTER
        setContentView(textview)
        textview.setOnClickListener{
            val intent = Intent(MainActivity@this, SecondActivity::class.java)
            intent.putExtra("extra_data", "extra_data")
            intent.putExtra("extra_int_data", 100)
            startActivityForResult(intent, 1000) //设置返回
        }
    }
  
    /// 获取返回后的参数
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        if(requestCode == 1000&&resultCode==Activity.RESULT_OK&&data!=null){
            val stringExtraResult = data.getStringExtra("result_extra_string")
            val intExtraResult = data.getIntExtra("result_extra_int", 0)

            textview.text = "${stringExtraResult}--${intExtraResult}"
        }
    }
}

/// 在SecondActivity.kt中: --------
class SecondActivity : AppCompatActivity(){
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val stringExtra = intent.getStringExtra("extra_data")
        val intExtra = intent.getIntExtra("extra_int_data",0)

        val textview = TextView(this)
        textview.text = "SecondActivity ${stringExtra}---${intExtra}"
        textview.gravity = Gravity.CENTER
        setContentView(textview)
      
        ///返回上一页, 传参
        textview.setOnClickListener{
            val resultIntent = Intent()
            resultIntent.putExtra("result_extra_string","result_extra_string")
            resultIntent.putExtra("result_extra_int",100)
            setResult(Activity.RESULT_OK, resultIntent)
            finish()//把页面关闭, 相当于点击了返回键
        }
    }
}

3、 Fragment生命周期图解

注意事项: Fragment并不能单独使用, 它需要嵌套在Activity中使用,尽管他拥有自己的生命周期,但是还是会受到宿主Activity的生命周期的影响,比如Activity 被destory销毁了,他也会跟着销毁!一个Activity可以嵌套多个Fragment。

Activity中添加Fragment :

Sp1 创建SecondFragment.kt:

class SecondFragment: Fragment() {
  
      lateinit var argments: Bundle
  
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val textView = TextView(context)
        textView.text = "SecondFragment"
        textView.gravity = Gravity.CENTER

        return textView
    }
  
    /// 获取从Activity传递过来的参数:
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        // 取出参数
        val intArgument = argments?.getInt("key_int")
        val stringArgument = argments?.getInt("key_string_value")

        //view 就是 onCreateView 返回的控件
        val textView = view as TextView
        textView.text = "${intArgument} --- ${stringArgument}"
    }
}

Sp2 在activity_second.xml中:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--    指定容器-->
    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

Sp3 在SecondActivity.kt中, 执行添加Fragment操作:

class SecondActivity : AppCompatActivity(){
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)

        val fragment = SecondFragment()
      
            /// 创建bundle对象、并填充数据赋值给fragment的argments字段:
        val bundle = Bundle()
        bundle.putInt("key_int",100)
        bundle.putString("key_string","key_string_value")
        fragment.argments= bundle
      
          /// 将Fragment添加到Activity中:
        val ft = supportFragmentManager.beginTransaction()
        //把Fragment添加到事务中, 当且仅当该Fragment未被添加过
        if(!fragment.isAdded()){
            ft.add(R.id.container,fragment)// 参数一: Fragment在SecondActivity绑定的xml中对应的容器id
        }
//        ft.show(fragment) //显示出fragment的视图
//        ft.hide(fragment) //隐藏fragment,使得它的视图不可见
//        ft.remove(fragment)//移除fragment
//        ft.replace(R.id.container,fragment)//替换fragment,之前添加过的fragment都会被暂时移除,把当前这个fragment添加到事务中
        ft.commitAllowingStateLoss()//提交事务, 并执行对Fragment的add、replace、show、hide操作
    }
}

AS小技巧

1.对于红色警告⚠️: 可以按住option+commant, 选择解决方案

待续....

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,219评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,363评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,933评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,020评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,400评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,640评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,896评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,597评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,327评论 1 244
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,581评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,072评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,399评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,054评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,849评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,672评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,585评论 2 270

推荐阅读更多精彩内容