【问题标题】:Can I open the drawer layout with animation programmatically?我可以以编程方式打开带有动画的抽屉布局吗?
【发布时间】:2013-08-06 21:47:26
【问题描述】:

我使用以下库创建了应​​用程序抽屉: http://developer.android.com/training/implementing-navigation/nav-drawer.html

我想在打开应用程序时显示带有动画的导航抽屉。 我该怎么做?

【问题讨论】:

    标签: android android-support-library navigation-drawer


    【解决方案1】:

    预绘制监听器,也就是安全通道

    这是预绘制监听器示例。它会尽快开始动画,这可能有点太快了。您可能希望将此与第二个显示的可运行文件结合起来。我不会将两者结合起来,只会分开显示。

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        // Building NavDrawer logic here. Just a method call would be best.
        ...
    
        ViewTreeObserver vto = drawer.getViewTreeObserver();
        if (vto != null) vto.addOnPreDrawListener(new ShouldShowListener(drawer));
    }
    
    private static class ShouldShowListener implements OnPreDrawListener {
    
        private final DrawerLayout drawerLayout;
    
        private ShouldShowListener(DrawerLayout drawerLayout) {
            this.drawerLayout= drawerLayout;
        }
    
        @Override
        public boolean onPreDraw() {
            if (view != null) {
                ViewTreeObserver vto = view.getViewTreeObserver();
                if (vto != null) {
                    vto.removeOnPreDrawListener(this);
                }
            }
    
            drawerLayout.openDrawer(Gravity.LEFT);
            return true;
        }
    }
    

    PostDelay Runnable,又名生活危险

    // Delay is in milliseconds
    static final int DRAWER_DELAY = 200;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        // Building NavDrawer logic here. Just a method call would be best.
        ...
        new Handler().postDelayed(openDrawerRunnable(), DRAWER_DELAY);
    }
    
    private Runnable openDrawerRunnable() {
        return new Runnable() {
    
            @Override
            public void run() {
                drawerLayout.openDrawer(Gravity.LEFT);
            }
        }
    }
    

    警告

    如果他们第一次在应用程序启动时轮换BOOM!阅读此博客文章以获取更多信息http://corner.squareup.com/2013/12/android-main-thread-2.html。最好的办法是使用预绘制侦听器或在 onPause 中删除您的可运行文件。

    【讨论】:

    • 如果在所有情况下 200 毫秒都不够怎么办?
    • 然后把它做成你需要的任何长度。
    • 我不是这个意思。这种方法不好——只要准备时间比预期的多,它就会失败。正如你所说的那样,“祝你好运”真的很合适...... :-)
    • 我听到你在说什么,但我认为如果你在 onCreate 之后花费超过 200 或 300 毫秒来构建你的抽屉和活动,那么你做错了什么。
    • 不。没有什么不对。旧设备,例如 - HTC Hero。或者我的开发机器上的模拟器。在这种情况下,这根本行不通。您需要在绘制 Activity 时准确触发抽屉的打开。为此,将 onPreDrawListener 置于 ViewTreeObserver 中——这总是比依赖固定时间好!
    【解决方案2】:

    您可以在DrawerLayout 上调用openDrawer(int gravity) 使其通过动画打开抽屉。

    【讨论】:

    • 我在 Fragment Activity 的 onStart() 方法中调用它,抽屉显示时没有动画。我是在错误的地方调用还是应该为参数设置什么重力值?
    • 如果它像典型的那样从应用的左侧出来,请使用 Gravity.LEFT。看看是否有帮助。否则,请尝试在片段生命周期的后期调用它,例如 onResume。
    • 如果我在 onResume() 中调用它,这是否意味着即使进行多任务切换,抽屉也会打开?
    • 我也在寻找解决方案。从 onResume() 调用时它也不会动画。文档中似乎也有错字。在一个版本的 openDrawer 上,它说“...将其动画化”,而在另一个版本上,它说“...将其动画化”
    • 您可以尝试使用 postDelayed(Runnable, long) 将其延迟片刻。这样,在 UI 确定之前不会打开它。
    【解决方案3】:

    您需要调用drawerLayout.openDrawer(Gravity.LEFT) 来为抽屉打开设置动画。如果您在 Activity 生命周期中过早调用,抽屉将不会动画。

    最简单的解决方案是在 onCreate() 中设置一个标志并在 onResume() 中对其进行操作。

    您要确保仅在 savedInstanceState 为 null 时设置标志,表示 Activity 未从后台恢复。您不希望每次更改方向或切换应用程序时抽屉都会滑出。

    public class MainActivity extends ActionBarActivity {
        private DrawerLayout drawerLayout;
        private boolean firstResume = false;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            drawerLayout = (DrawerLayout)findViewById(R.id.drawer);
    
            if(savedInstanceState == null){
                firstResume = true;
            }
        }
    
        @Override
        protected void onResume() {
            super.onResume();
    
            if(firstResume) {
                drawerLayout.openDrawer(Gravity.LEFT);
            }
    
            firstResume = false;
        }
    }
    

    您也可以使用 OnPreDrawListener,但我觉得它有点不必要地复杂,因为 onPreDraw 被多次调用,因此您需要在打开抽屉后移除监听器。您还假设 preDraw 是激活抽屉的合适时间,抽屉是抽屉布局的内部实现。例如,在 onDraw 之后,未来的实现可能无法正确设置动画。

    将抽屉打开延迟任意毫秒是解决此问题的危险方法。在最坏的情况下,如果用户快速导航离开,打开抽屉的调用可能发生在 onDestroy 之后。

    【讨论】:

      猜你喜欢
      • 2020-01-04
      • 2021-04-10
      • 2015-08-17
      • 1970-01-01
      • 2019-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多