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

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

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);
}
}

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

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: chinese国产老太性 | 2021国产麻豆剧传媒新片 | 亚洲国产精品久久丫 | 国产自拍偷拍自拍 | 欧美亚洲桃花综合 | 亚洲国产99在线精品一区69堂 | 亚洲国产经典 | 久久久久国产一级毛片高清片 | 色屁屁www | 亚洲国产在 | 2021麻豆剧果冻传媒入口永久 | 国产精品免费久久久久影院小说 | 国产美女极品免费视频 | 99热这里只有精品在线 | 色婷婷六月丁香在线观看 | 2020最新版的ab片 | 日本人啪啪 | 日本高清中文字幕一区二区三区 | 好大好猛好爽好深视频免费 | 欧美3p大片在线观看完整版 | 精品免费国产 | 亚洲精品成人A8198A片漫画 | 四虎在线精品观看免费 | 啊好大好粗 | 国产精品俺来也在线观看了 | 日韩精选在线 | 国产亚洲一级精品久久 | 无码一区国产欧美在线资源 | 日本孕妇与黑人xxxxxx | 国产精品va在线观看手机版 | 色琪琪久久草在线视频 | 欧美亚洲国产另类在线观看 | 99热久久国产精品这里 | 国产高清在线播放免费观看 | 国产欧美综合一区二区 | 激情另类国内一区二区视频 | 国产精品露脸国语对白99 | 日韩 视频在线播放 | 日b视频免费 | 国内外精品免费视频 | 热99re久久精品国产首页 |