如何实现带有可见手柄的DrawerLayout

32
我已经成功地为我的应用程序实现了一个NavigationDrawer。
我的应用程序显示一个抽屉,它打开在屏幕的左侧。
我的问题是我需要在左侧添加一个按钮。这个按钮可以被点击或滑动以打开左侧的抽屉。这个我可以做到。
但是这个按钮应该看起来像是抽屉的一部分,会溢出到屏幕上。
这意味着按钮应该同时滑动,当抽屉开启和关闭时。
关闭状态:
打开状态:
我尝试将按钮添加到左侧抽屉的布局中,但似乎你不能让东西出现在其边界之外,当你关闭它时,抽屉总是会完全隐藏。
现在我正在尝试将其添加到主DrawerLayout,并使其对齐到左侧抽屉的右侧... 但是没有运气... 看起来DrawerLayout不能有超过两个子元素...
任何帮助都将不胜感激。
我正在使用支持库(v4)
编辑:我支持API级别8... 所以无法使用ImageView.setTranslationX或View.OnAttachStateChangeListener

1
你有找到任何解决方案吗? - alicanbatur
我自己的(被接受的)答案是我选择的解决方案。 - Armel Larcier
2个回答

12

这有点棘手。

我认为这类似于新版Google地图应用程序中对抽屉手柄的处理方式。不确定,仅供参考。:)

我编写了一个开关,它停留在Activity内容视图的边缘。 当拖动DrawerLayout时,我将视图在x轴上平移了最小子项的数量(即DrawerLayout内容视图),减去阴影(如果有)。由于阴影所产生的影响和DrawerLayout的内容视图组合起来形成整个抽屉的完整测量宽度。

我快速将滑动偏移量和最小子项相乘,找到x轴的平移距离。

[编辑:已删除代码以提高可读性,并将其移至下面提供的链接]

在您的活动中:

mDrawerToggle = new DrawerLayoutEdgeToggle(
    this, 
    mDrawerLayout, 
    R.drawable.ic_launcher, 
    R.drawable.ic_launcher,
    Gravity.LEFT, 
    true) {

        @Override
        public void onDrawerClosed(View view) {
            super.onDrawerClosed(view); //must call super
        }

        @Override
        public void onDrawerOpened(View view) {
            super.onDrawerOpened(view); //must call super
        }

        @Override
        public void onDrawerSlide(View view, float slideOffset) {
            super.onDrawerSlide(view, slideOffset); //must call super

        }
    };
mDrawerLayout.setDrawerListener(mDrawerToggle);

创意提升:您可以添加更多的化妆品,比如与ActionBar的距离,您可以将其设置为手柄的边距。

此外,您还可以通过在Y轴上平移来沿左/右移动手柄,从而模仿“单拉链效果”。 :)

编辑:您可以在我的GitHub上找到它。

编辑2: 对于那些无法在开头看到手柄的人,请使用mDrawerToggle.setVerticalPostionOffset(0)


非常感谢。不过我不确定能否采用你的解决方案,因为我需要支持API级别8,正如我在我的编辑中所写的那样。有什么想法吗? 会尝试一下。 - Armel Larcier
@ArmelLarcier 我已经想办法支持旧版本 <= 11。我没有时间添加NineOldAndroids动画库。如果你有时间,请随意创建拉取请求并添加它。请查看我的GitHub以获取您所请求的更改。 - Nikola Despotoski
无法正确使用您的库,句柄未显示,但当触摸屏幕某些部分(远离通常打开抽屉的左侧)时,抽屉似乎突然出现了。我也不想使用SlidingDrawer,因为我觉得那个小部件非常缓慢。最终,仅使用nineoldandroids库,我就能够通过在抽屉旁边放置另一个视图并以与抽屉移动相同的速度动画化x值来实现所需的结果。 - Jordy
这基本上就是库所做的事情。当您不设置句柄的垂直位置时,可能会出现一种奇怪的行为。我有时间会修复它。对于那些遇到此问题的人,只需使用 setVerticalPostionOffset(0) 即可。 - Nikola Despotoski
请添加一些示例活动。处理程序的图标放在哪里? - Palak Darji
这个 setVerticalPostionOffset(0) 方法应该在哪个对象上调用? - nvinayshetty

6
我发现这个非常容易实现,多亏了Mobistry编写的Aniqroid库(SO伪代码)。 我使用了SlidingTray类,它是android SlidingDrawer的副本,但可以让您将抽屉放置在屏幕的任何角落。 我通过xml声明了元素。
<com.sileria.android.view.SlidingTray 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer"
    android:layout_width="match_parent"
    android:layout_height="270dp"
    android:content="@+id/content"
    android:handle="@+id/handle" >

    <ImageView
        android:id="@+id/handle"
        android:layout_width="320dp"
        android:layout_height="24dp"
        android:background="@drawable/tray_btn" />

    <LinearLayout
        android:id="@+id/content"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="fill_vertical"
        android:orientation="vertical" >
    </LinearLayout>

</com.sileria.android.view.SlidingTray>

我刚才必须拨打电话

Kit.init(this);

在我的主要Activity中,在填充布局之前。

我感谢aniqroid的开发人员!

https://code.google.com/p/aniqroid/


我在尝试集成这个库时遇到了很多错误。 - Henadzi Rabkin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接