Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/221.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 抽屉布局';s项目单击-何时是替换片段的正确时间?_Android_Android Fragments_Navigation Drawer_Fragmenttransaction_Drawerlayout - Fatal编程技术网

Android 抽屉布局';s项目单击-何时是替换片段的正确时间?

Android 抽屉布局';s项目单击-何时是替换片段的正确时间?,android,android-fragments,navigation-drawer,fragmenttransaction,drawerlayout,Android,Android Fragments,Navigation Drawer,Fragmenttransaction,Drawerlayout,我正在开发一个使用导航抽屉模式(带抽屉布局)的应用程序 每次单击抽屉中的项目,都会替换主容器中的片段 但是,我不确定何时是执行片段事务的正确时间? 抽屉什么时候开始关上?还是在它关闭之后 在谷歌的网站中,你可以看到他们正在做交易 在项目之后单击,然后关闭抽屉。 结果,抽屉看起来很迟钝,不光滑,而且看起来很糟糕(这种情况也发生在我的应用程序中) 另一方面,在和应用程序中,似乎他们在抽屉关闭后进行交易(我说的对吗?)。 因此,抽屉不是拖拉的,也不是很平滑,但至少需要1秒钟(抽屉关闭所需的时间)才能看

我正在开发一个使用导航抽屉模式(带抽屉布局)的应用程序

每次单击抽屉中的项目,都会替换主容器中的片段

但是,我不确定何时是执行片段事务的正确时间? 抽屉什么时候开始关上?还是在它关闭之后

在谷歌的网站中,你可以看到他们正在做交易 在项目之后单击,然后关闭抽屉。
结果,抽屉看起来很迟钝,不光滑,而且看起来很糟糕(这种情况也发生在我的应用程序中)

另一方面,在和应用程序中,似乎他们在抽屉关闭后进行交易(我说的对吗?)。
因此,抽屉不是拖拉的,也不是很平滑,但至少需要1秒钟(抽屉关闭所需的时间)才能看到下一个片段

看起来,在立即进行碎片交易时,出票人是不可能平顺的

你觉得怎么样


提前谢谢

是的,非常同意,执行片段(带视图)事务会导致布局过程,从而导致视图上的janky动画被动画化,引用
DrawerLayout

DroperLayout.DroperListener可用于监视抽屉视图的状态和运动。避免在动画期间执行昂贵的操作,如布局,因为这可能会导致口吃;尝试在空闲状态下执行昂贵的操作


因此,请在抽屉关闭或有人修补支持库后执行碎片事务,以某种方式解决此问题:)

这是我为实现类似于Gmail应用程序的平滑事务动画所做的:

活动\u drawer.xml

<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" >

    <!-- The main content view -->
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <!-- The navigation drawer -->
    <ListView 
    android:id="@+id/left_drawer"
        android:layout_width="280dp"
        android:layout_height="match_parent"
        android:layout_gravity="left"
        android:choiceMode="singleChoice" />

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

希望对你有帮助!:-)

另一个解决方案是在关闭抽屉后创建一个
处理程序
,并发布一个延迟的
Runnable
,如下所示:。这种方法的好处是,与等待
DrawerListener\#onDrawerClosed()
相比,您的片段将被替换得更快,但当然,任意延迟并不能100%保证抽屉动画能够及时完成

这就是说,我使用了200毫秒的延迟,它工作得非常好

private class DrawerItemClickListener implements OnItemClickListener {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
        drawerLayout.closeDrawer(drawerList);
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                switchFragments(position); // your fragment transactions go here
            }
        }, 200);
    }
}
私有类DrawerItemClickListener实现了OnItemClickListener{
@凌驾
public void onItemClick(AdapterView父对象、视图、最终整型位置、长id){
抽屉布局。封闭抽屉(抽屉列表);
new Handler().postDelayed(new Runnable()){
@凌驾
公开募捐{
switchFragments(position);//您的片段事务转到这里
}
}, 200);
}
}

