项目中用到手势解锁,然而没有在GitHub上找到想要的样式= =,仅仅好自己来定义了。以下来看代码~~

基本上非常多应用的手势解锁全都是九宫格的,内部内就是九个小圈圈而已。

那么我们就先来自己定义这个小圈圈吧~

圈圈的颜色选择状态有大致有三种状态。所以我定义了一个枚举来区分

package com.juzisang.com.library;

/**

* Created by 橘子桑 on 2016/3/27.

*/

public enum LockState {

SELECT_STATE,//选中

ERRER_STATE, //错误

DEFAULT_COLOR //默认

}

圈圈分为边框。内部填充色。还有内部圆。所以我定义了三个画笔来区分。

package com.juzisang.com.library;

import android.content.Context;

import android.content.res.TypedArray;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.util.AttributeSet;

import android.view.View;

/**

* Created by 橘子桑 on 2016/3/27.

*/

public class MarkerView extends View {

//是否显示内部的圈圈

private boolean mInsideNodeShow;

//宽度

protected int mContentWidth;

//宽度

protected int mContentRadius;

//选中状态

protected LockState mCurrentState = LockState.DEFAULT_COLOR;

//画边框画圆的的画笔

private Paint mNodeFramePaint;

private Paint mNodeCirclePaint;

private Paint mNodeFullPaint;

//默认的颜色

private int mDefaultColor = Color.parseColor("#757575");

private int mDefailtFullColor = Color.parseColor("#64757575");

private int mNodeDefaultColor = Color.parseColor("#757575");

//选中的颜色

private int mSelectColor = Color.parseColor("#7ECEF4");

private int mFrameSelectFullColor = Color.parseColor("#647ECEF4");

private int mNodeSelectColor = Color.parseColor("#7ECEF4");

//错误时候的颜色

private int mErrerColor = Color.parseColor("#EC6941");

private int mErrerFullColor = Color.parseColor("#64EC6941");

private int mErrerNodeColor = Color.parseColor("#EC6941");

//边框的宽度

private int mFrameLineWidth;

private int mNodeRadius;

//每一个圈圈的内边距

private int mNodePadding;

//触摸有效的范围

private float mTouchRatio;

//当前标记的位置

private int mNum;

public MarkerView(Context context, AttributeSet attrs) {

super(context, attrs);

initView(context, attrs, 0);

}

public MarkerView(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

initView(context, attrs, defStyleAttr);

}

//以后外部布局传来的參数

public MarkerView(Context context, int mDefaultColor, int mDefailtFullColor, int mNodeDefaultColor,

int mSelectColor, int mFrameSelectFullColor, int mNodeSelectColor,

int mErrerColor, int mErrerFullColor, int mErrerNodeColor,

int mFrameLineWidth, int mNodeRadius, int mNodePadding, boolean insideNodeShow) {

super(context);

this.mInsideNodeShow = insideNodeShow;

this.mDefaultColor = mDefaultColor;

this.mDefailtFullColor = mDefailtFullColor;

this.mNodeDefaultColor = mNodeDefaultColor;

this.mSelectColor = mSelectColor;

this.mFrameSelectFullColor = mFrameSelectFullColor;

this.mNodeSelectColor = mNodeSelectColor;

this.mErrerColor = mErrerColor;

this.mErrerFullColor = mErrerFullColor;

this.mErrerNodeColor = mErrerNodeColor;

this.mFrameLineWidth = mFrameLineWidth;

this.mNodeRadius = mNodeRadius;

this.mNodePadding = mNodePadding;

//内边距

setPadding(mNodePadding, mNodePadding, mNodePadding, mNodePadding);

//外部圆

mNodeFramePaint = new Paint();

mNodeFramePaint.setColor(mDefaultColor);

mNodeFramePaint.setAntiAlias(true);

mNodeFramePaint.setStrokeWidth(mFrameLineWidth);

mNodeFramePaint.setStyle(Paint.Style.STROKE);//仅仅画出边框

//内部填充色

mNodeFullPaint = new Paint();

mNodeFullPaint.setColor(mDefailtFullColor);

mNodeFullPaint.setStyle(Paint.Style.FILL);

mNodeFullPaint.setAntiAlias(true);

//内部圆

mNodeCirclePaint = new Paint();

mNodeCirclePaint.setColor(mNodeDefaultColor);

mNodeCirclePaint.setStyle(Paint.Style.FILL);//填充

mNodeCirclePaint.setAntiAlias(true);

}

//取当前透明度的百分比

public int getFullAlpha(int color, float ratio) {

return Color.argb((int) (Color.alpha(color) * ratio), Color.red(color), Color.green(color), Color.blue(color));

}

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

mContentWidth = getWidth();

mContentRadius = mContentWidth / 2 - Math.abs(getPaddingLeft()) - mFrameLineWidth / 2;

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

switch (mCurrentState) {

case DEFAULT_COLOR: //默认

mNodeFramePaint.setColor(mDefaultColor);

mNodeFullPaint.setColor(mDefailtFullColor);

mNodeCirclePaint.setColor(mNodeDefaultColor);

//外圆

canvas.drawCircle(mContentWidth / 2, mContentWidth / 2, mContentRadius, mNodeFramePaint);

//填充色

canvas.drawCircle(mContentWidth / 2, mContentWidth / 2, mContentRadius - mFrameLineWidth / 2, mNodeFullPaint);

//中心圆

if (mInsideNodeShow)

canvas.drawCircle(mContentWidth / 2, mContentWidth / 2, mNodeRadius, mNodeCirclePaint);

break;

case ERRER_STATE://错误

mNodeFramePaint.setColor(mErrerColor);

mNodeFullPaint.setColor(mErrerFullColor);

mNodeCirclePaint.setColor(mErrerNodeColor);

//外圆

canvas.drawCircle(mContentWidth / 2, mContentWidth / 2, mContentRadius, mNodeFramePaint);

//填充色

canvas.drawCircle(mContentWidth / 2, mContentWidth / 2, mContentRadius - mFrameLineWidth / 2, mNodeFullPaint);

//中心圆

canvas.drawCircle(mContentWidth / 2, mContentWidth / 2, mNodeRadius, mNodeCirclePaint);

break;

case SELECT_STATE://选中

mNodeFramePaint.setColor(mSelectColor);

mNodeFullPaint.setColor(mFrameSelectFullColor);

mNodeCirclePaint.setColor(mNodeSelectColor);

//外圆

canvas.drawCircle(mContentWidth / 2, mContentWidth / 2, mContentRadius, mNodeFramePaint);

//填充色

canvas.drawCircle(mContentWidth / 2, mContentWidth / 2, mContentRadius - mFrameLineWidth / 2, mNodeFullPaint);

//中心圆

canvas.drawCircle(mContentWidth / 2, mContentWidth / 2, mNodeRadius, mNodeCirclePaint);

break;

}

}

