什麼是 Action View 和 Action Provider?

Action View
是一種Action,在App Bar中提供豐富的功能。如Search Action View可以讓使用者在App Bar中輸入搜尋文字而不必轉換Activity或Fragment。
 
Action Provider
是一種Action,並有客製化介面。一開始顯示為按鈕或menu item。當使用者點擊時,可以用任何方式控制 Action 的行為。
Android support library提供專門的Action View和Action Provider。 例如SearchView用於輸入搜索查詢,ShareActionProvider用於與其他應用程序共享的操作。也可以定義自己的Action View和 Action Provider。
 

加入 Action View

在 app/src /main/res目錄建立 menu 資源文件,並在其中新增<item>元素。<item>元素中加入以下屬性
actionViewClass:實作該action的類別。
actionLayout:佈局資源檔用來描述該action的外觀。
設定showAsAction屬性為“ifRoom | collapseActionView”或“never | collapseActionView”。
collapseActionView用來描述當使用者未互動時如何顯示。如果Action位於App Bar上顯示為icon。如果Action位於overflow menu,則顯示為menu item。當使用者和Action交互時,會填滿App Bar。如下在App Bar中加入 Search View
/app/src/main/res/menu/action_view_actions.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/action_search"
    android:title="search action"
    android:icon="@android:drawable/ic_menu_search"
    app:showAsAction="ifRoom|collapseActionView"
    app:actionViewClass="androidx.appcompat.widget.SearchView" />
</menu>

若使用者未和Action互動時,會顯示為android:icon。若App Bar空間不足則顯示在overflow menu。
如果需要調整Action,可以在Activity的onCreateOptionsMenu方法實作。 可以通過呼叫getActionView方法獲取Action View的參考。 例如,以下為取得SearchView的參考

public class ActionViewActivity extends AppCompatActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_action_view);
    Toolbar toolBar = findViewById(R.id.app_toolbar);
    setSupportActionBar(toolBar);
  }
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.action_view_actions, menu);
    MenuItem searchItem = menu.findItem(R.id.action_search);
    SearchView searchView = (SearchView) searchItem.getActionView();
    // Configure the search info and add any event listeners...
    return super.onCreateOptionsMenu(menu);
  }
}

 
啟動App 可以看到App Bar已經加入Search View。
點擊放大鏡icon會出現搜尋框讓使用者輸入內容。

關於如何更進一步的使用SearchView參考這裡https://developer.android.com/guide/topics/search/index.html
完整程式碼如下
/app/src/main/res/layout/activity_action_view.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
  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=".action_view_and_action_provider.ActionViewActivity">
  <include
    android:id="@+id/app_toolbar"
    layout = "@layout/toolbar_main"
    />
</androidx.constraintlayout.widget.ConstraintLayout>

/app/src/main/res/manu/toolbar_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.Toolbar
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="?attr/actionBarSize"
  android:background="?attr/colorPrimary"
  android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
</androidx.appcompat.widget.Toolbar>

 

加入 Action Provider

在app/src /main/res目錄建立menu 資源文件,並在其中新增<item>元素。<item>元素中加入actionProviderClass屬性並對該屬性設定action provider完整路徑。如
androidx.appcompat.widget.ShareActionProvider
以下新增SharedActionProvider
app/src/main/res/menu/action_provider_actions.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/action_shared"
    android:title="shared action"
    android:icon="@android:drawable/ic_menu_share"
    app:showAsAction="ifRoom"
    app:actionProviderClass="androidx.appcompat.widget.ShareActionProvider" />
</menu>

因為SharedActionProvider具有自己的icon,因此不必提供android:icon屬性。
 

實作 Action Provider 行為

透過在onCreateOptionsMenu方法內初始化ShareActionProvider,並設定其行為。

public class ActionProviderActivity extends AppCompatActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_action_provider);
    Toolbar toolBar = findViewById(R.id.app_toolbar);
    setSupportActionBar(toolBar);
  }
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.action_provider_actions, menu);
    initShareActionProvider(menu);
    return super.onCreateOptionsMenu(menu);
  }
  private void initShareActionProvider(Menu menu) {
    MenuItem shareActionMenuItem = menu.findItem(R.id.action_shared);
    ShareActionProvider shareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(shareActionMenuItem);
    Intent sendAction = new Intent(Intent.ACTION_SEND);
    sendAction.setType("text/plain");
    sendAction.putExtra(Intent.EXTRA_TEXT, "share action text");
    shareActionProvider.setShareIntent(sendAction);
  }
}

啟動App可以看到一個分享的icon顯示在App Bar上。

點擊分享icon,會顯示要分享的方式。

完整程式碼如下
/app/src/main/res/layout/activity_action_provider.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
  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=".action_view_and_action_provider.ActionProviderActivity">
  <include
    android:id="@+id/app_toolbar"
    layout="@layout/toolbar_main"
    />
</androidx.constraintlayout.widget.ConstraintLayout>

/app/src/main/res/menu/toolbar_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.Toolbar
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="?attr/actionBarSize"
  android:background="?attr/colorPrimary"
  android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
</androidx.appcompat.widget.Toolbar>

以上為Action View和Action Provider的範例。
 
以下為App Bar的相關內容
http://34.80.81.192/?p=6149
http://34.80.81.192/?p=6176
http://34.80.81.192/?p=6165