QQ5.0的侧滑效果和viewdrawhelper的简单使用

1自定义MySlidingMenu

public class MySlidingMenu extends FrameLayout {}

1.1在MainActivity中使用

<com.myname.qq50.MySlidingMenu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/sliding"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <include layout="@layout/layout_menu" />
    <include layout="@layout/layout_main" />
</com.myname.qq50.MySlidingMenu>

1.2 布局layout_main

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#fff"
    android:orientation="vertical">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:background="#18B4ED">

        <ImageView
            android:id="@+id/iv_head"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="30dp"
            android:src="@mipmap/head" />
    </FrameLayout>

    <ListView
        android:id="@+id/main_listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

1.3layout_menu

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingLeft="15dp">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:background="@mipmap/head" />

    <ListView
        android:id="@+id/menu_listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="5dp"></ListView>

</LinearLayout>

自定义控件MyslidingMenu

1.1今天比较懒就不一步一步写了


/**
 * Created by Administrator on 2017/1/18.
 */

public class MySlidingMenu extends FrameLayout {

    private View menu;
    private View main;
    private ViewDragHelper viewDragHelper;
    private int maxLeft;
    private onSlidingMenuListen listener;

    public MySlidingMenu(Context context, AttributeSet attrs) {
        this(context, attrs, -1);
    }

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

    public MySlidingMenu(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

//加viewdrawhelper 是为了处理 触摸事件
        //ViewDragHelper是一个用于编写自定义ViewGroups的实用程序类。它提供了一些
        // 有用的操作和状态允许用户拖动和重新定位,追踪
        //他们的父母的ViewGroup之内的意见。
        viewDragHelper = ViewDragHelper.create(this, callback);
    }

    /*
     *2017/1/18 18:47
     *当加载完布局结束标签的时候,调用的方法,表示布局加载完控件
     * 这个时候是没有执行测量款到,所以获取不到宽高
     */
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        menu = getChildAt(0);
        main = getChildAt(1);
    }

    ViewDragHelper.Callback callback = new ViewDragHelper.Callback() {

        private int newLeft;

        /*
                         *2017/1/18 18:56
                         *
                         */
        @Override
        public void onViewDragStateChanged(int state) {
            super.onViewDragStateChanged(state);
        }

        /**
         * 当view位置改变的时候调用的方法
         * @param changedView
         * @param left
         * @param top
         * @param dx
         * @param dy
         */
        @Override
        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
            super.onViewPositionChanged(changedView, left, top, dx, dy);
            //当 滑动内容页的时可以滑动,菜单页的位置不改变 只是缩放
            if (changedView == menu) {
                //设置菜单页位置不能改变
                //对 子控件重新排版,是位置固定
                menu.layout(0, 0, menu.getMeasuredWidth(), menu.getMeasuredHeight());
                //更改内容页面的位置
                newLeft = main.getLeft() + dx;
                newLeft = getLeft(newLeft);
                main.layout(newLeft, 0, main.getMeasuredWidth() + newLeft, main.getMeasuredHeight());
            }

            //根据缩放的百分比进行缩放效果的实现
            float fraction = main.getLeft() * 1f / maxLeft;
            execAnim(fraction);
            //通过回调将百分比传递给activity
            if (listener != null) {
                listener.setRotate(fraction);
                if (fraction == 0f) {

                    listener.setIsOpen(false);
                } else if (fraction == 1f) {
                    listener.setIsOpen(true);
                }
            }
        }

        //捕获触摸事件调用的       @Override
        public void onViewCaptured(View capturedChild, int activePointerId) {
            super.onViewCaptured(capturedChild, activePointerId);
        }

        /**
         * 手指抬起的时候
         * @param releasedChild
         * @param xvel  速度
         * @param yvel
         */
        @Override
        public void onViewReleased(View releasedChild, float xvel, float yvel) {
            super.onViewReleased(releasedChild, xvel, yvel);
            //当手指松开的时候,回弹
            if (main.getLeft() > maxLeft / 2) {
                //平滑回弹效果
                viewDragHelper.smoothSlideViewTo(main, maxLeft, 0);
                //安卓提供的兼容性方法,效果跟invalidate一样是重新触发滚动
                ViewCompat.postInvalidateOnAnimation(MySlidingMenu.this);
            } else {
                viewDragHelper.smoothSlideViewTo(main, 0, 0);
                ViewCompat.postInvalidateOnAnimation(MySlidingMenu.this);
            }
        }

        /**
         * 设置是否强制进行水平滑动,如果需要强制水平滑动,返回大于0的值
         * @param child
         * @return
         */
        @Override
        public int getViewHorizontalDragRange(View child) {
            return 1;
        }

        /*
         *2017/1/18 18:57        设置时候可以捕获view的触摸事件
         *  触摸事件的view对象        多点触摸的索引
         *
         */
        @Override
        public boolean tryCaptureView(View child, int pointerId) {
            return true;
        }

        /**
         * 当view滑动的时候调用的方法
         * @param child
         * @param left  viewdraghelper认为我们要将控件移动的距离
         * @param dx 手指滑动的距离
         * @return实际我们想让控件移动的距离
         */
        @Override
        public int clampViewPositionHorizontal(View child, int left, int dx) {
            if (child == main) {
                left = getLeft(left);
            }
            return left;
        }
    };

    private void execAnim(float fraction) {
        //floatevaluator float类型的估值器根据百分比计算出对应的值
        //argbRvaluator 颜色的估值器
        ArgbEvaluator argbEvaluator = new ArgbEvaluator();
        //缩放的值=开始的值+(结束的值-开始的值)*缩放的百分比
        Float evaluate = new FloatEvaluator().evaluate(fraction, 1.0f, 0.8f);
        //首页缩放的操作
        main.setScaleX(evaluate);
        main.setScaleY(evaluate);
        //菜单页 的缩放操作  0.3f->1.0f 除了有缩放 还有偏移从一半开始偏移
        menu.setScaleX(new FloatEvaluator().evaluate(fraction, 0.3, 1.0f));
        menu.setScaleY(new FloatEvaluator().evaluate(fraction, 0.3, 1.0f));
        menu.setTranslationX(new FloatEvaluator().evaluate(fraction, -menu.getMeasuredWidth() / 2, 0));
        //设置背景的滤镜效果  渐变操作
        if (getBackground() != null) {
            int color = (int) argbEvaluator.evaluate(fraction, Color.BLACK, Color.TRANSPARENT);
            //覆盖的类型.PorterDuff.Mode.SRC
            //显示上层绘制图片
            getBackground().setColorFilter(color, PorterDuff.Mode.SRC_OVER);
        }

    }

    //重写 -computescroll才会实现回弹
    @Override
    public void computeScroll() {
        super.computeScroll();
        //判断是否可以继续滑动
        if (viewDragHelper.continueSettling(true)) {
            ViewCompat.postInvalidateOnAnimation(MySlidingMenu.this);
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        maxLeft = (int) (getMeasuredWidth() * 0.6f);
    }

    /**
     * 将触摸事件 传递给viewdraghelper ,方便进行触摸 滑动操作
     * 如果ominterceptouchevent拦截事件,ontouch里面的方法不执行
     * 所以为了保证触摸时间可以完全传递到viewdraghelper 我们需要对两个方法进行重写
     *
     * @param ev
     * @return
     */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        boolean result = viewDragHelper.shouldInterceptTouchEvent(ev);
        return result;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //需要将出迷时间传递给viewdrawhelper
        viewDragHelper.processTouchEvent(event);
        return true;
    }

    public int getLeft(int left) {
        if (left < 0) {
            left = 0;
        } else if (left > maxLeft) {
            left = maxLeft;
        }
        return left;
    }

    public void setonSlidingMenuListener(onSlidingMenuListen listener) {
        this.listener = listener;
    }

    //通过设置回调设置imageview的旋转和打开操作  在自定义方法中
    //创建回调方法 将百分比传给activity使用 
    public interface onSlidingMenuListen {
        public void setRotate(float fraction);

        public void setIsOpen(boolean isOpen);

    }

}

