安卓的一些学习总结
安卓学习总结
四大组件
1.Activity:是所有Android程序的门面,凡是在应用中看到的东西都放这里面,就是界面的意思
2.Service:无法看到它,在后台运行,即使退出程序任然可以继续运行
3.BroadbcastReceiver:允许应用接受各处的广播消息,比如电话和短信,
4.ContentProvidr:为应用程序之间共享数据成为可能,比如读取系统通讯录中的联系人
复制代码
注册主Activity setContentView()引入布局
所有的Activi都在AndroidManifest.xml中注册,以下是注册主Activity
<activity android:name=".MainActivity">
<intent-filter>
//这两行代码是注册主Activity
//决定应用的入口Activity,也就是我们启动应用时首先显示哪一个Activity。
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
复制代码
然后是mainActivity代码
所有自定义的Activity都要继承它获子类,才能拥有它的特性
class MainActivity : AppCompatActivity() {
//这个方法是Activity被创建必定被执行的方法
override fun onCreate(savedInstanceState: Bundle?) {
//调用父类的构造函数,savedInstanceState保存当前Activity的状态信息
super.onCreate(savedInstanceState)
//设置当前Activity内容
setContentView(R.layout.activity_main)
}
}
复制代码
安卓日志Log
//第一个参数一般闯入类名,对打印信息过誉
//msg要打印的内容
Log.d(tag,msg)
复制代码
Toast的使用
Toast可以使用它在程序中将一些短小的消息通知给用户,这些消息在一段时间中消失,不占屏幕空间
setOnclickListener()设置监听器
点击按钮就会执行监听器,弹出Toast的功能要在Onclick()方法中编写
Toast用法:
1.通过静态方法makeToast()创建一个Toast对象
Toast.makeToast(this,"提醒内容",时长).show()
//时长有两个 Toast.LENGTH_SHORT
Toast.LENGTH_LONG
复制代码
//为button设置了一个监听器,但点击时,弹出Toast的文本内容
val button:Button=findViewById(R.id.button)
button.setOnClickListener {
Toast.makeText(this,"提示逆",Toast.LENGTH_LONG).show()
}
复制代码
menu的使用
作用节约屏幕空间
右击res-》兴建一个叫menu的目录-》在此目录下右击new Menu respurce file-》文件名main
**item这个标签用来创建具体的某一个菜单项 **
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/add_item"
android:title="add_item"/>
<item
android:id="@+id/remove_item"
android:title="remove_item"/>
</menu>
复制代码
然后再FirstActivity来重写方法
函数onCreateOptionsMenu()为创建Menu菜单的项目
函数onOptionsItemSelected()为处理菜单被选中运行后的事件处理
inflate方法的使用
infalte(这个参数是通过那个资源文件创建菜单,创建的菜单项添加到那个Menu对象当中)
复制代码
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
super.getMenuInflater()
menuInflater.inflate(R.menu.main,menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when(item.itemId){
R.id.add_item->Toast.makeText(this,"你好",Toast.LENGTH_SHORT).show()
R.id.remove_item->Toast.makeText(this,"你不好",Toast.LENGTH_SHORT).show()
}
return true
}
}
复制代码
摧毁一个Activity: finish()方法
方式一:在监听器中
val button:Button=findViewById(R.id.button)
button.setOnClickListener {
finish()
}
复制代码
方式二:手机back键
使用Intent在Activity中穿梭
主Activity跳转到其它Activity
显示Intent
//第一个参数就是主Activi作为上下文,第二个参数就是传入的要启动的目标Activity
val intent=Intent(this,SecondActivity::class.java)
//启动
startActivity(inten)
复制代码
第一步兴建一个Activity,在主FirstActivity中修改代码,
val button:Button=findViewById(R.id.button)
button.setOnClickListener {
val intent=Intent(this,SecondActivity::class.java)
startActivity(intent)
}
复制代码
隐式的Intent
不明确指定哪一个Activity,而是指定抽象的action和category,交由系统分析启动哪一个Activity
修改AndroidManifest.xml代码
<activity android:name=".SecondActivity">
<intent-filter>
<action android:name="com.example.activitytest.ACTION_START"/>
//这是一个默认的category
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
复制代码
在FirstActivity中启动匹配
val button:Button=findViewById(R.id.button)
button.setOnClickListener {
val intent=Intent("com.example.activitytest.ACTION_START")
startActivity(intent)
}
复制代码
更多隐式Intent
调用系统浏览器来启动网页
将一个网址字符串解析成一个Uri对象
在通过Intent的setdata将Uri对象传递出去
intent.data=Uri.parse("https://www.baidu.com")
复制代码
val button:Button=findViewById(R.id.button)
button.setOnClickListener {
//这是安卓内置动作
val intent=Intent(Intent.ACTION_VIEW)
intent.data= Uri.parse("https://www.baidu.com")
startActivity(intent)
}
复制代码
在data标签主要匹配内容
android:scheme 用于指定数据的协议部分,如www.baidu.com中的http部分。
android:host 用于指定数据的主机名部分,如www.baidu.com中的www.baidu.com部分。
android:port 用于指定数据的端口部分,一般紧随在主机名之后,如www.rowyer:8080/mypath中的808…
android:path 用于指定主机名和端口之后的部分,如一段网址中跟在域名之后的内容,如www.rowyer:8080/mypath中的/my…
android:mimeType 用于指定可以处理的数据类型,允许使用通配符的方式进行指定。
————————————————
兴建一个Activity,修改注册信息
<activity android:name=".ThirdActivity" tools:ignore="AppLinkUrlError">//无视警告
<intent-filter >
//action显示的是android.intent.action.VIEW常量值
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="https"/>
</intent-filter>
</activity>
复制代码
像下一个Activity传递数据
Intent重载方法 putExtra()
intent.putExtra(第一个参数是键值用与从intent取值,第个参数是真正要传递的参数)
复制代码
修改FirstActivity中的监听器
val button:Button=findViewById(R.id.button)
button.setOnClickListener {
val data="Hello,SecondActivty"
val intent= Intent(this,SecondActivity::class.java)
intent.putExtra("item_data",data)
startActivity(intent)
}
}
复制代码
然后打开SecondActivity,通过Lod.d日志来查看
//这里的Intent其实是调用了父类的getIntent()方法获取用与启动的SecondActovoty的Intent
//getStringExtra()这个方法是获取键值,从而获取传来的数据
val data=Intent.getStringExtra("item_data")
复制代码
返回数数据给Activity传递数据
返回数据给上一个Activity方法:SrartActivityForResult()
StartActivityForResult(第一个参数数Intent,请求码)
复制代码
setResult()专门用来向上一个Activiry返回数据
第一个参数一般用来向上一个Activiry返回处理结果,一般使用RESULT_OK
第二个参数是把带有Intent数据传递出去
setRusult(RESULT_OK,intent)
复制代码
因为是通过startActivityForResult启动SecondActivity,在SecondActivity销毁前会回调上一个Activity的onActivityResult方法,所以我们要重写
//第一个参数是请求码,第二个参数是处理的结果,第三个参数是携带返回数据的Intent
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when(requestCode){
1 ->if (resultCode== RESULT_OK){
val resultdata=data?.getStringExtra("item_data")
Log.d("FirstTctivity","data is $resultdata")
}
}
}
复制代码
Activity的生命周期·
onCreate() 这个方法在Activity第一次被创建的时候调用。
onStart() 这个方法在Activity由不可见变为可见的时候调用。
onResume() 这个方法在Activity准备好和用户进行交互的时候调用。
onPause() 这个方法在系统准备去启动或者恢复另一个Activity的时候调用。
onStop() 这个方法在Activity完全不可见的时候调用。
onDestroy() 这个方法在Activity被销毁之前调用。
onRestart() 这个方法在Activity由停止状态变为运行状态之前调用,也就是Activity被重新启动了。
复制代码

