zoukankan      html  css  js  c++  java
  • 第二阶段冲刺(九)

    昨天学习了有关九宫格登录功能

    遇到的困难是不知道怎么动态添加内容 或变更格数

    今天准备对程序普查,查找bug。

    package com.example.liuan.jiugongge;
     
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.graphics.Point;
    import android.text.TextUtils;
    import android.util.AttributeSet;
    import android.util.TypedValue;
    import android.view.MotionEvent;
    import android.view.View;
     
    import java.util.ArrayList;
    import java.util.List;
     
    /**
     * 图案解锁
     * Name: LockPatternView
     * Author: liuan
     * creatTime:2017-01-11 20:45
     */
     
    public class LockPatternView extends View {
        // 正常状态的颜色
        private static final int SELECTED_COLOR = 0xFF979797;
        // 正常状态的颜色
        private static final int NORMAL_COLOR = 0xFF70DBDB;
        private Paint mCiclePaint;
        private Paint mLinePoaint;
        private float mRadius;
        //圆心数组
        private PointView[][] mPointViewArray = new PointView[3][3];
        //保存选中点的集合
        private List<PointView> mSelectedPointViewList;
        //解锁团的边长
        private int mPatternWidth;
        //每个圆圈的下标
        private int mIndex = 1;
        //正在滑动 并且没有任何点选中
        private boolean mIsMovingWithoutCircle = false;
        //是否绘制结束
        private boolean mIsFinsihed;
        private float mCurrentX, mCurrentY;
        //图案监听器
        private OnPatternChangeListener mOnPatternChangeListener;
        //第一个点是否选中
        private boolean mIsSelected;
     
     
        public LockPatternView(Context context) {
            this(context, null);
     
        }
     
        public LockPatternView(Context context, AttributeSet attrs) {
            super(context, attrs);
            //圆的画笔
            mCiclePaint = new Paint();
            mCiclePaint.setAntiAlias(true);
            mCiclePaint.setDither(true);
            mCiclePaint.setColor(NORMAL_COLOR);
            mCiclePaint.setStyle(Paint.Style.FILL);
            //线的画笔
            mLinePoaint = new Paint();
            mLinePoaint.setAntiAlias(true);
            mLinePoaint.setDither(true);
            mLinePoaint.setStrokeWidth(20);
            mLinePoaint.setColor(SELECTED_COLOR);
            mLinePoaint.setStyle(Paint.Style.STROKE);
     
            mRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, getResources().getDisplayMetrics());
            mSelectedPointViewList = new ArrayList<>();
        }
     
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            //获取屏幕长和宽中的较小值作为图案的边长
            mPatternWidth = Math.min(getMeasuredHeight(), getMeasuredWidth());
            setMeasuredDimension(mPatternWidth, mPatternWidth);
     
        }
     
        @Override
        protected void onDraw(Canvas canvas) {
            //画圆
            drawCicle(canvas);
            //将选中的圆 重新绘制一遍  将选中的点和未选中的点区别开来
            for (PointView pointView : mSelectedPointViewList) {
                mCiclePaint.setColor(SELECTED_COLOR);
                canvas.drawCircle(pointView.x, pointView.y, mRadius, mCiclePaint);
                //每重新绘制一个,将画笔的颜色重置 保证不会影响到其他圆的绘制
                mCiclePaint.setColor(NORMAL_COLOR);
            }
            //点与点画线
            if (mSelectedPointViewList.size() > 0) {
                //第一个选中的点为A点
                Point pointViewA = mSelectedPointViewList.get(0);
                for (int i = 0; i < mSelectedPointViewList.size(); i++) {
                    //其余的点为B点
                    Point pointViewB = mSelectedPointViewList.get(i);
                    drawLine(canvas, pointViewA, pointViewB);
                    pointViewA = pointViewB;
     
                }
                //点于鼠标当前位置绘制轨迹
     
                if (mIsMovingWithoutCircle & !mIsFinsihed) {
                    drawLine(canvas, pointViewA, new PointView((int) mCurrentX, (int) mCurrentY));
                }
     
     
            }
            super.onDraw(canvas);
     
        }
     
     
     
     
        private void drawCicle(Canvas canvas) {
            //canvas 画布
            //初始点的位置
            for (int i = 0; i < mPointViewArray.length; i++) {
                for (int j = 0; j < mPointViewArray.length; j++) {
                    //圆心坐标
                    int cx = mPatternWidth / 4 * (j + 1);
                    int cy = mPatternWidth / 4 * (i + 1);
                    //将圆心放在一个点数组中
                    PointView pointView = new PointView(cx, cy);
                    pointView.setIndex(mIndex);
                    mPointViewArray[i][j] = pointView;
                    canvas.drawCircle(cx, cy, mRadius, mCiclePaint);
                    mIndex++;
     
                }
     
            }
            mIndex = 1;
        }
     
        private void drawLine(Canvas canvas, Point pointA, Point pointB) {
            canvas.drawLine(pointA.x, pointA.y, pointB.x, pointB.y, mLinePoaint);
        }
     
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            mCurrentX = event.getX();
            mCurrentY = event.getY();
            PointView selectedPointView = null;
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
     
                    //重新绘制
                    if (mOnPatternChangeListener != null) {
                        mOnPatternChangeListener.onPatternStarted(true);
     
                    }
                    mSelectedPointViewList.clear();
                    mIsFinsihed = false;
                    selectedPointView = checkSelectPoint();
                    if (selectedPointView != null) {
                        //第一次按下的位置在圆内,被选中
                        mIsSelected = true;
                    }
                    break;
                case MotionEvent.ACTION_MOVE:
                    if (mIsSelected) {
                        selectedPointView = checkSelectPoint();
                    }
                    if (selectedPointView == null) {
                        mIsMovingWithoutCircle = true;
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    mIsFinsihed = true;
                    mIsSelected = false;
                    break;
     
            }
            //将选中的点收藏起来
            if (!mIsFinsihed && mIsSelected && selectedPointView != null) {
                if (!mSelectedPointViewList.contains(selectedPointView)) {
                    mSelectedPointViewList.add(selectedPointView);
                }
            }
            if (mIsFinsihed) {
                if (mSelectedPointViewList.size() == 1) {
                    mSelectedPointViewList.clear();
                } else if (mSelectedPointViewList.size() < 5 && mSelectedPointViewList.size() > 0) {
                    //绘制错误
                    if (mOnPatternChangeListener != null) {
                        mOnPatternChangeListener.onPatternChange(null);
                    }
                } else {
                    //绘制成功
                    String patternPassword = "";
                    if (mOnPatternChangeListener != null) {
                        for (PointView pointView : mSelectedPointViewList) {
                            patternPassword += pointView.getIndex();
                        }
                        if (!TextUtils.isEmpty(patternPassword)) {
                            mOnPatternChangeListener.onPatternChange(patternPassword);
                        }
                    }
     
     
                }
            }
     
            invalidate();
            return true;
        }
     
     
        /**
         * 判断当前按下的位置是否在圆心数组中
         *
         * @return 返回选中的点
         */
        private PointView checkSelectPoint() {
            for (int i = 0; i < mPointViewArray.length; i++) {
                for (int j = 0; j < mPointViewArray.length; j++) {
                    PointView pointView = mPointViewArray[i][j];
                    if (isWithInCircle(mCurrentX, mCurrentY,pointView.x,pointView.y,mRadius)) {
                        return pointView;
                    }
     
     
                }
            }
     
            return null;
        }
     
        private boolean isWithInCircle(float mCurrentX, float mCurrentY, int x, int y, float mRadius) {
                    //如果点和圆心的距离 小于半径,则证明在圆内
            if (Math.sqrt(Math.pow(x - mCurrentX, 2) + Math.pow(y - mCurrentY, 2)) < mRadius) {
                return true;
     
            }
            return false;
        }
     
     
     
        public void setOnPatternChangeListener(OnPatternChangeListener onPatternChangeListener) {
            if (onPatternChangeListener != null) {
                this.mOnPatternChangeListener = onPatternChangeListener;
            }
        }
     
        /**
         * 图案监听器
         */
        public interface OnPatternChangeListener {
            //图案改变 图案密码patternPassword
            void onPatternChange(String patternPassword);
     
            //图案是否重新绘制
            void onPatternStarted(boolean isStarted);
        }
    }
    
    package com.example.liuan.jiugongge;
     
    import android.graphics.Point;
     
    /**
     * 自定义点对象
     * Name: PointView
     * Author: liuan
     * creatTime:2017-01-11 21:02
     */
    public class PointView extends Point{
        //用于转化密码的下标
        public int index;
     
     
        public PointView(int x, int y) {
            super(x, y);
        }
        public int getIndex(){
            return index;
        }
     
        public void setIndex(int index) {
            this.index = index;
        }
    }
    
    package com.example.liuan.jiugongge;
     
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.widget.TextView;
     
    public class MainActivity extends AppCompatActivity implements LockPatternView.OnPatternChangeListener {
     
        private LockPatternView lpv;
        private TextView tv;
     
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            lpv = (LockPatternView) findViewById(R.id.lock_pattern_view);
            tv = (TextView) findViewById(R.id.text);
            lpv.setOnPatternChangeListener(this);
        }
     
        @Override
        public void onPatternChange(String patternPassword) {
            if(patternPassword==null){
                tv.setText("请至少5个点");
            }else{
                tv.setText(patternPassword);
            }
     
        }
     
        @Override
        public void onPatternStarted(boolean isStarted) {
            if(isStarted){
                tv.setText("请绘制图案");
            }
     
        }
    }
    
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
    android:orientation="vertical"
        tools:context="com.example.liuan.jiugongge.MainActivity">
     
        <TextView
            android:layout_gravity="center"
            android:id="@+id/text"
            android:textColor="#18b968"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="状态显示" />
        <com.example.liuan.jiugongge.LockPatternView
            android:clickable="true"
     
            android:id="@+id/lock_pattern_view"
            android:layout_weight="1"
            android:layout_width="match_parent"
            android:layout_height="0dp" />
    </LinearLayout>
  • 相关阅读:
    js冒泡排序
    HTML5 canvas 计时器
    centos 6.4安装杀毒软件clamAV 0.98[转]
    PHP大文件下载
    如何在 Eclipse 中使用插件构建 PHP 开发环境[转]
    CentOS 单用户模式:修改Root密码和grub加密[转]
    CentOS 6.0 VNC远程桌面配置[转]
    gprof使用介绍 (gcc -pg) [转]
    VMware NAT端口映射外网访问虚拟机linux
    shell判断文件是否存在[转]
  • 原文地址:https://www.cnblogs.com/lq13035130506/p/11005770.html
Copyright © 2011-2022 走看看