Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.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 加速';导航抽屉';关闭时的动画速度?_Android - Fatal编程技术网

Android 加速';导航抽屉';关闭时的动画速度?

Android 加速';导航抽屉';关闭时的动画速度?,android,Android,按预期实现和工作,因此这里确实没有值得发布的代码,只是想看看是否有人有加快抽屉打开和关闭时间的经验?例如,YouTube应用程序要快得多 您当然可以调整动画的持续时间,但这需要您从支持库中复制类,然后相应地编辑它们 ViewDragHelper 然后应用于抽屉布局 您需要创建一个修改版本的ViewDragHelper.forceSettleCapturedViewWat,该版本将在duration参数中传递 forceSettleCapturedViewAt(... int duration)

按预期实现和工作,因此这里确实没有值得发布的代码,只是想看看是否有人有加快抽屉打开和关闭时间的经验?例如,YouTube应用程序要快得多

您当然可以调整动画的持续时间,但这需要您从支持库中复制类,然后相应地编辑它们

ViewDragHelper

然后应用于
抽屉布局

您需要创建一个修改版本的
ViewDragHelper.forceSettleCapturedViewWat
,该版本将在duration参数中传递

forceSettleCapturedViewAt(... int duration)
然后创建您的
ViewDragHelper.smoothSlideViewWTO
版本

public boolean smoothSlideViewTo(... int duration) {
        ...
        return forceSettleCapturedViewAt(... int duration);
    }
抽屉布局

接下来,您需要修改并匹配新的
ViewDragHelper
修改

ActionBarDrawerToggle


您还必须复制
ActionBarDrawerToggle
ActionBarDrawerToggle
。但这些文件不需要任何编辑

首先从下面的链接下载sourcode文件

将上述两个文件粘贴到您的应用程序util包中(或您想要的位置),并在活动中引用此抽屉布局,而不是android.support.v4.widget.DrawerLayout在活动的布局文件中更改抽屉布局引用

现在调整

对于ViewDrawerHelper,要加速,只需增加值;要降低,只需减少值。

mLeftDrawer.ItemClick += delegate (object sender, Android.Widget.AdapterView.ItemClickEventArgs e)
        {
            // Mark that item is selected and ask redraw
            e.View.Selected = true;
            adapter.NotifyDataSetChanged();

            var handler = new Handler();
            handler.PostDelayed(new Java.Lang.Runnable(() =>
            {
                _mLeftDrawerLayout.CloseDrawers();

                // Here you should call your activity
            }), 100);

        };
如果您想在操作栏切换按钮上添加操作,请从下面的链接下载的源文件

并将上述文件粘贴到您的应用程序util包(或您想要的地方)注意:-确保每个新添加文件的导入包引用的是应用程序项目中的文件,而不是android.support.v4.widget。*


如果上面的链接不起作用,请添加http://

如果要在没有任何动画的情况下强制立即消失左侧面板,只需设置其x值即可。抽屉布局打开时,其左侧面板的x值变为0,关闭时变为-1*(其宽度)。所以,如果在打开时将x值设置为-2*width,左面板将立即消失。当然,在它关闭后,不要忘记将x设置为-1*宽度。 例如:

DisplayMetrics metrics = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(metrics);
//obtain left panel's width in px
private float mToggleStartX=-260*metrics.density; //260 is the width of left panel in dpi

//while drawer layout is opened, to disappear left panel
ll_drawerLayoutMenuPanel.setX(mToggleStartX*2); //ll_drawerLayoutMenuPanel is the left panel layout
mDrawerLayout.closeDrawers();

//don't forget reset x value in the onDrawerClosed method.
mDrawerToggle = new ActionBarDrawerToggle(this,mDrawerLayout,mainToolBar,R.string.drawer_open,R.string.drawer_close) {
    public void onDrawerClosed(View view) {
        super.onDrawerClosed(view);

        ll_drawerLayoutMenuPanel.setX(mToggleStartX);
    }
    ......
};

