android 九宫格滑动解锁开机实例源码学习

效果图由于网站占时不能上传,以后补上。
NinePointLineView.java


代码如下:

package org.demo.custon_view;
import org.demo.utils.MLog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Cap;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class NinePointLineView extends View {
Paint linePaint = new Paint();
Paint whiteLinePaint = new Paint();
Paint textPaint = new Paint();
// 由于两个图片都是正方形,所以获取一个长度就行了
Bitmap defaultBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.lock);
int defaultBitmapRadius = defaultBitmap.getWidth() / 2;
// 初始化被选中图片的直径、半径
Bitmap selectedBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.indicator_lock_area);
int selectedBitmapDiameter = selectedBitmap.getWidth();
int selectedBitmapRadius = selectedBitmapDiameter / 2;
// 定义好9个点的数组
PointInfo[] points = new PointInfo[9];
// 相应ACTION_DOWN的那个点
PointInfo startPoint = null;
// 屏幕的宽高
int width, height;
// 当ACTION_MOVE时获取的X,Y坐标
int moveX, moveY;
// 是否发生ACTION_UP
boolean isUp = false;
// 最终生成的用户锁序列
StringBuffer lockString = new StringBuffer();
public NinePointLineView(Context context) {
super(context);
this.setBackgroundColor(Color.WHITE);
initPaint();
}
public NinePointLineView(Context context, AttributeSet attrs) {
super(context, attrs);
this.setBackgroundColor(Color.WHITE);
initPaint();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
MLog.i("onMeasure");
// 初始化屏幕大小
width = getWidth();
height = getHeight();
if (width != 0 && height != 0) {
initPoints(points);
}
MLog.i("width、height = " + width + "、" + height);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
MLog.i("onLayout");
super.onLayout(changed, left, top, right, bottom);
}
private int startX = 0, startY = 0;
@Override
protected void onDraw(Canvas canvas) {
canvas.drawText("用户的滑动顺序:" + lockString, 0, 40, textPaint);
if (moveX != 0 && moveY != 0 && startX != 0 && startY != 0) {
// 绘制当前活动的线段
drawLine(canvas, startX, startY, moveX, moveY);
}
drawNinePoint(canvas);
super.onDraw(canvas);
}
// 记住,这个DOWN和MOVE、UP是成对的,如果没从UP释放,就不会再获得DOWN;
// 而获得DOWN时,一定要确认消费该事件,否则MOVE和UP不会被这个View的onTouchEvent接收
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean flag = true;
if (isUp) {// 如果已滑完,重置每个点的属性和lockString
finishDraw();
// 当UP后,要返回false,把事件释放给系统,否则无法获得Down事件
flag = false;
} else {// 没滑完,则继续绘制
handlingEvent(event);
// 这里要返回true,代表该View消耗此事件,否则不会收到MOVE和UP事件
flag = true;
}
return flag;
}
private void handlingEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
moveX = (int) event.getX();
moveY = (int) event.getY();
MLog.i("onMove:" + moveX + "、" + moveY);
for (PointInfo temp : points) {
if (temp.isInMyPlace(moveX, moveY) && temp.isNotSelected()) {
temp.setSelected(true);
startX = temp.getCenterX();
startY = temp.getCenterY();
int len = lockString.length();
if (len != 0) {
int preId = lockString.charAt(len - 1) - 48;
points[preId].setNextId(temp.getId());
}
lockString.append(temp.getId());
break;
}
}
invalidate(0, height - width, width, height);
break;
case MotionEvent.ACTION_DOWN:
int downX = (int) event.getX();
int downY = (int) event.getY();
MLog.i("onDown:" + downX + "、" + downY);
for (PointInfo temp : points) {
if (temp.isInMyPlace(downX, downY)) {
temp.setSelected(true);
startPoint = temp;
startX = temp.getCenterX();
startY = temp.getCenterY();
lockString.append(temp.getId());
break;
}
}
invalidate(0, height - width, width, height);
break;
case MotionEvent.ACTION_UP:
MLog.i("onUp");
startX = startY = moveX = moveY = 0;
isUp = true;
invalidate();
break;
default:
MLog.i("收到其他事件!!");
break;
}
}
private void finishDraw() {
for (PointInfo temp : points) {
temp.setSelected(false);
temp.setNextId(temp.getId());
}
lockString.delete(0, lockString.length());
isUp = false;
invalidate();
}
private void initPoints(PointInfo[] points) {
int len = points.length;
int seletedSpacing = (width - selectedBitmapDiameter * 3) / 4;
// 被选择时显示图片的左上角坐标
int seletedX = seletedSpacing;
int seletedY = height - width + seletedSpacing;
// 没被选时图片的左上角坐标
int defaultX = seletedX + selectedBitmapRadius - defaultBitmapRadius;
int defaultY = seletedY + selectedBitmapRadius - defaultBitmapRadius;
// 绘制好每个点
for (int i = 0; i < len; i++) {
if (i == 3 || i == 6) {
seletedX = seletedSpacing;
seletedY += selectedBitmapDiameter + seletedSpacing;
defaultX = seletedX + selectedBitmapRadius
- defaultBitmapRadius;
defaultY += selectedBitmapDiameter + seletedSpacing;
}
points[i] = new PointInfo(i, defaultX, defaultY, seletedX, seletedY);
seletedX += selectedBitmapDiameter + seletedSpacing;
defaultX += selectedBitmapDiameter + seletedSpacing;
}
}
private void initPaint() {
initLinePaint(linePaint);
initTextPaint(textPaint);
initWhiteLinePaint(whiteLinePaint);
}
/**
* 初始化文本画笔
* @param paint
*/
private void initTextPaint(Paint paint) {
textPaint.setTextSize(30);
textPaint.setAntiAlias(true);
textPaint.setTypeface(Typeface.MONOSPACE);
}
/**
* 初始化黑线画笔
*
* @param paint
*/
private void initLinePaint(Paint paint) {
paint.setColor(Color.GRAY);
paint.setStrokeWidth(defaultBitmap.getWidth());
paint.setAntiAlias(true);
paint.setStrokeCap(Cap.ROUND);
}
/**
* 初始化白线画笔
*
* @param paint
*/
private void initWhiteLinePaint(Paint paint) {
paint.setColor(Color.WHITE);
paint.setStrokeWidth(defaultBitmap.getWidth() - 5);
paint.setAntiAlias(true);
paint.setStrokeCap(Cap.ROUND);
}
/**
* 绘制已完成的部分
*
* @param canvas
*/
private void drawNinePoint(Canvas canvas) {
if (startPoint != null) {
drawEachLine(canvas, startPoint);
}
// 绘制每个点的图片
for (PointInfo pointInfo : points) {
if (pointInfo.isSelected()) {// 绘制大圈
canvas.drawBitmap(selectedBitmap, pointInfo.getSeletedX(),
pointInfo.getSeletedY(), null);
}
// 绘制点
canvas.drawBitmap(defaultBitmap, pointInfo.getDefaultX(),
pointInfo.getDefaultY(), null);
}
}
/**
* 递归绘制每两个点之间的线段
*
* @param canvas
* @param point
*/
private void drawEachLine(Canvas canvas, PointInfo point) {
if (point.hasNextId()) {
int n = point.getNextId();
drawLine(canvas, point.getCenterX(), point.getCenterY(),
points[n].getCenterX(), points[n].getCenterY());
// 递归
drawEachLine(canvas, points[n]);
}
}
/**
* 先绘制黑线,再在上面绘制白线,达到黑边白线的效果
*
* @param canvas
* @param startX
* @param startY
* @param stopX
* @param stopY
*/
private void drawLine(Canvas canvas, float startX, float startY,
float stopX, float stopY) {
canvas.drawLine(startX, startY, stopX, stopY, linePaint);
canvas.drawLine(startX, startY, stopX, stopY, whiteLinePaint);
}
/**
* 用来表示一个点
*
* @author zkwlx
*
*/
private class PointInfo {
// 一个点的ID
private int id;
// 当前点所指向的下一个点的ID,当没有时为自己ID
private int nextId;
// 是否被选中
private boolean selected;
// 默认时图片的左上角X坐标
private int defaultX;
// 默认时图片的左上角Y坐标
private int defaultY;
// 被选中时图片的左上角X坐标
private int seletedX;
// 被选中时图片的左上角Y坐标
private int seletedY;
public PointInfo(int id, int defaultX, int defaultY, int seletedX,
int seletedY) {
this.id = id;
this.nextId = id;
this.defaultX = defaultX;
this.defaultY = defaultY;
this.seletedX = seletedX;
this.seletedY = seletedY;
}
public boolean isSelected() {
return selected;
}
public boolean isNotSelected() {
return !isSelected();
}
public void setSelected(boolean selected) {
this.selected = selected;
}
public int getId() {
return id;
}
public int getDefaultX() {
return defaultX;
}
public int getDefaultY() {
return defaultY;
}
public int getSeletedX() {
return seletedX;
}
public int getSeletedY() {
return seletedY;
}
public int getCenterX() {
return seletedX + selectedBitmapRadius;
}
public int getCenterY() {
return seletedY + selectedBitmapRadius;
}
public boolean hasNextId() {
return nextId != id;
}
public int getNextId() {
return nextId;
}
public void setNextId(int nextId) {
this.nextId = nextId;
}
/**
* 坐标(x,y)是否在当前点的范围内
*
* @param x
* @param y
* @return
*/
public boolean isInMyPlace(int x, int y) {
boolean inX = x > seletedX
&& x < (seletedX + selectedBitmapDiameter);
boolean inY = y > seletedY
&& y < (seletedY + selectedBitmapDiameter);
return (inX && inY);
}
}
}

