Android Jetpack之AppCompat(一)

来源:https://www.cnblogs.com/wenhanxiao/archive/2019/03/11/10513498.html
-Advertisement-
Play Games

今天我們來聊一聊有關AppCompat,作為Android Jetpack系列文章的開篇。說到Android Jetpack,我們先看一下這張圖: 從圖中我們可以看到,整個Android Jetpack分為了四大部分,而我們今天要講述的就是Foundation中的AppCompat小節,官方將該部分 ...


今天我們來聊一聊有關AppCompat,作為Android Jetpack系列文章的開篇。說到Android Jetpack,我們先看一下這張圖:
Jetpack一覽
從圖中我們可以看到,整個Android Jetpack分為了四大部分,而我們今天要講述的就是Foundation中的AppCompat小節,官方將該部分翻譯為“基礎”。
Google官方網站:
https://developer.android.com/jetpack
按照Google官方的描述,AppCompat就是指v7 appcompat庫。

“This library adds support for the Action Bar user interface design pattern. This library includes support for material design user interface implementations.”

意思是:此庫添加了對操作欄用戶界面設計模式的支持。這個庫包括對Material Design用戶界面實現的支持。也就是說,我們可以藉助該庫,對Material Design有更便捷和相容性更好的實現。
進入AppCompat章節後,我們發現它又被分為了4個部分,這4個部分被稱為“key class”,也就是重點類,它們分別是:

  • ActionBar:提供Actionbar用戶界面模式的實現;
  • AppCompatActivity:添加可用作使用支持庫操作欄實現的Activity的基類;
  • AppCompatDialog:添加一個可用作AppCompat主題的Dialog的基類;
  • ShareActionProvider:添加對可包含在ActionBar中的標準化共用操作(如電子郵件或發佈到社交應用程式)的支持。

想要使用這些類,我們需要添加v7支持庫。
到現在為止,支持庫的最新版本是28,添加的庫名稱和版本如下:

com.android.support:appcompat-v7:28.0.0

今天我們就先來聊一聊ActionBar,也是這裡面最為複雜的一個部分。
依稀記得,伴隨著Google I/O 2014的召開,早在Android 5.0的時代,Google 官方推出了ToolBar組件,在那之後,ToolBar就登上了歷史舞臺,扮演著重要的角色。之前我在CSDN上面也發表過相關主題的文章,因為發佈的時機剛好是ToolBar登場之際,所以獲得了很多的閱讀量。快5年過去了,回頭再看那幾篇連載,感覺文筆很是稚嫩。今天藉著講述Jetpack,再次聊聊ToolBar那些事,相信你我都會有新的收穫。

首先解決疑問:

  1. 問:既然有了ActionBar,為何還要用ToolBar? 答:使用AppCompat Toolbar能相容更廣泛的設備(ActionBar要求最低Android 3.0,ToolBar要求最低Android 2.1,但只有Android 5.0及以上才能在不使用AppCompat相容包的前提下支持Material Design),以及各式各樣的自定義需求。

  2. 問:ToolBar上面都應該包含哪些內容? 答:根據Google的指導,應用欄區域應具備以下要素:1)一個專用區域,可以標識您的應用並指示用戶在應用中的位置;2)以可預測的方式訪問搜索等重要操作;3)支持導航和視圖切換(通過標簽頁或下拉列表)。

一、添加ToolBar
想要添加一個ToolBar,總共3步走:
1. 更改application主題樣式,操作對象:styles.xml。
對於新建的Android項目,AndroidManifest.xml中已經定義了所使用的theme,即:

android:theme="@style/AppTheme"

此時,我們修改styles.xml文件即可,將預設的繼承值改掉,如下所示:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

2. 在Activity佈局中添加ToolBar,操作對象:layout佈局文件

<android.support.v7.widget.Toolbar
    android:id="@+id/activity_main_tb"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    android:elevation="4dp"
    android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

對高度掌握不好火候的同學,直接如上使用ActionBar的高度就可以了。
android:evevation指“仰角”,這部分知識請參考:
https://developer.android.com/training/material/shadows-clipping
這裡就不再贅述了。
如果你的項目已經遷移到Android X,你的佈局文件代碼片應該是:

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

3. 在Activity類中找到ToolBar,並應用它,操作對象:Activity類
這一步並不複雜,參考普通的Android控制項。類似地,我們通過findViewById()找到ToolBar,並做執行一些設定,即可完成該步驟,示例如下:

private Toolbar topTb;
topTb = findViewById(R.id.activity_main_tb);        
setSupportActionBar(topTb);