加速动画并等待动画完成的另一种方法是首先避免动画:只需调用
startActivity()
,而不调用
closeDrawer()
。虽然您没有看到抽屉关闭,但活动转换动画仍然提供了一个非常好的效果,它立即发生,无需等待抽屉关闭动画首先完成设置,没有波动,感知延迟更短


细节 (如果您只想查看代码,可以跳过此说明。)

要实现此功能,您需要一种方法,在使用“后退”按钮导航回“活动”时,无需任何关闭动画即可关闭抽屉。(不调用
closeDrawer()
将使该活动实例中的抽屉保持打开状态;一种相对浪费的解决方法是在返回时强制活动
重新创建()您还需要确保只有在导航后返回时才关闭抽屉,而不是在方向改变后,但这很容易

尽管从
onCreate()
调用
closeDrawer()
将使抽屉在没有任何动画的情况下开始关闭,但从
onResume()
调用时情况并非如此。从
onResume()
调用
closeDrawer()
将关闭抽屉,用户可以立即看到动画
DrawerLayout
不提供任何方法来关闭没有该动画的抽屉,但可以添加一个

正如@syesilova指出的,关闭抽屉实际上只是将其从屏幕上滑下。因此,通过将抽屉直接移动到其“关闭”位置,可以有效地跳过动画。平移方向将根据重力的不同而变化(无论是左抽屉还是右抽屉),准确的位置取决于抽屉的大小,一旦它与所有子抽屉一起布置好

然而,仅仅移动它是不够的,因为
DrawerLayout
在extended
LayoutParams
中保留一些内部状态,它使用这些状态来知道抽屉是否打开。如果你只是把抽屉从屏幕上移开,它就不会知道它已经关闭了,这会导致其他问题。(例如,抽屉将在下一次方向更改时重新出现。)

由于您正在将支持库编译到应用程序中,因此您可以在
android.support.v4.widget
包中创建一个类,以访问其默认(包专用)部分,或者扩展
DrawerLayout
,而无需复制它所需的任何其他类。这还将减少在将来更改支持库时更新代码的负担。(最好尽可能将代码与实现细节隔离。)可以使用
movedrawertoffset()
移动抽屉,并设置
LayoutParams
,使其知道抽屉已关闭


代码 这是将跳过动画的代码:

// move drawer directly to the closed position
moveDrawerToOffset(drawerView, 0.f); 

/* EDIT: as of v23.2.1 this direct approach no longer works
         because the LayoutParam fields have been made private...
// set internal state so DrawerLayout knows it's closed
final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams();
lp.onScreen = 0.f;
lp.knownOpen = false;

invalidate();
/*/
// ...however, calling closeDrawer will set those LayoutParams
//    and invalidate the view.
closeDrawer(drawerView);
/**/
@Overrid6e
protected void onResume() {
    super.onResume();

    if(mCloseNavDrawer && mDrawerLayout != null && mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
        Support4Widget.setDrawerClosed(mDrawerLayout, GravityCompat.START);
        mCloseNavDrawer = false;
    }
}
@Overrid6e
protected void onResume() {
    super.onResume();

    if(mCloseNavDrawer && mDrawerLayout != null && mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
        mDrawerLayout.setDrawerClosed(GravityCompat.START);
        mCloseNavDrawer = false;
    }
}
注意:如果只调用
moveDrawerToOffset()
而不更改
LayoutParams
,抽屉将在下一次方向更改时移回其打开位置


选项1(使用现有抽屉布局) 这种方法将实用程序类添加到support.v4包中,以获得对包pri的访问
@Overrid6e
protected void onResume() {
    super.onResume();

    if(mCloseNavDrawer && mDrawerLayout != null && mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
        Support4Widget.setDrawerClosed(mDrawerLayout, GravityCompat.START);
        mCloseNavDrawer = false;
    }
}
package android.support.v4.widget;

import android.content.Context;
import android.support.annotation.IntDef;
import android.support.v4.view.GravityCompat;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

public class CustomDrawerLayout extends DrawerLayout {

    /** @hide */
    @IntDef({Gravity.LEFT, Gravity.RIGHT, GravityCompat.START, GravityCompat.END})
    @Retention(RetentionPolicy.SOURCE)
    private @interface EdgeGravity {}
    
    public CustomDrawerLayout(Context context) {
        super(context);
    }

    public CustomDrawerLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomDrawerLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    
    public void setDrawerClosed(View drawerView) {
        if (!isDrawerView(drawerView)) {
            throw new IllegalArgumentException("View " + drawerView + " is not a sliding drawer");
        }
        
        // move drawer directly to the closed position
        moveDrawerToOffset(drawerView, 0.f); 
        
        /* EDIT: as of v23.2.1 this no longer works because the
                 LayoutParam fields have been made private, but
                 calling closeDrawer will achieve the same result.
        
        // set internal state so DrawerLayout knows it's closed
        final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams();
        lp.onScreen = 0.f;
        lp.knownOpen = false;
        
        invalidate();
        /*/
        // Calling closeDrawer updates the internal state so DrawerLayout knows it's closed
        // and invalidates the view for us.
        closeDrawer(drawerView);
        /**/
    }

    public void setDrawerClosed(@EdgeGravity int gravity) {
        final View drawerView = findDrawerWithGravity(gravity);
        if (drawerView == null) {
            throw new IllegalArgumentException("No drawer view found with gravity " +
                    gravityToString(gravity));
        }

        // move drawer directly to the closed position
        moveDrawerToOffset(drawerView, 0.f); 
        
        /* EDIT: as of v23.2.1 this no longer works because the
                 LayoutParam fields have been made private, but
                 calling closeDrawer will achieve the same result.
        
        // set internal state so DrawerLayout knows it's closed
        final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams();
        lp.onScreen = 0.f;
        lp.knownOpen = false;

        invalidate();
        /*/
        // Calling closeDrawer updates the internal state so DrawerLayout knows it's closed
        // and invalidates the view for us.
        closeDrawer(drawerView);
        /**/
    }
}
<android.support.v4.widget.CustomDrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    >
public static final String CLOSE_NAV_DRAWER = "CLOSE_NAV_DRAWER";
private boolean mCloseNavDrawer;

@Override
public void onCreate(Bundle savedInstanceState) {
    // ...
    if (savedInstanceState != null) {
        mCloseNavDrawer = savedInstanceState.getBoolean(CLOSE_NAV_DRAWER);
    }
}

@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {

    // ...

    startActivity(intent);
    mCloseNavDrawer = true;
}

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    savedInstanceState.putBoolean(CLOSE_NAV_DRAWER, mCloseNavDrawer);
    super.onSaveInstanceState(savedInstanceState);
}   
@Overrid6e
protected void onResume() {
    super.onResume();

    if(mCloseNavDrawer && mDrawerLayout != null && mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
        mDrawerLayout.setDrawerClosed(GravityCompat.START);
        mCloseNavDrawer = false;
    }
}
drawerLayout.closeDrawer(Gravity.LEFT, false);
mLeftDrawer.ItemClick += delegate (object sender, Android.Widget.AdapterView.ItemClickEventArgs e)
        {
            // Mark that item is selected and ask redraw
            e.View.Selected = true;
            adapter.NotifyDataSetChanged();

            var handler = new Handler();
            handler.PostDelayed(new Java.Lang.Runnable(() =>
            {
                _mLeftDrawerLayout.CloseDrawers();

                // Here you should call your activity
            }), 100);

        };
@Override
public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.

        yourFunction();

        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                drawer.closeDrawer(GravityCompat.START);
            }
        }, 100);
        return true;
}