个人Android开发之旅(一):BaseActivity的浅入之简单封装 Toolbar

为何要写BaseAcivity

咱们都知道在作Android应用开发的时候都须要建立一个Activity,但不少时候咱们的程序有多个界面而且每一个界面都有类似的内容(例如:Toolbar、DrawerLayout)和后台的操做有共同的方法,这个时候咱们写一个BaseActivity做为每个Activity的基类,统一管理程序中的每一个Activity。php

一行代码实现 Toolbar 效果

activity_main.xml 的代码java

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" android:gravity="center" android:background="@android:color/holo_blue_light">

    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="我是MainActivity的界面" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" />

</LinearLayout>
复制代码

MainAcitvity.java 的代码android

public class MainActivity extends BaseActivity {

    @Override
    protected int getContentView() {
        return R.layout.activity_main;
    }
}

复制代码

在这里插入图片描述
在上面的 activity_main.xml 中能够看出,父布局设置了背景颜色和里面只有一个TextView,并没图中的Toolbar。那究竟是为何呢?其实细心观察的小伙伴们会发现,怎么MainActivity中的代码和日常不同呢?onCreate()方法呢?别急,咱们重头开始!

“少啰嗦,先看东西”

  • 建立 BaseActivitygit

    在项目建立后,咱们能够看到AndroidStudio自动帮咱们生成了MainActivity.java和activity_main.xml文件,而后咱们再建立一个新的Activity,命名为BaseActivity。github

    在这里插入图片描述

  • 修改 activity_base.xml 文件app

    接着打开activity_base.xml文件,把父布局的ConstraintLayout换成垂直的LinearLayout(其实也能够不换的,主要是我喜欢用LinearLayout),并在里面添加两个元素Toolbar和FrameLayout。ide

    注意:因为Toolbar代替 ActionBar,因此先把 ActionBar 去掉,咱们经过设置 Application 的 theme 来隐藏,这样项目中全部的界面的 ActionBar 就都隐藏了。布局

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

    <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

    <FrameLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent">

    </FrameLayout>

</LinearLayout>
复制代码
  • 修改 BaseActivity.java 文件gradle

    接下来打开 BaseActivity.java 文件,让 BaseActivity 继承 AppCompatActivity ,修改代码以下ui

    注意:protected abstract int getContentView(); 是一个抽象方法,因此咱们要将 BaseActivity 修改为抽象类。为何要修改为抽象类呢?缘由很简单,由于一个类里是不容许有一个抽象方法的,如要有抽象方法,那这个类就必须是抽象类。那可能你又会问,为何要用抽象方法呢?(你是十万个为何吗?哪来的那么多为何)由于咱们想让其余 Activity 的界面显示到 BaseActivity 中,那这个方法是必需要实现的,若是设置成普通的方法的话,咱们颇有可能在写代码的时候忘记了调用了这个方法,致使界面不显示。因此咱们得用抽象方法,这样每一个 Activity 继承这个 BaseActivity 的时候就必须覆写 getContentView() 这个方法。

public abstract class BaseActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_base);
        initView();
    }

    private void initView() {
        // 绑定控件
        Toolbar toolbar = findViewById(R.id.toolbar);
        FrameLayout container = findViewById(R.id.container);
        // 初始化设置Toolbar
        toolbar.setTitle("我是BaseActivity的Toolbar");
        setSupportActionBar(toolbar);
        // 将继承了BaseActivity的布局文件解析到 container 中,这样 BaseActivity 就能显示 MainActivity 的布局文件了
        LayoutInflater.from(this).inflate(getContentView(), container);
    }

    /** * 获取要显示内容的布局文件的资源id * * @return 显示的内容界面的资源id */
    protected abstract int getContentView();

}

复制代码
  • 修改 activity_main.xml 文件 打开 activity_main.xml 文件,而后咱们将父布局的背景颜色修改一下,方便咱们辨别究竟是 MainActivity 的布局文件仍是 BaseActivity 的布局文件。再添加添加一个 TextView ,缘由也是和修改背景颜色是同样的。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" android:gravity="center" android:background="@android:color/holo_blue_light">

    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="我是MainActivity的界面" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" />

</LinearLayout>
复制代码
  • 修改 MainActivity.java 文件 让 MainActivity 继承 BaseActivity 并覆写 getContentView() 方法,而后删除onCreate()方法。经过 getContentView() 方法返回当前的布局资源ID给 BaseActivity,让 BaseActivity 加载布局文件。
public class MainActivity extends BaseActivity {

