利用nineoldandroids-2.4.0.jar和实现侧滑抽屉菜单

一.效果图


二.准备工作

2.1 导入nineoldandroids-2.4.0.jar包

2.2 中间的白色界面 MyFrameLayout  

 public class MyFrameLayout extends FrameLayout {
        private MyMainDragView dl;

        public MyFrameLayout(Context context) {
            super(context);
        }

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

        public MyFrameLayout(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }

        public void setDragLayout(MyMainDragView dl) {
            this.dl = dl;
        }

        @Override
        public boolean onInterceptTouchEvent(MotionEvent event) {
            if (dl.getStatus() != MyMainDragView.Status.Close) {
                return true;
            }
            return super.onInterceptTouchEvent(event);
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            if (dl.getStatus() != MyMainDragView.Status.Close) {
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    dl.close();
                }
                return true;
            }
            return super.onTouchEvent(event);
        }

    }

2.3 抽屉样式的自定义View

public class MyMainDragView extends FrameLayout {

    private boolean isShowShadow = true;
    private boolean isCanSlide=true;

    private GestureDetectorCompat gestureDetector;
    private ViewDragHelper dragHelper;
    private DragListener dragListener;
    private int range;
    private int width;
    private int height;
    private int mainLeft;
    private Context context;
    private ImageView iv_shadow;
    private RelativeLayout vg_left;
    private MyFrameLayout vg_main;
    private Status status = Status.Close;

    public MyMainDragView(Context context) {
        this(context, null);
    }

    public MyMainDragView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
        this.context = context;
    }

    public MyMainDragView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        gestureDetector = new GestureDetectorCompat(context, new YScrollDetector());
        dragHelper = ViewDragHelper.create(this, dragHelperCallback);
    }

    class YScrollDetector extends GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float dx, float dy) {
            return Math.abs(dy) <= Math.abs(dx);
        }
    }

    private ViewDragHelper.Callback dragHelperCallback = new ViewDragHelper.Callback() {

        @Override
        public int clampViewPositionHorizontal(View child, int left, int dx) {
            if (mainLeft + dx < 0) {
                return 0;
            } else if (mainLeft + dx > range) {
                return range;
            } else {
                return left;
            }
        }

        @Override
        public boolean tryCaptureView(View child, int pointerId) {
            return isCanSlide;
        }

        @Override
        public int getViewHorizontalDragRange(View child) {
            return width;
        }

        @Override
        public boolean onEdgeLock(int edgeFlags) {
            return false;
        }

        @Override
        public void onViewReleased(View releasedChild, float xvel, float yvel) {
            super.onViewReleased(releasedChild, xvel, yvel);
            if (xvel > 0) {
                open();
            } else if (xvel < 0) {
                close();
            } else if (releasedChild == vg_main && mainLeft > range * 0.3) {
                open();
            } else if (releasedChild == vg_left && mainLeft > range * 0.7) {
                open();
            } else {
                close();
            }
        }

        @Override
        public void onViewPositionChanged(View changedView, int left, int top,
                                          int dx, int dy) {
            if (changedView == vg_main) {
                mainLeft = left;
            } else {
                mainLeft = mainLeft + left;
            }
            if (mainLeft < 0) {
                mainLeft = 0;
            } else if (mainLeft > range) {
                mainLeft = range;
            }

            if (isShowShadow) {
                iv_shadow.layout(mainLeft, 0, mainLeft + width, height);
            }
            if (changedView == vg_left) {
                vg_left.layout(0, 0, width, height);
                vg_main.layout(mainLeft, 0, mainLeft + width, height);
            }

            dispatchDragEvent(mainLeft);
        }
    };

    public interface DragListener {
        public void onOpen();

        public void onClose();

        public void onDrag(float percent);
    }

    public void setDragListener(DragListener dragListener) {
        this.dragListener = dragListener;
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        if (isShowShadow) {
            iv_shadow = new ImageView(context);
//            iv_shadow.setImageResource(R.drawable.shadow);
            LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
            addView(iv_shadow, 1, lp);
        }
        vg_left = (RelativeLayout) getChildAt(0);
        vg_main = (MyFrameLayout) getChildAt(isShowShadow ? 2 : 1);
        vg_main.setDragLayout(MyMainDragView.this);
        vg_left.setClickable(true);
        vg_main.setClickable(true);
    }

    public ViewGroup getVg_main() {
        return vg_main;
    }

    public ViewGroup getVg_left() {
        return vg_left;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = vg_left.getMeasuredWidth();
        height = vg_left.getMeasuredHeight();
        range = (int) (width * 0.5f);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        vg_left.layout(0, 0, width, height);
        vg_main.layout(mainLeft, 0, mainLeft + width, height);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return dragHelper.shouldInterceptTouchEvent(ev) && gestureDetector.onTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        try {
            dragHelper.processTouchEvent(e);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return false;
    }

    public  void setIsCanSlide(boolean  isCanSlide){
        this.isCanSlide=isCanSlide;
    }

    private void dispatchDragEvent(int mainLeft) {
        if (dragListener == null) {
            return;
        }
        float percent = mainLeft / (float) range;
        animateView(percent);
        dragListener.onDrag(percent);
        Status lastStatus = status;
        if (lastStatus != getStatus() && status == Status.Close) {
            dragListener.onClose();
        } else if (lastStatus != getStatus() && status == Status.Open) {
            dragListener.onOpen();
        }
    }

    private void animateView(float percent) {
        float f1 = 1 - percent * 0.1f;
        ViewHelper.setScaleX(vg_main, f1);
        ViewHelper.setScaleY(vg_main, f1);
        ViewHelper.setTranslationX(vg_left, -vg_left.getWidth() / 2.3f + vg_left.getWidth() / 2.3f * percent);
        ViewHelper.setScaleX(vg_left, 0.5f + 0.5f * percent);
        ViewHelper.setScaleY(vg_left, 0.5f + 0.5f * percent);
        ViewHelper.setAlpha(vg_left, percent);
        if (isShowShadow) {
            ViewHelper.setScaleX(iv_shadow, f1 * 1.4f * (1 - percent * 0.12f));
            ViewHelper.setScaleY(iv_shadow, f1 * 1.85f * (1 - percent * 0.12f));
        }
//        getBackground().setColorFilter(evaluate(percent, Color.BLACK, Color.TRANSPARENT), Mode.SRC_OVER);
    }

    private Integer evaluate(float fraction, Object startValue, Integer endValue) {
        int startInt = (Integer) startValue;
        int startA = (startInt >> 24) & 0xff;
        int startR = (startInt >> 16) & 0xff;
        int startG = (startInt >> 8) & 0xff;
        int startB = startInt & 0xff;
        int endInt = (Integer) endValue;
        int endA = (endInt >> 24) & 0xff;
        int endR = (endInt >> 16) & 0xff;
        int endG = (endInt >> 8) & 0xff;
        int endB = endInt & 0xff;
        return (int) ((startA + (int) (fraction * (endA - startA))) << 24)
                | (int) ((startR + (int) (fraction * (endR - startR))) << 16)
                | (int) ((startG + (int) (fraction * (endG - startG))) << 8)
                | (int) ((startB + (int) (fraction * (endB - startB))));
    }

    @Override
    public void computeScroll() {
        if (dragHelper.continueSettling(true)) {
            ViewCompat.postInvalidateOnAnimation(this);
        }
    }

    public enum Status {
        Drag, Open, Close
    }

    public Status getStatus() {
        if (mainLeft == 0) {
            status = Status.Close;
        } else if (mainLeft == range) {
            status = Status.Open;
        } else {
            status = Status.Drag;
        }
        return status;
    }

    public void open() {
        open(true);
    }

    public void open(boolean animate) {
        if (animate) {
            if (dragHelper.smoothSlideViewTo(vg_main, range, 0)) {
                ViewCompat.postInvalidateOnAnimation(this);
            }
        } else {
            vg_main.layout(range, 0, range * 2, height);
            dispatchDragEvent(range);
        }
    }

    public void close() {
        close(true);
    }

    public void close(boolean animate) {
        if (animate) {
            if (dragHelper.smoothSlideViewTo(vg_main, 0, 0)) {
                ViewCompat.postInvalidateOnAnimation(this);
            }
        } else {
            vg_main.layout(0, 0, width, height);
            dispatchDragEvent(0);
        }
    }

}

