学习笔记:Android

本篇是 Android 开发中需要掌握的基础内容

一、前言

1.开发方向

(1).传统Windows开发

  • SDK、DDK、C++、C#(.Net Framework、.Net Core)

(2).移动开发

  • HTML+CSS、AJAX、JS、XML(XPath)、图形图像
  • 基于 ARM 架构
  • SOC

(3).Web开发

  • CoM
  • 前端:HTML+CSS、AJAX、JS、图形图像
  • 后台:CGI+DB,PHP,ASP.NET、JSP

(4).嵌入式开发

2.学习内容

  • 算法(数据结构)
  • 接口
  • 方法论

二、基础内容

1.零碎

  • Android 讲究逻辑设视图分离 —— 在布局文件中编写界面,然后在活动中引入进来
  • res 文件夹下最后自己再创建 drawable-hdpi、drawable-xhdpi、drawable-xxhdpi 等文件夹,用来存放不同分辨率的图片

2.环境搭建

  • 关于软件下载,可以去这个网站
  • 关于安卓信息,可以去这个网站了解

(1).ADT

  • 关于ADT版本和SDK Tools的对应版本可以查看这里,里面详细说明了不同版本的ADT所对应的JDK版本要求,eclipse版本要求及SDK Tools版本要求。

(2).Android Studio

  • 关于其概述,可以查看这里
  • 安装教程查看这里

3.日志工具

  • Android 中的日志工具类是 Log,该类中提供了以下五个方法:
    Log.v():对应级别verbose,打印所有日志信息
    Log.d():对应级别debug,打印调试信息
    Log.i():对应级别info,打印比较重要的数据
    Log.w():对应级别warn,打印警告信息
    Log.e():对应级别error,打印错误信息
  • 该方法中需要两个字符串参数:
    tag:用于对打印信息进行过滤
    msg:想要打印的具体内容

三、活动(Activity)

1.基础

  • 项目中的任何活动都应该重写 Activity 的 onCreate() 方法

2.简单编写

(1).创建活动

  • 在项目的 app/src/main/java 下的包中右键新建 Empty Activity

(2).创建布局文件

  • 在项目的 app/src/main/res 下右键新建一个Directory,并将其命名为

(3).设计布局文件

(4).加载布局文件

  • 使用 setContentView() 方法,一般需要传入一个布局文件的id

(5).注册活动

  • 将活动在 AndroidManifest.xml 文件中注册
  • 活动的注册声明要放在 <application> 标签内,通过 <activity> 标签来对活动进行注册
  • <activity> 标签中使用 android:name 来指定具体注册哪一个活动,因为前面包名已经指定,所以只需要写 .活动名 即可

(6).配置主活动

  • <activity> 标签内部加入 <intent-filter> 标签,并在标签中写入如下内容:
    1
    2
    3
    4
    5
    6
    7
     <activity android:name=".FirstActivity"
    android:label="FirstActivity"> <!--指定活动中标题栏内容,并且成为应用名-->
    <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    </activity>

(7).销毁活动

  • 第一种:按下Back键就可以销毁当前的活动
  • 第二种:调用Activity类中的finish() 方法
    1
    2
    3
    4
    @Override
    public void onClick(View v){
    finish();
    }

3.Toast

  • 通过静态方法 makeText() 创建出一个 Toast 对象,然后调用 show() 将 Toast 显示出来就可以了

  • 该方法需要传入3个参数:
    Context:Toast要求的上下文
    Text:Toast显示的文本内容
    Time:Toast显示的时长,可选值为:Toast.LENGTH_SHORT与Toast.LENGTH_LONG

  • 如下就是通过点击一个按钮来使其显示 Toast

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.first_layout);
    // 获取到在布局文件中定义的元素并返回View对象
    Button button1 = (Button) findViewById(R.id.button_1);
    // 为按钮注册一个监听器
    button1.setOnClickListener(new View.OnClickListener(){
    // 为按钮添加单击响应事件
    @Override
    public void onClick(View v){
    Toast.makeText(FirstActivity.this,"You clicked Button 1",Toast.LENGTH_SHORT).show();
    }
    });
    }