//设置状态,而且重绘

public void setState(LockState CurrentState) {

mCurrentState = CurrentState;

invalidate();

}

//是否选中

public boolean isHighLighted() {

if (mCurrentState == LockState.SELECT_STATE || mCurrentState == LockState.ERRER_STATE) {

return true;

}

return false;

}

//中心点X

public int getCenterX() {

return (getLeft() + getRight()) / 2;

}

//中心点Y

public int getCenterY() {

return (getTop() + getBottom()) / 2;

}

//设置圈圈在手势锁其中的位置

protected void setNum(int num) {

mNum = num;

}

protected int getNum() {

return mNum;

}

}

以上就是一个简单的圆了

那么,自己定义View当然会有自己定义属性,所以有这么多T0T,不要问我为什么这么多属性。任性= =(事实上我还想写很多其它),自己定义属性的方法

LockView的代码

package com.juzisang.com.library;

import android.content.Context;

import android.content.res.TypedArray;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.util.AttributeSet;

import android.view.MotionEvent;

import android.view.ViewGroup;

import java.util.ArrayList;

/**

* Created by 橘子桑 on 2016/3/27.

*/

public class LockView extends ViewGroup {

//画连接线的画笔

private Paint mLinePaint;

//能够触摸的区域百分比

private float mTouchRatio;

//线的颜色

protected int mLineColor;

//先的宽度

protected float mLineWidth;

//已经选中了的View

ArrayList mNodeViews = new ArrayList<>();

//存储password

protected StringBuilder pawBuilder = new StringBuilder();

//当前手指触摸的x坐标

protected float x;

//当前手指触摸的y坐标

protected float y;

//回调

private onLockCallback mOnLockCallback;

protected int mDefaultColor;

protected int mSelectColor;

protected int mErrerColor;

//禁用手势锁

private boolean mLockScreen;

private boolean isTouch;

//是否把连接线绘制在子View的上面

private boolean mLineTop = false;

//手指离开马上重绘

private boolean mFingerLeaveRedraw = true;

public LockView(Context context) {

this(context, null);

}

public LockView(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public LockView(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

initView(context, attrs, defStyleAttr);

}

protected void initView(Context context, AttributeSet attrs, int defStyleAttr) {

TypedArray r = context.obtainStyledAttributes(attrs, R.styleable.MarkerView);

boolean insideNodeShow = r.getBoolean(R.styleable.LockView_insideNodeShow, false);

//默认的颜色

mDefaultColor = r.getColor(R.styleable.LockView_defaultColor, context.getResources().getColor(android.R.color.holo_blue_dark));

int mDefailtFullColor = r.getColor(R.styleable.LockView_defaultFullColor, getFullAlpha(mDefaultColor, 0.3F));

int mNodeDefaultColor = (int) r.getColor(R.styleable.LockView_defaultNodeColor, mDefaultColor);

//选中的颜色

mSelectColor = (int) r.getColor(R.styleable.LockView_selectColor, context.getResources().getColor(android.R.color.holo_blue_light));

int mFrameSelectFullColor = r.getColor(R.styleable.LockView_selectFrameFullColor, getFullAlpha(mSelectColor, 0.3F));

int mNodeSelectColor = r.getColor(R.styleable.LockView_selectNodeColor, mSelectColor);

//错误时候的颜色

mErrerColor = r.getColor(R.styleable.LockView_errorColor, context.getResources().getColor(android.R.color.holo_red_light));

int mErrerFullColor = r.getColor(R.styleable.LockView_errorFullColor, getFullAlpha(mErrerColor, 0.3F));

int mErrerNodeColor = r.getColor(R.styleable.LockView_errorNodeColor, mErrerColor);

//圆框变的宽度

int mFrameLineWidth = (int) r.getDimension(R.styleable.LockView_frameLineWidth, DensityUtils.dip2px(context, 5));

//内圆的直径

int mNodeRadius = (int) r.getDimension(R.styleable.LockView_nodeRadius, DensityUtils.dip2px(context, 5));

//内边距

int mNodePadding = (int) r.getDimension(R.styleable.LockView_nodePadding, DensityUtils.dip2px(context, 10));

//触摸有效区域

mTouchRatio = r.getFloat(R.styleable.LockView_touchRatio, mTouchRatio);

mLineColor = r.getColor(R.styleable.LockView_lineColor, mDefaultColor);

mLineWidth = r.getDimension(R.styleable.LockView_lineWidth, DensityUtils.dip2px(context, 5));

r.recycle();

//设置线的颜色

mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);

mLinePaint.setColor(mLineColor);

mLinePaint.setStyle(Paint.Style.STROKE);

mLinePaint.setStrokeWidth(mLineWidth);

mLinePaint.setStrokeCap(Paint.Cap.ROUND);

mLinePaint.setStrokeJoin(Paint.Join.ROUND);

for (int i = 0; i < 9; i++) {

MarkerView view = new MarkerView(context, mDefaultColor, mDefailtFullColor, mNodeDefaultColor, mSelectColor, mFrameSelectFullColor, mNodeSelectColor,

mErrerColor, mErrerFullColor, mErrerNodeColor, mFrameLineWidth, mNodeRadius, mNodePadding, insideNodeShow);

view.setNum(i + 1);

ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);

view.setLayoutParams(params);

addView(view);

}

// 清除FLAG,否则 onDraw() 不会调用。原因是 ViewGroup 默认透明背景不须要调用 onDraw()

setWillNotDraw(false);

}

