【问题标题】:Android Navigation Drawer on top ActionBar顶部 ActionBar 上的 Android 导航抽屉
【发布时间】:2014-06-11 06:37:53
【问题描述】:

当它像这个应用程序一样向右滑动时,我正在尝试在操作栏上制作导航抽屉: [已删除]

这是我主要活动的布局:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout ...>
    <RelativeLayout android:orientation="vertical" 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent">
        ...
    </RelativeLayout>
    <fragment android:name="com...." 
        android:layout_gravity="start" 
        android:id="@id/navigation" 
        android:layout_width="@dimen/navigation_menu_width" 
        android:layout_height="fill_parent" />
</android.support.v4.widget.DrawerLayout>

stackoverflow 上的其他一些问题类似,例如this question,但所有答案都建议使用滑动菜单库。但是这个应用程序他们仍然使用 android.support.v4.widget.DrawerLayout 并且他们成功了。不要问我怎么知道他们使用标准的抽屉式导航,但我很确定。

非常感谢您的帮助。


这是最终解决方案:非常感谢 @Peter Cai 这非常有效。 https://github.com/lemycanh/DrawerOnTopActionBar

【问题讨论】:

    标签: android navigation android-actionbar drawer


    【解决方案1】:

    我从https://github.com/jfeinstein10/SlidingMenu 学到了一个小“技巧”​​来实现你需要的效果。

    您只需要删除窗口装饰视图的第一个孩子,并将第一个孩子添加到抽屉的内容视图中。之后,您只需要将抽屉添加到窗口的装饰视图中即可。

    以下是您执行此操作的一些详细步骤。

    首先,创建一个名为“decor.xml”的 xml 或任何你喜欢的东西。只把DrawerLayout和抽屉放进去。下面的“FrameLayout”只是一个容器。我们将使用它来包装您的活动内容。

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v4.widget.DrawerLayout ...>
        <FrameLayout android:id="@+id/container"
            android:orientation="vertical" 
            android:layout_width="fill_parent" 
            android:layout_height="fill_parent"/>
        <fragment android:name="com...." 
            android:layout_gravity="start" 
            android:id="@id/navigation" 
            android:layout_width="@dimen/navigation_menu_width" 
            android:layout_height="fill_parent" />
    </android.support.v4.widget.DrawerLayout>
    

    然后删除主布局中的 DrawerLayout。现在你的主要活动的布局应该看起来像

    <RelativeLayout android:orientation="vertical" 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent">
        ...
    </RelativeLayout>
    

    我们假设主活动的布局命名为“main.xml”。

    在您的 MainActivity 中,编写如下:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    
        // Inflate the "decor.xml"
        LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        DrawerLayout drawer = (DrawerLayout) inflater.inflate(R.layout.decor, null); // "null" is important.
    
        // HACK: "steal" the first child of decor view
        ViewGroup decor = (ViewGroup) getWindow().getDecorView();
        View child = decor.getChildAt(0);
        decor.removeView(child);
        FrameLayout container = (FrameLayout) drawer.findViewById(R.id.container); // This is the container we defined just now.
        container.addView(child);
    
        // Make the drawer replace the first child
        decor.addView(drawer);
    
        // Do what you want to do.......
    
    }
    

    现在你有了一个可以在 ActionBar 上滑动的 DrawerLayout。但是您可能会发现它被状态栏覆盖。您可能需要在 Drawer 中添加一个 paddingTop 来解决这个问题。

    【讨论】:

    • 确认此 hack 按预期工作。我们需要为抽屉添加填充,这是获取状态栏高度的技巧:stackoverflow.com/questions/20584325/…。另一个技巧是当我们想将片段添加到容器时,而不是像这样添加:fragmentTransaction.replace(R.id.container, fragment);我们应该替换为 R.id.content。 fragmentTransaction.replace(getContentIdResource(), 片段); ... private int getContentIdResource() { return getResources().getIdentifier("content", "id", "android"); }
    • @lemycanh 我用来添加片段的另一个解决方案是在主布局中添加一个容器。抽屉布局已经从主布局中分离出来,所以 R.id.container 只是为了包装 main.xml 中定义的布局。
    • 很好的答案!在实现这个之后,我意识到我们实际上是从另一个布局中窃取视图并丢弃它!哈哈
    • 我按照上面的方式安排了我的代码,但是我的操作栏出了点问题。出现打开/关闭导航抽屉的切换按钮。你猜为什么?
    • 执行此操作后,我的操作栏底部似乎模糊了。此外,我需要在选择导航抽屉项目时替换的每个片段中添加 paddingTop 属性 ( = 80dp )。为什么会这样?
    【解决方案2】:

    更新:如何用导航抽屉覆盖操作栏。 (使用新的工具栏) 在 build.gradle 的依赖项中使用这些

    compile 'com.android.support:appcompat-v7:21.0.0'
    compile 'com.android.support:support-v4:21.0.0'
    

    这是你的抽屉布局

    <!-- A DrawerLayout is intended to be used as the top-level content view using match_parent for both width and height to consume the full space available. -->
    <android.support.v4.widget.DrawerLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <LinearLayout
            android:id="@+id/layout_main"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
        <include layout="@layout/toolbar"/>
        <!-- As the main content view, the view below consumes the entire
             space available using match_parent in both dimensions. -->
        <FrameLayout
            android:id="@+id/content_frame"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/white"/>
    
        </LinearLayout>
        <fragment android:id="@+id/navigation_drawer"
            android:layout_width="@dimen/navigation_drawer_width"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:background="@color/list_background"
             />
    
    </android.support.v4.widget.DrawerLayout>
    

    在布局文件夹中创建新的 toolbar.xml 文件。

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.widget.Toolbar
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/toolbar"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        android:minHeight="?attr/actionBarSize"
        android:background="?attr/colorPrimary" />
    

    转到扩展导航抽屉的活动。 并在 SetContentView() 之后添加它

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    

    不要忘记在你的 values 文件夹中扩展你的主题 NoActionBar。

    <style name="Theme.Whtsnxt" parent="@style/Theme.AppCompat.Light.NoActionBar">
        <item name="windowActionBar">false</item>
        <!-- colorPrimary is used for the default action bar background -->
        <item name="windowActionModeOverlay">true</item>
        <item name="android:textColorPrimary">@color/white</item>
        <item name="colorPrimary">@color/splashscreen</item>
        <item name="colorPrimaryDark">@color/holo_blue_light</item>
    
        <item name="android:windowBackground">@color/white</item>
        <item name="android:colorBackground">@color/white</item>
    
    </style>
    

    【讨论】:

    • 可以使用apktool查看布局。这很糟糕,但我没有办法:(
    • 不应使用此库。很久没有更新了,当谷歌有 DrawerLayout 时,它违反了设计准则。查看 Google I/O 应用程序,特别是 Android L 的 Material 版本(在 GitHub 页面上:github.com/google/iosched)。 DrawerLayout 可以覆盖操作栏。
    • 在回答时,我知道没有这样的解决方案!感谢您的建议,我编辑了答案!
    【解决方案3】:

    如果您不想使用 lib 或此 hack:

    1. 扩展“Theme.AppCompat.NoActionBar”
    2. 将 DrawerLayout 的第一个元素移动到 LinearLayout。
    3. 向此 LinearLayout 添加一个工具栏。

      <android.support.v7.widget.Toolbar
          android:id="@+id/toolbar"
          android:minHeight="?attr/actionBarSize"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          app:titleTextColor="@android:color/white"
          android:background="?attr/colorPrimary">
      </android.support.v7.widget.Toolbar>
      
    4. 在 Activity 中,在 setContentView 之后添加以下行

      setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
      
    5. 现在应该可以工作了。

    【讨论】:

    • 现在看到 here 是相同的答案,但代码更多。
    【解决方案4】:

    我已经发布了一个技巧,可以在之前的 Android L 版本中实现这一点。 你可以找到我的解决方案in this post。希望它对某人有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-28
      • 1970-01-01
      相关资源
      最近更新 更多