4.Menu

5.Intent

6.生命周期

7.启动模式

(1).standard

(2).singleTop

(3).singleTask

(4).singleInstance

8.活动的最佳实践

(1).知晓当前在哪一个活动

(2).随时随地退出程序

(3).启动活动的最佳写法

四、UI 设计

1.视图(View)

  • 任何可视化控件都需要从 android.view.View 类中继承,而任何继承自该类的类都称为视图
  • View 可以分为三种:布局(layout)、视图容器类(View Container)、视图类(Button、TextView、EditText等)
  • 视图的继承关系如下图:
    Android02.png

2.视图之视图类

(1).TextView

  • 主要用于在界面上显示一段文本信息

(2).Button

  • 主要用于在界面上显示一个按钮

  • 在布局文件中设置的文字有小写,但实际会转为大写,可以添加如下文件来禁用这一默认特性:

    1
    2
    3
    4
    5
    6
    <Button
    android:id="@+id/button"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textAllCaps="false" //禁用默认特性
    android:text="Button" />
  • 绑定点击事件之匿名类注册监听器,如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Button button = (Button) findViewById(R.id.button);
    button.setOnClickListener(new View.OnClickListener(){
    @Override
    public void onClick(View v){
    //此处写逻辑
    }
    });
    }
    }
  • 绑定点击事件之实现接口注册监听器,如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Button button = (Button) findViewById(R.id.button);
    // 实现接口方式注册监听器
    button.setOnClickListener(this);
    }
    @Override
    public void onClick(View v){
    switch(v.getId()){
    case R.id.button:
    //此处写逻辑
    break;
    default:
    break;
    }
    }
    }

(3).EditText

  • 主要用于在控件里输入和编辑内容,并可以在程序中对这些内容进行处理

(4).ImageView

  • 主要用于引入图片并进行相关操作
  • 在引入之前最后自己在 res 目录下自己新建一个 drawable-xhdpi 的文件夹并将图片放入其中

(5).ProgressBar

  • 主要用于在界面上显示一个进度条,表示程序正在加载一些数据
  • 如果想要更改进度条的样式,可以如下设置:
    1
    2
    3
    4
    5
    6
    7
    <ProgressBar
    android:id="@+id/progress_bar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    // 更改进度条样式并设置最大值
    style="?android:attr/progressBarStyleHorizontal"
    android:max="100" />

(6).AlertDialog

  • 可以在当前界面弹出一个对话框,且置顶于所有界面元素之上的
  • 具体实现如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    // 点击按钮弹出一个对话框
    @Override
    public void onClick(View v){
    switch (v.getId()){
    case R.id.button:
    AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
    dialog.setTitle("This is Dialog");
    dialog.setMessage("这很重要,你确定要删除吗?");
    // 设置可以用返回键来关闭对话框
    dialog.setCancelable(false);
    dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
    }
    });
    dialog.setNegativeButton("Cancle", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
    }
    });
    // 显示对话框
    dialog.show();
    break;
    default:
    break;
    }
    }

(7).ProgressDialog

  • 可以在当前界面弹出一个对话框,且置顶于所有界面元素之上的,区别于上面的是,该对话框可以显示进度条,一般用于表示当前操作比较耗时
  • 具体实现如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // 点击按钮弹出对话框且显示进度条
    @Override
    public void onClick(View v){
    switch (v.getId()){
    case R.id.button:
    ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);
    progressDialog.setTitle("This is ProgressDialog");
    progressDialog.setMessage("Loading....");
    progressDialog.setCancelable(true);
    progressDialog.show();
    break;
    default:
    break;
    }
    }

(8).相关属性

a).android:id 属性

  • 语法如下:
