何时调用openDrawer()(或任何其他动画)以使其在启动时可见?

时间:2014-12-27 15:59:22

标签: android android-fragments android-navigation

我希望我的应用程序在创建主活动后立即显示侧面导航抽屉。 我的代码工作正常 - 用户启动应用程序并获得打开的抽屉 - 但我想实际看到侧抽屉从左侧滑动;相反,我发现抽屉完全打开了。

我应该在什么时候致电openDrawer()? 尝试过来电话:

  • 主要活动OnCreate;
  • 抽屉托管的片段中的类似点。

我可以试试OnPrepareOptionsMenu,但我认为它会在活动生命周期中被多次调用。我也试过OnStart(),我担心我的选择已经结束了。 任何的想法?我确定这很简单,但我无法弄清楚。

编辑:我意识到我对问题的第一次阐述(@Biu)并不是那么清楚。我在这里谈论一个纯粹的图形问题。重点是:

  • 我在创业时会发生一些事情;在我的情况下,我们谈到导航抽屉滑入主屏幕,但它可能是我认为的任何动画;

  • 就我而言,可以打电话:

    protected void OnCreate(Bundle b) {
    ...
    DrawerLayout.openDrawer()
    }
    
  • 以上解决方案效果很好。我所谈论的问题是图形化;使用上面的代码,您启动应用程序并找到已打开的抽屉所涵盖的主要活动。相反,我希望用户能够了解正在讨厌的内容,看看面板的来源;换句话说,要看开场动画。

所以我的问题是:我应该何时致电openDrawer()?主要的活动onCreate是不对的,因为动画在用户看到屏幕上的内容之前结束。

我认为在加载所有内容时启动的愿望会更常见。

3 个答案:

答案 0 :(得分:1)

@benjosantony建议你应该在onResume打开你的抽屉,但不保证当时活动可见:

  

onResume不是你的最佳指标   活动对用户可见;使用onWindowFocusChanged(boolean)来确定   您的活动对用户可见

您认为可以使用onWindowFocusChanged并完成,但您无法做到。还有过渡动画,它打破了(至少对我而言)抽屉的动画......

对于API 21 +:
onEnterAnimationComplete,您可以打开抽屉并正确查看动画。然而21+是一个要求太大的要求..

对于较低的API:
我能想到的唯一可能的方法是通过主题调整删除活动的动画:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:windowAnimationStyle">@null</item>
</style>

如此打开抽屉:

private static final String DRAWER_STATE = "mDrawerOpened";
private DrawerLayout mDrawer;
private ListView mDrawerList;
private boolean mDrawerOpened;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    mDrawerList = (ListView) findViewById(R.id.left_drawer);
}

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    if (!mDrawerOpened && hasFocus) {
        mDrawer.openDrawer(mDrawerList);
        mDrawerOpened = true;
    }
}

@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putBoolean(DRAWER_STATE, mDrawerOpened);
}

@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    mDrawerOpened = savedInstanceState.getBoolean(DRAWER_STATE);
}

仅在活动开始时,这将为抽屉设置动画。

当您的活动被异常销毁时,保存布尔值,例如轮换或需要系统资源。

如果您不想设置instanceState,可以使用SharedPreferences作为@Biu建议,但是IMO不能成为正确的解决方案,因为Android已经为此提供了工具,那里&#39没有必要重新发明自行车。

答案 1 :(得分:0)

您可以使用SharedPreferences

来使用此hack
 boolean firstTime = true;

 SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
 public void onCreate(Bundle bundle) 
 {
     if (pref.getBoolean("firstTime", true) == true)
     {
          drawer.openDrawer(yourDrawer);
          firstTime = false;
          pref.editor().putBoolean("firstTime", firstTime).apply();
     }
  }

答案 2 :(得分:-1)

Activity

活动的前景生命周期发生在对onResume()的调用之间,直到对onPause()的相应调用。在此期间,活动位于所有其他活动之前并与用户交互。

因此我认为onResume是打开抽屉的最佳场所。