SlidingPaneLayout:没有平滑动画的幻灯片?

时间:2013-07-03 20:51:40

标签: android slidingpanelayout

我正在使用最新支持库中提供的新SlidingPaneLayout,该库提供了openPane()closePane()方法来平滑打开和关闭面板。不幸的是,没有动画就没有公开的方法。

还有办法还是这样吗?我有一种感觉反思可能是必要的。

P.S。该文件位于sdk/extras/android/support/v4/src/java/android/support/v4/widget/

1 个答案:

答案 0 :(得分:2)

我最后编写了一个提供两种方法的子类openPaneNoAnimation()closePaneNoAnimation()。是的,这是反思,可能会停止与未来的支持库一起工作,但是现在它可以完成这项工作。最糟糕的情况是,这些方法可以追溯到使用openPane()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();
        }
    }

}