0

I'm using the new SlidingPaneLayout available in the latest support library, which provides the openPane() and closePane() methods to smooth open and close the panel. Unfortunately, there are no public methods to do so without animation.

Is there a way to still do this? I have a feeling reflection may be necessary.

P.S. The file is available under sdk/extras/android/support/v4/src/java/android/support/v4/widget/.

4

1 回答 1

2

我最终编写了一个提供两种方法的子类,openPaneNoAnimation()并且closePaneNoAnimation(). 是的,它是反射,并且可能会停止使用未来的支持库,但现在它可以完成这项工作。最坏的情况下,这些方法会退回到使用openPane()and closePane()

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import android.content.Context;
import android.support.v4.widget.SlidingPaneLayout;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class AnimationlessSlidingPaneLayout extends SlidingPaneLayout {
    private boolean mSlideEnabled = true;
    private Field mSlideOffsetField = null;
    private Field mSlideableViewField = null;
    private Method updateObscuredViewsVisibilityMethod = null;
    private Method dispatchOnPanelOpenedMethod = null;
    private Method dispatchOnPanelClosedMethod = null;
    private Field mPreservedOpenStateField = null;
    private Method parallaxOtherViewsMethod = null;

    public AnimationlessSlidingPaneLayout(Context context) {
        this(context, null, 0);
    }

    public AnimationlessSlidingPaneLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public AnimationlessSlidingPaneLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        try {
            mSlideOffsetField = SlidingPaneLayout.class.getDeclaredField("mSlideOffset");
            mSlideableViewField = SlidingPaneLayout.class.getDeclaredField("mSlideableView");
            updateObscuredViewsVisibilityMethod = SlidingPaneLayout.class.getDeclaredMethod("updateObscuredViewsVisibility",
                                                                                            View.class);
            dispatchOnPanelClosedMethod = SlidingPaneLayout.class.getDeclaredMethod("dispatchOnPanelClosed", View.class);
            dispatchOnPanelOpenedMethod = SlidingPaneLayout.class.getDeclaredMethod("dispatchOnPanelOpened", View.class);
            mPreservedOpenStateField = SlidingPaneLayout.class.getDeclaredField("mPreservedOpenState");
            parallaxOtherViewsMethod = SlidingPaneLayout.class.getDeclaredMethod("parallaxOtherViews", float.class);

            mSlideOffsetField.setAccessible(true);
            mSlideableViewField.setAccessible(true);
            updateObscuredViewsVisibilityMethod.setAccessible(true);
            dispatchOnPanelOpenedMethod.setAccessible(true);
            dispatchOnPanelClosedMethod.setAccessible(true);
            mPreservedOpenStateField.setAccessible(true);
            parallaxOtherViewsMethod.setAccessible(true);
        } catch (Exception e) {
            Log.w("ASPL", "Failed to set up animation-less sliding layout.");
        }
    }

    public void openPaneNoAnimation() {
        try {
            View slideableView = (View) mSlideableViewField.get(this);
            mSlideOffsetField.set(this, 1.0f);
            parallaxOtherViewsMethod.invoke(this, 1.0f);
            requestLayout();
            invalidate();
            dispatchOnPanelOpenedMethod.invoke(this, slideableView);
            mPreservedOpenStateField.set(this, true);
        } catch (Exception e) {
            openPane();
        }
    }

    public void closePaneNoAnimation() {
        try {
            View slideableView = (View) mSlideableViewField.get(this);
            mSlideOffsetField.set(this, 0.0f);
            parallaxOtherViewsMethod.invoke(this, 0.0f);
            requestLayout();
            invalidate();
            updateObscuredViewsVisibilityMethod.invoke(this, slideableView);
            dispatchOnPanelClosedMethod.invoke(this, slideableView);
            mPreservedOpenStateField.set(this, false);
        } catch (Exception e) {
            closePane();
        }
    }

}
于 2013-07-07T18:05:04.573 回答