public int getFullAlpha(int color, float ratio) {

return Color.argb((int) (Color.alpha(color) * ratio), Color.red(color), Color.green(color), Color.blue(color));

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

int size = Math.min(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec)); // 測量宽度

setMeasuredDimension(size, size);

for (int i = 0; i < getChildCount(); i++) {

measureChild(getChildAt(i), widthMeasureSpec, heightMeasureSpec);

}

}

@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

if (changed) {

float areaWidth = (r - l - getPaddingLeft() * 2) / 3;

for (int n = 0; n < 9; n++) {

MarkerView node = (MarkerView) getChildAt(n);

// 获取3*3宫格内坐标

int row = n / 3;

int col = n % 3;

//加上内间距

int left = (int) (getPaddingLeft() + col * areaWidth);

int top = (int) (getPaddingTop() + row * areaWidth);

int right = (int) (left + areaWidth);

int bottom = (int) (top + areaWidth);

node.layout(left, top, right, bottom);

}

}

}

/**

* 设置连接线是否绘制在子View的上面

* true 绘制在子View的上面

* false 绘制在子View的以下

*

*@param isLineTop 设置连接线是否绘制在子View的上面

*/

public void setLineTop(boolean isLineTop) {

mLineTop = isLineTop;

invalidate();

}

