一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - 模仿百度紅包福袋界面實例代碼

模仿百度紅包福袋界面實例代碼

2020-03-26 14:03Git_Android JAVA教程

新年到新年到,紅包搶不停。在我搶紅包的時候意外的發現了百度的福袋界面挺不錯的,于是抽時間專門寫篇文章來完成百度紅包界面吧

新年到新年到,紅包搶不停。在我搶紅包的時候意外的發現了百度的福袋界面挺不錯的,于是抽時間專門寫篇文章來完成百度紅包界面吧。

當然啦,這其實就是解鎖界面的進化版本。不過其包含的知識點還是挺多的,寫篇博文記錄一下看看具體有哪些技術點啦。看看百度的效果圖:

模仿百度紅包福袋界面實例代碼

1.編程思路

看看界面,不難發現,其就是一個放入九張圖片的容器,繪制其實可以在其上面另創建一個透明View負責繪制線與圓圈。下面我們將介紹一下實現過程。

㈠自定義ViewGroup

我們知道,自定義ViewGroup一定需要實現其onLayout()方法。該方法是設置子View位置與尺寸的時候調用。還有一個onMeasure()方法,該方法是測量view及其內容來確定view的寬度和高度。

㈡存儲其點與圓的位置及繪制參數

當重回界面的時候,是不會保存上一次繪制界面的內容,必須存儲以備重繪時候繪制到界面

㈢簡單的縮放動畫

㈣自定義View實現繪制界面

㈤繪制完成時,清除界面繪制內容,并且保證不連接重復圖片

下面我們將完成這些步驟。

2.自定義ViewGroup

