【问题标题】:How to make background Activity smaller while opening the Navigation Drawer?打开导航抽屉时如何使背景活动更小?
【发布时间】:2013-11-19 20:46:31
【问题描述】:

我想在打开Navigation Drawer时让我的背景Activity小一点,模拟Airbnb应用程序中存在的效果。我想最好的解释是截图:

但重点不是让 View 变得更小,而是让它成为一个与 Drawer Open/Close 动画同步的动画。所以如果你开始打开Drawer并且在中间决定停止并返回,后台的Activity规模就会受到相应的影响。

如何使用 DrawerLayout 中的构建来做到这一点?有一些实现吗?

【问题讨论】:

    标签: java android animation android-activity navigation-drawer


    【解决方案1】:

    您可以使用支持库 v4 中的 ActionBarDrawerToggle 来执行此效果。

    您所要做的就是重写 onDrawerSlide 方法以检索抽屉菜单的打开百分比,然后缩放放置片段的 FrameLayout。

    代码示例:

    main_layout.xml

    <?xml version="1.0" encoding="utf-8"?>
    <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">
    
        <FrameLayout android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>    
    
        <ListView android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp"/>
    
    </android.support.v4.widget.DrawerLayout>
    

    现在在您的 Activity 中,其中包含抽屉:

    public class ConfigurerActivity extends ActionBarActivity 
    {
        private DrawerLayout mDrawerLayout;
        private ListView mDrawerList;
        private ActionBarDrawerToggle mDrawerToggle;
        private FrameLayout frame;
        private float lastScale = 1.0f;
    
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main_layout);
    
            mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
            mDrawerList = (ListView) findViewById(R.id.left_drawer);
            frame = (FrameLayout) findViewById(R.id.content_frame);
    
            mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.ic_drawer, R.string.acc_drawer_open, R.string.acc_drawer_close) 
            {            
                @SuppressLint("NewApi")
                public void onDrawerSlide(View drawerView, float slideOffset)
                {
                    float min = 0.9f;
                    float max = 1.0f;
                    float scaleFactor = (max - ((max - min) * slideOffset));
    
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) 
                    {
                        frame.setScaleX(scaleFactor);
                        frame.setScaleY(scaleFactor);
                    }
                    else
                    {               
                        ScaleAnimation anim = new ScaleAnimation(lastScale, scaleFactor, lastScale, scaleFactor, frame.getWidth()/2, frame.getHeight()/2);
                        anim.setDuration(0);
                        anim.setFillAfter(true);
                        frame.startAnimation(anim);
    
                        lastScale = scaleFactor;
                    }
                }
            };
    
            mDrawerLayout.setDrawerListener(mDrawerToggle);
    
            // ... more of your code
        }
    }
    

    请注意,我使用 2 种不同的方法进行缩放,因为 setScaleX/Y 在 PRE - Honeycomb Android 版本中不可用。

    有了这个,您可以设置自己的 scaleFactor(我认为 0.9f 足够小)或者根据抽屉的打开百分比尝试新的效果(更改颜色)。

    希望对你有帮助。

    【讨论】:

    • 非常感谢,它看起来是正确的答案,我唯一的问题是在我的应用程序中,NavDrawer Activity 基本上是我拥有的所有其他 Activity 的包装器 Activity,所以我想要的布局调整大小而不是直接坐在同一个活动中,所以我不知道如何获取它的实例。这是您示例中的框架实例。我会看看我能做什么,很快就会接受你的回答。
    • 您的解决方案非常完美,我对其进行了测试,然后对我的代码进行了必要的更改,并且它按预期工作。对不同 sdk 版本的动画方法进行了很好的补充,尽管我已经知道这一点,但对其他人有帮助。非常感谢:)
    • 很高兴它对您有所帮助!
    • 完美。非常感谢
    • 如果图标抽屉 (ic_drawer) 没有移动或切换。只需删除您的 onDrawerClose 和 onDrawerOpen 侦听器并更改为 slideOffset 的 if 语句,此处引用 stackoverflow.com/a/23373562/1309629
    【解决方案2】:

    您还可以为较小的活动提供最佳效果。检查ResideMenu

    带库的演示。

    【讨论】:

      【解决方案3】:

      如果你看看第三方库SlidingMenu,应该有你想要的一切。

      你感兴趣的是behindScrollScale,上面写着:

      behindScrollScale - 一个浮点数,表示上面的视图滚动和后面的视图滚动之间的关系。如果设置为 0.5f,上面的视图每滚动 2px,后面的视图就会滚动 1px。如果设置为 1.0f,上面的视图每滚动 1px,后面的视图就会滚动 1px。如果设置为 0.0f,后面的视图将永远不会滚动;它将是静态的。这个玩起来很有趣。默认为 0.25f。

      【讨论】:

      • 我猜你可能是对的,但我正确地使用了 DrawerLayout 中的构建,我并不是真的想更改这个实现而是添加它。有没有其他方法可以做到这一点?
      • 不使用本机 DrawerLayout 我不认为。 Google's design guidelines for DrawerLayout 声明内容不应该移动,抽屉应该出现在内容上,所以我怀疑他们会支持破坏这一点的东西。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多