/**

* 设置连接线是否绘制在子View的上面

* true 绘制在子View的上面

* false 绘制在子View的以下

*/

public boolean getLineTop() {

return mLineTop;

}

@Override

public boolean onTouchEvent(MotionEvent event) {

if (getLockScreen()) {

invalidate();

return false;

}

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

//恢复默认

resetDefault();

x = event.getX();

y = event.getY();

isTouch = true;

break;

case MotionEvent.ACTION_MOVE:

x = event.getX(); // 这里要实时记录手指的坐标

y = event.getY();

MarkerView nodeView = getNodeAt(x, y);

//没有选中

if (nodeView != null && !nodeView.isHighLighted()) {

nodeView.setState(LockState.SELECT_STATE);

mNodeViews.add(nodeView);

//进度

if (mOnLockCallback != null) {

pawBuilder.setLength(0);

for (MarkerView markerView : mNodeViews) {

pawBuilder.append(markerView.getNum());

}

mOnLockCallback.onProgress(pawBuilder.toString(), nodeView.getNum());

}

}

if (mNodeViews.size() > 0) {

invalidate();

}

break;

case MotionEvent.ACTION_UP:

LogUtils.i("手指抬起了");

isTouch = false;

pawBuilder.setLength(0);

if (mNodeViews.size() <= 0) return true;

pawBuilder.delete(0, pawBuilder.length());

if (mOnLockCallback != null) {

for (MarkerView markerView : mNodeViews) {

pawBuilder.append(markerView.getNum());

}

mOnLockCallback.onFinish(pawBuilder.toString());

}

if (mFingerLeaveRedraw) {

resetDefault();

} else {

invalidate();

}

break;

}

return true;

}

@Override

protected void onDraw(Canvas canvas) {

//线画在子view的以下

if (!mLineTop) onDrawLock(canvas);

}

//画子View的地方

protected void dispatchDraw(Canvas canvas) {

super.dispatchDraw(canvas);

//放在这里的原因是。线会被子View挡到

if (mLineTop) onDrawLock(canvas);

}

