移动主要内容以显示抽屉 [英] Moving the main content to reveal a drawer
问题描述
我想创建一个导航抽屉效果,但不是抽屉从左侧滑出,而是必须在主视图的后面",所以滑动的项就是视图本身(即,向右) -抽屉根本不动,但是通过滑动主视图使其露出".手指滑动(并点击汉堡图标)的动作与抽屉相同,只是显示效果不同.
主视图的移动方式与此处可以实现的方式相同
但是对于我而言,我希望抽屉"静态地停留在主视图下方.
我已经通过覆盖视图并使抽屉透明来实现了预期的效果-当然,这意味着抽屉不再用于导航;只是为了效果.使用上面链接中的代码
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/whole_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- everything here is now the new "drawer" -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="BOO I am hiding!"
android:id="@+id/tv2"
android:layout_gravity="left|top" />
<!-- /everything here is now the new "drawer" -->
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<!-- The This is the main content frame -->
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="MOOOOOO!"
android:id="@+id/textView"
android:layout_gravity="left|top" />
</FrameLayout>
<!-- The see-through navigation drawer -->
<RelativeLayout
android:layout_width="280dp"
android:layout_height="match_parent"
android:id="@+id/left_drawer"
android:clickable="false"
android:background="@drawable/transparent_bg" <!-- #00FFFFFF -->
android:layout_gravity="start">
</RelativeLayout>
</android.support.v4.widget.DrawerLayout>
一切都很完美,除了打开抽屉"时id/tv2(或该层上的其他项目)不可点击.
我尝试过:
1) 使上面的布局不可点击(drawer_layout,content_frame和left_drawer setClickable(false)无效).
2) 上面链接中的代码在X轴上移动content_frame,而不是在drawyer_layout上移动-我尝试了在移动抽屉式布局而不是在框架上-这无法正常工作,因为您无法再单击最右边的按钮来再次关闭抽屉.>
3) 更改抽屉式布局的android:layout_width到fill_parent,但这仍然是一个问题,因为它不是将图层移开.
我的猜测是DrawerLayout(android.support.v4.widget.DrawerLayout)并不意味着位于另一个布局之上,我可能需要创建自己的抽屉才能实现所需的效果-任何想法或建议都很棒.
我相信我已经找到了一个相对简单的解决方案.以下DrawerLayout
设置非常标准-即首先使用ViewGroup
内容,最后使用标准属性View
抽屉,等等.此外,类似于发布的链接中所示的技术可用于滑动内容和抽屉.
该示例中的技巧是抽屉本身的设置.我们将使用两个嵌套的ViewGroup
-外部的是常规的滑动抽屉View
;内部是ViewGroup
,代表实际抽屉内容.然后,我们将使用DrawerListener
(在我们的示例中为ActionBarDrawerToggle
)使内部内容ViewGroup
与抽屉的滑动方向相反,从而使抽屉在左侧显得静止.
示例DrawerLayout
,main.xml
.请注意在drawer_container
ViewGroup
上设置的标准抽屉属性:
<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"
android:background="#000000">
<FrameLayout
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#cccccc" />
<FrameLayout
android:id="@+id/drawer_container"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start">
<LinearLayout
android:id="@+id/drawer_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_launcher" />
...
</LinearLayout>
</FrameLayout>
</android.support.v4.widget.DrawerLayout>
此示例Activity
显示了我们需要添加到常规导航抽屉设置中的几行额外内容.除了获取对View
的引用之外,主要位在ActionBarDrawerToggle
的onDrawerSlide()
方法中:
public class MainActivity extends Activity {
ActionBarDrawerToggle toggle;
DrawerLayout drawerLayout;
View drawerContainer;
View drawerContent;
View mainContent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerContainer = findViewById(R.id.drawer_container);
drawerContent = findViewById(R.id.drawer_content);
mainContent = findViewById(R.id.main_content);
toggle = new ActionBarDrawerToggle(...) {
@Override
public void onDrawerSlide(View drawer, float slideOffset) {
super.onDrawerSlide(drawer, slideOffset);
drawerContent.setTranslationX(drawerContainer.getWidth() * (1 - slideOffset));
mainContent.setTranslationX(drawerContainer.getWidth() * slideOffset);
}
};
drawerLayout.addDrawerListener(toggle);
}
}
请记住,DrawerLayout
在重新创建Activity
时会恢复抽屉的打开/关闭状态,因此,例如在方向更改等过程中,您可能需要考虑到这一点.
I'd like to create a navigation drawer effect, but rather than the drawer sliding out from the left, it must be "behind" the main view, so the item that slides is the view itself (i.e. to the right) - the drawer doesn't move at all, but is "revealed" by sliding the main view out of the way. The finger swipe (and tap on hamburger icon) action is the same as with the drawer, just the reveal effect is different.
The way the main view moves is the same to what can be achieved here
How to move main content with Drawer Layout left side
but in my case I want the "drawer" to stay statically underneath the main view.
I've achieved the desired effect by overlaying views and making the drawer transparent - of course this means that the drawer is no longer used for navigation; just for effect. Using the code in the above link
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/whole_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- everything here is now the new "drawer" -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="BOO I am hiding!"
android:id="@+id/tv2"
android:layout_gravity="left|top" />
<!-- /everything here is now the new "drawer" -->
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<!-- The This is the main content frame -->
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="MOOOOOO!"
android:id="@+id/textView"
android:layout_gravity="left|top" />
</FrameLayout>
<!-- The see-through navigation drawer -->
<RelativeLayout
android:layout_width="280dp"
android:layout_height="match_parent"
android:id="@+id/left_drawer"
android:clickable="false"
android:background="@drawable/transparent_bg" <!-- #00FFFFFF -->
android:layout_gravity="start">
</RelativeLayout>
</android.support.v4.widget.DrawerLayout>
Everything is perfect except that id/tv2 (or other items on that layer) are not clickable when the "drawer" is opened.
I've tried:
1) Making the layouts above not clickable (drawer_layout, content_frame and left_drawer setClickable(false) without effect).
2) The code in the above link moves the content_frame on X axis and not the drawyer_layout - I tried moving drawer_layout instead of the frame - this doesn't work properly as you can no longer click on the far right to close the drawer again.
3) Changing the android:layout_width of the drawer_layout to fill_parent, but this is still a problem as it is not the layer being moved out of the way.
My guess is that DrawerLayout ( android.support.v4.widget.DrawerLayout ) is not meant to be above another layout and I might need to create my own drawer to achieve the desired effect - any ideas or suggestions would be great.
I believe I've figured out a relatively simple solution. The following DrawerLayout
setup is pretty standard - i.e., the content ViewGroup
first, the drawer View
last, using standard attributes, etc. Additionally, a technique similar to that shown in your posted link is used to slide the content with the drawer.
The trick in the example is the setup of the drawer itself. We're going to use two nested ViewGroup
s - the outer one is the regular sliding drawer View
; the inner, a ViewGroup
for the actual drawer contents. We'll then slide the inner content ViewGroup
opposite the direction of the drawer's slide using a DrawerListener
(an ActionBarDrawerToggle
in our example), making the drawer appear static against the left side.
The example DrawerLayout
, main.xml
. Note the standard drawer attributes set on the drawer_container
ViewGroup
:
<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"
android:background="#000000">
<FrameLayout
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#cccccc" />
<FrameLayout
android:id="@+id/drawer_container"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start">
<LinearLayout
android:id="@+id/drawer_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_launcher" />
...
</LinearLayout>
</FrameLayout>
</android.support.v4.widget.DrawerLayout>
This example Activity
shows the few extra lines we need to add to a regular Navigation Drawer setup. Other than getting references to the View
s, the main bit is in the ActionBarDrawerToggle
's onDrawerSlide()
method:
public class MainActivity extends Activity {
ActionBarDrawerToggle toggle;
DrawerLayout drawerLayout;
View drawerContainer;
View drawerContent;
View mainContent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerContainer = findViewById(R.id.drawer_container);
drawerContent = findViewById(R.id.drawer_content);
mainContent = findViewById(R.id.main_content);
toggle = new ActionBarDrawerToggle(...) {
@Override
public void onDrawerSlide(View drawer, float slideOffset) {
super.onDrawerSlide(drawer, slideOffset);
drawerContent.setTranslationX(drawerContainer.getWidth() * (1 - slideOffset));
mainContent.setTranslationX(drawerContainer.getWidth() * slideOffset);
}
};
drawerLayout.addDrawerListener(toggle);
}
}
Keep in mind that DrawerLayout
restores the drawer opened/closed state during Activity
re-creation, so you might need to account for that, for example, during orientation changes, etc.
这篇关于移动主要内容以显示抽屉的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!