Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
242 views
in Technique[技术] by (71.8m points)

android - Moving the main content to reveal a drawer

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 ViewGroups - 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 Views, 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...