Android开发

布局

前面三种布局分别是

  1. LinearLayout-线性
  2. RelativeLayout-相对
  3. FrameLayout-单帧

这三种都挺简单的,不用多说

ConstrainLayout

约束布局-为子view添加约束来确定位置

通过减少嵌套,来减少过度绘制,从而优化布局

View

几点注意:

  1. 在线性布局中垂直布局,可以用orientation=”vertical”来实现

跑马灯的效果

  1. android:singleLine="true"
  2. android:ellipsize="marquee"

在代码中,开启:textView.setSelected(true);即可实现跑马灯的效果

Activity

安卓生命周期图:
20240713214342

开始阶段:

  1. onCreate:页面创建(用于数据初始化,比如绑定事件)
  2. onStart:页面可见,但不能交互
  3. onResume:页面可见,且能交互

结束阶段

  1. onPause:页面不能交互了
  2. onStop:页面不可见-但是后台还在
  3. onDestory:页面摧毁-后台也没了(数居收尾,保存工作)

Activity之间的跳转

  1. 显式跳转

就是直接指明源头和目的地,注意,要执行startActivity方法才行

1
2
Intent intent = new Intent(MainActivity.this, RegisterActivity.class);
startActivity(intent);
  1. 隐式跳转

不明确的指明要跳转到哪个页面,而是通过条件筛选确定目的页面

如果想要当前的activity可以被隐式跳转意图匹配,那么必须在intent-filter里声明category,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<activity android:name=".CustomActivity"
android:exported="true">
<intent-filter>
<action android:name="com.zzmr.activityjump.CustomActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<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>

跳转时,这么写:

1
2
3
4
5
public void toCustom(View view) {
Intent intent = new Intent();
intent.setAction("com.zzmr.activityjump.CustomActivity");
startActivity(intent);
}

Activity启动模式

  1. standard模式:一个叠加一个,符合先进后出的规律
    20240714140946
  2. singleTask模式:会将目标activity上的其他activity清除,只保留自己(栈内复用)
    1. 判断当前任务栈内是否已经有了该Activity
    2. 如果没有,则新建一个,并正常入栈
    3. 如果已经有了,则把该Activity上面的全部弹出,将该Activity暴露在最上面
  3. singleTop:栈顶复用
    1. 判断当前任务栈的栈顶是否是该Activity
    2. 如果不是,则新建一个,并正常入栈
    3. 如果栈顶是,则直接复用栈顶的Activity,不新建Activity,以下是不复用的情况(standard模式)
    4. 20240714142655
  4. singleInstance:独享栈空间
    1. 如果没有该Activity,则直接开辟一个新的栈,专门盛放该Activity,独享一个任务栈
    2. 20240714143242

多页面情况下的生命周期

20240714144518

两种情况

  1. 点击返回键退出app,此时是先销毁然后重新入栈
    20240714144618
  2. 点击home键,会将系统桌面入栈,再重新进入软件,此时系统桌面出栈,Activity重新成为栈顶-复现
    20240714144936

弹出对话框对生命周期的影响
就是没有影响,因为对话框的上下文Context传入时就是该Activity,所以可以说这个对话框是依附于Activity的,相当于是它的一部分,因此,对话框弹出并不影响Activity的生命周期

1
2
3
4
5
6
7
8
9
10
11
public void popDialog(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Dialog Title");
builder.setMessage("Hello");
builder.setNegativeButton("cancel", (DialogInterface dialog, int which) -> {
Log.i(TAG, "popDialog: popDialog cancel");
});
builder.setPositiveButton("confirm", null);
AlertDialog alertDialog = builder.create();
alertDialog.show();
}

但是如果这个对话框是新进入的一个Activity上面的,那肯定就要引起生命周期的变化了,当然引起生命周期变化的并不是对话框,而是新的Activity

而这个变化,是导致原Activity pause,然后结束对话框之后重新resume

同理,跳到一个透明的Activity也是一样的
20240714195125

传递数据

  1. 单独传递
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    // 传递:
    public void jumpAndParam(View view) {
    Intent intent = new Intent(MainActivity.this, ActivityReceive.class);
    intent.putExtra("userName", "zzmr");
    intent.putExtra("password", 123);
    startActivity(intent);
    }

    // 接收:
    Intent intent = getIntent();
    if (intent != null) {
    String userName = intent.getStringExtra("userName");
    int password = intent.getIntExtra("password", 0);
    Log.i(TAG, "onCreate---userName is " + userName);
    Log.i(TAG, "onCreate---password is " + password);
    }
  2. 打包传递
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    // 传递数据
    public void jumpByBundle(View view) {
    Intent intent = new Intent(MainActivity.this, ActivityReceive2.class);
    Bundle bundle = new Bundle();
    bundle.putString("userName", "zzmr");
    bundle.putInt("password", 123);
    bundle.putBoolean("isLogin", true);
    // 注意这里是putExtras
    intent.putExtras(bundle);
    startActivity(intent);
    }
    // 接收数据
    Intent intent = getIntent();
    if (intent != null) {
    // 接收Bundle
    Bundle bundle = intent.getExtras();
    String userName = bundle.getString("userName");
    int password = bundle.getInt("password");
    boolean isLogin = bundle.getBoolean("isLogin");
    Log.i(TAG, "userName,password,isLogin" + userName + password + isLogin);
    }
  3. 传递对象
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    // 传递
    public void jumpObject(View view) {
    Intent intent = new Intent(MainActivity.this, ActivityReceive3.class);
    User user = new User();
    user.setUserName("zzmr");
    user.setAge(22);
    user.setLogin(true);
    intent.putExtra("user", user);
    startActivity(intent);
    }

    // 接收
    Intent intent = getIntent();
    if (intent != null) {
    User user = (User) intent.getSerializableExtra("user");
    Log.i(TAG, "onCreate: user:" + user);
    }
  4. 回传数据-MainActivity跳转到Activity2,并希望返回时收到Activity带回来的数据
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public void jumpAndReceive(View view) {
    Intent intent = new Intent(MainActivity.this, ActivityReceive4.class);
    startActivityForResult(intent, 0);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 0 && resultCode == 1 && data != null) {
    String userName = data.getStringExtra("userName");
    Log.i("backResult", "onActivityResult: " + userName);
    }
    }

    // 回传数据
    public void backToMain(View view) {
    Intent intent = new Intent();
    intent.putExtra("userName", "zzmr");
    setResult(1, intent);
    this.finish();
    }

存储工具SharedPreference

主要就是存SharedPreferences,要用到edit.putXXX,取的时候不需要edit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public void saveData(View view) {
// 拿到输入框的数据
String content = etText.getText().toString();
SharedPreferences spRecord = getSharedPreferences("spRecord", MODE_PRIVATE);
SharedPreferences.Editor edit = spRecord.edit();
edit.putString("content", content);
// 提交到磁盘
edit.commit();
// 提交到内存
// edit.apply();

Toast.makeText(this, "已保存" + content, Toast.LENGTH_SHORT).show();
// 清空输入框
etText.setText("");

}

public void getData(View view) {
SharedPreferences spRecord = getSharedPreferences("spRecord", MODE_PRIVATE);
String content = spRecord.getString("content", "");
etText.setText(content);
etText.setSelection(content.length());
}

数据库SQLite