1116text(推拉门)

来源:互联网 发布:mac怎么重命名文件 编辑:程序博客网 时间:2024/04/28 15:23

先说发现的一个小问题:OnCreate()有两个,一个是public一个是protected,貌似以前也遇过这种问题,再深究
第二
赏析代码
这个推拉门主要是先创建左边布局的镜像文件,就是那个什么3D,把他垫在父布局左边,检测到滑动的时候给左边要显示的布局拍个照,然后对这个拍照图片把玩,目前我的理解是这个

import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Matrix;import android.util.AttributeSet;import android.view.View;import android.graphics.Camera;/** * Created by Administrator on 2015/11/14. */public class Image3dView extends View {    /**     * 源视图,用于生成图片对象。     */    private View sourceView;    /**     * 根据传入的源视图生成的图片对象。     */    private Bitmap sourceBitmap;    /**     * 源视图的宽度。     */    private float sourceWidth;    /**     * Matrix对象,用于对图片进行矩阵操作。     */    private Matrix matrix = new Matrix();    /**     * Camera对象,用于对图片进行三维操作。     */    private Camera camera = new Camera();    /**     * Image3dView的构造函数     *     * @param context     * @param attrs     */    public Image3dView(Context context, AttributeSet attrs) {        super(context, attrs);    }    /**     * 提供外部接口,允许向Image3dView传入源视图。     *     * @param view     *            传入的源视图     */    public void setSourceView(View view) {        sourceView = view;        sourceWidth = sourceView.getWidth();    }    /**     * 清除掉缓存的图片对象。     */    public void clearSourceBitmap() {        if (sourceBitmap != null) {            sourceBitmap = null;        }    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        if (sourceBitmap == null) {            getSourceBitmap();        }        // 计算图片需要旋转的角度        float degree = 90 - (90 / sourceWidth) * getWidth();        camera.save();        camera.rotateY(degree);        camera.getMatrix(matrix);        camera.restore();        // 将旋转的中心点移动到屏幕左边缘的中间位置        matrix.preTranslate(0,-getHeight() / 2);        matrix.postTranslate(0,getHeight() / 2);        canvas.drawBitmap(sourceBitmap, matrix, null);    }    /**     * 获取源视图对应的图片对象。     */    private void getSourceBitmap() {        if (sourceView != null) {            sourceView.setDrawingCacheEnabled(true);            sourceView.layout(0, 0, sourceView.getWidth(), sourceView.getHeight());            sourceView.buildDrawingCache();            sourceBitmap = sourceView.getDrawingCache();        }    }}

上面这个代码可以赏析一下:
camera的主要作用是产生一个Matrix,view根据这个来设置宽度长度等等
canvas.drawBitmap(sourceBitmap, matrix, null);
也就是画一个虚拟图

这就是我说的那个垫屁股的

package com.com.fish.transcation.add;import android.content.Context;import android.os.AsyncTask;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.VelocityTracker;import android.view.View;import android.view.ViewConfiguration;import android.view.ViewGroup;import android.view.WindowManager;import android.widget.RelativeLayout;import com.example.qqlike.R;/** * Created by Administrator on 2015/11/14. */public class ThreeDSlidingLayout extends RelativeLayout implements View.OnTouchListener {    /**     * 滚动显示和隐藏左侧布局时,手指滑动需要达到的速度。     */    public static final int SNAP_VELOCITY = 200;    /**     * 滑动状态的一种,表示未进行任何滑动。     */    public static final int DO_NOTHING = 0;    /**     * 滑动状态的一种,表示正在滑出左侧菜单。     */    public static final int SHOW_MENU = 1;    /**     * 滑动状态的一种,表示正在隐藏左侧菜单。     */    public static final int HIDE_MENU = 2;    /**     * 记录当前的滑动状态     */    private int slideState;    /**     * 屏幕宽度值。     */    private int screenWidth;    /**     * 右侧布局最多可以滑动到的左边缘。     */    private int leftEdge = 0;    /**     * 右侧布局最多可以滑动到的右边缘。     */    private int rightEdge = 0;    /**     * 在被判定为滚动之前用户手指可以移动的最大值。     */    private int touchSlop;    /**     * 记录手指按下时的横坐标。     */    private float xDown;    /**     * 记录手指按下时的纵坐标。     */    private float yDown;    /**     * 记录手指移动时的横坐标。     */    private float xMove;    /**     * 记录手指移动时的纵坐标。     */    private float yMove;    /**     * 记录手机抬起时的横坐标。     */    private float xUp;    /**     * 左侧布局当前是显示还是隐藏。只有完全显示或隐藏时才会更改此值,滑动过程中此值无效。     */    private boolean isLeftLayoutVisible;    /**     * 是否正在滑动。     */    private boolean isSliding;    /**     * 是否已加载过一次layout,这里onLayout中的初始化只需加载一次     */    private boolean loadOnce;    /**     * 左侧布局对象。     */    private View leftLayout;    /**     * 右侧布局对象。     */    private View rightLayout;    /**     * 在滑动过程中展示的3D视图     */    private Image3dView image3dView;    /**     * 用于监听侧滑事件的View。     */    private View mBindView;    /**     * 左侧布局的参数,通过此参数来重新确定左侧布局的宽度,以及更改leftMargin的值。     */    private MarginLayoutParams leftLayoutParams;    /**     * 右侧布局的参数,通过此参数来重新确定右侧布局的宽度。     */    private MarginLayoutParams rightLayoutParams;    /**     * 3D视图的参数,通过此参数来重新确定3D视图的宽度。     */    private ViewGroup.LayoutParams image3dViewParams;    /**     * 用于计算手指滑动的速度。速率追踪者     */    private VelocityTracker mVelocityTracker;    /**     * 重写SlidingLayout的构造函数,其中获取了屏幕的宽度。     *     * @param context     * @param attrs     */    public ThreeDSlidingLayout(Context context, AttributeSet attrs) {        super(context, attrs);        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);        screenWidth = wm.getDefaultDisplay().getWidth();        touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();    }    /**     * 绑定监听侧滑事件的View,即在绑定的View进行滑动才可以显示和隐藏左侧布局。     *     * @param bindView     *            需要绑定的View对象。     */    public void setScrollEvent(View bindView) {        mBindView = bindView;        mBindView.setOnTouchListener(this);    }    /**     * 将屏幕滚动到左侧布局界面,滚动速度设定为10.     */    public void scrollToLeftLayout() {        image3dView.clearSourceBitmap();        new ScrollTask().execute(-10);    }    /**     * 将屏幕滚动到右侧布局界面,滚动速度设定为-10.     */    public void scrollToRightLayout() {        image3dView.clearSourceBitmap();        new ScrollTask().execute(10);    }    /**     * 左侧布局是否完全显示出来,或完全隐藏,滑动过程中此值无效。     *     * @return 左侧布局完全显示返回true,完全隐藏返回false。     */    public boolean isLeftLayoutVisible() {        return isLeftLayoutVisible;    }    /**     * 在onLayout中重新设定左侧布局和右侧布局的参数。     */    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        super.onLayout(changed, l, t, r, b);        if (changed && !loadOnce) {            // 获取左侧布局对象            leftLayout = findViewById(R.id.menu);            leftLayoutParams = (MarginLayoutParams) leftLayout.getLayoutParams();            rightEdge = -leftLayoutParams.width;            // 获取右侧布局对象            rightLayout = findViewById(R.id.content);            rightLayoutParams = (MarginLayoutParams) rightLayout.getLayoutParams();            rightLayoutParams.width = screenWidth;            rightLayout.setLayoutParams(rightLayoutParams);            // 获取3D视图对象            image3dView = (Image3dView) findViewById(R.id.image_3d_view);//这个东西在布局中没有指定位置,只是在父左            // 将左侧布局传入3D视图中作为生成源            image3dView.setSourceView(leftLayout);            loadOnce = true;        }    }    @Override    public boolean onTouch(View v, MotionEvent event) {        createVelocityTracker(event);        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                // 手指按下时,记录按下时的横坐标                xDown = event.getRawX();                yDown = event.getRawY();                slideState = DO_NOTHING;                break;            case MotionEvent.ACTION_MOVE:                // 手指移动时,对比按下时的横坐标,计算出移动的距离,来调整右侧布局的leftMargin值,从而显示和隐藏左侧布局                xMove = event.getRawX();                yMove = event.getRawY();                int moveDistanceX = (int) (xMove - xDown);                int moveDistanceY = (int) (yMove - yDown);                checkSlideState(moveDistanceX, moveDistanceY);                switch (slideState) {                    case SHOW_MENU:                        rightLayoutParams.rightMargin = -moveDistanceX;                        onSlide();                        break;                    case HIDE_MENU:                        rightLayoutParams.rightMargin = rightEdge - moveDistanceX;                        onSlide();                        break;                    default:                        break;                }                break;            case MotionEvent.ACTION_UP:                xUp = event.getRawX();                int upDistanceX = (int) (xUp - xDown);                if (isSliding) {                    // 手指抬起时,进行判断当前手势的意图                    switch (slideState) {                        case SHOW_MENU:                            if (shouldScrollToLeftLayout()) {                                scrollToLeftLayout();                            } else {                                scrollToRightLayout();                            }                            break;                        case HIDE_MENU:                            if (shouldScrollToRightLayout()) {                                scrollToRightLayout();                            } else {                                scrollToLeftLayout();                            }                            break;                        default:                            break;                    }                } else if (upDistanceX < touchSlop && isLeftLayoutVisible) {                    scrollToRightLayout();                }                recycleVelocityTracker();                break;        }        if (v.isEnabled()) {            if (isSliding) {                unFocusBindView();                return true;            }            if (isLeftLayoutVisible) {                return true;            }            return false;        }        return true;    }    /**     * 执行滑动过程中的逻辑操作,如边界检查,改变偏移值,可见性检查等。     */    private void onSlide() {        checkSlideBorder();        rightLayout.setLayoutParams(rightLayoutParams);        image3dView.clearSourceBitmap();        image3dViewParams = image3dView.getLayoutParams();        image3dViewParams.width = -rightLayoutParams.rightMargin;        // 滑动的同时改变3D视图的大小        image3dView.setLayoutParams(image3dViewParams);        // 保证在滑动过程中3D视图可见,左侧布局不可见        showImage3dView();    }    /**     * 根据手指移动的距离,判断当前用户的滑动意图,然后给slideState赋值成相应的滑动状态值。     *     * @param moveDistanceX     *            横向移动的距离     * @param moveDistanceY     *            纵向移动的距离     */    private void checkSlideState(int moveDistanceX, int moveDistanceY) {        if (isLeftLayoutVisible) {            if (!isSliding && Math.abs(moveDistanceX) >= touchSlop && moveDistanceX < 0) {                isSliding = true;                slideState = HIDE_MENU;            }        } else if (!isSliding && Math.abs(moveDistanceX) >= touchSlop && moveDistanceX > 0                && Math.abs(moveDistanceY) < touchSlop) {            isSliding = true;            slideState = SHOW_MENU;        }    }    /**     * 在滑动过程中检查左侧菜单的边界值,防止绑定布局滑出屏幕。     * 这个如果不用会非常炫酷     */    private void checkSlideBorder() {        if (rightLayoutParams.rightMargin > leftEdge) {            rightLayoutParams.rightMargin = leftEdge;        } else if (rightLayoutParams.rightMargin < rightEdge) {            rightLayoutParams.rightMargin = rightEdge;        }    }    /**     * 判断是否应该滚动将左侧布局展示出来。如果手指移动距离大于屏幕的1/2,或者手指移动速度大于SNAP_VELOCITY,     * 就认为应该滚动将左侧布局展示出来。     *     * @return 如果应该滚动将左侧布局展示出来返回true,否则返回false。     */    private boolean shouldScrollToLeftLayout() {        return xUp - xDown > leftLayoutParams.width / 2 || getScrollVelocity() > SNAP_VELOCITY;    }    /**     * 判断是否应该滚动将右侧布局展示出来。如果手指移动距离加上leftLayoutPadding大于屏幕的1/2,     * 或者手指移动速度大于SNAP_VELOCITY, 就认为应该滚动将右侧布局展示出来。     *     * @return 如果应该滚动将右侧布局展示出来返回true,否则返回false。     */    private boolean shouldScrollToRightLayout() {        return xDown - xUp > leftLayoutParams.width / 2 || getScrollVelocity() > SNAP_VELOCITY;    }    /**     * 创建VelocityTracker对象,并将触摸事件加入到VelocityTracker当中。     *     * @param event     *            右侧布局监听控件的滑动事件     */    private void createVelocityTracker(MotionEvent event) {        if (mVelocityTracker == null) {            mVelocityTracker = VelocityTracker.obtain();        }        mVelocityTracker.addMovement(event);    }    /**     * 获取手指在右侧布局的监听View上的滑动速度。     *     * @return 滑动速度,以每秒钟移动了多少像素值为单位。     */    private int getScrollVelocity() {        mVelocityTracker.computeCurrentVelocity(1000);        int velocity = (int) mVelocityTracker.getXVelocity();        return Math.abs(velocity);    }    /**     * 回收VelocityTracker对象。     */    private void recycleVelocityTracker() {        mVelocityTracker.recycle();        mVelocityTracker = null;    }    /**     * 使用可以获得焦点的控件在滑动的时候失去焦点。     */    private void unFocusBindView() {        if (mBindView != null) {            mBindView.setPressed(false);            mBindView.setFocusable(false);            mBindView.setFocusableInTouchMode(false);        }    }    /**     * 保证此时让左侧布局不可见,3D视图可见,从而让滑动过程中产生3D的效果。     */    private void showImage3dView() {        if (image3dView.getVisibility() != View.VISIBLE) {            image3dView.setVisibility(View.VISIBLE);        }        if (leftLayout.getVisibility() != View.INVISIBLE) {            leftLayout.setVisibility(View.INVISIBLE);        }    }    class ScrollTask extends AsyncTask<Integer, Integer, Integer> {        @Override        protected Integer doInBackground(Integer... speed) {            int rightMargin = rightLayoutParams.rightMargin;            // 根据传入的速度来滚动界面,当滚动到达左边界或右边界时,跳出循环。            while (true) {                rightMargin = rightMargin + speed[0];                if (rightMargin < rightEdge) {                    rightMargin = rightEdge;                    break;                }                if (rightMargin > leftEdge) {                    rightMargin = leftEdge;                    break;                }                publishProgress(rightMargin);                // 为了要有滚动效果产生,每次循环使线程睡眠5毫秒,这样肉眼才能够看到滚动动画。                sleep(5);            }            if (speed[0] > 0) {                isLeftLayoutVisible = false;            } else {                isLeftLayoutVisible = true;            }            isSliding = false;            return rightMargin;        }        @Override        protected void onProgressUpdate(Integer... rightMargin) {            rightLayoutParams.rightMargin = rightMargin[0];            rightLayout.setLayoutParams(rightLayoutParams);            image3dViewParams = image3dView.getLayoutParams();            image3dViewParams.width = -rightLayoutParams.rightMargin;            image3dView.setLayoutParams(image3dViewParams);            showImage3dView();            unFocusBindView();        }        @Override        protected void onPostExecute(Integer rightMargin) {            rightLayoutParams.rightMargin = rightMargin;            rightLayout.setLayoutParams(rightLayoutParams);            image3dViewParams = image3dView.getLayoutParams();            image3dViewParams.width = -rightLayoutParams.rightMargin;            image3dView.setLayoutParams(image3dViewParams);            if (isLeftLayoutVisible) {                // 保证在滑动结束后左侧布局可见,3D视图不可见。                image3dView.setVisibility(View.INVISIBLE);                leftLayout.setVisibility(View.VISIBLE);            }        }    }    /**     * 使当前线程睡眠指定的毫秒数。     *     * @param millis     *            指定当前线程睡眠多久,以毫秒为单位     */    private void sleep(long millis) {        try {            Thread.sleep(millis);        } catch (InterruptedException e) {            e.printStackTrace();        }    }}

这个还没看全,代更新
checkSlideBorder这个如果不用的话…
这里写图片描述
这里写图片描述
这里写图片描述

这里主要是对布局进行触摸监控
然后进行移动等操作

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小孩的腰有点弯怎么办 小朋友不听话被老师罚站怎么办 幼儿园小朋友被老师罚站怎么办 生完小孩弯腰驼背怎么办 小孩爱捡垃圾是怎么办 腰扭了不敢弯腰怎么办 小人狗在背后骂我怎么办 微信表情缺失了怎么办 动图过大 微信 怎么办 我能怎么办图片带字 我该怎么办图片带字 学化妆找不到模特练妆怎么办? cf进房间闪退怎么办 手游cf账号封了怎么办 大门牙缺了一块怎么办 缺了一颗牙齿怎么办 CF购买医疗包竞猜币没到账怎么办 CF手游昵称不合法怎么办 微信gif尺寸过大怎么办 微信表情上限300怎么办 太受欢迎了怎么办快穿 兔宝宝沾上人气味怎么办 我该怎么办的文字图片 爱奇艺缓存视频显示下载失败怎么办 把老公惹生气了怎么办 苹果x用电量太快怎么办 小中考地生没过怎么办 如果遇到不负责的语文老师怎么办 孩子的语文老师教的不好怎么办 刚买的小猫很凶怎么办 2月幼犬不吃东西怎么办 小狗狗不吃狗粮怎么办 母猫不会照顾小猫怎么办 刚买的小狗拉稀怎么办 母兔子吃小兔子怎么办 照片照出来背亮景人是黑的怎么办 手机透明壳变黄了怎么办 ae视频渲染太慢怎么办 3ce口红太干了怎么办 中考误用0.38mm的笔怎么办 ps画笔都锁住了怎么办