在滑动时移动和调整 DrawerLayout 的内容

Moving and resizing DrawerLayout's content on sliding

我刚刚发现这个应用程序并看到了 DrawerLayout 的自定义动画。 我猜它必须先截屏,然后在 Activity 中绘制自定义 View,但我不确定,也不确定细节。 有人知道怎么做吗?

您可以通过在 DrawerLayout 上的 DrawerListeneronDrawerSlide() 方法中翻译和缩放内容 View 来完成此操作。由于内容 View 本身正在调整大小,并且右下角出现了一个单独的 TextView,我们将把它们都放在另一个支架 ViewGroup 中。如果不需要该标签 TextView,则也可以省略持有人 ViewGroup

示例的基本 DrawerLayout 设置:

<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="#222222">

    <RelativeLayout android:id="@+id/holder"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout android:id="@+id/content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="#E97411" />

            <ImageView android:id="@+id/main_content"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:background="#EEEEEE"
                android:src="@drawable/ic_launcher" />

        </LinearLayout>

        <TextView android:id="@+id/label"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:visibility="gone"
            android:textSize="26dp"
            android:text="My App" />

    </RelativeLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="left"
        android:background="#555555" />

</android.support.v4.widget.DrawerLayout>

示例 Activity 显示了标准 View 初始化,以及实际执行工作的 DrawerListener

public class MainActivity extends AppCompatActivity {

    private static final float END_SCALE = 0.7f;

    private DrawerLayout drawerLayout;
    private NavigationView navigationView;
    private Toolbar toolbar;
    private TextView labelView;
    private View contentView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        navigationView = (NavigationView) findViewById(R.id.navigation_view);
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        labelView = (TextView) findViewById(R.id.label);
        contentView = findViewById(R.id.content);

        toolbar.setNavigationIcon(new DrawerArrowDrawable(this));
        toolbar.setNavigationOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (drawerLayout.isDrawerOpen(navigationView)) {
                        drawerLayout.closeDrawer(navigationView);
                    }
                    else {
                        drawerLayout.openDrawer(navigationView);
                    }
                }
            }
        );

        drawerLayout.setScrimColor(Color.TRANSPARENT);
        drawerLayout.addDrawerListener(new DrawerLayout.SimpleDrawerListener() {
                @Override
                public void onDrawerSlide(View drawerView, float slideOffset) {
                    labelView.setVisibility(slideOffset > 0 ? View.VISIBLE : View.GONE);

                    // Scale the View based on current slide offset
                    final float diffScaledOffset = slideOffset * (1 - END_SCALE);
                    final float offsetScale = 1 - diffScaledOffset;
                    contentView.setScaleX(offsetScale);
                    contentView.setScaleY(offsetScale);

                    // Translate the View, accounting for the scaled width
                    final float xOffset = drawerView.getWidth() * slideOffset;
                    final float xOffsetDiff = contentView.getWidth() * diffScaledOffset / 2;
                    final float xTranslation = xOffset - xOffsetDiff;
                    contentView.setTranslationX(xTranslation);
                }

                @Override
                public void onDrawerClosed(View drawerView) {
                    labelView.setVisibility(View.GONE);
                }
            }
        );
    }
}

该示例使用 SimpleDrawerListener,但如果使用 ActionBarDrawerToggle,可以类似地覆盖 onDrawerSlide() 方法。在这种情况下,需要调用 super 方法来保留汉堡箭头动画。

请注意 DrawerLayoutActivity 重新创建期间保留抽屉状态,因此在处理方向更改等时可能需要考虑到这一点。

Drawer behavior 是一个使用 Android DrawerLayout Support library as Parent Class [Easy to migrate] 的库,它在抽屉上提供额外的行为,例如移动视图或缩放视图的高度,同时幻灯片上的抽屉。

如果当前项目使用 Android DrawerLayout Support library 并且效果有点无聊。然后,只需更改 animation/effect.

的布局代码和调用必要的方法

Check out github code

Gradle

dependencies {
   implementation 'com.infideap.drawerbehavior:drawer-behavior:0.1.5'
}

如果 gradle 无法同步,您可以在项目级别 gradle、

中包含此行
repositories {
 maven{
   url "https://dl.bintray.com/infideap2/Drawer-Behavior"
 }
}