【问题标题】:What are the common issues when migrating from ActionBarSherlock to ActionBarCompat?从 ActionBarSherlock 迁移到 ActionBarCompat 时的常见问题是什么?
【发布时间】:2014-01-05 13:12:03
【问题描述】:

我想从我的应用程序中删除 ActionBarSherlock 并将其替换为标准 ActionBarCompat。

  • 如何实现 ActionBarCompat?
  • 如何迁移 Activity?
  • 哪些导入替换了 ActionBarSherlock 导入?
  • 什么是典型问题?

【问题讨论】:

    标签: android android-actionbar actionbarsherlock android-actionbar-compat


    【解决方案1】:

    我做了一些迁移并写下了我遇到的所有问题。没有一个是认真的,但需要时间来研究。在了解了这一切之后,我能够在几个小时内迁移一个相当大的应用程序。这可能有助于加快迁移过程。

    如何从 ActionBarSherlock 转换为 ActionBarCompat?

    注意:从支持库的 v22.1.0 开始,ActionBarActivity 类已被弃用。您应该改用 AppCompatActivity。阅读此处了解更多信息:What's the enhancement of AppCompatActivity over ActionBarActivity?

    == 切换库 ==

    转到应用属性并删除 ActionBarSherlock 并添加 ActionBarCompat。这需要存在 v7 appcompat 库,有关详细信息,请参阅http://developer.android.com/tools/support-library/setup.html。严格按照说明操作,ActionBarCompat 必须是库项目。

    并行不起作用(很容易),因为两个库中都有很多属性。

    更换库后,不要因数百个错误而气馁。绝大多数会自动消失。

    == 修复 XML 错误 ==

    首先要修复所有 XML 错误,以便编译和查找其他错误。

    用 ActionBarCompat 主题替换 sherlock 主题,例如
    <style name="AppBaseTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">

    删除双重属性,例如<attr name="buttonBarStyle" format="reference" />.

    现在删除所有单独的操作栏样式。进一步了解如何处理这些问题。

    == 修复构建错误 ==

    首先选择最简单的活动。 ActionBarCompat 不区分Activity和FragmentActivity,现在都是ActionBarActivity。

    删除 ActionBarSherlock 导入并扩展到 ActionBarActivity (import android.support.v7.app.ActionBarActivity;)

    保存后,这应该会大大减少活动中的错误。

    首先修复菜单周围的错误,暂时忽略片段错误,它们应该稍后会消失。

    == 替换 ==

    进口:

    • 导入com.actionbarsherlock.app.SherlockActivity; -> 导入 android.support.v7.app.ActionBarActivity;
    • 导入com.actionbarsherlock.app.SherlockFragmentActivity; -> 导入 android.support.v7.app.ActionBarActivity;
    • 导入com.actionbarsherlock.app.SherlockFragment; -> 导入 android.support.v4.app.Fragment;
    • 导入com.actionbarsherlock.app.SherlockListFragment; -> 导入 android.support.v4.app.ListFragment;
    • 导入com.actionbarsherlock.app.SherlockListActivity; -> 导入 android.support.v7.app.ActionBarActivity; (参见 ListActivity / SherlockListActivity)
    • 导入com.actionbarsherlock.view.Menu; -> 导入 android.view.Menu;
    • 导入com.actionbarsherlock.view.MenuItem; -> 导入 android.view.MenuItem;
    • 进口com.actionbarsherlock.view.MenuInflater; -> 导入 android.view.MenuInflater;
    • 导入com.actionbarsherlock.view.Window; -> 导入 android.view.Window;
    • 导入com.actionbarsherlock.widget.SearchView; -> 导入 android.support.v7.widget.SearchView;
    • 导入 com.actionbarsherlock.widget.SearchView.OnQueryTextListener -> 导入 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 中得到更好的控制。

    == 搜索视图 ==

    结果证明这有点麻烦。

    替换如下:

    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:需要定义为兼容11之前的android版本。
    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;
       }
    }
    

    == 样式 ==

    可以实现样式化的操作栏,请参阅原始谷歌帖子: 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));
    

    查看这些帖子:

    == 示例 ==

    带有操作栏 Sherlock 的 Google Navigation Drawer 包含所有原始代码(现在旨在支持库)和格式。只有一些属性必须替换为类似的属性,因为它们仅从 v11 开始可用。

    下载地址:https://github.com/GunnarBs/NavigationDrawerWithActionBarCompat

    == 另见 ==

    【讨论】:

    • 在 actionBarCompat 上是否也可以使用 searchview 的所有功能?例如折叠/展开、收听文本变化、...
    • 还没有尝试过,但看起来非常全面,似乎可以为我节省不少时间。为好答案点赞
    • 最近刚完成迁移,你的回答 def 有帮助。添加到列表中:我必须在我的 attrs.xml 文件中将我的 &lt;declare-styleable name="Theme" 名称更改为 name="AppTheme",因为 ActionBarCompat 使用该命名空间。命名可样式化的"name=Theme" 导致了一系列关于找不到资源等的冲突错误。还必须在我的 ActionBarActivity 类中将onContentChanged 的用法更改为onSupportContentChanged,因为onContentChanged 在库中是最终的。
    • 另一个可能需要处理的问题https://stackoverflow.com/questions/21158710/actionbar-compat-do-not-show-dropdown-menu。子菜单在旧设备中不使用下拉样式视图。
    • 感谢您的详细回答,无疑为我节省了数小时甚至数天。我能够在一小时内迁移到 ABC,除非有一些小问题。如果我遇到 Gunnar Bernstein,我会请他/她喝啤酒。
    【解决方案2】:

    值得一提的是PreferenceActivity没有支持版本,所以如果你使用SherlockPreferenceActivity,需要重构一个支持PreferenceFragment。

    更多信息:How to add Action Bar from support library into PreferenceActivity?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-15
      • 1970-01-01
      • 2018-02-02
      • 1970-01-01
      • 1970-01-01
      • 2018-02-13
      相关资源
      最近更新 更多