第一次使用 ActionBarCompat
1.首先要做前面轉換步驟的步驟1,把 appcompat library project 加入你的專案。2.再來是修改你的 application theme,請打開 AndroidManifest.xml 修改如下:
<application
android:theme="@style/Theme.AppCompat.Light.DarkActionBar"
...
>
如果你有用 Action Bar Style 產生器,則可能會是
android:theme="@style/Theme.Myabs"
以上只要做一次,接下來就是製作 App 的內容了,現在你可能不會建立 Activity ,而是 ActionBarActivity (android.support.v7.app.ActionBarActivity),一樣在 onCreate 中指定 layout ,如此就是基本的使用 ActionBar 的 App 了。3.要建立 Action buttons (選單按鈕),必須在專案的 res 目錄中建立 menu 目錄,並在其中建立一個 xml 檔 (menu/main.xml),內容如下:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_refresh"
android:title="更新"
android:icon="@android:drawable/ic_menu_revert"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_search"
android:title="搜尋"
android:icon="@android:drawable/ic_menu_search"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_settings"
android:title="@string/action_settings"
app:showAsAction="never" />
</menu>
app:showAsAction 的選項有
["ifRoom" | "never" | "withText" | "always" | "collapseActionView"]
選項說明:
- ifRoom:如果空間夠用,就顯示。
- never:永遠不顯示,隱藏在 overflow 裡。
- withText:顯示文字,可和 ifRoom 並用。
- always:一定顯示。
- collapseActionView:折疊顯示。
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
其中 inflate 的就是剛才建立的 main.xml。這樣在 ActionBar 的右邊就會出現選單了。大概會像這樣:
要讓選單被選擇時執行某些動作,必須覆寫 onOptionsItemSelected,如下:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case R.id.action_refresh:
Toast.makeText(this, "Refresh", Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
ActionBar 常用操作
接下來要介紹 ActionBar 的一些常用的操作。隱藏 ActionBar
某些特殊情況下,可能必須讓 ActionBar 消失,請呼叫 hide() 方法:ActionBar actionBar = this.getSupportActionBar();
actionBar.hide();
重要!這裡必須注意你的 import 套件是否正確,如果是用 support library 的,必須是 android.support.v7.app.ActionBar,如果不是,則為 android.app.ActionBar,而且是使用 getActionBar(),這在之後很多地方,例如 Fragment 等,都要注意 import 是否正確。
返回箭號
要讓 ActionBar 左邊的 App icon 出現返回的箭號,可以設定actionBar.setDisplayHomeAsUpEnabled(true);
true 表示出現箭號,false 則沒有。沒指定就是不顯示。當出現箭號時,使用者點選 App icon 可以觸發事件,這時候要在 onOptionsItemSelected 方法裡,添加項目 id,如下:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case android.R.id.home:
this.finish();
break;
case R.id.action_refresh:
Toast.makeText(this, "Refresh", Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
注意!是 android.R.id.home。另外有一個設定是
actionBar.setHomeButtonEnabled(false);
這個方法和 setDisplayHomeAsUpEnabled 會互相影響。setHomeButtonEnabled 若為 true 則 App icon 可以被點選,若為 false 則無任何事件觸發。簡單的說,只要顯示返回箭號,就一定可以被點選,反之,則點選無效;但可以透過強制把 setHomeButtonEnabled 設為 true 讓 App icon 即使沒有顯示箭號,仍可以被點選。
圖示
在未指定的情況下,ActionBar 上的圖示是 App 的啟動圖示,如果要換掉,可以指定:actionBar.setIcon(R.drawable.ic_launcher);
標題
當然也可指定 ActionBar 的標題:actionBar.setTitle("ABC");
通常會用在切換不同的 Fragment 或 Activity 時,特別設定和該頁面相關的標題名稱。
切換 Fragment
使用 ActionBar 的用途之一就是將原本由許多 Activity 組成的 App 改成由 Fragment 組成,必須把原本的 Activity 換成 ActionBarActivity。原本的 layout 換成類似這個 fragment_content.xml:<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.DrawerLayout>
就只有一個空的 FrameLayout,之後會用來換成不同的 Fragment。
MainFragment.java
建立主要的 Fragment,叫做 MainFragment,接著覆寫 onCreateView:@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
return initView(inflater, container);
}
private View initView(LayoutInflater inflater, ViewGroup container) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
return view;
}
和原本 Activity 在 onCreate 初始化 view 的地方不同,Fragment 是在 onCreateView 初始化。inflate 的功能等同於 setContentView 。接著建立一個產生實體的方法,方便產生實體:
public static MainFragment create(){
MainFragment mainFragment = new MainFragment();
return mainFragment;
}
MainActivity.java
接下來回到 MainActivity 中,把 MainFragment 加入:private void initView(){
setContentView(R.layout.fragment_content);
initFragment();
}
private void initFragment() {
MainFragment mainFragment = (MainFragment) MainFragment.create();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.content_frame, mainFragment, "main");
fragmentTransaction.commit();
}
以前的做法是 [A] Activity -> [B] Activity -> [C] Activity現在的做法是 [A] Activity == [A] Fragment -> [B] Fragment -> [C] Fragment
Activity 是個容器,用來裝其他的 Fragment 。
Back
要讓 [B] Fragment 的 ActionBar 的 App icon 仍夠執行 back 的動作,必須在 Activity 中設定選單行為:@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case android.R.id.home:
FragmentManager fm = getSupportFragmentManager();
if(fm.getBackStackEntryCount() > 0){
fm.popBackStack();
}
break;
}
return false;
}
只要堆疊數量大於 0 ,就執行 popBackStack() 把目前的 Fragment 給丟掉,自然就會顯示前一個 Fragment 了。續:使用 Android ActionBarCompat 製作導覽列(3)
本文網址:http://blog.tonycube.com/2014/02/android-actionbarcompat-2.html
由 Tony Blog 撰寫,請勿全文複製,轉載時請註明出處及連結,謝謝 😀
由 Tony Blog 撰寫,請勿全文複製,轉載時請註明出處及連結,謝謝 😀
不好意思請問一下...
回覆刪除private void initView(){
setContentView(R.layout.fragment_content);
initFragment();
}
private void initFragment() {
MainFragment mainFragment = (MainFragment) MainFragment.create();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.content_frame, mainFragment, "main");
fragmentTransaction.commit();
}
這兩個方法是要用在哪裡??
今年一月的初學者,剛好遇到ADT改版fragment改版,基礎學習上有很大的困難
大家都說先把FRAGMENT刪掉先用Activity寫,但我爬文找到這篇,排名也很前面
就進來看到前輩你的文章,超讚的!,可是就這邊看不太懂= ="
可否麻煩前輩稍微講解一下!!?
initView()會用來初始化view,先建立layout,再建立fragment。
刪除實際上你把這兩行直接寫在 onCreate 裡面也是可以。
initFragment() 裡面只是建立 Fragment 而已,建立 MainFragment 後,透過管理器(FragmentManager)置換掉 layout 中的 R.id.content_frame,
一個 Activity 中可以有多個 Fragment ,但是一次只會顯示一個。
在 Fragment 式的程式中,可能會不斷的 replace Fragment 來顯示不同個 Fragment。
版主你好
回覆刪除我在跟著你的步驟做的時候發現在
app:showAsAction 出現問題
eclipse會罵我 沒有 showAsAction這個 attribute
然後我將app 改為 android 問題解決了
是否sdk 版本的 問題 還是 版主錯誤得示範?
相容性問題,在API Level 11 之前沒有這個屬性,
刪除所以加了 「xmlns:app="http://schemas.android.com/apk/res-auto"」這行
讓舊版本可以用 app: 開頭來使用這個屬性。
11 之後的版本可以使用內建的 android: 來取用該屬性。
請問版主
回覆刪除MainActivity 中
FragmentManager fragmentManager = getSupportFragmentManager();
eclipse 顯示The method getSupportFragmentManager() is undefined for the type MainActivity
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
顯示 Type mismatch: cannot convert from android.app.FragmentTransaction to android.support.v4.app.FragmentTransaction
請問我是不是忘了 import 什麼或是 extend錯誤?
getSupportFragmentManager() 如果 undefined,表示你不是用 support.v4 的版本,所以不需要 Support
刪除用 getFragmentManager() 就可以了。
第二個錯誤
android.app.FragmentTransaction 無法轉換成 android.support.v4.app.FragmentTransaction
和前一個錯誤是同樣原因,因為你不是用 support.v4 所以當然無法轉換
請確認是否使用相同版本的類別及方法。
版主你好
回覆刪除可以請問一下嗎?怎麼將別的activity放入fragment裡做整合的動作。
EX:將一個MapActivity放入其中一個fragment
還有怎麼在fragment裡增加原本就存在的toolbar的iconButton?
已經卡關很久了,跪求方法~
Activity 是母體,不能放進子體 Fragment 中,有 MapFragment 可用。
刪除「怎麼在fragment裡增加原本就存在的toolbar的iconButton?」
不太明白你的意思,如果你是指toolbar 左邊的 Home icon,
可以用getsupportactionbar()去指定 setDisplayShowHomeEnabled(true)來顯示。
(https://developer.android.com/intl/zh-tw/reference/android/support/v7/app/ActionBar.html#setDisplayShowHomeEnabled%28boolean%29)
版主你好 我是APP初學者 但一學就有難題了
回覆刪除所以想請教你 要用什麼工具可以開發 多個使用者一起計劃的功能? 功能類似google doc
Android studio可以嗎?如果可以 要怎麼做?
謝謝