最近發現 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
沒有留言:
張貼留言