    @Override
    protected int getContentView() {
        return R.layout.activity_main;
    }
}
复制代码
  • 运行项目

    如今你运行一下项目,咱们并无在 MainActivity 的布局中添加 ToolBar,可是运行出来的效果是 Toolbar 已经存在了。

    在这里插入图片描述
    如今就能作到用一行代码实现 Toolbar 的效果。那你如今可能就会有疑问,若是我像对 Toolbar 修改标题和添加按钮呢?其实也简单,咱们继续往下看。

  • 修改标题 咱们在 BaseActivity 中再添加一个抽象方法,并在初始化 Toolbar 那一处调用咱们写的这个抽象方法。

public abstract class BaseActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_base);
        initView();
    }

    private void initView() {
        // 绑定控件
        Toolbar toolbar = findViewById(R.id.toolbar);
        FrameLayout container = findViewById(R.id.container);
        // 初始化设置Toolbar
        toolbar.setTitle(setTitle());
        setSupportActionBar(toolbar);
        // 将继承了BaseActivity的布局文件解析到 container 中,这样 BaseActivity 就能显示 MainActivity 的布局文件了
        LayoutInflater.from(this).inflate(getContentView(), container);
    }

    /** * 获取要显示内容的布局文件的资源id * * @return 显示的内容界面的资源id */
    protected abstract int getContentView();

    /** * 设置标题 * * @return 要显示的标题名称 */
    protected abstract String setTitle();

}
复制代码
  • 修改 MainActivity.java 咱们仍是像刚才同样覆写 setTitle() 方法,并在返回值输入咱们想要显示的标题
public class MainActivity extends BaseActivity {

    @Override
    protected int getContentView() {
        return R.layout.activity_main;
    }

    @Override
    protected String setTitle() {
        return "我是MainActivity的标题";
    }
}
复制代码

这个时候再运行如下你的程序就会出现你设置的标题了。

在这里插入图片描述
那么如今你可能又会问了,若是我想对 Toolbar 添加一个返回按钮,并能对他进行操做应该怎么办?(我不想写了,你也别问了!)其实很简单,在 BaseActivity 里自定义一个接口,在子类中设置这个接口的实例就行。

  • 显示返回按钮 咱们先给 Toolbar 显示返回按钮,经过 getSupportActionBar() 获得 ActionBar 的实例,再调用 ActionBar 的 setDisplayHomeAsUpEnabled(true) 方法让返回按钮显示出来。

    Toolbar 最左侧的按钮是叫作HomeAsUp,默认是隐藏的,而且它的图标是一个返回箭头。还有一种 setNavigationcon() 方法也能设置图标,具体能够查找 Toolbar 的文档说明

private void initView() {
        // 绑定控件
        Toolbar toolbar = findViewById(R.id.toolbar);
        FrameLayout container = findViewById(R.id.container);
        // 初始化设置Toolbar
        toolbar.setTitle(setTitle());
        setSupportActionBar(toolbar);
        // 将继承了BaseActivity的布局文件解析到 container 中,这样 BaseActivity 就能显示 MainActivity 的布局文件了
        LayoutInflater.from(this).inflate(getContentView(), container);
        // 显示返回按钮
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
        }
        // 初始化
        init();
    }
复制代码
  • 本身定义一个接口并声明 这里我就用截图显示代码片断

    在这里插入图片描述

  • 设置监听事件 打开 MainActivity.java 文件,覆写 init() 方法,并调用父类的 setBackOnClickListener() 方法。

    这里我用了 lambda 表达式,这是 java 8 才支持的,默认项目是不支持的,你在 build.gradle 中须要声明一下。

@Override
    protected void init() {
        setBackOnClickListener(() ->
                Toast.makeText(this, "点击了一下返回按钮", Toast.LENGTH_SHORT).show()
        );
    }
复制代码
  • 运行app
    在这里插入图片描述

最后

相信你对 BaseActivity 有了一些简单的了解了,具体如何使用仍是得看你的项目,不是项目里就必定要写 BaseActivity 和全部 Activity 都要继承 BaseActivity ,我只是将我所理解的 BaseActivity 和你们分享一下。可能你看完了这一篇文章发现仍是没能理解,在这里我想说声抱歉,可能有些地方讲的不够通俗易懂或是讲解有误,还请您多多指教,我会虚心接受并及时改正(就算是讲错了我也不会改)。

Demo的Github地址: github.com/lmx0206/Bas… Demo的Gitee地址: gitee.com/Leungmx/Bas…

相关文章
相关标签/搜索