網頁

2014年7月13日 星期日

5.ActionBar

Android的ActionBar是一個很難搞的東西,除了版本的問題之外還有實體按鈕的MENU問題,導致我在摸索的時候花了很長的時間才了解問題的所在。



上面第一張圖的3,在ActionBar中稱為Overflow,請參考第二張圖,這個Overflow也是問題的所在,因為在我寫好的Android程式執行之後完全找不到Overflow,問題的原因經過不斷的在網路上爬文找的答案是,如果你的機器上有MENU的按鈕則不會顯示Overflow,如果沒有才會顯示,因此Overflow只是給沒有MENU的機器所使用的

在預設的Android中按MENU只會跳出Settings的MENU選項而已,這邊舉個例子增加MENU的選項,在res/menu目錄中找到你主要Activity的xml檔,以我的檔案為例,我的xml檔案名稱叫做main.xm,參考下面的範例:

main.xml
<menu 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" tools:context="com.example.golden.lab.MainActivity" > <item android:id="@+id/action_help" android:title="@string/action_help" android:icon="@drawable/ic_action_help" android:showAsAction="ifRoom" /> <item android:id="@+id/action_settings" android:orderInCategory="100" android:title="@string/action_settings" android:showAsAction="always" /> </menu>
上面的範例main.xml新增了一個help的MENU,android:id是物件的名稱,為了撰寫程式所使用,在後面會提到。android:title是指在MENU中顯示的文字,因為有@string因此會參考到res/values/strings.xml,必須在裡面新增help文字。android:icon是提供MENU圖案的功能,不過我目前還是沒有成功就是了,Android有提供Action Bar Icon Pack提供使用者下載或是使用者也可以加入自己想要的icon圖案,只要將icon圖案加入到res/drawable每個解析度底下就可以使用了。最後android:showAsAction的功能有一些參數我列在下面:

  • ifRoom - 如果有ActionBar有空間的話會就會顯示item出來
  • withText - 顯示item的文字,可以搭配|來使用,例如ifRoom|withText
  • never - 不會顯示在ActionBar上面
  • always - 總是顯示在ActionBar上面,但官方的文件說不建議這樣做
現在已經在MENU中新增了help選項了,但是需要在Activity主程式中加入,但是因為我使用的Eclipse已經幫我做到這一點了,我就不需要再做這個動作了。

MainActivity.java
public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; }
不過網路上有不少人這樣寫:
public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main, menu); return true; }
這兩者的寫法都可以產生MENU,要撰寫目錄的事件方法必須在onCreateOptionsMenu裡撰寫,MenuInflater是用來定義MENU用的,MenuInflater.inflate用來指定是哪個MENU。

最後我們將menu中的action_setting的android:showAsAction屬性改成never,再將action_help的android:showAsAction屬性改always使得action_help的icon能夠出現。

<menu 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" tools:context="com.example.golden.lab.MainActivity" > <item android:id="@+id/action_help" android:title="@string/action_help" android:icon="@drawable/ic_action_help" android:showAsAction="always" /> <item android:id="@+id/action_settings" android:orderInCategory="100" android:title="@string/action_settings" android:showAsAction="never" /> </menu>




新增Item事件


目前已經完成新增MENU的項目了,但是點下所新增的help項目沒有任何的反應,因此接下來的動作必須新增help的事件動作。要新增item的事件動作必須在onOptionsItemSelected裡進行撰寫,設定按下help跳到另一個Activity。

MainActivity.java public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch(item.getItemId()) { case R.id.action_help: Help(); return true; case R.id.action_settings: return true; default: return super.onOptionsItemSelected(item); } } private void Help() { Intent intent = new Intent(this,Help.class); startActivity(intent); } }
在上面的onOptionsItemSelected函數中可以看到使用switch來判斷是按下哪一個item,如果是按下help則會呼叫Help()方法,Help()方法中使用Intent切換到另一個Activity,因此還必須新增一個help.java的Activity。

MainActivity.java畫面
按下help到help.java的畫面






返回Activity畫面


雖然上圖help的Activity有一個左邊的箭頭可以返回到main的Activity,但是實際上在我的手機上面沒有,因此接下來的動作要在help的Activity加上返回的動作。 public class Help extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_help); ActionBar actionBar = getActionBar(); actionBar.setDisplayHomeAsUpEnabled(true); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.help, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch(item.getItemId()) { case R.id.action_settings: return true; case android.R.id.home: NavUtils.navigateUpFromSameTask(this); return true; default: return super.onOptionsItemSelected(item); } } }
使用actionBar.setDisplayHomeAsUpEnabled就可以讓ActionBar顯示返回的箭頭,但是不會返回到main的Activity,因此還必須在onOptionsItemSelected函數中加入android.R.id.home進行判斷,且利用NavUtils.navigateUpFromSameTask返回到主頁。




更換ActionBar icon和隱藏ActionBar


要更換ActionBar的icon很簡單,只需要一段文字actionBar.setIcon,指定好icon圖案就可以,接下來修改help的Activity來更換icon圖案,下面是範例。
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_help); ActionBar actionBar = getActionBar(); actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setIcon(R.drawable.help); }
從上面的圖可以看到icon已經被我換成自己所設定的了,除了主程式裡面可以更換icon還可以利用AndroidManifest.xml來進行設定,AndroidManifest.xml當中的<activity></activity>可以設定icon和ActionBar的標題,每一個<activity></activity>代表的是不同的Activity,因此可以根據不同的Activity畫面設定不同的icon,下面是範例:
<activity android:name=".MainActivity" android:label="Android" android:logo="@drawable/help" > </activity> android:label是設定ActionBar的標題,android:logo是設定ActionBar的icon ,如果要統一設定每個Activity的ActionBar的標題和icon在AndroidManifest.xml<application></application>進行設定,請參考下面的範例:
<application android:allowBackup="true" android:icon="@drawable/help" android:label="@string/app_name" android:theme="@style/AppTheme" > </application> 設定每個Activity的icon和標題分別是android:iconandroid:label,很簡單吧!!
 
ActionBar還有提供一個功能就是隱藏ActionBar,也是一樣只要一段文字就可以達成,actionBar.hide指的是將ActionBar隱藏起來,下面的範例一樣是針對help的Activity進行修改。 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_help); ActionBar actionBar = getActionBar(); actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setIcon(R.drawable.help); actionBar.hide(); }
可以看到ActionBar完全消失了,如果要顯示ActionBar只要使用actionBar.show就可以了

待續...

沒有留言:

張貼留言