在滑动时移动和调整 DrawerLayout 的内容
Moving and resizing DrawerLayout's content on sliding
我刚刚发现这个应用程序并看到了 DrawerLayout
的自定义动画。
我猜它必须先截屏,然后在 Activity
中绘制自定义 View
,但我不确定,也不确定细节。
有人知道怎么做吗?
您可以通过在 DrawerLayout
上的 DrawerListener
的 onDrawerSlide()
方法中翻译和缩放内容 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
方法来保留汉堡箭头动画。
请注意 DrawerLayout
在 Activity
重新创建期间保留抽屉状态,因此在处理方向更改等时可能需要考虑到这一点。
Drawer behavior 是一个使用 Android DrawerLayout Support library as Parent Class [Easy to migrate] 的库,它在抽屉上提供额外的行为,例如移动视图或缩放视图的高度,同时幻灯片上的抽屉。
如果当前项目使用 Android DrawerLayout Support library 并且效果有点无聊。然后,只需更改 animation/effect.
的布局代码和调用必要的方法
Gradle
dependencies {
implementation 'com.infideap.drawerbehavior:drawer-behavior:0.1.5'
}
如果 gradle 无法同步,您可以在项目级别 gradle、
中包含此行
repositories {
maven{
url "https://dl.bintray.com/infideap2/Drawer-Behavior"
}
}
我刚刚发现这个应用程序并看到了 DrawerLayout
的自定义动画。
我猜它必须先截屏,然后在 Activity
中绘制自定义 View
,但我不确定,也不确定细节。
有人知道怎么做吗?
您可以通过在 DrawerLayout
上的 DrawerListener
的 onDrawerSlide()
方法中翻译和缩放内容 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
方法来保留汉堡箭头动画。
请注意 DrawerLayout
在 Activity
重新创建期间保留抽屉状态,因此在处理方向更改等时可能需要考虑到这一点。
Drawer behavior 是一个使用 Android DrawerLayout Support library as Parent Class [Easy to migrate] 的库,它在抽屉上提供额外的行为,例如移动视图或缩放视图的高度,同时幻灯片上的抽屉。
如果当前项目使用 Android DrawerLayout Support library 并且效果有点无聊。然后,只需更改 animation/effect.
的布局代码和调用必要的方法Gradle
dependencies {
implementation 'com.infideap.drawerbehavior:drawer-behavior:0.1.5'
}
如果 gradle 无法同步,您可以在项目级别 gradle、
中包含此行repositories {
maven{
url "https://dl.bintray.com/infideap2/Drawer-Behavior"
}
}