1
android:id="@+id/user"

b).android:background 属性

  • 语法如下:
1
2
android:background="@mipmap/bg"
android:background="#bfa"

c).android:padding 属性

  • 语法如下:
1
2
android:padding="@dimen/activity_margin"
android:padding="16dp"
  • 还包括如下四个:
    android:paddingLeft
    android:paddingTop
    android:paddingRight
    android:paddingBottom
  • API 17新增加:
    android:paddingStart
    android:paddingEnd

d).android:gravity 属性

  • 用于指定文字的对齐方式,可选值有:top/bottom/left/right/center,也可以用 | 来指定多个值

e).android:textSize 属性

  • 用于设置文字的大小,在Android中字体大小时使用 sp 作为单位的

f).android:hint 属性

  • 常在EditText中使用,可以指定一段提示性文字

g).android:maxLines 属性

  • 常在EditText中使用,可以设置最大行数

h).android:visibility 属性

  • 所有控件都可以使用,用于设置控件的可见属性

  • 可选值如下:
    visible:可见的,默认值
    invisible:不可见的,但仍占据空间
    gone:不可见的,且不占据任何空间

  • 也可以使用代码设置控件的可见性,使用 setVisibility() 方法,可以传入 View.VISIBLE View.INVISIBLE View.GONE 三个值

3.视图之布局

  • 布局是一种可用于放置很多控件的容器,可以按照一定规律调整内部控件的位置

(1).线性布局(LinearLayout)

  • 在线性布局中,vertical下,高度就不可以指定为match;horizontal下,宽度就不可以指定为match
  • 相关属性请看下面的 ab

(2).相对布局(RelativeLayout)

  • 可以通过相对定位的方式让控件出现在布局的任何位置
  • 相关属性请看下面的 c~g

(3).帧布局(FrameLayout)

  • 所有的控件都会默认摆放在布局的左上角
  • 相关属性请看下面的 a

(4).百分比布局

  • 该布局只是作为相对布局和帧布局的拓展,分别为:PercentFrameLayout 和 PercentRelativeLayout
  • 只需要在项目的 build.gradle 中添加百分比布局库的依赖即可在所有系统版本上的兼容性了,打开 app/build.gradle ,在 dependencies 闭包中添加如下内容的最后一行,然后点击 Sync Now 即可:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    dependencies {
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.2.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
    implementation 'com.android.support:percent:24.2.1'
    }

(5).相关属性

a).android:layout_gravity 属性

  • 用于指定控件在布局中的对齐方式

b).android:layout_weight 属性

  • 用于使用比例的方式来指定控件的大小
  • 使用该属性时,可以将宽度修改为 0dp ,然后将该属性设置为1,则可以实现控件自动平分宽度
  • 在同一方向上也可以指定部分控件的该属性,使其自动适配

c).android:layout_alignParentXxx 属性

  • 其中XXX包含Left、Right、Top、Bottom
  • 使其相对于父元素定位

d).android:layout_centerInParent 属性

  • 使其相对于父元素居中

e).android:layout_above/below 属性

  • 可以让一个控件位于另一个控件的上方/下方
  • 使用该属性时作为参照物的控件需要写在最上边

f).android:layout_toLeftOf/toRightOf 属性

  • 可以让一个控件位于另一个控件的左侧/右侧
  • 使用该属性时作为参照物的控件需要写在最上边

g).android:layout_alignXXX 属性

  • 其中XXX包含Left、Right、Top、Bottom
  • 可以让一个控件的左/右/上/下边缘与另一个控件的边缘对齐

(6).引入布局或自定义控件

  • 通过引用布局,可以减少重复代码的编写
  • 当引入的布局中有些需要绑定点击事件时,就需要自定义控件来解决该问题了

