前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >仿QQ6.1手势锁

仿QQ6.1手势锁

作者头像
103style
发布2022-12-19 12:16:13
1900
发布2022-12-19 12:16:13
举报
文章被收录于专栏:Android开发经验分享

项目地址:https://github.com/103style/QQ6.1GestureLock

该项目是仿照当前版本的QQ手势锁,主要实现设置手势锁和检验手势锁的功能。

废话不多说 先上效果图。

主界面代码:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{     public static String password;     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);         ViewUtils.inject(this);     }

    @OnClick({R.id.bt, R.id.btCheck})     @Override     public void onClick(View v) {         switch (v.getId()){             case R.id.bt:                 startActivity(new Intent(MainActivity.this, SetGestureLockActivity.class));                 break;             case R.id.btCheck:                 if (password == null){                     Toast.makeText(MainActivity.this,"请先设置手势锁",Toast.LENGTH_SHORT).show();                 }else{                     Intent intent = new Intent(MainActivity.this, CheckActivity.class);                     intent.putExtra("password",password);                     startActivity(intent);                 }                 break;         }     } }

设置手势密码代码:

public class SetGestureLockActivity extends Activity {     // 手势密码点的状态     public static final int POINT_STATE_NORMAL = 0; // 正常状态     public static final int POINT_STATE_SELECTED = 1; // 按下状态     public static final int POINT_STATE_WRONG = 2; // 错误状态     @ViewInject(R.id.lock_indicator)     LockIndicator mLockIndicator;     @ViewInject(R.id.text_tip)     TextView mTextTip;     @ViewInject(R.id.gesture_container)     FrameLayout mGestureContainer;     private GestureContentView mGestureContentView;     private boolean mIsFirstInput = true;     private String mFirstPassword = null;     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_set_gesture_lock);         ViewUtils.inject(this);         initParam();     }     private void initParam() {         mGestureContentView = new GestureContentView(this, false, "", new GestureDrawline.GestureCallBack() {             @Override             public void onGestureCodeInput(String inputCode) {                 if (!isInputPassValidate(inputCode)) {                     mTextTip.setText(Html.fromHtml("<font color='#c70c1e'>最少链接4个点, 请重新输入</font>"));                     mGestureContentView.clearDrawlineState(0L);                     return;                 }                 if (mIsFirstInput) {                     mFirstPassword = inputCode;                     updateCodeList(inputCode);                     mGestureContentView.clearDrawlineState(0L);                 } else {                     if (inputCode.equals(mFirstPassword)) {                         Toast.makeText(SetGestureLockActivity.this, "设置成功", Toast.LENGTH_SHORT).show();                         mGestureContentView.clearDrawlineState(0L);                         MainActivity.password =mFirstPassword;                         SetGestureLockActivity.this.finish();                     } else {                         mTextTip.setText(Html.fromHtml("<font color='#ff0000'>与上一次绘制不一致,请重新绘制</font>"));                         // 左右移动动画                         Animation shakeAnimation = AnimationUtils.loadAnimation(SetGestureLockActivity.this, R.anim.shake);                         mTextTip.startAnimation(shakeAnimation);                         // 保持绘制的线,1.5秒后清除                         mGestureContentView.clearDrawlineState(1300L);                     }                 }                 mIsFirstInput = false;             }             @Override             public void checkedSuccess() {             }

            @Override             public void checkedFail() {             }         });         // 设置手势解锁显示到哪个布局里面         mGestureContentView.setParentView(mGestureContainer);         updateCodeList("");     }     private void updateCodeList(String inputCode) {         // 更新选择的图案         mLockIndicator.setPath(inputCode);     }     private boolean isInputPassValidate(String inputPassword) {         if (TextUtils.isEmpty(inputPassword) || inputPassword.length() < 4) {             return false;         }         return true;     } }

检验手势密码代码:

public class CheckActivity extends AppCompatActivity {     @ViewInject(R.id.text_tip)     TextView mTextTip;     @ViewInject(R.id.gesture_container)     FrameLayout mGestureContainer;

