【问题标题】:Android: NavigationDrawer and ActionBarCompatAndroid:导航抽屉和操作栏兼容
【发布时间】:2013-07-25 19:30:40
【问题描述】:

我开始使用 ActionBarSherlockNavigationDrawer 合作,并取得了不错的效果,但我的公司不太可能很快批准这个开源,所以我正在努力切换到 ActionBarCompat。

ActionBarCompat 昨天(2013 年 7 月 24 日)刚刚正式发布。有没有人让两者都能很好地合作?我希望我能回答我自己的问题,但看看是否有人让这个工作。比赛开始了! :-)

YouTube 上 ActionBarCompat 的发布: https://www.youtube.com/watch?v=6TGgYqfJnyc


更新(工作代码,是的!): 我已将 Google 的示例 NavigationDrawer 应用程序转换为使用 ActionBarCompat 并且运行良好。您可以在这里找到它作为参考或开始您的项目: https://github.com/bcrider/NavigationDrawerActionBarCompat

2.x 版本看起来比使用 ActionBarSherlock 的方式更好,但我必须更多地使用 ActionBarCompat 才能确定我是否更喜欢它。


【问题讨论】:

  • 我很想知道您使用 ActionBar compat 和 Nav 抽屉的经验吗?我也使用过 Nav 抽屉和 ABS,它工作正常。
  • 工作正常,除了菜单项。检查此答案以获取正确的语法stackoverflow.com/questions/17913311/…
  • Appcompat Drawer Nav 即使在我的 M860 摩托罗拉上也很慢,我尝试了一些自定义 Drawer lib,它们的性能要好得多

标签: android navigation drawer android-actionbar-compat


【解决方案1】:

注意:我太新了,无法在帖子中添加多个链接等,所以我回答我自己的问题而不是编辑它(希望这不违反规则?)。一旦允许,将编辑原件。

使用 ActionBarCompat 添加导航抽屉的简单方法: 我发现转换我现有的应用程序并没有我想象的那么糟糕。 Google 的样本让我相信 Fragment 是必需品,但事实并非如此……远非如此。

您可以简单地使用 DrawerLayout 包装现有布局并插入 ListView(或任何包含 ListView 的布局)以进行实际导航。然后将普通代码添加到您现有的 Activity(扩展 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

【讨论】:

    【解决方案2】:

    我昨天将我的应用从 ActionBarSherlock 转换为 ActionBarCompat。我遇到了一些问题,但没有太严重。

    我有一些cmets:

    要更新主题,我只需要将“Sherlock”覆盖为“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);

    如果你使用继承自 RoboSherlockActivity 的 RoboGuice,如果你只是复制它并更改为 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;
        }
    
    }
    

    现在,您使用 supportStartActionMode() 启动 ActionMode,并从库的包中导入 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

    【讨论】:

    • 非常好!我很高兴你提到了搜索视图,因为我将在下周左右开始使用它,在我(希望)从 ABS 转换为 ABC 之后。
    • 好吧,我遇到了 SearchView 的问题。看这里:stackoverflow.com/questions/17898282/…
    • 另一个障碍:ActionBarCompat 并在 MapActivity 上使用它。你有没有可能已经通过了那个障碍?我在这里发布了一个问题:stackoverflow.com/questions/17980503/…
    【解决方案3】:

    4.3 sdk 附带的示例看起来很有希望,但我将创建一个测试项目并尝试将我自己的应用程序转换为ActionBarCompact,看看它的功能是否比 ActionBarSherlock 更好或更差!如果我成功与否,我会更新这篇文章!

    【讨论】:

    • 终于能够回到这一点,我发现集成过程中缺少一个步骤。该视频没有明确提到(或者对我来说足够清楚)将项目作为库导入。一旦我这样做了,很多问题就消失了。我只是将 .\sdk\extras\android\support\v7\appcompat 导入我的工作区,然后将其作为库添加到我的主项目中。仅按照视频的建议复制 jar 文件是不够的。
    【解决方案4】:

    虽然提供的示例很好,但我制作了另一个示例,它更接近原始 Google Navigation Drawer 示例,因为它包含所有原始代码(现在旨在支持库)和格式。 只有一些属性必须替换为类似的属性,因为它们仅从 v11 开始可用。

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

    注意:这需要存在 v7 appcompat 库,有关详细信息,请参阅http://developer.android.com/tools/support-library/setup.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多