a).引入布局

  • 新建一个布局文件并编写好,在 activity_main.xml 中使用以下语法来引入:

    1
    <include layout="@layout/title" />
  • 如果需要去除系统自带的标题栏,则需要在 MainActivity.java 文件中这样编写:

    1
    2
    3
    4
    ActionBar actionbar = getSupportActionBar();
    if(actionbar != null){
    actionbar.hide();
    }

b).自定义控件

  • 新建一个java文件来继承自 LinearLayout ,并重写其构造函数,如下:

    1
    2
    3
    4
    5
    6
    public class TitleLayout extends LinearLayout {
    public TitleLayout(Context context, AttributeSet attrs){
    super(context,attrs);
    LayoutInflater.from(context).inflate(R.layout.title,this);
    }
    }
  • 在布局文件中添加该自定义控件,如下:

    1
    2
    3
    4
    5
    6
    7
    8
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- 引入自定义控件 -->
    <com.wrysmile.uilayouttest.TitleLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />
    </LinearLayout>
  • 在自定义控件中编写适当的点击事件即可

4.视图之视图容器类

(1).ListView

  • 当程序有大量数据时,使用该空间可以将屏幕外的数据滚入,屏幕内的数据滚出

b).点击事件

  • 我们需要使用 setOnItemClickListener() 方法为ListView注册一个监听器,当执行点击事件时,就会回调 onItemClick() 方法
  • 在该方法中通过 position 来判断点击的是哪一个子项,然后执行相应的操作,可看下方:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    private List<Fruit> fruitList = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // 初始化水果数据
    initFruits();
    FruitAdapter adapter = new FruitAdapter(MainActivity.this,R.layout.fruit_item,fruitList);
    ListView listView = (ListView) findViewById(R.id.list_view);
    listView.setAdapter(adapter);
    // 点击事件
    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id){
    Fruit fruit = fruitList.get(position);
    Toast.makeText(MainActivity.this,fruit.getName(),Toast.LENGTH_SHORT).show();
    }
    });
    }
    }

(2).RecyclerView

  • 增强版的 ListView,具有同样的效果,还优化了性能问题

  • 和百分比布局类似,它也属于新增的控件,需要在项目的 build.gradle 中的 dependencies 闭包中添加如下内容:

    1
    implementation 'androidx.recyclerview:recyclerview:1.1.0'
  • 然后在 activity_main.xml 文件中这样编写即可

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <?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/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
    </LinearLayout>

a).点击事件

5.制作 Nine-Patch 图片

  • Nine-Patch 图片可以让某一图片动态的跟随内容变换其长度和高度,而不是单纯的让图片平铺在背景上,主要用于实现类似于聊天框的效果
  • 将图片导入到项目中的 drawable-xhdpi 文件夹中,右击该图片,找到 Create 9-patch file 按钮,点击就进入了制作界面
  • 类似于 PS 的画笔功能,可以在四边用鼠标进行绘画一条直线,上边和左边是控制哪部分拉伸的,下边和右边是控制文本在哪里显示的
  • 修改好后右边可以看到效果图,满意保存替换源文件即可

2.ViewGroup 类

  • 它是一个抽象类,一般使用其子类来实现
  • 该类控制其子组件分布时依赖如下两个内部类:

(1).ViewGroup.LayoutParams 类

  • 该类主要控制布局的位置、高度和宽度的

  • 通常使用以下两个属性:
    android:layout_height:设置布局高度
    android:layout_width:设置布局宽度

  • 这两个属性有如下属性值:
    fill_parent:与父容器形同(API8以下使用)
    match_parent:与父容器相同
    wrap_content:包裹其自身的内容

(2).ViewGroup.MarginLayoutParams 类

  • 主要用于控制子组件的外边距
  • 通常包括四个属性:
    android:layout_marginLeft
    android:layout_marginTop
    android:layout_marginRight
    android:layout_marginBottom
  • API 17新增加:
    android:paddingStart
    android:paddingEnd

3.UI组件的层次结构

  • 如下图:
    Android01.png