    private GestureContentView mGestureContentView;     //设置的手势密码     private String password;     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_check);         ViewUtils.inject(this);         Intent intent = getIntent();         password = intent.getStringExtra("password");         Log.e("Password", password);         initViews();     }     private void initViews() {         // 初始化一个显示各个点的viewGroup         mGestureContentView = new GestureContentView(this, true, password,                 new GestureDrawline.GestureCallBack() {                     @Override                     public void onGestureCodeInput(String inputCode) {                     }                     @Override                     public void checkedSuccess() {                         mGestureContentView.clearDrawlineState(0L);                         Toast.makeText(CheckActivity.this, "密码正确", 1000).show();                         CheckActivity.this.finish();                     }                     @Override                     public void checkedFail() {                         mGestureContentView.clearDrawlineState(1300L);                         mTextTip.setVisibility(View.VISIBLE);                         mTextTip.setText(Html                                 .fromHtml("<font color='#ff0000'>密码错误</font>"));                         // 左右移动动画                         Animation shakeAnimation = AnimationUtils.loadAnimation(CheckActivity.this, R.anim.shake);                         mTextTip.startAnimation(shakeAnimation);                     }                 });         // 设置手势解锁显示到哪个布局里面         mGestureContentView.setParentView(mGestureContainer);     } }

package com.hnpolice.luoxiaoke.gesturelock; import android.widget.ImageView; 手势点的代码:

/**  * Created by Luoxiaoke on 2015/12/2 14:32.  */ public class GesturePoint {     /**      * 左边x的值      */     private int leftX;     /**      * 右边x的值      */     private int rightX;     /**      * 上边y的值      */     private int topY;     /**      * 下边y的值      */     private int bottomY;     /**      * 这个点对应的ImageView控件      */     private ImageView image;     /**      * 中心x值      */     private int centerX;     /**      * 中心y值      */     private int centerY;     /**      * 状态值      */     private int pointState;     /**      * 代表这个Point对象代表的数字,从1开始(直接感觉从1开始)      */     private int num;     public GesturePoint(int leftX, int rightX, int topY, int bottomY,                         ImageView image, int num) {         super();         this.leftX = leftX;         this.rightX = rightX;         this.topY = topY;         this.bottomY = bottomY;         this.image = image;         this.centerX = (leftX + rightX) / 2;         this.centerY = (topY + bottomY) / 2;         this.num = num;     }     public int getLeftX() {         return leftX;     }     public void setLeftX(int leftX) {         this.leftX = leftX;     }     public int getRightX() {         return rightX;     }     public void setRightX(int rightX) {         this.rightX = rightX;     }     public int getTopY() {         return topY;     }     public void setTopY(int topY) {         this.topY = topY;     }     public int getBottomY() {         return bottomY;     }     public void setBottomY(int bottomY) {         this.bottomY = bottomY;     }     public ImageView getImage() {         return image;     }     public void setImage(ImageView image) {         this.image = image;     }     public int getCenterX() {         return centerX;     }     public void setCenterX(int centerX) {         this.centerX = centerX;     }     public int getCenterY() {         return centerY;     }     public void setCenterY(int centerY) {         this.centerY = centerY;     }     public int getPointState() {         return pointState;     }     public void setPointState(int state) {         pointState = state;         switch (state) {             case SetGestureLockActivity.POINT_STATE_NORMAL:                 this.image.setBackgroundResource(R.mipmap.gesturepassward_locus_round_original);                 break;             case SetGestureLockActivity.POINT_STATE_SELECTED:                 this.image.setBackgroundResource(R.mipmap.gesturepassward_locus_round_click);                 break;             case SetGestureLockActivity.POINT_STATE_WRONG:                 this.image.setBackgroundResource(R.mipmap.gesturepassward_locus_round_wrong);                 break;             default:                 break;         }     }     public int getNum() {         return num;     }     public void setNum(int num) {         this.num = num;     }     @Override     public int hashCode() {         final int prime = 31;         int result = 1;         result = prime * result + bottomY;         result = prime * result + ((image == null) ? 0 : image.hashCode());         result = prime * result + leftX;         result = prime * result + rightX;         result = prime * result + topY;         return result;     }     @Override     public boolean equals(Object obj) {         if (this == obj)             return true;         if (obj == null)             return false;         if (getClass() != obj.getClass())             return false;         GesturePoint other = (GesturePoint) obj;         if (bottomY != other.bottomY)             return false;         if (image == null) {             if (other.image != null)                 return false;         } else if (!image.equals(other.image))             return false;         if (leftX != other.leftX)             return false;         if (rightX != other.rightX)             return false;         if (topY != other.topY)             return false;         return true;     }     @Override     public String toString() {         return "Point [leftX=" + leftX + ", rightX=" + rightX + ", topY="                 + topY + ", bottomY=" + bottomY + "]";     } }

手势密码路径绘制代码: public class GestureDrawline extends View {     private int mov_x;// 声明起点坐标     private int mov_y;     private Paint paint;// 声明画笔     private Canvas canvas;// 画布     private Bitmap bitmap;// 位图     private List<GesturePoint> list;// 装有各个view坐标的集合     private List<Pair<GesturePoint, GesturePoint>> lineList;// 记录画过的线     private Map<String, GesturePoint> autoCheckPointMap;// 自动选中的情况点     private boolean isDrawEnable = true; // 是否允许绘制     /**      * 屏幕的宽度和高度      */     private int[] screenDispaly;     /**      * 手指当前在哪个Point内      */     private GesturePoint currentPoint;     /**      * 用户绘图的回调      */     private GestureCallBack callBack;     /**      * 用户当前绘制的图形密码      */     private StringBuilder passWordSb;     /**      * 是否为校验      */     private boolean isVerify;     /**      * 用户传入的passWord      */     private String passWord;     public GestureDrawline(Context context, List<GesturePoint> list, boolean isVerify,                            String passWord, GestureCallBack callBack) {         super(context);         screenDispaly = AppUtil.getScreenDispaly(context);         paint = new Paint(Paint.DITHER_FLAG);// 创建一个画笔         bitmap = Bitmap.createBitmap(screenDispaly[0], screenDispaly[0], Bitmap.Config.ARGB_8888); // 设置位图的宽高         canvas = new Canvas();         canvas.setBitmap(bitmap);         paint.setStyle(Paint.Style.STROKE);// 设置非填充         paint.setStrokeWidth(10);// 笔宽5像素         paint.setColor(Color.rgb(245, 142, 33));// 设置默认连线颜色         paint.setAntiAlias(true);// 不显示锯齿         this.list = list;         this.lineList = new ArrayList<Pair<GesturePoint, GesturePoint>>();         initAutoCheckPointMap();         this.callBack = callBack;         // 初始化密码缓存         this.isVerify = isVerify;         this.passWordSb = new StringBuilder();         this.passWord = passWord;     }     private void initAutoCheckPointMap() {         autoCheckPointMap = new HashMap<String,GesturePoint>();         autoCheckPointMap.put("1,3", getGesturePointByNum(2));         autoCheckPointMap.put("1,7", getGesturePointByNum(4));         autoCheckPointMap.put("1,9", getGesturePointByNum(5));         autoCheckPointMap.put("2,8", getGesturePointByNum(5));         autoCheckPointMap.put("3,7", getGesturePointByNum(5));         autoCheckPointMap.put("3,9", getGesturePointByNum(6));         autoCheckPointMap.put("4,6", getGesturePointByNum(5));         autoCheckPointMap.put("7,9", getGesturePointByNum(8));     }     private GesturePoint getGesturePointByNum(int num) {         for (GesturePoint point : list) {             if (point.getNum() == num) {                 return point;             }         }         return null;     }     // 画位图     @Override     protected void onDraw(Canvas canvas) {         // super.onDraw(canvas);         canvas.drawBitmap(bitmap, 0, 0, null);     }     // 触摸事件     @Override     public boolean onTouchEvent(MotionEvent event) {         if (isDrawEnable == false) {             // 当期不允许绘制             return true;         }         paint.setColor(Color.rgb(18, 195, 249));// 设置默认连线颜色         switch (event.getAction()) {             case MotionEvent.ACTION_DOWN:                 mov_x = (int) event.getX();                 mov_y = (int) event.getY();                 // 判断当前点击的位置是处于哪个点之内                 currentPoint = getPointAt(mov_x, mov_y);                 if (currentPoint != null) {                     currentPoint.setPointState(SetGestureLockActivity.POINT_STATE_SELECTED);                     passWordSb.append(currentPoint.getNum());                 }                 // canvas.drawPoint(mov_x, mov_y, paint);// 画点                 invalidate();                 break;             case MotionEvent.ACTION_MOVE:                 clearScreenAndDrawList();

                // 得到当前移动位置是处于哪个点内                 GesturePoint pointAt = getPointAt((int) event.getX(), (int) event.getY());                 // 代表当前用户手指处于点与点之前                 if (currentPoint == null && pointAt == null) {                     return true;                 } else {// 代表用户的手指移动到了点上                     if (currentPoint == null) {// 先判断当前的point是不是为null                         // 如果为空,那么把手指移动到的点赋值给currentPoint                         currentPoint = pointAt;                         // 把currentPoint这个点设置选中为true;                         currentPoint.setPointState(SetGestureLockActivity.POINT_STATE_SELECTED);                         passWordSb.append(currentPoint.getNum());                     }                 }                 if (pointAt == null || currentPoint.equals(pointAt) || SetGestureLockActivity.POINT_STATE_SELECTED == pointAt.getPointState()) {                     // 点击移动区域不在圆的区域,或者当前点击的点与当前移动到的点的位置相同,或者当前点击的点处于选中状态                     // 那么以当前的点中心为起点,以手指移动位置为终点画线                     canvas.drawLine(currentPoint.getCenterX(), currentPoint.getCenterY(), event.getX(), event.getY(), paint);// 画线                 } else {                     // 如果当前点击的点与当前移动到的点的位置不同                     // 那么以前前点的中心为起点,以手移动到的点的位置画线                     canvas.drawLine(currentPoint.getCenterX(), currentPoint.getCenterY(), pointAt.getCenterX(), pointAt.getCenterY(), paint);// 画线                     pointAt.setPointState(SetGestureLockActivity.POINT_STATE_SELECTED);                     // 判断是否中间点需要选中                     GesturePoint betweenPoint = getBetweenCheckPoint(currentPoint, pointAt);                     if (betweenPoint != null && SetGestureLockActivity.POINT_STATE_SELECTED != betweenPoint.getPointState()) {                         // 存在中间点并且没有被选中                         Pair<GesturePoint, GesturePoint> pair1 = new Pair<GesturePoint, GesturePoint>(currentPoint, betweenPoint);                         lineList.add(pair1);                         passWordSb.append(betweenPoint.getNum());                         Pair<GesturePoint, GesturePoint> pair2 = new Pair<GesturePoint, GesturePoint>(betweenPoint, pointAt);                         lineList.add(pair2);                         passWordSb.append(pointAt.getNum());                         // 设置中间点选中                         betweenPoint.setPointState(SetGestureLockActivity.POINT_STATE_SELECTED);                         // 赋值当前的point;                         currentPoint = pointAt;                     } else {                         Pair<GesturePoint, GesturePoint> pair = new Pair<GesturePoint, GesturePoint>(currentPoint, pointAt);                         lineList.add(pair);                         passWordSb.append(pointAt.getNum());                         // 赋值当前的point;                         currentPoint = pointAt;                     }                 }                 invalidate();                 break;             case MotionEvent.ACTION_UP:// 当手指抬起的时候                 if (isVerify) {                     // 手势密码校验                     // 清掉屏幕上所有的线,只画上集合里面保存的线                     if (passWord.equals(passWordSb.toString())) {                         // 代表用户绘制的密码手势与传入的密码相同                         callBack.checkedSuccess();                     } else {                         // 用户绘制的密码与传入的密码不同。                         callBack.checkedFail();                     }                 } else {                     callBack.onGestureCodeInput(passWordSb.toString());                 }                 break;             default:                 break;         }         return true;     }     /**      * 指定时间去清除绘制的状态      * @param delayTime 延迟执行时间      */     public void clearDrawlineState(long delayTime) {         if (delayTime > 0) {             // 绘制红色提示路线             isDrawEnable = false;             drawErrorPathTip();         }         new Handler().postDelayed(new clearStateRunnable(), delayTime);     }     /**      * 清除绘制状态的线程      */     final class clearStateRunnable implements Runnable {         public void run() {             // 重置passWordSb             passWordSb = new StringBuilder();             // 清空保存点的集合             lineList.clear();             // 重新绘制界面             clearScreenAndDrawList();             for (GesturePoint p : list) {                 p.setPointState(SetGestureLockActivity.POINT_STATE_NORMAL);             }             invalidate();             isDrawEnable = true;         }     }     /**      * 通过点的位置去集合里面查找这个点是包含在哪个Point里面的      *      * @param x      * @param y      * @return 如果没有找到,则返回null,代表用户当前移动的地方属于点与点之间      */     private GesturePoint getPointAt(int x, int y) {         for (GesturePoint point : list) {             // 先判断x             int leftX = point.getLeftX();             int rightX = point.getRightX();             if (!(x >= leftX && x < rightX)) {                 // 如果为假,则跳到下一个对比                 continue;             }             int topY = point.getTopY();             int bottomY = point.getBottomY();             if (!(y >= topY && y < bottomY)) {                 // 如果为假,则跳到下一个对比                 continue;             }             // 如果执行到这,那么说明当前点击的点的位置在遍历到点的位置这个地方             return point;         }         return null;     }     private GesturePoint getBetweenCheckPoint(GesturePoint pointStart, GesturePoint pointEnd) {         int startNum = pointStart.getNum();         int endNum = pointEnd.getNum();         String key = null;         if (startNum < endNum) {             key = startNum + "," + endNum;         } else {             key = endNum + "," + startNum;         }         return autoCheckPointMap.get(key);     }     /**      * 清掉屏幕上所有的线,然后画出集合里面的线      */     private void clearScreenAndDrawList() {         canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);         for (Pair<GesturePoint, GesturePoint> pair : lineList) {             canvas.drawLine(pair.first.getCenterX(), pair.first.getCenterY(),                     pair.second.getCenterX(), pair.second.getCenterY(), paint);// 画线         }     }     /**      * 校验错误/两次绘制不一致提示      */     private void drawErrorPathTip() {         canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);         paint.setColor(Color.rgb(255,0,0));// 设置默认线路颜色         for (Pair<GesturePoint, GesturePoint> pair : lineList) {             pair.first.setPointState(SetGestureLockActivity.POINT_STATE_WRONG);             pair.second.setPointState(SetGestureLockActivity.POINT_STATE_WRONG);             canvas.drawLine(pair.first.getCenterX(), pair.first.getCenterY(),                     pair.second.getCenterX(), pair.second.getCenterY(), paint);// 画线         }         invalidate();     }     public interface GestureCallBack {         /**          * 用户设置/输入了手势密码          */         public abstract void onGestureCodeInput(String inputCode);         /**          * 代表用户绘制的密码与传入的密码相同          */         public abstract void checkedSuccess();         /**          * 代表用户绘制的密码与传入的密码不相同          */         public abstract void checkedFail();     } }

手势密码图案提示代码: public class LockIndicator extends View {     private int numRow = 3;    // 行     private int numColum = 3; // 列     private int patternWidth = 40;     private int patternHeight = 40;     private int f = 5;     private int g = 5;     private int strokeWidth = 3;     private Paint paint = null;     private Drawable patternNoraml = null;     private Drawable patternPressed = null;     private String lockPassStr; // 手势密码     public LockIndicator(Context paramContext) {         super(paramContext);     }     public LockIndicator(Context paramContext, AttributeSet paramAttributeSet) {         super(paramContext, paramAttributeSet, 0);         paint = new Paint();         paint.setAntiAlias(true);         paint.setStrokeWidth(strokeWidth);         paint.setStyle(Paint.Style.STROKE);         patternNoraml = getResources().getDrawable(R.mipmap.gesturepasswar_original);         patternPressed = getResources().getDrawable(R.mipmap.gesturepassward_click);         if (patternPressed != null) {             patternWidth = patternPressed.getIntrinsicWidth();             patternHeight = patternPressed.getIntrinsicHeight();             this.f = (patternWidth / 4);             this.g = (patternHeight / 4);             patternPressed.setBounds(0, 0, patternWidth, patternHeight);             patternNoraml.setBounds(0, 0, patternWidth, patternHeight);         }     }     @Override     protected void onDraw(Canvas canvas) {         if ((patternPressed == null) || (patternNoraml == null)) {             return;         }         // 绘制3*3的图标         for (int i = 0; i < numRow; i++) {             for (int j = 0; j < numColum; j++) {                 paint.setColor(-16777216);                 int i1 = j * patternHeight + j * this.g;                 int i2 = i * patternWidth + i * this.f;                 canvas.save();                 canvas.translate(i1, i2);                 String curNum = String.valueOf(numColum * i + (j + 1));                 if (!TextUtils.isEmpty(lockPassStr)) {                     if (lockPassStr.indexOf(curNum) == -1) {                         // 未选中                         patternNoraml.draw(canvas);                     } else {                         // 被选中                         patternPressed.draw(canvas);                     }                 } else {                     // 重置状态                     patternNoraml.draw(canvas);                 }                 canvas.restore();             }         }     }     @Override     protected void onMeasure(int paramInt1, int paramInt2) {         if (patternPressed != null)             setMeasuredDimension(numColum * patternHeight + this.g                     * (-1 + numColum), numRow * patternWidth + this.f                     * (-1 + numRow));     }     /**      * 请求重新绘制      * @param paramString 手势密码字符序列      */     public void setPath(String paramString) {         lockPassStr = paramString;         invalidate();     } }

手势密码容器类代码:

public class GestureContentView extends ViewGroup {     private int baseNum = 6;     private int[] screenDispaly;     /**      * 每个点区域的宽度      */     private int blockWidth;     /**      * 声明一个集合用来封装坐标集合      */     private List<GesturePoint> list;     private Context context;     private boolean isVerify;     private GestureDrawline gestureDrawline;     /**      * 包含9个ImageView的容器,初始化      *      * @param context      * @param isVerify 是否为校验手势密码      * @param passWord 用户传入密码      * @param callBack 手势绘制完毕的回调      */     public GestureContentView(Context context, boolean isVerify, String passWord, GestureDrawline.GestureCallBack callBack) {         super(context);         screenDispaly = AppUtil.getScreenDispaly(context);         blockWidth = screenDispaly[0] / 3;         this.list = new ArrayList<GesturePoint>();         this.context = context;         this.isVerify = isVerify;         // 添加9个图标         addChild();         // 初始化一个可以画线的view         gestureDrawline = new GestureDrawline(context, list, isVerify, passWord, callBack);     }     private void addChild() {         for (int i = 0; i < 9; i++) {             ImageView image = new ImageView(context);             image.setBackgroundResource(R.mipmap.gesturepassward_locus_round_original);             this.addView(image);             invalidate();             // 第几行             int row = i / 3;             // 第几列             int col = i % 3;             // 定义点的每个属性             int leftX = col * blockWidth + blockWidth / baseNum;             int topY = row * blockWidth + blockWidth / baseNum;             int rightX = col * blockWidth + blockWidth - blockWidth / baseNum;             int bottomY = row * blockWidth + blockWidth - blockWidth / baseNum;             GesturePoint p = new GesturePoint(leftX, rightX, topY, bottomY, image, i + 1);             this.list.add(p);         }     }     public void setParentView(ViewGroup parent) {         // 得到屏幕的宽度         int width = screenDispaly[0];         LayoutParams layoutParams = new LayoutParams(width, width);         this.setLayoutParams(layoutParams);         gestureDrawline.setLayoutParams(layoutParams);         parent.addView(gestureDrawline);         parent.addView(this);     }     @Override     protected void onLayout(boolean changed, int l, int t, int r, int b) {         for (int i = 0; i < getChildCount(); i++) {             //第几行             int row = i / 3;             //第几列             int col = i % 3;             View v = getChildAt(i);             v.layout(col * blockWidth + blockWidth / baseNum, row * blockWidth + blockWidth / baseNum,                     col * blockWidth + blockWidth - blockWidth / baseNum, row * blockWidth + blockWidth - blockWidth / baseNum);         }     }

    @Override     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {         super.onMeasure(widthMeasureSpec, heightMeasureSpec);         // 遍历设置每个子view的大小         for (int i = 0; i < getChildCount(); i++) {             View v = getChildAt(i);             v.measure(widthMeasureSpec, heightMeasureSpec);         }     }     /**      * 保留路径delayTime时间长      *      * @param delayTime      */     public void clearDrawlineState(long delayTime) {         gestureDrawline.clearDrawlineState(delayTime);     } }

源代码下载地址:http://download.csdn.net/detail/lxk_1993/9368281

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015-12-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档