開始的任務就是將九張圖片平均分布到圖片的位置,顯示在手機界面中。其代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
public class LYJViewGroup extends ViewGroup implements LYJGestureDrawline.OnAnimationCallback{
/**
* 每個點區域的寬度
*/
private int childWidth;
/***
* 上下文
*/
private Context context;
/***
* 保存圖片點的位置
*/
private List<LYJGesturePoint> list;
/***
* 創建view使其在ViewGroup之上。
*/
private LYJGestureView gestureDrawline;
private int baseNum = 5;
public LYJViewGroup(Context context) {
super(context);
this.context = context;
this.list = new ArrayList<>();
DisplayMetrics metric = new DisplayMetrics();
((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(metric);
childWidth = metric.widthPixels / 3; // 屏幕寬度(像素)
addChild();
// 初始化一個可以畫線的view
gestureDrawline = new LYJGestureView(context, list);
gestureDrawline.setAnimationCallback(this);
}
public void setParentView(ViewGroup parent){
// 得到屏幕的寬度
DisplayMetrics metric = new DisplayMetrics();
((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(metric);
int width = metric.widthPixels;
LayoutParams layoutParams = new LayoutParams(width, width);
this.setLayoutParams(layoutParams);
gestureDrawline.setLayoutParams(layoutParams);
parent.addView(this);
parent.addView(gestureDrawline);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
for (int i = 0; i < getChildCount(); i++) {
//第幾行
int rowspan = i / 3;
//第幾列
int column = i % 3;
android.view.View v = getChildAt(i);
v.layout(column * childWidth + childWidth / baseNum, rowspan * childWidth + childWidth / baseNum,
column * childWidth + childWidth - childWidth / baseNum, rowspan * childWidth + childWidth - childWidth / 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);
}
}
private void addChild() {
for (int i = 0; i < 9; i++) {
ImageView image = new ImageView(context);
image.setBackgroundResource(R.drawable.marker);
this.addView(image);
invalidate();
// 第幾行
int rowspan = i / 3;
// 第幾列
int column = i % 3;
// 定義點的左上角與右下角的坐標
int leftX = column * childWidth + childWidth / baseNum;
int topY = rowspan * childWidth + childWidth / baseNum;
int rightX = column * childWidth + childWidth - childWidth / baseNum;
int bottomY = rowspan * childWidth + childWidth - childWidth / baseNum;
LYJGesturePoint p = new LYJGesturePoint(leftX, topY, rightX,bottomY,i);
this.list.add(p);
}
}
@Override
public void startAnimationImage(int i) {
Animation animation= AnimationUtils.loadAnimation(getContext(), R.anim.gridlayout_child_scale_anim);
getChildAt(i).startAnimation(animation);
}
}

3.自定義點類

顧名思義,就是為了獲取點的相關的屬性,其中基礎屬性圖片左上角坐標與右下角坐標,計算圖片中心位置以便獲取圖片中心點。狀態標記,表示該點是否繪制到圖片。下面是其實體類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class LYJGesturePoint {
private Point pointLeftTop;//左上角坐標
private Point pointRightBottom;//右下角坐標
private int centerX;//圖片中心點X坐標
private int centerY;//圖片中心點Y坐標
private int pointState;//是否點擊了該圖片
private int num;
public int getNum() {
return num;
}
public int getPointState() {
return pointState;
}
public void setPointState(int pointState) {
this.pointState = pointState;
}
public Point getPointLeftTop() {
return pointLeftTop;
}
public Point getPointRightBottom() {
return pointRightBottom;
}
public LYJGesturePoint(int left,int top,int right,int bottom,int i){
this.pointLeftTop=new Point(left,top);
this.pointRightBottom=new Point(right,bottom);
this.num=i;
}
public int getCenterX() {
this.centerX=(this.pointLeftTop.x+this.pointRightBottom.x)/2;
return centerX;
}
public int getCenterY() {
this.centerY=(this.pointLeftTop.y+this.pointRightBottom.y)/2;
return centerY;
}
}

4.自定義圓類

這個類較簡單就三個屬性而已(圓中心點坐標及半徑),代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class LYJCirclePoint {
private int roundX;//圓中心點X坐標
private int roundY;//圓中心點Y坐標
private int radiu;//圓半徑
public int getRadiu() {
return radiu;
}
public int getRoundX() {
return roundX;
}
public int getRoundY() {
return roundY;
}
public LYJCirclePoint(int roundX,int roundY,int radiu){
this.roundX=roundX;
this.roundY=roundY;
this.radiu=radiu;
}
}

5.實現自定義繪制類View

代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
public class LYJGestureView extends android.view.View {
/***
* 聲明直線畫筆
*/
private Paint paint;
/***
* 聲明圓圈畫筆
*/
private Paint circlePaint;
/***
* 畫布
*/
private Canvas canvas;
/***
* 位圖
*/
private Bitmap bitmap;
/***
* 裝有各個view坐標的集合,用于判斷點是否在其中
*/
private List<LYJGesturePoint> list;
/***
* 記錄畫過的線
*/
private List<Pair<LYJGesturePoint, LYJGesturePoint>> lineList;
/***
* 記錄畫過的圓
*/
private List<LYJCirclePoint> circlePoints;
/**
* 手指當前在哪個Point內
*/
private LYJGesturePoint currentPoint;
/***
* 手指按下動畫
*/
private OnAnimationCallback animationCallback;
public interface OnAnimationCallback{
public void startAnimationImage(int i);
}
public void setAnimationCallback(OnAnimationCallback animationCallback) {
this.animationCallback = animationCallback;
}
public LYJGestureView(Context context, List<LYJGesturePoint> list){
super(context);
Log.i(getClass().getName(), "GestureDrawline");
paint = new Paint(Paint.DITHER_FLAG);// 創建一個畫筆
circlePaint=new Paint(Paint.DITHER_FLAG);
DisplayMetrics metric = new DisplayMetrics();
((Activity)context).getWindowManager().getDefaultDisplay().getMetrics(metric);
Log.i(getClass().getName(), "widthPixels" + metric.widthPixels);
Log.i(getClass().getName(), "heightPixels" + metric.heightPixels);
bitmap = Bitmap.createBitmap(metric.widthPixels, metric.heightPixels, Bitmap.Config.ARGB_8888); // 設置位圖的寬高
canvas = new Canvas();
canvas.setBitmap(bitmap);
paint.setStyle(Paint.Style.STROKE);// 設置非填充
paint.setStrokeWidth(20);// 筆寬20像素
paint.setColor(Color.rgb(245, 142, 33));// 設置默認連線顏色
paint.setAntiAlias(true);// 不顯示鋸齒
circlePaint.setStyle(Paint.Style.FILL);
circlePaint.setStrokeWidth(1);
circlePaint.setAntiAlias(true);
circlePaint.setColor(Color.rgb(245, 142, 33));
this.list = list;
this.lineList = new ArrayList<>();
this.circlePoints=new ArrayList<>();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
// 判斷當前點擊的位置是處于哪個點之內
currentPoint = getPointAt((int) event.getX(), (int) event.getY());
if (currentPoint != null) {
currentPoint.setPointState(Constants.POINT_STATE_SELECTED);
this.animationCallback.startAnimationImage(currentPoint.getNum());
canvas.drawCircle(currentPoint.getCenterX(), currentPoint.getCenterY(), 20, circlePaint);
circlePoints.add(new LYJCirclePoint(currentPoint.getCenterX(),currentPoint.getCenterY(),20));
}
invalidate();
break;
case MotionEvent.ACTION_MOVE:
clearScreenAndDrawList();
// 得到當前移動位置是處于哪個點內
LYJGesturePoint 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這個點設置選中狀態;
currentPoint.setPointState(Constants.POINT_STATE_SELECTED);
}
}
//如果移動到的點不為圖片區域或者移動到自己的地方,或者該圖片已經為選中狀態,直接畫直線就可以了
if(pointAt == null || currentPoint.equals(pointAt) || Constants.POINT_STATE_SELECTED == pointAt.getPointState()){
canvas.drawCircle(currentPoint.getCenterX(), currentPoint.getCenterY(), 20, circlePaint);
circlePoints.add(new LYJCirclePoint(currentPoint.getCenterX(), currentPoint.getCenterY(), 20));
canvas.drawLine(currentPoint.getCenterX(), currentPoint.getCenterY(), event.getX(), event.getY(), paint);
}else{//其他情況畫兩點相連直線,并且保存繪制圓與直線,并調用按下圖片的縮放動畫
canvas.drawCircle(pointAt.getCenterX(),pointAt.getCenterY(),20,circlePaint);
circlePoints.add(new LYJCirclePoint(pointAt.getCenterX(), pointAt.getCenterY(), 20));
this.animationCallback.startAnimationImage(pointAt.getNum());
pointAt.setPointState(Constants.POINT_STATE_SELECTED);
canvas.drawLine(currentPoint.getCenterX(), currentPoint.getCenterY(), pointAt.getCenterX(), pointAt.getCenterY(), paint);
Pair<LYJGesturePoint, LYJGesturePoint> pair = new Pair<>(currentPoint, pointAt);
lineList.add(pair);
currentPoint=pointAt;//設置選中點為當前點。
}
invalidate();//重繪
break;
case MotionEvent.ACTION_UP:
clearScreenAndDrawList();//防止多出一條沒有終點的直線
new Handler().postDelayed(new clearLineRunnable(), 1000);//1秒后清空繪制界面
invalidate();//重繪
break;
default:
break;
}
return true;
}
class clearLineRunnable implements Runnable {
public void run() {
// 清空保存點與圓的集合
lineList.clear();
circlePoints.clear();
// 重新繪制界面
clearScreenAndDrawList();
for (LYJGesturePoint p : list) {
//設置其為初始化不選中狀態
p.setPointState(Constants.POINT_STATE_NORMAL);
}
invalidate();
}
}
/**
* 通過點的位置去集合里面查找這個點是包含在哪個Point里面的
*
* @param x
* @param y
* @return 如果沒有找到,則返回null,代表用戶當前移動的地方屬于點與點之間
*/
private LYJGesturePoint getPointAt(int x, int y) {
for (LYJGesturePoint point : list) {
// 先判斷點是否在圖片的X坐標內
int leftX = point.getPointLeftTop().x;
int rightX = point.getPointRightBottom().x;
if (!(x >= leftX && x < rightX)) {
// 如果為假,則跳到下一個對比
continue;
}
//在判斷點是否在圖片的Y坐標內
int topY = point.getPointLeftTop().y;
int bottomY = point.getPointRightBottom().y;
if (!(y >= topY && y < bottomY)) {
// 如果為假,則跳到下一個對比
continue;
}
// 如果執行到這,那么說明當前點擊的點的位置在遍歷到點的位置這個地方
return point;
}
return null;
}
/**
* 清掉屏幕上所有的線,然后畫出集合里面的線
*/
private void clearScreenAndDrawList() {
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
for (Pair<LYJGesturePoint, LYJGesturePoint> pair : lineList) {
canvas.drawLine(pair.first.getCenterX(), pair.first.getCenterY(),
pair.second.getCenterX(), pair.second.getCenterY(), paint);// 畫線
}
for(LYJCirclePoint lyjCirclePoint : circlePoints){
canvas.drawCircle(lyjCirclePoint.getRoundX(),lyjCirclePoint.getRoundY(), lyjCirclePoint.getRadiu(),circlePaint);
}
}
//繪制用bitmap創建出來的畫布
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(bitmap, 0, 0, null);
}
}