NinePointView.java


代码如下:

package org.demo.custon_view;
import org.demo.utils.MLog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Cap;
import android.graphics.Path;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class NinePointView extends View {
Paint linePaint = new Paint();
Paint textPaint = new Paint();
Path path = new Path();
// 由于两个图片都是正方形,所以获取一个长度就行了
Bitmap defaultBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.lock);
int defaultBitmapRadius = defaultBitmap.getWidth() / 2;
// 初始化被选中图片的直径、半径
Bitmap selectedBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.indicator_lock_area);
int selectedBitmapDiameter = selectedBitmap.getWidth();
int selectedBitmapRadius = selectedBitmapDiameter / 2;
// 初始化指示器的图片
Bitmap indicateBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.indicator_lock_area_next);
Bitmap tempBitmap = null;
// 定义好9个点的数组
PointInfo[] points = new PointInfo[9];
// 屏幕的宽高
int width, height;
// 当ACTION_MOVE时获取的X,Y坐标
int moveX, moveY;
// 是否发生ACTION_UP
boolean isUp = false;
// 最终生成的用户锁序列
StringBuffer lockString = new StringBuffer();
Matrix matrix = new Matrix();
public NinePointView(Context context) {
super(context);
this.setBackgroundColor(Color.WHITE);
initLinePaint(linePaint);
initTextPaint(textPaint);
}
public NinePointView(Context context, AttributeSet attrs) {
super(context, attrs);
this.setBackgroundColor(Color.WHITE);
initLinePaint(linePaint);
initTextPaint(textPaint);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
MLog.i("onMeasure");
width = getWidth();
height = getHeight();
if (width != 0 && height != 0) {
initPoints(points);
}
MLog.i("width、height = " + width + "、" + height);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
MLog.i("onLayout");
super.onLayout(changed, left, top, right, bottom);
}
private int startX = 0, startY = 0;
@Override
protected void onDraw(Canvas canvas) {
canvas.drawText("用户的滑动顺序:" + lockString, 0, 40, textPaint);
if (moveX != 0 && moveY != 0 && startX != 0 && startY != 0) {
// 绘制当前活动的线段
canvas.drawLine(startX, startY, moveX, moveY, linePaint);
}
drawNinePoint(canvas, linePaint);
super.onDraw(canvas);
}
// 记住,这个DOWN和MOVE、UP是成对的,如果没从UP释放,就不会再获得DOWN;
// 而获得DOWN时,一定要确认消费该事件,否则MOVE和UP不会被这个VIEW的onTouchEvent接收
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean flag = true;
if (isUp) {// 如果已滑完,则把整个Canvas重置
finishDraw();
// 当UP后,要返回false,把事件释放给系统,否则无法获得Down事件
flag = false;
} else {// 没滑完,则继续绘制
handlingEvent(event);
// 这里要返回true,否则代表该View不消耗此事件,交给系统处理,则不会再收到MOVE和UP事件
flag = true;
}
return flag;
}
private void handlingEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
moveX = (int) event.getX();
moveY = (int) event.getY();
MLog.i("onMove:" + moveX + "、" + moveY);
for (PointInfo temp : points) {
if (temp.isInMyPlace(moveX, moveY) && temp.isNotSelected()) {
temp.setSelected(true);
startX = temp.getCenterX();
startY = temp.getCenterY();
int len = lockString.length();
if (len != 0) {
int preId = lockString.charAt(len - 1) - 48;
points[preId].setNextId(temp.getId());
}
lockString.append(temp.getId());
break;
}
}
invalidate(0, height - width, width, height);
break;
case MotionEvent.ACTION_DOWN:
int downX = (int) event.getX();
int downY = (int) event.getY();
MLog.i("onDown:" + downX + "、" + downY);
for (PointInfo temp : points) {
if (temp.isInMyPlace(downX, downY)) {
temp.setSelected(true);
startX = temp.getCenterX();
startY = temp.getCenterY();
lockString.append(temp.getId());
break;
}
}
invalidate(0, height - width, width, height);
break;
case MotionEvent.ACTION_UP:
MLog.i("onUp");
startX = startY = moveX = moveY = 0;
isUp = true;
invalidate();
break;
default:
MLog.i("收到其他事件!!");
break;
}
}
private void finishDraw() {
for (PointInfo temp : points) {
temp.setSelected(false);
temp.setNextId(temp.getId());
}
lockString.delete(0, lockString.length());
isUp = false;
invalidate();
}
private void initPoints(PointInfo[] points) {
int len = points.length;
int seletedSpacing = (width - selectedBitmapDiameter * 3) / 4;
// 被选择时显示图片的左上角坐标
int seletedX = seletedSpacing;
int seletedY = height - width + seletedSpacing;
// 没被选时图片的左上角坐标
int defaultX = seletedX + selectedBitmapRadius - defaultBitmapRadius;
int defaultY = seletedY + selectedBitmapRadius - defaultBitmapRadius;
for (int i = 0; i < len; i++) {
if (i == 3 || i == 6) {
seletedX = seletedSpacing;
seletedY += selectedBitmapDiameter + seletedSpacing;
defaultX = seletedX + selectedBitmapRadius
- defaultBitmapRadius;
defaultY += selectedBitmapDiameter + seletedSpacing;
}
points[i] = new PointInfo(i, defaultX, defaultY, seletedX, seletedY);
seletedX += selectedBitmapDiameter + seletedSpacing;
defaultX += selectedBitmapDiameter + seletedSpacing;
}
}
private void initTextPaint(Paint paint) {
textPaint.setTextSize(30);
textPaint.setAntiAlias(true);
textPaint.setTypeface(Typeface.MONOSPACE);
}
/**
* 初始化线画笔
*
* @param paint
*/
private void initLinePaint(Paint paint) {
paint.setColor(Color.GRAY);
paint.setStrokeWidth(defaultBitmap.getWidth());
paint.setAntiAlias(true);
paint.setStrokeCap(Cap.ROUND);
}
/**
* 绘制已完成的部分
*
* @param canvas
*/
private void drawNinePoint(Canvas canvas, Paint paint) {
// 先把用户画出的线绘制好
for (PointInfo pointInfo : points) {
if (pointInfo.hasNextId()) {
int n = pointInfo.getNextId();
canvas.drawLine(pointInfo.getCenterX(), pointInfo.getCenterY(),
points[n].getCenterX(), points[n].getCenterY(), paint);
}
}
// 绘制每个点的图片
for (PointInfo pointInfo : points) {
if (pointInfo.isSelected()) {
if (pointInfo.hasNextId()) {
matrix.reset();
int i = (int) Math.abs(Math.random() * 1000 - 640);
MLog.i("随机到的角度:" + i);
matrix.setRotate(i);
tempBitmap = Bitmap.createBitmap(indicateBitmap, 0, 0,
indicateBitmap.getWidth(),
indicateBitmap.getHeight(), matrix, false);
canvas.drawBitmap(tempBitmap, pointInfo.getSeletedX(),
pointInfo.getSeletedY(), paint);
} else {
canvas.drawBitmap(selectedBitmap, pointInfo.getSeletedX(),
pointInfo.getSeletedY(), paint);
}
}
canvas.drawBitmap(defaultBitmap, pointInfo.getDefaultX(),
pointInfo.getDefaultY(), paint);
}
}
private class PointInfo {
// 一个点的ID
private int id;
// 当前点所指向的下一个点的ID,当没有时为自己ID
private int nextId;
// 是否被选中
private boolean selected;
// 默认时图片的左上角X坐标
private int defaultX;
// 默认时图片的左上角Y坐标
private int defaultY;
// 被选中时图片的左上角X坐标
private int seletedX;
// 被选中时图片的左上角Y坐标
private int seletedY;
public PointInfo(int id, int defaultX, int defaultY, int seletedX,
int seletedY) {
this.id = id;
this.nextId = id;
this.defaultX = defaultX;
this.defaultY = defaultY;
this.seletedX = seletedX;
this.seletedY = seletedY;
}
public boolean isSelected() {
return selected;
}
public boolean isNotSelected() {
return !isSelected();
}
public void setSelected(boolean selected) {
this.selected = selected;
}
public int getId() {
return id;
}
public int getDefaultX() {
return defaultX;
}
public int getDefaultY() {
return defaultY;
}
public int getSeletedX() {
return seletedX;
}
public int getSeletedY() {
return seletedY;
}
public int getCenterX() {
return seletedX + selectedBitmapRadius;
}
public int getCenterY() {
return seletedY + selectedBitmapRadius;
}
public boolean hasNextId() {
return nextId != id;
}
public int getNextId() {
return nextId;
}
public void setNextId(int nextId) {
this.nextId = nextId;
}
/**
* 坐标(x,y)是否在当前点的范围内
*
* @param x
* @param y
* @return
*/
public boolean isInMyPlace(int x, int y) {
boolean inX = x > seletedX
&& x < (seletedX + selectedBitmapDiameter);
boolean inY = y > seletedY
&& y < (seletedY + selectedBitmapDiameter);
if (inX && inY) {
return true;
} else {
return false;
}
}
}
}