我知道这个问题很老,但我遇到了同样的问题,我想我会发布我的解决方案,因为我认为它比添加硬编码延迟时间更好。我所做的是在执行任务之前,使用
onDrawerClosed
函数验证抽屉是否已关闭

//on button click...
private void displayView(int position) {
    switch (position) {
    //if item 1 is selected, update a global variable `"int itemPosition"` to be 1
    case 1:
        itemPosition = 1;
        //();
        break;
    default:
        break;
    }

    // update selected item and title, then close the drawer
    mDrawerList.setItemChecked(position, true);
    mDrawerList.setSelection(position);
    mDrawerLayout.closeDrawer(mDrawerList); //close drawer
}
然后在绘图关闭中打开相应的活动

public void onDrawerClosed(View view) {
    getSupportActionBar().setTitle(mTitle);
    // calling onPrepareOptionsMenu() to show action bar icons
    supportInvalidateOptionsMenu();
    if (itemPosition == 1) {
        Intent intent = new Intent(BaseActivity.this, SecondActivity.class);
        startActivity(intent);
    }
}

如果您希望它平滑且没有任何延迟,请让抽屉保持打开状态,然后在返回时将其关闭(在onRestart()方法中)


返回时的副作用是(快速)动画,但这可能是可以接受的

只需在处理程序中编写代码并延迟200毫秒即可

 new Handler().postDelayed(new Runnable() {
  @Override
   public void run() {
       openSelectionDrawerItem(position);          
   }
 }, 200);

而不是延迟您的项目点击,这可能会使您的应用程序感觉缓慢。我会推迟mDrawerLayout的关闭。我也不会使用
DrawerLayout.OnDrawerListener onClose(…)
,因为调用这些回调非常慢

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        mDrawerLayout.closeDrawer(GravityCompat.START);
    }
}, 200);

我同意!当我让我的应用程序从抽屉的
onItemClick()
中启动新活动时,我会看到“快速关闭抽屉”动画。这可能是因为很多活动都发生在UI线程上。因此,现在我必须从
DrawerLayout.DrawerListener
内部启动一个新活动。。。正如您所提到的,这会降低用户体验。是否可以更改抽屉关闭动画的速度?速度似乎是一个重要的属性来暴露。。。但我在文档中找不到它!)@SomeoneSomewhere你可以更改动画长度,但这绝对不是一个优雅的解决方案:@SomeoneSomewhere我确实不喜欢急促的关闭动画,但我不喜欢让用户等待更长的时间。你可以看看这个解决方案:我喜欢这个解决方案,但我真的不知道如何让后堆栈行为正常工作。我可以在replace事务中添加“addToBackStack”,但由于之前的内容已被删除,因此这并没有达到预期效果。我试图隐藏而不是删除,但这也不起作用。@pbergqvist要获得后堆栈行为,您可以做的是:1。在删除“旧内容片段”之前,请使用另一个变量保存它。2.重写活动中的onBackPressed方法,并将其中的内容片段替换为“旧内容片段”。@pbergqvist更好的方法。如果将“remove fragment”事务、mChangeContentFragment=true和处理程序post都放在一个名为setContentFragment(fragment fragment)的方法中,则可以在onBackPressed中使用此方法,以避免重写同一代码两次。这对你有用吗?我想那会有用的,但只需要退一步。否则,我会让我自己维护一个堆栈。后堆栈不需要更改-谷歌的应用程序切换片段都不需要通过“后退”按钮。这很让人困惑。是不是只有支持库遇到了这个问题?如何等到状态变为状态_IDLE?这种方法会产生另一个描述的问题,在提交过程中崩溃,然后按下任务菜单you sir,你是个救命恩人:D在关闭抽屉和开始一项新活动之间还有一段时间。从什么地方回来?易居
 new Handler().postDelayed(new Runnable() {
  @Override
   public void run() {
       openSelectionDrawerItem(position);          
   }
 }, 200);
new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        mDrawerLayout.closeDrawer(GravityCompat.START);
    }
}, 200);