[开源解析]Yalantis/Side-Menu.Android

一、效果分析

[开源解析]Yalantis/Side-Menu.Android_第1张图片
效果图1
[开源解析]Yalantis/Side-Menu.Android_第2张图片
效果图2
布局:
  • DrawerLayout+Fragment
重点:
  • 侧边栏的数据结构(名称+资源文件)
  • 侧边栏的动画效果(点击ActionBar中的home按钮,显示侧边栏时的旋转效果)

二、自定义DrawerLayout侧边栏

DrawLayout需要注意两点:

  1. DrawerLayout最好是跟布局
  2. DrawerLayout中的子布局先后顺序要注意,抽屉布局要放在最后,因为DrawerLayout布局和RelativeLayout布局类似,后写的布局会覆盖前面的布局。

三、侧边栏结构设计

Interface:

public interface Resourceble {
    public int getImageRes();       //图片资源文件,引用时放在项目的drawable文件夹下
    public String getName();        //每个资源文件对应的名称
}

数据模型类:

public class SlideMenuItem implements Resourceble {
    private String name;
    private int imageRes;

    public SlideMenuItem(String name, int imageRes) {
        this.name = name;
        this.imageRes = imageRes;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getImageRes() {
        return imageRes;
    }

    public void setImageRes(int imageRes) {
        this.imageRes = imageRes;
    }
}

四、侧边栏动画设计

侧边栏的每一个Item都是SlideMenuItem实例。每个SlideMenuItem的动画效果是沿着Y轴旋转90度(显示是逆时针90°,隐藏是顺时针90°),为了动画的平滑效果,用到了加速插值器。

  • 自定义Animation
    FlipAnimation类,extends Animation。重写了initialize(),applyTransformation()方法。动画的平移,旋转,透明度变化都在applyTransformation中实现。注意代码中注释的角度计算,是重点。每个Item都是围绕Y轴做了旋转操作,度数都是90度。关键在于:
    1 如何做到显示和隐藏的角度计算?
    2 如何平滑显示和隐藏?
    3 每一个Item的动画效果延迟是如何实现的?
@Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        final float fromDegrees = mFromDegrees;
        
        //interpolatedTime范围固定0-1。
        //显示:mToDegrees为90, mFromDegrees为0,变化范围是-90度--->0度
        //隐藏:mToDegrees为0, mFromDegrees为90,变化范围是0度--->-90度
        float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);

        final float centerX = mCenterX;
        final float centerY = mCenterY;
        final Camera camera = mCamera;

        final Matrix matrix = t.getMatrix();
        camera.save();
        camera.rotateY(degrees);
        camera.getMatrix(matrix);
        camera.restore();

        matrix.preTranslate(-centerX, -centerY);
        matrix.postTranslate(centerX, centerY);

    }

显示抽屉菜单,代码可见,平滑动画的出现是因为使用了加速插值器rotation.setInterpolator(new AccelerateInterpolator());

private void animateView(int position) {
        final View view = viewList.get(position);
        view.setVisibility(View.VISIBLE);
        FlipAnimation rotation =
                new FlipAnimation(90, 0, 0.0f, view.getHeight() / 2.0f);
        rotation.setDuration(ANIMATION_DURATION);                           //175ms
        rotation.setFillAfter(true);
        rotation.setInterpolator(new AccelerateInterpolator());
        rotation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                view.clearAnimation();
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
        view.startAnimation(rotation);
    }

每一个Item动画交替出现是用了Handler延迟调用,最后的Fragment的图片切换效果是用了一个开源的库RevealFrameLayout

for (int i = 0; i < size; i++) {
  略...
  new Handler().postDelayed(new Runnable() {
                public void run() {
                    if (position < viewList.size()) {
                        animateView((int) position);
                    }
                    if (position == viewList.size() - 1) {                  //最后一个Item
                        screenShotable.takeScreenShot();               //调用接口的方式来改变Fragment中的图片(这个其实也是点击之后才发生的效果)
                        setViewsClickable(true);
                    }
                }
            }, (long) delay);
}

你可能感兴趣的:([开源解析]Yalantis/Side-Menu.Android)