2.4 主界面布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
                android:layout_height="match_parent" tools:context=".MainActivity">
    <com.example.linda.yami30.myView.MyMainDragView
        android:id="@+id/my_drawer"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="#28292e">
        <!-- 左侧滑动栏 -->
        <RelativeLayout
            android:id="@+id/main_left_drawer_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:paddingBottom="50dip" >
        </RelativeLayout>
        <com.example.linda.yami30.myView.MyFrameLayout
            android:id="@+id/main_content_frame_parent"
            android:background="#eeeeee"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </com.example.linda.yami30.myView.MyMainDragView>
    <com.example.linda.yami30.myView.MyBottomBar
        android:id="@+id/myBottomBar"
        android:layout_width="fill_parent"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"/>

</RelativeLayout>

2.4 主界面

public class MainActivity extends FragmentActivity {
    private MyTopBar mMyTopBar;
    private MyMainDragView mMyMainDragView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initDrawLayout();//初始化抽屉
        initMainView();//初始化 中间的fragment
    }

    private void initDrawLayout() {
        mMyMainDragView=(MyMainDragView)findViewById(R.id.my_drawer);
        mMyMainDragView.setDragListener(new MyMainDragView.DragListener() {
            @Override
            public void onOpen() {

            }

            @Override
            public void onClose() {

            }

            @Override
            public void onDrag(float percent) {

            }
        });
    }
    //中间白色布局初始化,可随意设置一个 MainFragment
    private void initMainView() {
        MainFragment  mainFragment=new MainFragment();
        FragmentManager fragmentManager = getSupportFragmentManager ();
        FragmentTransaction f_transaction = fragmentManager.beginTransaction ();
        f_transaction.replace(R.id.main_content_frame_parent, mainFragment);
        f_transaction.commit();
    }

}

三.  具体使用

3.1  MyMainDragView要进行监听才能有效果图中的滑动效果,也就是2.4 中的 mMyMainDragView.setDragListener(new MyMainDragView.DragListener() {......}

3.2 此时抽屉处于打开状态

 if(mMyMainDragView.getStatus () == MyMainDragView.Status.Open){}
3.3 此时抽屉处于关闭状态

if(mMyMainDragView.getStatus()==MyMainDragView.Status.Close)

3.4 关闭抽屉 

mMyMainDragView.close();
打开抽屉

 mMyMainDragView.open();
3.5 中间的fragment 可以根据自己的需要进行自定义,此处我用的是创建的一个fragment---- MainFragment,(MainFragment  继承fragment)其中具体布局,根据自己需要而定

四  总结

有时间试试中间界面能不能用Activity,这样才比较实用

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

十点了,好累,回去了,虽然还有很多东西要学,可是太晚了,一个人路上好不安全的,苦逼的程序媛




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值