4.控制UI界面的方法

(1).使用XML布局文件控制UI界面

  • res/layout 目录下编写XML布局文件
  • 在 Activity 中使用以下Java代码来显示XML文件中布局的内容
    1
    setContentView(R.layout.activity_main);

(2).在Java代码中控制UI界面

  • 新建的 MainActivity 类应该继承自 AppCompatActivity 类
  • 然后重写 onCreate 方法,且所有代码都得写在 super.onCreate(savedInstanceState); 语句的后面
  • 中间代码设置背景等样式
  • 还可以为按钮绑定单击响应事件
  • 最后需要将写好的内容通过以下代码加入 View 中——frameLayout.addView(text1);

(3).使用XML和Java混合控制UI界面

(4).开发自定义的View

五、碎片(手机平板的兼容)

1.基础

  • 碎片是一种可以嵌入在活动当中的 UI 片段,一般用于平板视图中

2.使用方式

(1).简单用法

  • 写一左一右两个布局文件
  • 新建一左一右两个类并让其继承自 Fragment 类,并在这两个类中通过 LayoutInflater 的 inflate() 方法将刚才定义的布局加载进来
  • 在 activity_main.xml 中使用 <fragment> 标签添加碎片
  • 注意:这里需要通过 android:name 属性来显示指明要添加的碎片类名

(2).动态添加碎片

a).方法

  • 创建待添加的碎片实例
  • 获取 FragmentManager,在活动中可以直接调用 getSupportFragmentManager() 方法得到
  • 开启一个事务,通过调用 beginTransaction() 方法开启
  • 向容器内添加或替换碎片,一般使用 replace() 方法实现,需要传入容器的id和待添加的碎片实例
  • 提交事务,调用 commit() 方法来完成

b).引申

  • 这里在 activity_main.xml 中加载布局可以使用 <FrameLayout></FrameLayout> 布局来写

(3).在碎片中返回栈

  • 作用:使碎片像活动一样有返回栈,按 Back键时会回到上一个页面
  • FragmentTransaction 中提供了一个 addToBackStack() 方法,可以用于将一个事务添加到返回栈中,一般传 null 即可,如下:
    1
    transaction.addToBackStack(null);

(4).碎片和活动的通信

  • 从布局文件中获取碎片的实例:

    1
    RightFragment rightFragment = (RightFragment) getSupportFragmentManager().findFragmentById(R.id.right_fragment);
  • 从碎片中调用活动的方法:

    1
    MainActivity activity = (MainActivity) getActivity();
  • 引申:碎片与碎片之间的通信可以先在一个碎片总得到与它相关联的活动,然后再通过这个活动去获取另外一个碎片的实例

  • 引申:当碎片需要使用 Context 对象时,也可以使用 getActivity() 方法

3.生命周期

  • 生命周期示意图如下:

(1).运行状态

  • 碎片可见,且与之关联的活动正处于运行状态

(2).暂停状态

  • 某一活动进入暂停状态,与之相关联的碎片也会处于暂停状态

(3).停止状态

  • 某一活动进入停止状态,与之相关联的碎片也会处于停止状态
  • 通过调用 FragmentTransaction 的 remove()和replace() 方法将碎片从活动中移除,但在事务提交前调用 addToBackStack() 方法,也会处于停止状态

(4).销毁状态

  • 某一活动被销毁时,与之相关联的碎片就会进入销毁状态
  • 通过调用 FragmentTransaction 的 remove()和replace() 方法将碎片从活动中移除,但在事务提交前没有调用 addToBackStack() 方法,也会处于销毁状态

(5).附加回调方法

  • onAttach():碎片和活动建立关联时调用
  • onCreateView():为碎片创建视图(加载布局)时调用
  • onActivityCreated():确保与碎片相关联的活动一定已经创建完毕时调用
  • onDestroyView():当与碎片相关联的视图被移除时调用
  • onDetach():当碎片和活动解除关联时调用