一旦我們setSupportActionBar()後,日後我們就可以通過getSupportActionBar()方法來獲取ToolBar實例,也可以使用相容包提供的ActionBar的各種API方法了。
到此,我們就完成了ToolBar的添加,還算簡單吧?

二、ToolBar外觀的自定義
不出意外的話,我們運行的結果將會和下圖類似:
預設的配色方案
大綠底,大黑字,實在不怎麼好看。
那麼,如果我們想要自定義配色方案,該如何做呢?參考下圖:
配色方案指導
這些值我們都可以在color.xml中定義,併在styles.xml中引用。下圖是一個重新定義配色方案後的截圖:
自定義的配色方案
相關的代碼片:
color.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#002FA7</color>
    <color name="colorPrimaryDark">#001F67</color>
    <color name="colorAccent">#003FB7</color>
    <color name="textColorPrimary">#FFFFFF</color>
</resources>

styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="android:textColorPrimary">@color/textColorPrimary</item>
</style>

細心的讀者會發現,後面的截圖中,右上角多了菜單項,這又是如何實現的呢?我們繼續往後看。

三、給ToolBar增加動作
首先我們來看看如何給ToolBar增加菜單,我們依然分為3步完成。
1. 編寫菜單xml文件,操作對象:menu文件夾下的菜單xml文件
這裡我添加了兩個菜單,如上圖所示,一個隱藏在“更多”里,另一個是搜索。如下代碼片所示:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/menu_main_info"
        android:title="@string/menu_main_activity_info"
        app:showAsAction="never" />

    <item
        android:id="@+id/menu_main_search"
        android:title="@string/menu_main_activity_search"
        app:actionViewClass="android.support.v7.widget.SearchView"
        app:showAsAction="always" />
</menu>

如上,我們可以看到有兩個item,分別對應Info和搜索,我們使用"app:showAsAction"的值來控制這個菜單是否顯示,常見的值有always,ifRoom,never。從字面上也很好理解,這裡就不多解釋了。

2. 接下來是Java代碼片段:

private SearchView tbSearchSv;

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main_activity_menu, menu);
    MenuItem searchItem = menu.findItem(R.id.menu_main_search);
    tbSearchSv = (SearchView) searchItem.getActionView();
    return super.onCreateOptionsMenu(menu);
}

細心的朋友會發現有這一行:

app:actionViewClass="android.support.v7.widget.SearchView"

它是做什麼的呢?
搜索欄效果
對了!它就是搜索欄,是原生的搜索欄。所以某些情況下,這個搜索欄是不用自己去實現的,系統已經給我們提供了SearchView!
典型的APP:網易雲音樂、知乎上方的搜索都是這樣的。

3. 為菜單設置監聽器,我們先來看最普通的Info按鈕,我們只需在Java代碼中Override指定的方法就可以了,如下所示:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.menu_main_info:
            Toast.makeText(MainActivity.this, R.string.menu_main_activity_info, Toast.LENGTH_LONG).show();
            break;
    }
    return super.onOptionsItemSelected(item);
}

對於搜索欄,首先我們想到的是,如何獲取用戶輸入的內容呢?
其實很簡單,玄機在於SearchView,只需對SearchView添加監聽器就可以了。

tbSearchSv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
    @Override
    public boolean onQueryTextSubmit(String s) {
        
        return false;
    }

    @Override
    public boolean onQueryTextChange(String s) {
        
        return false;
    }
});

這裡要註意,設置監聽器前,要確保SearchView(這裡的tbSearchSv)已經被實例化,否則,會出現空指針異常崩潰。
關於SearchView,還有一寫額外的設置,比如:

// 設置提交按鈕是否可見(預設不可見)
tbSearchSv.setSubmitButtonEnabled(true);

提交按鈕是否可見

// 設置左側是否顯示搜索圖標(預設不可見)
tbSearchSv.setIconifiedByDefault(false);

左側是否顯示搜索圖標
更多可使用的API請參考官方文檔:
https://developer.android.google.cn/reference/android/widget/SearchView

不過,我們這裡還需要做最後一點善後。如果你是一路下來照著本篇文章敲代碼的話,在搜索框打開的情況下按一下返回鍵,你期待的是什麼?是不是取消搜索操作,停留在當前界面?然而實際上是……退出了APP。
所以我們這裡要對返回鍵的預設動作做一個“攔截”,具體可參考如下代碼片:

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    switch (keyCode) {
        case KeyEvent.KEYCODE_BACK:
            if (!tbSearchSv.isIconified()) {
                tbSearchSv.setIconified(true);
                return true;
            }
            break;
    }
    return super.onKeyUp(keyCode, event);
}