這樣就可以得到如下界面效果(當然反編譯百度錢包,并沒有百度錢包中的圖片,只好隨便找了一張圖片):

模仿百度紅包福袋界面實例代碼

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 四虎免费影院在线播放 | 国产亚洲精品线观看77 | 美女在尿口隐私视频 | 久久成人a毛片免费观看网站 | 欧美高清无砖专区欧美精品 | 免费一级欧美片在线观看 | 免费看欧美一级特黄a大片一 | 国内揄拍国内精品久久 | 亚洲国产精品自在在线观看 | 国内精品一区二区在线观看 | 国产美女在线一区二区三区 | 波多野结衣之高校教师 | 国产午夜小视频 | 精品无人区乱码1区2区3区在线 | 成人精品在线 | 99在线免费观看视频 | 大桥未久midd—962在线 | 成人私人影院在线观看网址 | 国产成人综合久久精品红 | 亚洲AV久久久噜噜噜久久 | 国产成+人+亚洲+欧美综合 | 午夜神器18以下不能进免费 | 很很草| 五月最新女厕所高跟嘘嘘 | 欧美穿高跟鞋做爰 | 久久受www免费人成_看片中文 | 99超级碰碰成人香蕉网 | 好男人好资源在线观看 | 惊弦45集免费看 | 亚洲AV无码乱码在线观看浪潮 | tobu8在线观看免费高清 | 久久精品一区 | 91视频免费网站 | 亚洲成av人片天堂网 | 欧美日韩高清观看一区二区 | videos变态极端 | 草草在线视频 | 国产香蕉视频在线观看 | 亚州第一页 | 亚洲图片 自拍偷拍 | 国产高清国内精品福利色噜噜 |