/**

* 绘图的方法

*/

private void onDrawLock(Canvas canvas) {

//屏幕锁住了,仅仅画起点到终点的

if (getLockScreen()) {

onDrawNodeViewLock(canvas);

return;

}

if (isTouch || mFingerLeaveRedraw) {

//从第一个和最后一个的连接线

onDrawNodeViewLock(canvas);

//最后一个点,到手指之间的线

if (mNodeViews.size() > 0) {

MarkerView lastNode = mNodeViews.get(mNodeViews.size() - 1);

canvas.drawLine(lastNode.getCenterX(), lastNode.getCenterY(), x, y, mLinePaint);

}

} else {

//假设手指离开屏幕。而且设置了手指离开马上重绘

onDrawNodeViewLock(canvas);

}

}

private void onDrawNodeViewLock(Canvas canvas) {

//从第一个和最后一个的连接线

for (int i = 1; i < mNodeViews.size(); i++) {

MarkerView frontNode = mNodeViews.get(i - 1);

MarkerView backNode = mNodeViews.get(i);

canvas.drawLine(frontNode.getCenterX(), frontNode.getCenterY(), backNode.getCenterX(), backNode.getCenterY(), mLinePaint);

}

}

/**

* 获取给定坐标点的Node,返回null表示当前手指在两个Node之间

*/

private MarkerView getNodeAt(float x, float y) {

for (int n = 0; n < getChildCount(); n++) {

MarkerView node = (MarkerView) getChildAt(n);

//计算触摸区域以外的距离

float ratioPadding = (node.getWidth() - (node.getWidth() * mTouchRatio)) / 2;

if (!(x >= node.getLeft() + ratioPadding && x < node.getRight() - ratioPadding)) {

continue;

}

if (!(y >= node.getTop() + ratioPadding && y < node.getBottom() - ratioPadding)) {

continue;

}

return node;

}

return null;

}

/**

* 设置连接线的颜色

*

*@param color 颜色值

*/

public void setLineColor(int color) {

mLinePaint.setColor(color);

}

/**

* 手指离开马上重绘

*/

public void setfingerLeaveRedraw(boolean mFingerLeaveRedraw) {

this.mFingerLeaveRedraw = mFingerLeaveRedraw;

}

public boolean getfingerLeaveRedraw() {

return this.mFingerLeaveRedraw;

}

/**

* 重置状态 为默认状态

*/

public void resetDefault() {

setState(LockState.DEFAULT_COLOR);

mNodeViews.clear();

}

/**

* 重置状态错误状态

*/

public void resetErrer() {

setState(LockState.ERRER_STATE);

}

/**

* 重置为选中状态

*/

public void resetSelect() {

setState(LockState.SELECT_STATE);

}

/**

* 锁屏,不同意触摸

*/

public void LockScreen(boolean isScreen) {

mLockScreen = isScreen;

}

public boolean getLockScreen() {

return mLockScreen;

}

public void setState(LockState state) {

switch (state) {

case DEFAULT_COLOR:

case SELECT_STATE:

setLineColor(mSelectColor);

break;

case ERRER_STATE:

setLineColor(mErrerColor);

break;

}

int size = mNodeViews.size();

for (int i = 0; i < size; i++) {

mNodeViews.get(i).setState(state);

}

invalidate();

}

public void setLockCallback(onLockCallback lockCallback) {

mOnLockCallback = lockCallback;

}

//回调

public interface onLockCallback {

void onProgress(String paw, int current);

void onFinish(String paw);

}

}

以上凝视都写的非常清晰了。以下讲一下遇到的一些问题。

1.画出来的线被上面的圈圈覆盖了。

通过百度。知道ViewGroup的onDraw是画布局中的内容的,画子View的的方法在这种方法的后面运行。所以ViewGroup的内容会被子View覆盖。那么怎么才干把连接线画在子View的上面呢,非常easy

