如下图的AndroidManifest.xml是清单文件
这个文件为 Android 系统提供了关于应用的基本信息和配置,使得系统能够知道如何正确地启动应用以及应用中的各个组件如何相互交互。
该文件内容如下所示:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <application android:allowBackup="true" //是否允许备份应用数据 android:dataExtractionRules="@xml/data_extraction_rules" //数据提取规则 android:fullBackupContent="@xml/backup_rules" //完整备份内容 android:icon="@mipmap/ic_launcher" //应用的图标是什么,比如qq是🐧 android:label="@string/app_name" //应用的标题是什么 android:supportsRtl="true" //是否支持从右到左的布局 android:theme="@style/Theme.Lab4" //应用的主题 tools:targetApi="31"> //编译时使用的目标 API 级别 <activity android:name=".MainActivity" //活动的名称,通常是活动类的完整路径 android:exported="true"> //表示这个活动是否可以被其他应用启动 <intent-filter> //这通常用于声明该活动作为应用的入口点 <action android:name="android.intent.action.MAIN" /> //表示这是一个主活动 <category android:name="android.intent.category.LAUNCHER" /> //表示这个活动应该出现在应用的启动器列表中 </intent-filter> </activity> <activity android:name=".UserRegistrationActivity" /> <activity android:name=".AdminActivity" /> </application> </manifest>
每一个在 Android 应用中使用的
Activity
(活动)都必须在AndroidManifest.xml
清单文件中进行注册。这是 Android 系统识别和启动这些活动所必需的步骤。在应用中创建一个新的
Activity
类时,需要在AndroidManifest.xml
文件中添加一个新的<activity>
标签,并在android:name
属性中指定该活动的完整类名(或使用相对路径,如".MyActivity"
)。这样,当其他组件(如另一个活动或广播接收器)想要启动这个活动时,Android 系统就能知道如何找到和加载它。即使一个活动不是主活动(即不是应用的入口点),它仍然需要在清单文件中注册。这是因为 Android 系统需要知道所有可能由用户或其他组件启动的活动,以便正确地进行管理和调度。主活动通常是应用启动后首先显示的活动。非主活动则可能在用户与应用交互的过程中由主活动或其他非主活动启动。(即主页面和其它页面)
主活动的格式
<activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> //表示这是一个主入口点 <category android:name="android.intent.category.LAUNCHER" /> //表示这个活动应出现在应用启动器(如设备的主屏幕或应用抽屉)中 </intent-filter> </activity>
非主活动格式
<activity android:name=".UserRegistrationActivity" android:exported="false"> <!-- 这个活动没有 intent-filter,因此它不会出现在应用启动器中 --> </activity> <activity android:name=".AdminActivity" android:exported="true"> <!-- 这里可以添加其他 intent-filter,以便响应特定的 Intents --> </activity>
Android Studio)可以在创建新活动时自动添加相应的
<activity>
标签到清单文件中,但<intent-filter>
和其他属性通常需要开发者手动设置,以确保它们正确地反映了应用的需求和行为。a
在java下创建的类和布局文件中的xml文件是一一对应的,创建类时会自动生成
res/目录下各种资源
图片资源
应用图标资源(软件的图标,比如qq的🐧)放在mipmap文件家中(可以看到有很多的mipmap-开头的文件夹,它们都是图片资源只不过是适应不同尺寸屏幕的图片比如120~160dpi的密度范围值的mipmap文件夹名字是mipmap-mdpi),界面中使用的图片资源(进入软件后界面的图片)存放在drawable文件夹中,
调用图片资源的方法
通过java代码, 如 getResources().getDrawable(R.drawable.ic_launcher_background);
(R是一个类是由Android编译器根据项目中的资源文件自动生成的,包含了应用程序中所有资源的引用。资源可以包括布局文件、字符串、图像等,这些资源的ID被保存在R类的不同静态内部类中,如
R.layout
、R.string
、R.drawable
等。这些内部类中的静态整型变量就是对应资源的唯一标识符。当我们在代码中引用资源时,我们会使用
R.类型.资源名
的形式,如R.string.hello
。这样,编译器就可以根据这些ID找到对应的资源。因为R类是由编译器根据资源文件自动生成的,这些资源文件通常位于项目的
res
目录下。因此,在某种程度上,我们可以说R类是由资源文件“生成”的,但这并不意味着R本身是一个文件。实际上,R是一个编译时生成的类,它存在于编译后的代码中,用于在运行时引用资源在xml布局文件中调用,如android:background="@drawable/ic_launcher_background"
简单值(如字符串、颜色)资源
常用的字符串、颜色等样式可以直接在对应文件写明,下次使用时直接调用即可
比如文本颜色使用时引用@color/颜色即可
android:textColor="@color/black"
创建并实现跳转
如上直接创建一个类的同时自动生成对应的xml布局文件。
或者如下自己分别创建一个类继承AppCompatActivity(AppCompatActivity`是Android中用于创建活动的一个基础类,它提供了许多与活动相关的功能),并重写onCreate方法(onCreate`是活动生命周期中的一个重要方法,当活动被创建时,这个方法会被调用,通过调用
super.onCreate(savedInstanceState)
来调用父类的onCreate
方法。然后,使用setContentView
方法来设置活动的内容视图,这里设置的是activity_main
布局文件)。在主界面里面创建点击事件实现跳转。注意自己创建完类后要在AndroidManifest.xml注册活动
(在
onClick
方法中,首先创建了一个新的Intent
对象。然后,使用setClass
方法来设置这个Intent
的源活动(MainActivity.this
)和目标活动(Main2.class
)。最后,调用startActivity
方法来启动目标活动。在Java中,
this
关键字用于引用当前对象实例。当在内部类或匿名内部类中引用外部类(在这里是MainActivity
)的对象时,需要使用MainActivity.this
来明确指定我们想要引用的是外部类的当前实例,而不是内部类或匿名内部类的实例。在这个例子中,
MainActivity.this
用于在OnClickListener
内部类中引用MainActivity
的实例,从而确保我们可以正确地从MainActivity
中启动另一个活动。)如上实现简单的通过点击主界面按钮跳转到另一个Main2的界面。
简单控件
设置文本大小,
java代码中调用setTextSize,或者XML文件中通过属性andriod:textSize,字号单位:px(手机屏幕的最小显示单位)dp(于设备无关,只与屏幕的尺寸有关)sp(专门用来设置字体大小)
设置文本颜色
java中直接调用setTextColor方法,具体色值从Color类取,或者XML文件通过属性andriod:textColor指定文本颜色,(色值有8位十六进制与6位十六进制两种表达方式,
除了使用十六进制色值外,你还可以使用颜色资源(在
res/values/colors.xml
中定义)或者直接使用预定义的颜色常量(如Color.RED
,Color.BLUE
等)。
// Java代码示例 TextView textView = findViewById(R.id.my_text_view); textView.setTextColor(Color.parseColor("#FF0000")); // 设置为红色 // 或者对于8位十六进制色值 textView.setTextColor(Color.parseColor("#80FF0000")); // 设置为半透明的红色
设置视图的宽高
在XML文件中通过为视图元素指定andriod:
layout_width
和andriod:layout_height
属性来设置其宽高。这些属性可以接受多种不同的值:match_parent:表示与上级视图保持一致
wrap_content:表示与内容自适应
以dp为单位的具体尺寸
在java代码中
设置视图的间距(有两种方式)
使用andriod:layout__margin设置外边距,指定当前视图与周围平级视图之间的距离。包括
android:layout_marginTop、
android:layout_marginBottom、
android:layout_marginLeft
、android:layout_marginRight
来为视图设置外边距。这些外边距会添加在视图的外部,与相邻的视图之间创建间隔。
上图可以知道蓝色的宽度为20,黄色与红色之间为60,即使设置了view为match_parent还是有一定的宽度。
使用andriod:padding设置内边距,指定当前视图与内部下级视图之间的距离,包括
android:paddingTop
、android:paddingBottom
、android:paddingLeft
、android:paddingRight
这些内边距会影响视图内容的位置,但不会改变视图本身占据的布局空间。视图的对齐方式
这主要通过两种属性来实现:
layout_gravity
和gravity
。
layout_gravity
属性用于指定当前视图相对于其上级视图的对齐方式。影响的是当前视图在父容器的视图对齐。
gravity
属性则用于指定下级视图相对于当前视图的对齐方式。影响的是当前视图内部的子视图的对齐。二者取值如下
当
layout_gravity
的值为top
时,视图会朝上对齐;值为bottom
时,视图会朝下对齐;值为left
时,视图会靠左对齐;值为right
时,视图会靠右对齐。如果希望视图同时满足多个对齐条件,可以使用竖线|
来连接不同的值,如android:layout_gravity="top|left"
表示视图既朝上又靠左对齐。
常用布局
线性布局(LinearLayout)
内部各视图有水平和垂直两种排列方式,用android:orientation属性来设置垂直、水平android:orientation="vertical"或“horizontal”,如果不指定则默认是水平方向
线性布局的权重(layout_weight),指线性布局的下级视图各自拥有多大比例的宽高,其属性不在LinearLayout节点设置,而在下级视图设置
如果不设置权重,或者权重设置为0,那么子视图只会占据其需要的基本空间,不会参与剩余空间的分配。
当使用权重时,通常需要将子视图的
layout_width
(对于水平方向的线性布局)或layout_height
(对于垂直方向的线性布局)设置为0dp
。这是因为权重是基于剩余空间进行分配的,如果子视图已经指定了一个固定的尺寸,那么权重就不会有任何效果。
layout_width=0dp
时,layout_weight表示水平方向的宽度比例
layout_height=0dp
时,layout_weight表示垂直方向的高度比例
如上图所示,第一行是各占自己所在布局的1/2,而第二个垂直布局的的权重中,按照高度来划分,第一个占2/3空间,而第二个占1/3
相对布局(RelativeLayout)
下级视图位置由其它视图确定,用于确定下级视图位置的参照物分两种(与该视图自身平级的视图,该视图的上级视图),如果不设置下级参照物,则下级视图默认显示在RelativeLayout内部的左上角
相对位置的取值,
【Android】相对布局(RelativeLayout)最全解析-CSDN博客
和网格布局(GridLayout)
支持多行多列,默认从左往右,从上到下排列。columnCount属性指定列数,即每行能放多少个视图。rowCount属性指定行数,即每列能放多少个视图。
把文字放中间使用到之前学习的grivity,将子视图text放中间
发现最右边还是有空白,因为我们分配的宽度为180,没有填满整个宽度,用权重来调整
滚动视图(ScrollView)
滚动视图有两种(垂直方向滚动ScrollView,水平方向滚动HorizontalScrollView)
垂直时,layout_width=match_parent,layout_height=wrap_parent,
水平时设置为layout_width=wrap_parent,layout_height=match_parent,
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical"> <HorizontalScrollView android:layout_width="wrap_content" android:layout_height="200dp"> <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:orientation="horizontal"> <View android:layout_width="300dp" android:layout_height="match_parent" android:background="#aaffff"/> <View android:layout_width="300dp" android:layout_height="match_parent" android:background="#aaff00"/> </LinearLayout> </HorizontalScrollView> <ScrollView android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:orientation="vertical"> <View android:layout_width="match_parent" android:layout_height="400dp" android:background="#aa3344"/> <View android:layout_width="match_parent" android:layout_height="400dp" android:background="#ff9999"/> </LinearLayout> </ScrollView> </LinearLayout>
上图的效果如下图所示,上面部分采用水平滑动,下面则是垂直滑动
帧布局(FrameLayout)、表格布局(TableLayout)等
ConstrainLayout约束布局
要有垂直和水平方向的约束,不然会爆红,当然也可以忽略警告(。
代码调整
分号,ctrl+shift+回车
提示,ctrl+p
格式化代码ctrl+alt+回车
常用控件
TextView
android:lines=2限制只有两行,多于的内容则不显示
ellipsize=end,多的内容显示不了最后会用三个点类似省略号表示,还有start、none、marquee,ellipsize可实现跑马灯效果(4.0以上必须获得焦点才有该效果,即要在java代码中设置获取焦点,控件名.setSelected(true);
在java代码中可用getText()获取文字,setText()设置文字
typeface字体,
drawableTop等属性在指定位置插入图片
EditText
android:hint提示内容
android:textColorHint提示内容颜色
android:inputType可以输入的内容属性(数字、文字等)
例如可以的取值:number(数字)、numberpassword(数字密码)、password(文本密码)、text(默认,文本)、phone(手机号)、email、date等
按钮控件Button
由TextView派生而来,相互区别:button拥有默认的按钮背景(而textview没有),内部文本默认居中对齐(textview默认靠左对其),默认将英文字母转为大写(textview保持原始的大小写)
button的常见属性:
textAllCaps=true表示自动转为大写,false则不做大写转换
onClick=“doClick”,设置点击动作,指定点击按钮时要触发doClick方法
使用匿名内部类实现按钮点击事件
button点击获取EditText内容
imageView
background属性是图片背景(宽高可以被单独缩放),src是图片内容(宽或高必须同时缩放,以最小的缩放为准),上图右边可以看出二者的不同,
scaletype缩放属性用于确定如何调整图像的大小以适应
ImageView
的边界。RadioButton单选按钮,但是只有结合RadioGroup一起使用才可实现多个选项单选的效果,
<RadioGroup android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <RadioButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="女"/> <RadioButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="男"/> </RadioGroup>
如上可以实现男女按钮的单项选择。
为单选添加切换事件(可以用匿名内部类事件,也可以用实现接口的方式)
第一种方法使用了匿名内部类来监听单选按钮的选中状态变化。
public class MainActivity3 extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main3); RadioGroup gender = findViewById(R.id.radio_gender); gender.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup radioGroup, int checkedId) { switch(checkedId){ case R.id.female: Log.i("onChecked","女"); break; case R.id.male: Log.i("onChecked","男"); break; } } }); } }
第二种方法将当前Activity(
MainActivity3
)作为监听器,并实现了RadioGroup.OnCheckedChangeListener
接口中的onCheckedChanged
方法。public class MainActivity3 extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main3); RadioGroup gender = findViewById(R.id.radio_gender); gender.setOnCheckedChangeListener(this); } @Override public void onCheckedChanged(RadioGroup radioGroup, int checkedId) { switch(checkedId){ case R.id.female: Log.i("onChecked","女"); break; case R.id.male: Log.i("onChecked","男"); break; } } }
(this表示当前执行的类的对象,在
MainActivity3
的onCreate
方法中,当调用gender.setOnCheckedChangeListener(this);
时,你实际上是将当前MainActivity3
实例(即this
)作为OnCheckedChangeListener
传递给gender
(一个RadioGroup
实例)。这意味着当RadioGroup
中的任何一个RadioButton
的选中状态发生变化时,MainActivity3
的onCheckedChanged
方法将被调用。注意:(虽然
int checkedId
和R.id.female
在代码中的表示形式不同(一个是变量,一个是常量),在 Android 中,R.id
是一个由资源编译器自动生成的资源 ID 的集合,它包含了你在 XML 布局文件中定义的所有组件的 ID。这些 ID 实际上是整数(int
类型),它们被用作引用 XML 文件中定义的组件的键。R.id.female
和R.id.male
这些常量在编译时就被转换成了它们对应的整数 ID,这些 ID 与你在switch
语句中使用的int checkedId
变量是兼容的,因为它们在运行时都是整数类型。因此,它们可以被直接比较,并且switch
语句可以正确地根据checkedId
的值来执行相应的分支。)CheckBox(复选框)是button的子类
<CheckBox android:id="@+id/cb_game" android:text="打游戏" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <CheckBox android:id="@+id/cb_music" android:checked="true" android:text="听音乐" android:layout_width="wrap_content" android:layout_height="wrap_content"/> 在XML布局文件中设置android:checked="true"或在代码中调用setChecked(true)来设置默认选中状态
CheckBox cb_game = findViewById(R.id.cb_game); cb_game.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean isCheched) { Log.i("onCheckedChanged",cb_game.getText().toString()+(isCheched ? "被选中":"取消选中")); } });
注意这里是和上面都是切换事件,但是方法归属的类不同,同样也可以像上面一样使用实现接口的方式来设置该事件,注意实现的接口名不同,且如果要实现多个接口,用逗号隔开就好。
public class MainActivity3 extends AppCompatActivity implements CompoundButton.OnCheckedChangeListener { private CheckBox cb_game; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main3); cb_game = findViewById(R.id.cb_game); cb_game.setOnCheckedChangeListener(this); @Override public void onCheckedChanged(CompoundButton compoundButton, boolean isCheched) { // 使用传递的compoundButton参数来识别是哪个CheckBox触发了事件 if (compoundButton == cb_game) { Log.i("onCheckedChanged", cb_game.getText().toString() + (isCheched? "被选中" : "取消选中")); } // 如果有其他CheckBox,可以在这里添加逻辑来处理它们 } }
注意:在
onCheckedChanged
回调方法中,使用了cb_game
这个在onCreate
方法中的局部变量,它在onCreate
方法执行完毕后就不再可访问了。由于onCheckedChanged
方法是在类级别定义的(作为接口的实现),它无法直接访问onCreate
方法中的局部变量。如上将cb_game
变量提升为类的成员变量(即属性),这样它就可以在类的任何方法中被访问了。a
Toast
在Android开发中,Toast是一种简易的消息提示框,用于向用户显示一些简短的信息,如操作提示、状态更新等。Toast通常用于在屏幕上显示一个短暂的消息,不需要用户进行任何交互,一段时间后会自动消失。
使用Toast类的最简单方法是调用静态方法makeText()来构造所需的Toast对象,并设置要显示的文本和显示时间。然后,通过调用show()方法来显示Toast。
Toast.makeText(MainActivity3.this,"what", Toast.LENGTH_SHORT).show(); /* * makeText(Context,text,duration);创建提示框 * context:上下文 * text:显示的内容 * duration:显示的持续时间 Toast.LENGTH_SHORT :1秒,实际值0 ,即可以直接写数字 * LENGTH_LONG: 2s,实际值1 * show() :显示提示框, * * */
MainActivity3.this
是一种显式的方式来引用当前MainActivity3
类的实例。在 Android 中,当处于MainActivity3
的某个非静态方法或内部类中时,可以直接使用this
来引用当前实例。但是,如果需要在内部类或匿名类中引用外部类的实例,或者需要显式地指定类名以避免混淆(例如,在嵌套类或匿名类中),你可以使用MainActivity3.this
。补充:如果有多个点击事件,可用实现接口的方式,在实现点击事件的方法中,通过id的不同,触发不同的效果。
public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Button bt_game; private Button bt_music; private Button bt_book; private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bt_game = findViewById(R.id.bt_game); bt_music = findViewById(R.id.bt_music); bt_book = findViewById(R.id.bt_book); textView.findViewById(R.id.textView); bt_game.setOnClickListener(this); bt_music.setOnClickListener(this); bt_book.setOnClickListener(this); } @Override public void onClick(View view) { int id = view.getId(); if(id==R.id.bt_game){ textView.setText("game"); } else if (id == R.id.bt_music) { textView.setText("music"); }else if (id == R.id.bt_book) { textView.setText("book"); } //下面效果等同于上面效果 switch(id){ case R.id.bt_game: textView.setText("game"); break; case R.id.bt_music: textView.setText("music"); break; case R.id.bt_book: textView.setText("book"); break; default: break; } } }
AlertDialog
单选
自定义界面
ListView
RecycleView
Activity生命周期(各生命周期阶段会调用对应的函数及其使用建议)
onCreate():页面创建(可做一些控件、数据的初始化工作)
onstart():页面可见了,但不能交互(可做一些小数据的保存,但会影响下一个页面的打开速度)
onResume():页面可见,且能交互(做一些收尾工作,数据保存工作)
以上在打开应用时会顺序执行上面的方法,结束后则顺序执行下面的方法。
onPause():页面不能交互了
onStop():页面不可见了
onDestory():页面销毁
Activity之间的跳转(显示跳转)
三种跳转方式,(从LoginTest活动的页面跳转到MainActivity)
public class LoginTest extends AppCompatActivity implements View.OnClickListener { private Button btn1; private Button btn2; private Button btn3; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login_test); btn1=findViewById(R.id.login1); btn2=findViewById(R.id.login2); btn3=findViewById(R.id.login3); btn1.setOnClickListener(this); btn2.setOnClickListener(this); btn3.setOnClickListener(this); } @Override public void onClick(View view) { int id = view.getId(); switch(id){ case R.id.login1: Intent intent1= new Intent(LoginTest.this, MainActivity.class); startActivity(intent1); break; case R.id.login2: /* Intent intent2 = new Intent(); intent2.setClassName("com.example.recycleviewtest.Activity","com.example.recycleviewtest.MainActivity"); startActivity(intent2);*/ Intent intent2=new Intent(); intent2.setClass(this,MainActivity.class); startActivity(intent2);//它与第一种方式在功能上是等效的,但使用了不同的方法来设置目标活动。 break; case R.id.login3: Intent intent3 = new Intent(); intent3.setClassName(LoginTest.this,"com.example.recycleviewtest.MainActivity"); startActivity(intent3); break; default: break; } } }
隐式跳转(不同于显式跳转中写明从源界面跳转到目标界面,其不明确指明要跳转到哪个页面,而是通过条件筛选确定目的页面)
筛选条件的规则(Action动作、Category类别,对intent的一种额外描述,Data数据,也是对intent的一种额外描述)