Android: NavigationDrawer и ActionBarCompat

Я начал работать с NavigationDrawer с помощью ActionBarSherlock и получил хорошие результаты, но моя компания, одобряющая этот Open Source, вряд ли придет в ближайшее время, поэтому я работаю, чтобы переключиться на ActionBarCompat.

ActionBarCompat был только что официально опубликован вчера (24 июля 2013 г.). Кто-нибудь получил оба, чтобы хорошо работать друг с другом? Я надеюсь, что смогу ответить на свой вопрос, но посмотрю, кто-нибудь получил это, чтобы работать. Гонка продолжается! 🙂

YouTube на выпуске ActionBarCompat: https://www.youtube.com/watch?v=6TGgYqfJnyc


UPDATE (рабочий код, да!): Я получил пример приложения NavigationDrawer из Google, преобразованного для использования ActionBarCompat, и он работает нормально. Вы можете найти его здесь как ссылку или начать свой проект: https://github.com/bcrider/NavigationDrawerActionBarCompat

Версия 2.x выглядит даже лучше, чем с ActionBarSherlock, но мне придется работать с ActionBarCompat намного больше, чтобы увидеть, нравится ли мне это лучше.


Solutions Collecting From Web of "Android: NavigationDrawer и ActionBarCompat"

ПРИМЕЧАНИЕ. Я слишком новичок, чтобы добавить несколько ссылок в сообщение и т. Д., Поэтому я отвечаю на свой вопрос, а не редактирую его (надеюсь, что это не противоречит правилам?). Будет разрешено редактирование оригинала.

Простой способ добавить навигационный ящик с помощью ActionBarCompat: я обнаружил, что преобразование моего существующего приложения было не таким плохим, как я думал, это будет. Образец Google привел меня к мысли, что Фрагменты были необходимостью, но это было не так … далеко от него.

Вы можете просто обернуть ваши существующие макеты с помощью DrawerLayout и подключить ListView (или любой макет, содержащий ListView, если на то пошло) для фактической навигации. Затем добавьте обычный код в существующее действие (расширьте ActionBarActivity) и создайте навигацию, как и следовало бы.

Вот пример кода, с помощью которого можно обернуть существующий макет:

<?xml version="1.0" encoding="utf-8"?> <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" > [YOUR EXISTING LAYOUT GOES HERE] <ListView android:id="@+id/left_drawer" android:layout_width="300dp" android:layout_height="match_parent" android:layout_gravity="start" android:background="#111" android:choiceMode="singleChoice" android:divider="@android:color/transparent" android:dividerHeight="0dp" /> </android.support.v4.widget.DrawerLayout> 

Если вы хотите начать с примера приложения, которое использует фрагменты и оттуда, вот мой репозиторий github на основе кода примера: https://github.com/bcrider/NavigationDrawerActionBarCompat

Вчера я конвертировал свое приложение из ActionBarSherlock в ActionBarCompat. У меня были некоторые проблемы, но ничего серьезного.

У меня есть некоторые комментарии:

Чтобы обновить темы, мне просто нужно было переопределить «Шерлок» на «AppCompat». Например, вместо наследования из @ style / Theme.Sherlock.Light.DarkActionBar, я наследую от @ style / Theme.AppCompat.Light.DarkActionBar.

Для элементов действия просто обновите этот способ:

 <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:yourapp="http://schemas.android.com/apk/res-auto" > <item android:id="@+id/action_search" android:icon="@drawable/ic_action_search" android:title="@string/action_search" yourapp:showAsAction="ifRoom" /> ... </menu> 

И в onCreateOptionsMenu используйте обычный MenuItem, но используйте статические методы MenuItemCompat, чтобы делать вещи ActionBar. Например: MenuItemCompat.expandActionView (searchMenuItem);

