最近發現 google 也推出 actionbar compat 的版本, 所以就改使用 google.
以下是使用範例 :
要使用 actionbar, 首先在 menu layout 就必須做一些修正.
以下是使用的 layout, 可以看到在 showAsAction 的部份的不同. myapp 可以自訂成自己所要使用的字串
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:myapp="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/action_settings" android:title="@string/action_settings" android:orderInCategory="100" android:icon="@android:drawable/ic_menu_preferences" myapp:showAsAction="ifRoom" /> </menu>
以下是測試的 layout.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" android:orientation="vertical"> <ListView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout>
而要使用 AppCompat 的話, activity 必須繼承 ActionBarActivty
package tw.clotai.appcompatexample; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v7.app.ActionBarActivity; import android.view.Menu; import android.widget.ArrayAdapter; import android.widget.ListView; public class MainActivity extends ActionBarActivity { final String[] data = {"1", "2", "3", "4", "5", "6"}; ListView mList = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ArrayAdapter<String> adapter = new ArrayAdapter<String>( this, android.R.layout.simple_list_item_1, data); mList = (ListView)findViewById(R.id.list); mList.setAdapter(adapter); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
特別注意的是在 AndroidManifest.xml 裡面的 theme 必須使用以下幾種, 否則就會有問題.
Theme.AppCompat
Theme.AppCompat.Light
Theme.AppCompat.Light.DarkActionBar
而在我的應用中, 我通常會使用 fragment, 但是改用成 fragment 後就發現有些問題了.
以下是原本 fragment 的使用. MainActivity 改成以下
package tw.clotai.appcompatexample; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v7.app.ActionBarActivity; import android.view.Menu; public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Fragment frag = getSupportFragmentManager().findFragmentById(android.R.id.content); if (frag == null) { MainFrag m = new MainFrag(); getSupportFragmentManager().beginTransaction().add(android.R.id.content, m).commit(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
MainFrag 如下
package tw.clotai.appcompatexample;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class MainFrag extends Fragment {
final String[] data = {"1", "2", "3", "4", "5", "6"};
ListView mList = null;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_main, container, false);
mList = (ListView)v.findViewById(R.id.list);
return super.onCreateView(inflater, container, savedInstanceState);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
getActivity(), android.R.layout.simple_list_item_1, data);
mList.setAdapter(adapter);
}
}
執行結果會發現如果是 android 3.0 以上就沒問題, 但以下則會什麼也沒有.
原因出在 AppCompat 會依據 android 版本來選擇使用不同的 content id.
如果是 android 3.0 以上, 就會使用 android.R.id.content, 所以當我測試時就沒問題
但是如果是以下, 則會使用 android.support.v7.appcompat.R.id.action_bar_activity_content
這也是為什麼會有問題的原因.
另外也要注意的是, setTitle 部份, 如果使用 AppCompat, 3.0 以下則必須也要使用 getSupportActionBar().setTitle()
來設定, 否則標題列就不會顯示你所設定的 Title 喔.
為了方便使用, 以下是我自己使用的 ActionBarActivty
package tw.clotai.appcompatexample;
import android.os.Build;
import android.support.v7.app.ActionBarActivity;
public class MyActionBarActivity extends ActionBarActivity {
@Override
public void setTitle(CharSequence title) {
getSupportActionBar().setTitle(title);
super.setTitle(title);
}
@Override
public void setTitle(int titleId) {
getSupportActionBar().setTitle(titleId);
super.setTitle(titleId);
}
protected final int getContentViewCompat() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
return android.R.id.content;
} else {
return android.support.v7.appcompat.R.id.action_bar_activity_content;
}
}
}
之後我要使用則繼承我自己所寫的這個 activity.
原始碼: AppCompatExampleProject.zip
沒有留言:
張貼留言