(0)

相关推荐

  • Android实现九宫格解锁的实例代码

    当年感觉九宫格解锁很是高大上,一脸懵逼,今天正好要做解锁这一块业务,回头来看九宫格,这特么简单啊 首先理清一下逻辑,我们要做NxN的九宫格 下图是3x3的简单图例 // -(--)-(--)-(--)- // -(--)-(--)-(--)- // -(--)-(--)-(--)- 我们就把九宫格分解成 外圆 .内圆.连线三部分 外圆半径Radius,内圆半径dp(5) 建立一个集合来放置 外圆的圆心( 内圆的圆心也一样) private ArrayList<Point> mListCircl

  • Android自定义控件实现九宫格解锁功能

    最终Android九宫格解锁效果如下 1.进行定义实体point点 public class Point { private float x; private float y; //正常模式 public static final int NORMAL_MODE = 1; //按下模式 public static final int PRESSED_MODE = 2; //错误模式 public static final int ERROR_MODE = 3; private int state

  • 轻松实现Android自定义九宫格图案解锁

    Android实现九宫格图案解锁,自带将图案转化成数字密码的功能,代码如下: LockPatternView.java package com.jackie.lockpattern; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Point; import android.text.TextUtils; i

  • 使用Android自定义控件实现滑动解锁九宫格

    本文概述:  滑动解锁九宫格的分析: 1.需要自定义控件: 2.需要重写事件onTouchEvent(); 3.需要给九个点设置序号和坐标,这里用Map类就行: 4.需要判断是否到滑到过九点之一,并存储滑到过的点的序号,而且需要一个方法可以返回它们,这里用List类就行: 滑动解锁当前还是比较流行的,今天写了个简单的滑动解锁九宫格的例程,分享出来让初学者看看. 我的是这样的: Demo 首先,自定义一个View /** * 九宫格 */ public class NineGridView ext

  • Android 仿小米锁屏实现九宫格解锁功能(无需图片资源)

    最近公司要求做个九宫格解锁,本人用的是小米手机,看着他那个设置锁屏九宫格很好看,就做了该组件,不使用图片资源,纯代码实现. 尊重每个辛苦的博主,在http://blog.csdn.net/mu399/article/details/38734449的基础上进行修改 效果图: 关键代码类: MathUtil.Java /** * @author SoBan * @create 2016/12/5 15:52. */ public class MathUtil { public static dou

  • 轻松实现安卓(Android)九宫格解锁

    效果图 思路 首先我们来分析一下实现九宫格解锁的思路:当用户的手指触摸到某一个点时,先判断该点是否在九宫格的某一格范围之内,若在范围内,则该格变成选中的状态:之后用户手指滑动的时候,以该格的圆心为中心,用户手指为终点,两点连线.最后当用户手指抬起时,判断划过的九宫格密码是否和原先的密码匹配. 大致的思路流程就是上面这样的了,下面我们可以来实践一下. Point 类 我们先来创建一个 Point 类,用来表示九宫格锁的九个格子.除了坐标 x ,y 之外,还有三种模式:正常模式.按下模式和错误模式.

  • Android实现九宫格解锁的方法

    相信大家都有使用九宫格解锁,比如在设置手机安全项目中,可以使用九宫格解锁,提高安全性,以及在使用支付功能的时候,为了提高安全使用九宫锁,今天就为大家介绍Android实现九宫格的方法,分享给大家供大家参考.具体如下: 运行效果截图如下: 具体代码如下: 布局文件如下: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas

  • android 九宫格滑动解锁开机实例源码学习

    效果图由于网站占时不能上传,以后补上. NinePointLineView.java 复制代码 代码如下: package org.demo.custon_view; import org.demo.utils.MLog; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; imp

  • Android管理与操作Wifi简单实例源码

    因为需要一直在弄网络的问题,今天看了一下Wifi的操作,经过整理,做出来了一个类,可能不全,但是个人感觉已经完全能够满足需要了,当然,里面的方法也有可能是错误的或者是不全的,这个类我没有进行完整的测试,只测试了其中的一些方法. 其实操作Wifi也是很简单的,主要使用以下几个对象或变量: private WifiManager wifiManager;// 声明管理对象OpenWifi private WifiInfo wifiInfo;// Wifi信息 private List<ScanRes

  • Android实现一个比相册更高大上的左右滑动特效(附源码)

    目录 实现思路 源码如下: 在Android里面,想要实现一个类似相册的左右滑动效果,我们除了可以用Gallery.HorizontalScrollView.ViewPager等控件,还可以用一个叫做 ViewFlipper 的类来代替实现,它继承于 ViewAnimator.如见其名,这个类是跟动画有关,会将添加到它里面的两个或者多个View做一个动画,然后每次只显示一个子View,通过在 View 之间切换时执行动画,最终达到一个类似相册能左右滑动的效果. 本次功能要实现的两个基本效果 最基

  • Android通过访问网页查看网页源码实例详解

    Android通过访问网页查看网页源码 1.添加网络权限 <!--访问网络的权限--> <uses-permission android:name="android.permission.INTERNET"/> 2.获取网络中网页的数据 /** * 获取网页HTML源代码 * @param path 网页路径 */ public static String getHtml(String path) throws Exception { URL url=new U

  • vue loadmore 组件滑动加载更多源码解析

    上一篇讲到在项目中使用上拉加载更多组件,但是由于实际项目开发中由于需求变更或者说在webview中上拉加载有些机型在上拉时候会把webview也一起上拉导致上拉加载不灵敏等问题,我们有时候也会换成滑动到底部自动加载的功能. 既然都是加载更多,很多代码思想势必相似,主要区别在于上拉和滑动到底部这个操作上,所以,我们需要注意: 上拉加载是point指针touch触摸事件,现在因为是滑动加载,需要添加scroll事件去监听然后执行相应回调 上拉加载主要计算触摸滚动距离,滑动加载主要计算containe

  • 基于jQuery和hwSlider实现内容左右滑动切换效果附源码下载(一)

    内容滑动切换应用非常广,常见的有幻灯片焦点图.画廊切换等.随着WEB前端技术的广泛应用,内容滑动切换效果占据着web页面重要地位,因此本站Helloweba特别给广大前端爱好者安排了浅显易懂的内容滑动切换效果的开发教程. 先给大家展示下效果图,感觉还不错请参数实现代码,具体效果如下所示: 效果展示      源码下载 本次教程分三个部分: 1.使用jQuery开发基本的内容滑动切换效果, 2.支持移动端触控自适应的内容滑动切换效果, 3.封装内容滑动切换效果jQuery插件. 本文讲解第一部分,

  • Android入门之使用eclipse进行源码开发的方法

    本文实例讲述了Android入门之使用eclipse进行源码开发的方法.分享给大家供大家参考,具体如下: 一.版本说明: 1. eclipse for javaEE 3.5.2 2. jdk1.6 3. adt12.0 4. linux/Ubuntu10.04 或者 linux/ubuntu10.10 二.准备工作: 1. 下载 Android2.3.7 源码 欲了解具体内容可以参看 android 官网. 2. 编译源码 必须编译源码,否则会引发很多问题.记住:如果下载没问题的话,编译只是时间

  • android实现滑动解锁

    本文实例为大家分享了android实现滑动解锁的具体代码,供大家参考,具体内容如下 效果图 需要用到的画笔, 整体灰色的背景,  滑块, 滑动之后绿色背景, 字体 mSliPaint = new Paint(); mSliPaint.setColor(Color.parseColor("#4a4c5b")); mSliPaint.setAntiAlias(true); mBgPaint = new Paint(); mBgPaint.setColor(Color.parseColor(

  • Android okhttp的启动流程及源码解析

    前言 这篇文章主要讲解了okhttp的主要工作流程以及源码的解析. 什么是OKhttp 简单来说 OkHttp 就是一个客户端用来发送 HTTP 消息并对服务器的响应做出处理的应用层框架. 那么它有什么优点呢? 易使用.易扩展. 支持 HTTP/2 协议,允许对同一主机的所有请求共用同一个 socket 连接. 如果 HTTP/2 不可用, 使用连接池复用减少请求延迟. 支持 GZIP,减小了下载大小. 支持缓存处理,可以避免重复请求. 如果你的服务有多个 IP 地址,当第一次连接失败,OkHt

  • Android源码学习之组合模式定义及应用

    组合模式定义: Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly. 将对象组合成树形结构以表示"部分-整体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性. 如上图所示(截取自<Head First De

随机推荐