Я создаю приложение, которое имеет 4 основных раздела. Я хотел бы иметь очень простой способ сделать навигацию, которая будет означать, если телефон поддерживает панель действий, тогда я бы хотел, чтобы она отображала панель действий с вкладками. В противном случае обычная кнопка меню, показывающая меню, прекрасна.
Проблема состоит в том, что панель действий не может управляться или не создаваться при ее использовании на телефонах с версией sdk, которая фактически поддерживает панели действий.
Я использую файл menu/menu.xml для создания меню и элементов, которые я хочу отобразить. Затем я использую onCreateOptionsMenu() с MenuInflater для заполнения меню для каждого действия. Это прекрасно работает на всех телефонах, но на телефонах, которые используют панель действий, я получаю панель заголовка с иконкой приложения слева от нее, текущее название Activity рядом с ним, а затем справа находится значок для первый элемент меню, за которым следуют 3 квадрата (которые, когда вы нажимаете на них, показывают остальные пункты меню). Эта ситуация остается неизменной независимо от активности, в которой я участвую.
Я хочу, чтобы панель вкладок отображалась вместо значка и текста (если есть место для текста) и имеет любую текущую активность, которую пользователь просматривает, "выбран" в панели вкладок. Точно так же показано здесь:
http://developer.android.com/images/ui/actionbar.png (я не могу сделать это образ из-за того, что был новым пользователем)
Вот код, который я использую:
manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mypackage"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission
android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission
android:name="android.permission.READ_PHONE_STATE" />
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="15" />
<application
android:icon="@drawable/icon"
android:label="@string/app_name"
android:theme="@android:style/Theme.Holo">
<uses-library android:name="com.google.android.maps" />
<activity
android:name=".ActivityLoad"
android:label="label">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
....more activities....
</application>
</manifest>
menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/menuMap"
android:title="@string/A_MAP_TITLE"
android:icon="@drawable/nav_map"
android:showAsAction="ifRoom|withText">
</item>
<item
android:id="@+id/menuList"
android:title="@string/A_LIST_TITLE"
android:icon="@drawable/nav_list"
android:showAsAction="ifRoom|withText">
</item>
<item
android:id="@+id/menuMore"
android:title="@string/A_MORE_TITLE"
android:icon="@drawable/nav_more"
android:showAsAction="ifRoom|withText">
</item>
<item
android:id="@+id/menuReport"
android:title="@string/A_REPORT_TITLE"
android:icon="@drawable/nav_report"
android:showAsAction="ifRoom|withText">
</item>
</menu>
MyActivity.java
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options, menu);
return super.onCreateOptionsMenu(menu);
}
Я попытался настроить режим навигации на панели действий, используя этот код в своих методах onCreate(), но все, что происходит, - это пустая панель действий, отображаемая ниже "плохой" панели действий, которую я получаю по умолчанию:
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
Все учебники шва, чтобы просто сказать "использовать стиль" или что-то, но я не знаю, куда положить файл стиля xml или как установить это в мое меню или что я должен делать здесь. Если бы кто-нибудь мог помочь, это было бы очень признательно!
Сначала убедитесь, что MyActivity.java реализует ActionBar.TabListener, что означает, что вам нужно будет переопределить 3 функции. Я не знаю, как вы сделали ваши фрагменты, но так я сделал это в MyActivity.java:
public class MyActivity extends FragmentActivity implements ActionBar.TabListener {
private static final String STATE_SELECTED_NAVIGATION_ITEM = "selected_navigation_item";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set up the action bar.
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// For each of the section, add a tab to the action bar.
actionBar.addTab(actionBar.newTab().setText(R.string.title_status).setTabListener(this));
actionBar.addTab(actionBar.newTab().setText(R.string.title_configuration).setTabListener(this));
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
if (savedInstanceState.containsKey(STATE_SELECTED_NAVIGATION_ITEM)) {
getActionBar().setSelectedNavigationItem(
savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM));
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putInt(STATE_SELECTED_NAVIGATION_ITEM,
getActionBar().getSelectedNavigationIndex());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
//getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
@Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
// When the given tab is selected, show the tab contents in the container
Fragment fragment = new DummySectionFragment();
Bundle args = new Bundle();
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, tab.getPosition() + 1);
fragment.setArguments(args);
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, fragment)
.commit();
}
@Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
/**
* A dummy fragment representing a section of the app, but that simply displays dummy text.
*/
public static class DummySectionFragment extends Fragment {
public DummySectionFragment() {
}
public static final String ARG_SECTION_NUMBER = "section_number";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
TextView textView = new TextView(getActivity());
textView.setGravity(Gravity.CENTER);
Bundle args = getArguments();
textView.setText(Integer.toString(args.getInt(ARG_SECTION_NUMBER)));
return textView;
}
}
}
Чтобы настроить панель действий, вам нужно использовать пользовательский стиль, в котором Theme.Holo будет являться родителем. Таким образом, он наследует все от темы Holo, но затем вы можете переписать то, что хотите. Внутри manifest.xml используется:
<application
android:theme="@style/AppTheme">
вместо:
<application
android:theme="@android:style/Theme.Holo">
Затем внутри values /styles.xml добавьте свой собственный стиль:
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="AppTheme" parent="android:Theme.Holo.Light">
<item name="android:actionBarStyle">@style/MyActionBar</item>
<item name="android:actionBarTabStyle">@style/MyActionBarTabStyle</item>
<item name="android:actionBarTabBarStyle">@style/MyActionBarTabBar</item>
</style>
Здесь он становится немного сложнее. в том же файле (values /styles.xml) вам необходимо определить каждый стиль, на который вы ссылались выше.
<style name="MyActionBar" parent="@android:style/Widget.Holo.Light.ActionBar">
<item name="android:background">@drawable/menu_bar</item> <!-- remove if you don't have custom background for action bar -->
<item name="android:displayOptions"></item> <!-- get rid of logo on left and title, if you want logo on left put useLogo here -->
<item name="android:customNavigationLayout">@layout/custom_action_bar</item> <!-- This is where you define how you want things to layout in your actionbar. I use a relative layout -->
</style>
<!-- Style for tab bar -->
<style name="MyActionBarTabBar" parent="@android:style/Widget.Holo.Light.ActionBar.TabBar">
<item name="android:showDividers">none</item>
<item name="android:paddingLeft">20dp</item>
</style>
<!-- Style for action bar tabs -->
<style name="MyActionBarTabStyle" parent="@android:style/Widget.Holo.Light.ActionBar.TabView">
<item name="android:background">@drawable/menu_tab</item> <!-- I use a background for my tabs also -->
</style>
Если вам неважно, что пользовательский фон для каждой вкладки удаляет последний стиль сверху. Если у вас есть настраиваемый фон для каждой вкладки (вам понадобится выбранное состояние.9.png и не выбранное изображение.9.png), вам понадобится drawable/menu_tab.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:constantSize="false"
android:dither="true"
android:variablePadding="false" >
<item android:state_selected="true" >
<inset android:insetTop="23dp"
android:insetBottom="26dp" >
<bitmap android:src="@drawable/menu_selected" ></bitmap>
</inset>
</item>
<item android:state_selected="false" >
<inset android:insetTop="20dp"
android:insetBottom="26dp" >
<bitmap android:src="@drawable/menu_not_selected" ></bitmap>
</inset>
</item>
</selector>
Теперь создайте layout/custom_action_bar.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:contentDescription="@string/LogoText"
android:paddingRight="20dp"
android:paddingTop="20dp"
android:src="@drawable/ic_launcher" />
</RelativeLayout>
Custom_action_bar может быть, однако, вы хотите разместить остальные элементы панели действий. Я просто помещаю логотип справа, но в вашем случае вы можете использовать кнопку меню переполнения или что угодно. Я использую настраиваемый фон для панели действий и для каждой вкладки. Если вы это сделаете, вам нужно будет создать файлы.9.png, чтобы убедиться, что они совместимы с разными экранами.
Конечный результат выглядит следующим образом: