Подтвердить что ты не робот

Каковы общие проблемы при переходе с ActionBarSherlock на ActionBarCompat?

Я хочу удалить ActionBarSherlock из своего приложения и заменить его на стандартный ActionBarCompat.

  • Как реализовать ActionBarCompat?
  • Как перенести Activites?
  • Какой импорт заменяет импорт ActionBarSherlock?
  • Каковы типичные проблемы?
4b9b3361

Ответ 1

Я немного переместился и записал все проблемы, с которыми я столкнулся. Ни один из них не был серьезным, но уделил время исследованиям. Через пару часов я смог перенести довольно большое приложение, зная все это. Пусть это поможет ускорить процесс миграции.

Как мне преобразовать из ActionBarSherlock в ActionBarCompat?

Примечание. Поскольку Библиотека поддержки v22.1.0, класс ActionBarActivity устарел. Вместо этого вы должны использовать AppCompatActivity. Читайте здесь для получения дополнительной информации: Какое расширение AppCompatActivity над ActionBarActivity?

== Переключить библиотеки ==

Перейдите в свойства приложения и удалите ActionBarSherlock и вместо этого добавьте ActionBarCompat. Для этого требуется наличие библиотеки appcompat v7, см. http://developer.android.com/tools/support-library/setup.html. В точности следуйте инструкциям, ActionBarCompat должен быть проектом библиотеки.

Параллель не работает (легко), так как в обеих библиотеках много атрибутов.

Не следует обескураживать сотни ошибок после замены библиотек. Подавляющее большинство уходит автоматически.

== Исправить ошибки XML ==

Прежде всего, нужно исправить все ошибки XML, чтобы компилировать и находить другие ошибки.

Заменить тему sherlock с помощью темы ActionBarCompat, например.
<style name="AppBaseTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">

Удалите двойной attr, например. <attr name="buttonBarStyle" format="reference" />.

Теперь удалите все стили отдельных стилей. Смотрите далее, как с ними справиться.

== Исправить ошибки сборки ==

Сначала выберите самые простые действия. ActionBarCompat не различает Activity и FragmentActivity, оба теперь ActionBarActivity.

Удалите импорт ActionBarSherlock и расширьте его до ActionBarActivity (import android.support.v7.app.ActionBarActivity;)

После сохранения это должно значительно уменьшить ошибки в активности.

Сначала устранить ошибки вокруг меню и игнорировать ошибки фрагментов, они должны уходить позже.

== Замены ==

Импорт

  • import com.actionbarsherlock.app.SherlockActivity; → import android.support.v7.app.ActionBarActivity;
  • import com.actionbarsherlock.app.SherlockFragmentActivity; → import android.support.v7.app.ActionBarActivity;
  • import com.actionbarsherlock.app.SherlockFragment; → import android.support.v4.app.Fragment;
  • import com.actionbarsherlock.app.SherlockListFragment; → import android.support.v4.app.ListFragment;
  • import com.actionbarsherlock.app.SherlockListActivity; → import android.support.v7.app.ActionBarActivity; (см. ListActivity/SherlockListActivity).
  • import com.actionbarsherlock.view.Menu; → import android.view.Menu;
  • import com.actionbarsherlock.view.MenuItem; → import android.view.MenuItem;
  • import com.actionbarsherlock.view.MenuInflater; → import android.view.MenuInflater;
  • import com.actionbarsherlock.view.Window; → import android.view.Window;
  • import com.actionbarsherlock.widget.SearchView; → import android.support.v7.widget.SearchView;
  • import com.actionbarsherlock.widget.SearchView.OnQueryTextListener → import android.support.v7.widget.SearchView.OnQueryTextListener;

Замены кода:

  • SherlockActivity → ActionBarActivity
  • SherlockFragmentActivity → ActionBarActivity
  • SherlockListActivity → ListActivity (см. ListActivity/SherlockListActivity)
  • SherlockListFragment → ListFragment;

  • getSupportMenuInflater → getMenuInflater

  • getSherlockActivity() → getActivity()
  • com.actionbarsherlock.widget.SearchView.OnQueryTextListener() → OnQueryTextListener (см. SearchView)

  • m.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); → MenuItemCompat.setShowAsAction(m, MenuItem.SHOW_AS_ACTION_ALWAYS);

Типичные изменения кода для ActionBarCompat

  • getActionBar() → getSupportActionBar()
  • invalidateOptionsMenu() → supportInvalidateOptionsMenu()

== Фрагмент ==

Фрагмент не поддерживает функциональность ActionBarCompat. Это проблема при попытке вызвать getSupportActionBar.

Это можно решить, используя метод onAttach:

@Override
public void onAttach(Activity activity) {
  super.onAttach(activity);
  ((ActionBarActivity)activity).getSupportActionBar().setDisplayHomeAsUpEnabled(false);
}

Обычно это лучше контролируется в FragmentActivity.

== SearchView ==

Это оказалось немного хлопот.

Замените примерно так:

MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();

с

MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);

Вам также нужно настроить свое меню:

<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
    android:id="@+id/action_search"
    android:actionViewClass="com.actionbarsherlock.widget.SearchView"
    android:icon="@android:drawable/ic_menu_search"
    android:orderInCategory="80"
    android:showAsAction="always|collapseActionView"
    android:title="@string/action_search"/>
</menu>

с

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" >
<item
    android:id="@+id/action_search"
    android:icon="@android:drawable/ic_menu_search"
    android:orderInCategory="80"
    android:title="@string/action_search"
    app:actionViewClass="android.support.v7.widget.SearchView"
    app:showAsAction="always|collapseActionView"/>
</menu>

app: необходимо определить совместимость с версиями Android до 11.
SearchView должен быть классом поддержки v7.

== ListActivity/SherlockListActivity ==

ListActivity не поддерживается ActionBarCompat, поэтому важнейшие функции ListActivity необходимо выполнить вручную, что довольно просто:

private ListView mListView;

protected ListView getListView() {
   if (mListView == null) {
    mListView = (ListView) findViewById(android.R.id.list);
   }
   return mListView;
}

protected void setListAdapter(ListAdapter adapter) {
  getListView().setAdapter(adapter);
}

protected ListAdapter getListAdapter() {
   ListAdapter adapter = getListView().getAdapter();
   if (adapter instanceof HeaderViewListAdapter) {
      return ((HeaderViewListAdapter)adapter).getWrappedAdapter();
   } else {
      return adapter;
   }
}

== Стили ==

Можно создать панель действий в стиле, см. оригинальную публикацию google: http://android-developers.blogspot.de/2013/08/actionbarcompat-and-io-2013-app-source.html

В окне стиля SearchView сложнее:
Это работает:

MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
SearchView.SearchAutoComplete theTextArea = (SearchView.SearchAutoComplete) searchView.findViewById(R.id.search_src_text);
theTextArea.setTextColor(getResources().getColor(R.color.yourColor));

Смотрите эти сообщения:

== Пример ==

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

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

== См. также ==