這裡SearchView的isIconfied()方法可以返回當前的SearchView展開狀態。

四、返回上一層

ToolBar還有一個比較常見的功能就是左上角的返回按鈕,提供返回上一層操作,很多的APP開發者都習慣於自定義一個ImageButton或類似的空間,然後使用美工提供的圖像素材,設置監聽器,寫Selector……一套下來,費時費力。
其實Google已經為開發者提供了現成的非常易用的返回邏輯處理。要實現這些處理,兩步就搞定了。

1. 在ToolBar對象上啟用返回鈕

getSupportActionBar().setDisplayHomeAsUpEnabled(true);

這裡註意,雖然之前將ToolBar通過setSupportActionBar()方式當做參數被set了一次,但是ToolBar類本身並不提供setDisplayHomeAsUpEnabled()方法,因此,我們還需要getSupportActionBar(),先獲取ActionBar對象,然後使用該對象,而不是直接使用ToolBar對象。

2. 在AndroidManifest.xml中定義要跳轉的Activity
如題,我們在AndroidManifest.xml中,對子Activity做處理,這裡不要忘記相容低版本的系統。

<activity
    android:name=".MainActivity"
    android:parentActivityName=".SecondActivity">
    <!-- 相容 Android4.0 及以下版本-->
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value=".SecondActivity" />
</activity>

將SecondActivity改為入口Activity,然後重新運行程式,將實現如下效果:
返回鍵視頻演示
到此,關於ToolBar常見用法的梳理告一段落。源碼請自取:
https://github.com/wh1990xiao2005/JetpackDemo

我會在接下來的文章中,和大家分享關於ToolBar的剩餘內容,以及AppCompat相容包中的其他知識,希望對你我都有幫助。
共勉!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 我只是搬運工。。。 1.我也下載了,好像不能超過500M每次,100個站。下了也不會看。有沒有高手能介紹下專門下載某個省的所有氣象站氣溫資料的方法,從而計算出每個站每月的平均氣溫。。格式為txt。2 http://www.esrl.noaa.gov/psd/data/gridded/reanalys ...
  • 本文由雲+社區發表 作者:漆洪凱 規則1 :一般情況可以選擇MyISAM存儲引擎,如果需要事務支持必須使用InnoDB存儲引擎。 註意:MyISAM存儲引擎 B tree索引有一個很大的限制:參與一個索引的所有欄位的長度之和不能超過1000位元組。另外MyISAM數據和索引是分開,而InnoDB的數據 ...
  • 存儲過程如同一門程式設計語言,同樣包含了數據類型、流程式控制制、輸入和輸出和它自己的函數庫。 一、基本數據類型:略 二、變數: 自定義變數:DECLARE a INT ; SET a=100; 可用以下語句代替:DECLARE a INT DEFAULT 100; 變數分為用戶變數和系統變數,系統變數又 ...
  • 測試是軟體開發中的基礎,它經常被數據開發者忽視,但是它很重要。在本文中會展示如何使用Python的uniittest.mock庫,對一段PySpark代碼進行測試。筆者會從數據科學家的視角來進行工作,這意味著本文將不會深入某些軟體開發的細節。 本文鏈接:https://www.cnblogs.com ...
  • mysql 5.7或以上的新版本sql_mode 預設開啟開 ONLY_FULL_GROUP_BY,如果 select 中出現的欄位,沒有使用聚合函數,或不存在group by中就會提示,this is incompatible with sql_mode=only_full_group_by。 解 ...
  • InnoDB鎖的基本概念 文章總共分為五個部分: "InnoDB的鎖機制淺析(一)—基本概念/相容矩陣" "InnoDB的鎖機制淺析(二)—探索InnoDB中的鎖(Record鎖/Gap鎖/Next key鎖/插入意向鎖)" "InnoDB的鎖機制淺析(三)—幻讀" "InnoDB的鎖機制淺析(四) ...
  • rxretrofitlibrary是一個已經寫好的網路框架庫,先以本地Module導入到自己的項目中。 1、它的初始化操作大多在自定義的application中完成,如: public class App extends Application { @Override public void onC ...
  • 【說明】 1、主界面上添加父容器:FragmentTabHost 2、顯示內容區域 3、導航區域 【註意】 1、指定id時為android:id/tabhost,綁定時使用android.R.id.tabhost. 2、每一個Tab對應的Fragment的會填充到tabcontext上 【效果】 【 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...