仅仅要在画子View的方法中运行就好了

//画子View的地方

protected void dispatchDraw(Canvas canvas) {

super.dispatchDraw(canvas);

//放在这里的原因是。线会被子View挡到

if (mLineTop) onDrawLock(canvas);

}

以下是View的draw()方法

@CallSuper

public void draw(Canvas canvas) {

final int privateFlags = mPrivateFlags;

final boolean dirtyOpaque = (privateFlags & PFLAG_DIRTY_MASK) == PFLAG_DIRTY_OPAQUE &&

(mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState);

mPrivateFlags = (privateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN;

// Step 1, draw the background, if needed

int saveCount;

if (!dirtyOpaque) {

drawBackground(canvas);

}

// skip step 2 & 5 if possible (common case)

final int viewFlags = mViewFlags;

boolean horizontalEdges = (viewFlags & FADING_EDGE_HORIZONTAL) != 0;

boolean verticalEdges = (viewFlags & FADING_EDGE_VERTICAL) != 0;

if (!verticalEdges && !horizontalEdges) {

// Step 3, draw the content

if (!dirtyOpaque) onDraw(canvas);

// Step 4, draw the children

//这里就是画子View的方法了

dispatchDraw(canvas);

// Overlay is part of the content and draws beneath Foreground

if (mOverlay != null && !mOverlay.isEmpty()) {

mOverlay.getOverlayView().dispatchDraw(canvas);

}

// Step 6, draw decorations (foreground, scrollbars)

onDrawForeground(canvas);

// we're done...

return;

}

2.怎么设置触摸的区域?

/**

* 获取给定坐标点的Node,返回null表示当前手指在两个Node之间

*/

private MarkerView getNodeAt(float x, float y) {

for (int n = 0; n < getChildCount(); n++) {

MarkerView node = (MarkerView) getChildAt(n);

//计算触摸区域以外的距离

float ratioPadding = (node.getWidth() - (node.getWidth() * mTouchRatio)) / 2;

if (!(x >= node.getLeft() + ratioPadding && x < node.getRight() - ratioPadding)) {

continue;

}

if (!(y >= node.getTop() + ratioPadding && y < node.getBottom() - ratioPadding)) {

continue;

}

return node;

}

return null;

}

看上面代码。

依据圆圈的宽度减去可触摸区域的长度除2。得到可触摸区域距离边框的距的距离。

光看代码看着有点圆。画个图看一下吧

画个图是不是清晰非常多,仅仅要用getLeft+边距。和getRight-边距,就能得到可触摸区域在x轴上的范围了。Y轴同理。不懂的同学自己用笔画一下吧~

几乎相同就上面两个问题了

手势解锁java后端设计_自己定义九宫格手势解锁相关推荐

  1. 手势解锁java后端设计_canvas手势解锁源码

    (function(){/** * 实现画圆和划线: * 1.添加事件touchstart.touchmove.touchend * 2.touchstart判断是否点击的位置处于圆内getPosit ...

  2. ## 大一java课程设计_航班查询系统(我是小白)

    大一java课程设计_航班查询系统(我是小白) 备注:第一个java程序有借鉴别人的成分,因为忘了在哪个大佬上面借鉴的,所以在此备注,如有侵权,请联系删除,(仅用于学习使用,并未想盈利) 框体介绍 一 ...

  3. Java 课程设计_学生选课管理系统(控制台)

    Java 课程设计_学生选课管理系统 需求分析 本数据库的用户主要是学生,通过对用户需求的收集和分析,获得用户对数据库的如下要求. 1.信息需求 学生信息:学号,姓名,性别,专业 登陆信息:账号,密码 ...

  4. java orm设计_大搜车orm框架设计思路

    orm基本概念 ORM,即Object-Relational Mapping(对象关系映射),它的作用是在关系型数据库和业务实体对象之间作一个映射,这样,我们在具体的操作业务对象的时候,就不需要再去和 ...

  5. 宿舍住宿管理java课程设计_宿舍管理系统Java课程设计

    宿舍管理系统Java课程设计 Java 课程设计设计(论文) 题目: 宿舍管理系统 所 在 院: 专 业 : 班 级 : 学 生 姓 名: 学 号: 指 导 教 师: 年 月 日课程设计(论文)任务书 ...

  6. 自己定义九宫格手势解锁

    项目中用到手势解锁,然而没有在GitHub上找到想要的样式= =,仅仅好自己来定义了.以下来看代码~~ 基本上非常多应用的手势解锁全都是九宫格的,内部内就是九个小圈圈而已. 那么我们就先来自己定义这个 ...

  7. 人事管理java 课程设计_数据库+Java课程设计 人事管理系统 (一)

    一.JAVA与数据库的合作 此次开发语言为Java,所用的数据库驱动是mysql-connector-java-5.1.8-bin.jar 第一步   用Java连接MySQL数据库(驱动下载:htt ...

  8. java 后端校验_如何实现Java后端数据校验?看这篇就足够!

    前言 每次我们在搭建一个开源项目的首要任务包括:项目的统一异常处理.统一结果封装以及做项目的数据校验,在前后端分离的情况下,不仅前端需要做数据校验,同样后端也要实现,前端主要使用一些类似与jQuery ...

  9. java后端概述_项目概述

    一.项目简介 一个简单的前后端分离的web项目,后端语言为java ,着重记录项目环境搭建,发布到服务器中遇到的一些问题.项目代码会上传github,但是不会讲解太多后端代码的内容.项目会涉及vsft ...

  10. java扫雷设计_毕业设计Java版扫雷的设计与实现介绍

    毕业设计Java版扫雷的设计与实现介绍 java语言eclipse环境 源码+精品文档 价格98元 扫雷是一款玩法相当简单的大众化的小游戏,游戏的胜利条件是在最短的时间内根据点击格子出现的数字找出所有 ...

最新文章

  1. python正则取字符串日期_python 正则表达式获取字符串中所有的日期和时间
  2. JS event使用方法详解
  3. 112.局部变量和全局变量在内存中是怎样存储的?113.WLAN无线传输协议
  4. lua如何判断是否支持cookie_我们应该如何判断机油是否变质?
  5. LeetCode Algorithm 530. 二叉搜索树的最小绝对差
  6. .NET 程序集单元测试工具 SmokeTest 应用指南
  7. ubuntu简单的小命令
  8. 暴露的全局方法_Dubbo源码解析实战 - 服务暴露原理
  9. python 关于反射和类的特殊成员方法
  10. 使用Ant打包java程序
  11. 历届美国梦之队战斗力汇总:梦一无敌 梦十二平淡
  12. 通过身份证号码判断男女
  13. Share Your Music - HTML5 Music Web App
  14. 【TouchDesigner】三维渲染
  15. Cross-modal Pretraining in BERT(跨模态预训练)
  16. java 实现秒抢_Java实现抢红包算法,附完整代码(公平版和手速版)
  17. PX4从放弃到精通(二十四):自定义机型
  18. paypal开发者账户申请步骤(最新最实用)
  19. Photoshop的时间轴是灰色的,不能使的解决方法
  20. 了解一下,Android 10 Build系统

热门文章

  1. 搭建一个开发Predix软件的Windows系统(1)准备工作
  2. 摄像头的MIPI接口、DVP接口和CSI接口
  3. 凤凰系统基于android x x86,凤凰系统X86|Phoenix OS X86 V3.0.8.529官方版
  4. Cisco Packet Tracer思科模拟器中路由器PPP封装与验证
  5. oninput onpropertychange
  6. 中标麒麟打包qt(Shell文本)
  7. 如何拥有类似 hi@hahah.fun 的个人专属域名的邮箱
  8. Html5视频播放代码
  9. WinDbg 入门教程
  10. 链路冗余的解决和故障的备用方案