Если вы используете RoboGuice, наследующий RoboSherlockActivity, у вас возникнут проблемы, если вы просто скопируете его и перейдете в ActionBarActivity. Вот мое решение:

 public class RoboActionBarActivity extends ActionBarActivity implements RoboContext { protected EventManager eventManager; protected HashMap<Key<?>, Object> scopedObjects = new HashMap<Key<?>, Object>(); @Inject ContentViewListener ignored; // BUG find a better place to put this @Override protected void onCreate(Bundle savedInstanceState) { final RoboInjector injector = RoboGuice.getInjector(this); eventManager = injector.getInstance(EventManager.class); injector.injectMembersWithoutViews(this); super.onCreate(savedInstanceState); eventManager.fire(new OnCreateEvent(savedInstanceState)); } @Override public void setContentView(int layoutResID) { super.setContentView(layoutResID); contentViewChanged(); } @Override public void setContentView(View view) { super.setContentView(view); contentViewChanged(); } @Override public void setContentView(View view, ViewGroup.LayoutParams params) { super.setContentView(view, params); contentViewChanged(); } @Override public void addContentView(View view, ViewGroup.LayoutParams params) { super.addContentView(view, params); contentViewChanged(); } private void contentViewChanged() { RoboGuice.getInjector(this).injectViewMembers(this); eventManager.fire(new OnContentChangedEvent()); } @Override protected void onRestart() { super.onRestart(); eventManager.fire(new OnRestartEvent()); } @Override protected void onStart() { super.onStart(); eventManager.fire(new OnStartEvent()); } @Override protected void onResume() { super.onResume(); eventManager.fire(new OnResumeEvent()); } @Override protected void onPause() { super.onPause(); eventManager.fire(new OnPauseEvent()); } @Override protected void onNewIntent( Intent intent ) { super.onNewIntent(intent); eventManager.fire(new OnNewIntentEvent()); } @Override protected void onStop() { try { eventManager.fire(new OnStopEvent()); } finally { super.onStop(); } } @Override protected void onDestroy() { try { eventManager.fire(new OnDestroyEvent()); } finally { try { RoboGuice.destroyInjector(this); } finally { super.onDestroy(); } } } @Override public void onConfigurationChanged(Configuration newConfig) { final Configuration currentConfig = getResources().getConfiguration(); super.onConfigurationChanged(newConfig); eventManager.fire(new OnConfigurationChangedEvent(currentConfig, newConfig)); } @Override public void onContentChanged() { super.onContentChanged(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); eventManager.fire(new OnActivityResultEvent(requestCode, resultCode, data)); } @Override public Map<Key<?>, Object> getScopedObjectMap() { return scopedObjects; } } 

Теперь вы запускаете ActionMode с помощью supportStartActionMode () и импортируете ActionMode из пакета библиотеки.

Чтобы использовать SearchView, вам нужно сделать что-то вроде этого:

 <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/search" app:actionViewClass="android.support.v7.widget.SearchView" android:icon="@drawable/abc_ic_search" app:showAsAction="always|collapseActionView" android:title="@string/search"/> </menu> @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.search_menu, menu); searchMenuItem = menu.findItem(R.id.search); searchView = (SearchView) MenuItemCompat.getActionView(searchMenuItem); if (searchView != null) { searchView.setIconifiedByDefault(false); SearchView.OnQueryTextListener queryTextListener = new SearchView.OnQueryTextListener() { public boolean onQueryTextChange(String newText) { return true; } public boolean onQueryTextSubmit(String query) { doSomething(query); return true; } }; searchView.setOnQueryTextListener(queryTextListener); } return super.onCreateOptionsMenu(menu); } 

Другие вещи работают без изменений, кроме пакета импорта.

Вы можете увидеть дополнительную информацию здесь: http://developer.android.com/guide/topics/ui/actionbar.html .

Образцы, которые поставляются с 4.3 sdk, выглядят многообещающими, но я собираюсь создать тестовый проект и попытаться преобразовать свое приложение в ActionBarCompact и посмотреть, работает ли он лучше или хуже ActionBarSherlock! Я буду обновлять этот пост, если я выиграю или нет!

Хотя приведенный пример хорош, я сделал еще один пример, который немного ближе к исходному примеру Google Navigation Drawer, так как он включает весь исходный код (теперь он предназначен для поддержки библиотеки) и форматирования. Только некоторые атрибуты должны были быть заменены аналогичными, поскольку они доступны только начиная с версии v11.

Загрузите по адресу: https://github.com/GunnarBs/NavigationDrawerWithActionBarCompat

Примечание. Для этого требуется наличие библиотеки appcompat v7, см. http://developer.android.com/tools/support-library/setup.html.