六、广播接收器

1.基础

  • 发送广播使用 Intent,而接收广播使用 Broadcast Receiver(广播接收器)
  • 广播类型分为:
    标准广播:一种完全异步执行的广播,广播发出以后,所有的广播接收器几乎在同一时刻接收到这条广播信息
    有序广播:一种同步执行的广播,广播发出以后,同一时刻只有一个广播接收器能收到这条广播信息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递

2.接收系统广播

(1).动态注册

  • 广播接收器想要监听什么广播,就使用 intentFilter 添加相应的 action 即可
  • 动态注册的广播接收器一定要取消注册才行,可以在 onDestroy() 方法中调用 unregisterReceiver() 方法来实现
  • 注意 Android 系统为了保护用户设备的安全和隐私,做了严格的规定:如果程序需要进行一些对用户来说比较敏感的操作,就必须在配置文件中声明权限才可以,否则程序会直接崩溃

附、问题集合

1.Android Studio启动后gradle下载太慢

  • 在尝试进行第一次编译程序时,发现gradle下载很慢,即使挂梯子也下载很慢,于是在网上找到需要的压缩包进行自行配置,需要的可以点击这里(提取码:m33b)直接进行下载
  • gradlegradle-6.1.1-all.zip(或者其他版本名字) 下载完成之后放着待用
  • 在你的c盘中找到该路径 C:\Users\你的用户名\.gradle\wrapper\dists\gradle-6.1.1-all(或者其他版本名字)\cfmwm155h49vnt3hynmlrsdst
  • 将其中的文件全部删除,再把刚刚下载好的文件粘贴进去
  • 重启 Android Studio,此时会自动跳过下载并开始解压i

2.给 Button 添加背景之后不显示

  • 添加背景后依然显示默认颜色,此时需要给布局处加入以下这一行

    1
    xmlns:app="http://schemas.android.com/apk/res-auto"
  • 然后在按钮的设置处加入以下这行

    1
    app:backgroundTint="@null" 

3.如何修改AS的模拟器位置

  • C:\user\用户名\.android\avdC:\Android\.android\avd 中找到模拟器文件夹,一个文件夹对应一个配置文件

  • 将模拟器文件夹移动到你所需要移动到的位置,我这里移动到了这里:

    1
    D:\Android\avd\Pixel_3a_API_30_x86.avd
  • 修改C盘的配置文件中的path字段即可,如下:

    1
    2
    3
    4
    avd.ini.encoding=UTF-8
    path=D:\Android\avd\Pixel_3a_API_30_x86.avd
    path.rel=avd\Pixel_3a_API_30_x86.avd
    target=android-30
  • 打开AS测试模拟器是否可以正常运行

4.如何修改Android项目的包名

当你引用别人的项目时,会发现包名是别人的包名,想要修改成为自己的包名按以下操作即可

  • 建议在Project格式下,找到 app/src/main/java 路径,在这之下就是项目的包名,点击右上角的齿轮图标,如下图:
    Android03.png
  • Compact Middle Packages 选项取消勾选,更改后如下图:
    Android04.png
  • 点击你需要更改的包名,按快捷键 shift + F6 进行重命名操作,并选择 Rename package,如下图:
    Android05.png
  • 填好包名后点击 Refactor,此时下方会弹出小框提示哪些文件需要一并修改,这里AS会自动检测并帮我们自动修改,点击 Do Refactor,如下图:
    Android06.png
  • 完成后修改 app 目录下的 build.gradle 文件中的 applicationId 字样,成功后点击 Sync now 修改完成,如下图:
    Android07.png
  • https://www.jianshu.com/p/14d92eecfada
  • 双击返回键退出应用:https://blog.csdn.net/qq_23179075/article/details/60587202
  • 实现沉浸式状态栏:https://blog.csdn.net/weixin_43796132/article/details/102250632