Activity回调方法 onSaveInstanceState()
当一个Activity进入停止状态时,可能就会被回收,例如:用户在Activity a的转态下启动Activity b,a就进入停止状态,但是由于系统内存不足,a就会被回收,但是但我们按下back键回到a时,还是会正常显示,但是是执行onCreat方法,这个a被重新创建,如果我们在a中有些数据,那么返回原先的数据就会消失。
** 这个onSaveInstanceState()方法是保证Activity被回收之前调用,这个方法携带一个Bundle类型参数
putString用来保存字符串
在ManActivity添加代码进行临时保存
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
val end="This is a red"
outState.putString("data_key",end)
}
复制代码
取值修改onCreat方法
private val tag="MainActivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d(tag,"onCreate")
setContentView(R.layout.activity_main)
if (savedInstanceState!=null){
val data=savedInstanceState.getString("data_key")
Log.d(tag,"data is $data")
}
复制代码
Activity的启动模式
选择启动模式
在标签指定android:luchMode属性来选择启动模式
默认启动模式之standard
如果再次启动这个Activity就会再次兴建一个新的Activity的实例
启动模式之Single Top
在栈顶已经是该Activity,再次启动可以直接使用它,不会在创建新的Activity
<activity android:name=".ThirdActivity"
android:launchMode="singleTop"
tools:ignore="AppLinkUrlError">
复制代码
启动模式之SingleTask
使用SingleTask可以解决多次重复创建Activity的问题,使用这个模式,首先还在返回栈中检查有没有这个Activity实例,如果有则使用该实例,把这个Activity之上的其它Activity统统出栈
知晓当前在哪一个Activity中
首先兴建一个普通类Test继承AppCompatActivity(),并重写onCreate方法
open class Test:AppCompatActivity(){
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//获取类名
Log.d("Test",javaClass.simpleName)
}
}
复制代码
接着让这个类成为ActivityTest项目的父类
随时随地退出程序
兴建一个单例类为ActivityColler
package com.example.activitytest
import android.app.Activity
object ActivityColler {
val Activityes=ArrayList<Activity>()
fun adda(activity: Activity){
Activityes.add(activity)
}
fun removea(activity: Activity){
Activityes.remove(activity)
}
fun finishalla(activity: Activity){
for (activty in Activityes){
if (!activity.isFinishing){
activity.finish()
}
}
Activityes.clear()
}
}
复制代码
修改Test方法
open class Test:AppCompatActivity(){
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d("Test",javaClass.simpleName)
//把正在创建的Activity添加到集合里面
ActivityColler.adda(this)
}
//移除马上销毁的Activity
override fun onDestroy() {
super.onDestroy()
ActivityColler.removea(this)
}
}
复制代码
例如你在这个界面就可以单击按钮可以直接退出程序
class ThirdActivity : Test() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.third_layout)
val button3:Button=findViewById(R.id.button3)
button3.setOnClickListener {
ActivityColler.finishalla(this)
}
}
}
复制代码
启动Activity的最佳写法
情景,例如自己开发这个SecondActivity,不清楚启动这个要传递那些数据,换一种写法可以解决
class SecondActivity : Test() {
//静态
companion object{
fun start(context: Context,data1:String,data2:String){
val intent=Intent(context,SecondActivity::class.java)
intent.putExtra("pramal1",data1)
intent.putExtra("pramal2",data2)
context.startActivity(intent)
}
}
//启动方式
val button2:Button=findViewById(R.id.Button2)
button2.setOnClickListener {
SecondActivity.start(this,"data1","data2")
}
复制代码
Kotlin:标准函数和静态方法
标准函数with,run,apply
val result=with(任意类型对象){
//lambda表达式
}
复制代码
Run :特点只接受一个Lambda表达式,并且会提供调用对象的上下文,最后一行代码作为返回值返回
apply:无法指定返回值,只会返回调用对象本身
val intent=Intent(context,SecondActivity::class.java)
intent.putExtra("pramal1",data1)
intent.putExtra("pramal2",data2)
context.startActivity(intent)
}
--------------
val intent=Intent(context,SecondActivity::class.java).apply{
putExtra("pramal1",data1)
putExtra("pramal2",data2)
context.startActivity(intent)
}
复制代码
静态方法
class Util {
fun doAction(){
println("do Action")
}
companion object{
//真正的静态方法
@JvmStatic //这个注解只能加到单例类获 companion object方法上
fun doAction2(){
println("do Action")
}
}
}
//单例类,虽然不是静态方法,但是可以通过Util2.doAction3来调用
object Util2{
fun doAction3(){
println("doAction")
}
}
复制代码
常用控件
TextView
TextView的文字默认左上角对齐
常用属性
android:gravity="center"//文字对齐方法
android:textSize="30sp"//字体大小
android:textColor="#00ff00"//字体颜色
复制代码
EditText
用于和用户进行交互
<EditText
android:id="@+id/EditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入内容"//友好提示
android:maxLines="2"/>限制2行,超过文本向上滚动
复制代码
通过按下button按钮把EaitText的输入内容打印
package com.example.uiwidgetest
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
class MainActivity : AppCompatActivity(),View.OnClickListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val button:Button=findViewById(R.id.button)
button.setOnClickListener(this)
}
override fun onClick(v: View?) {
when(v?.id){
R.id.button->{
val editText:EditText=findViewById(R.id.EditText)
val puttext=editText.text.toString()
Toast.makeText(this,puttext,Toast.LENGTH_SHORT).show()
}
}
}
}
复制代码
imageView
展示图片的控件
android:src="@drawable/img_1"//指定图片
复制代码
`动态修改图片
class MainActivity : AppCompatActivity(),View.OnClickListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val button:Button=findViewById(R.id.button)
button.setOnClickListener(this)
}
override fun onClick(v: View?) {
when(v?.id){
R.id.button->{
//通过这个方法该图片
val imageView:ImageView=findViewById(R.id.imageview)
imageView.setImageResource(R.drawable.img_2)
}
}
}
}
复制代码
progressBar
安卓的可见属性 android:visibility
invisible:表示控件不可见 ,仍占原来位置和大小,控件类似透明转态
gone:控件不仅不可见,而且不占如何屏幕空间
visible:空间可见切默认
复制代码
//这个属性可以改成水平进度条
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
//给进度条设置一个最大值
android:max="100
复制代码
动态更改进度条
override fun onClick(v: View?) {
when (v?.id) {
R.id.button -> {
//每次加10的进度
val progree: ProgressBar = findViewById(R.id.prpgressBar)
progree.progress=progree.progress+10
}
}
}
复制代码
AlertDialog
可以在当前界面弹出对话框,置于所有界面元素之上,用与提示一些重要信息
override fun onClick(v: View?) {
when (v?.id) {
R.id.button -> {
AlertDialog.Builder(this).apply{
setTitle("This is Dialog")
setMessage("Something improt")
setCancelable(false)
setPositiveButton("OK"){
dialog, which ->
}
setNegativeButton("Cancel"){dialog, which -> }
show()
}
}
}
}
复制代码
3种基本布局
线性布局LinearLayout
android:orientation="horizontal"//水平布局 默认
android:orientation="vertical"//垂直布局
android:layout_weight=""//布局控件的大小
复制代码
相对布局RelativeLayout
可以通过相对定位方法让控件成为布局任何方向
帧布局FrameLayout
默认左上角
android:layout_gravity="right"//居右对齐
android:layout_gravity="left"//居左对齐
复制代码
引入布局
<?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/titlit"/>
</LinearLayout>
复制代码
//在主Activity中吧自带的标题栏隐藏掉
supportActionBar?.hide()
//用与布局和控件指定背景
android:background="@drawable/title_bg">
//用与指定控件的间距
android:layout_margin="5dp"
复制代码
自定义布局
Context,attrs:AttributeSet):LinearLayout(context,attrs) {
init {
//LayoutInflater.from(context)构建一个对象
//inflate动态加载布局
LayoutInflater.from(context).inflate(R.layout.titlit,this)
val button:Button=findViewById(R.id.button)
button.setOnClickListener{
//as强转
val activity=context as Activity
activity.finish()
}
val button2:Button=findViewById(R.id.button2)
button2.setOnClickListener{
Toast.makeText(context,"小伙子",Toast.LENGTH_SHORT).show()
}
}
}
复制代码
ListView
package com.example.listviewtest
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.ArrayAdapter
import android.widget.ListView
class MainActivity : AppCompatActivity() {
private val data= listOf("AAAA","BBB","CCCC","DDDD","EEEE","FFFF",
"GGGGG","HHHHH","WWWWWW")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//适配器
//1.传入Activity实例,2、安卓内置文件,3.数据源
val adber=ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,data)
val listView:ListView=findViewById(R.id.listView)h
//调用listView的setAdapter()把创建对象传递进去
listView.adapter=adber
}
}
复制代码
定制ListView的界面
repeat(2){}//数据添加两遍
复制代码
//自定义适配器
class FuitAdapter(activity:Activity,val resourceId:Int,data:List<Firut>):ArrayAdapter<Firut>(activity,resourceId,data) {
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val view=LayoutInflater.from(context).inflate(resourceId,parent,false)
val imageView:ImageView=view.findViewById(R.id.iamgeView)
val textView:TextView=view.findViewById(R.id.textView)
val firut=getItem(position)//获取当前fruit的实例
if (firut!=null){
imageView.setImageResource(firut.imageID)//获取图片
textView.text=firut.name//获取文字
}
return view
}
}
复制代码
优化convertView将之前加载好的布局缓存
val view:View
if (convertView==null){
view=LayoutInflater.from(context).inflate(resourceId,parent,false)
}else{
view=convertView
}
复制代码
inner class()
inner class()
复制代码
RecyclerView
第一步在build gradle下添加
implementation 'androidx.recyclerview:recyclerview:1.0.0'
复制代码
<?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">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
复制代码
//自定义适配器
package com.example.recyclerview
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class FriutAdpater(val friutList: List<Fruit>):
RecyclerView.Adapter<FriutAdpater.ViewHolder>(){
//内部类,这个view一般是子项的最外层布局
inner class ViewHolder(view: View):RecyclerView.ViewHolder(view){
val fruitImageView:ImageView=view.findViewById(R.id.fruitImage)
val fruitName:TextView=view.findViewById(R.id.fruitName)
}
//用与创建ViewHolder实例,将fruit_item布局加载进来
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view=LayoutInflater.from(parent.context)
.inflate(R.layout.fruit_item,parent,false)
return ViewHolder(view)
}
//告诉一共有多少子项
override fun getItemCount()=friutList.size
//用与对子项的数据进行赋值,position获取当前项的Fruit实例
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val fruit=friutList[position]
holder.fruitImageView.setImageResource(fruit.imageId)
holder.fruitName.text=fruit.name
}
}
复制代码
initFruit()//初始化水果数据
//创建LinearLayoutManager实例
val layoutManager=LinearLayoutManager(this)
val recyclerView:RecyclerView=findViewById(R.id.recyclerview)
//线性布局
recyclerView.layoutManager=layoutManager
val adaper=FriutAdpater(fruitList)
recyclerView.adapter=adaper
复制代码