1.2mainActivity中的逻辑

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ListView menuListView = (ListView) findViewById(R.id.menu_listview);
        final ListView mainListView = (ListView) findViewById(R.id.main_listview);
        final ImageView imageview= (ImageView) findViewById(R.id.iv_head);
        MySlidingMenu slidingMenu = (MySlidingMenu) findViewById(R.id.sliding);
        mainListView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,Constant.NAMES));
        menuListView.setAdapter(new ArrayAdapter<String >(this,android.R.layout.simple_list_item_1,Constant.sCheeseStrings){
            @NonNull
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                TextView textView = (TextView) super.getView(position, convertView, parent);
                textView.setTextColor(Color.WHITE);
                return textView;
            }
        });
        slidingMenu.setonSlidingMenuListener(new MySlidingMenu.onSlidingMenuListen() {
            @Override
            public void setRotate(float fraction) {
                imageview.setRotation(360*fraction);
            }

            @Override
            public void setIsOpen(boolean isOpen) {
                if (isOpen) {
                    Toast.makeText(MainActivity.this,"开",Toast.LENGTH_SHORT).show();
                }else{

                    Toast.makeText(MainActivity.this,"关",Toast.LENGTH_SHORT).show();
                }
            }
        });

    }
}

1.4参数

public interface Constant {
    public static final String[] sCheeseStrings = {
            "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
            "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale",
            "Aisy Cendre", "Allgauer Emmentaler", "Alverca", "Ambert", "American Cheese",
            "Ami du Chambertin", "Anejo Enchilado", "Anneau du Vic-Bilh", "Anthoriro", "Appenzell",
            "Aragon", "Ardi Gasna", "Ardrahan", "Armenian String", "Aromes au Gene de Marc",
            "Cougar Gold", "Coulommiers", "Coverdale", "Crayeux de Roncq", "Cream Cheese",
            "Cream Havarti", "Crema Agria", "Crema Mexicana", "Creme Fraiche", "Crescenza",
            "Croghan", "Crottin de Chavignol", "Crottin du Chavignol", "Crowdie", "Crowley",
            "Zamorano", "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"
    };

    public static final String[] NAMES = new String[]{"宋江", "卢俊义", "吴用",
            "公孙胜", "关胜", "林冲", "秦明", "呼延灼", "花荣", "柴进", "李应", "朱仝", "鲁智深",
            "武松", "董平", "张清", "杨志", "徐宁", "索超", "戴宗", "刘唐", "李逵", "史进", "穆弘",
            "雷横", "李俊", "阮小二", "张横", "阮小五", " 张顺", "阮小七", "杨雄", "石秀", "解珍",
            " 解宝", "燕青", "朱武", "黄信", "孙立", "宣赞", "郝思文", "韩滔", "彭玘", "单廷珪",
            "魏定国", "萧让", "裴宣", "欧鹏", "邓飞", " 燕顺", "杨林", "凌振", "蒋敬", "吕方",
            "郭 盛", "安道全", "皇甫端", "王英", "扈三娘", "鲍旭", "樊瑞", "孔明", "孔亮", "项充",
            "李衮", "金大坚", "马麟", "童威", "童猛", "孟康", "侯健", "陈达", "杨春", "郑天寿",
            "陶宗旺", "宋清", "乐和", "龚旺", "丁得孙", "穆春", "曹正", "宋万", "杜迁", "薛永", "施恩",
    };
}

效果

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值