激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

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

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

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

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

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

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

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

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

1.編程思路

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

㈠自定義ViewGroup

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

㈡存儲其點與圓的位置及繪制參數(shù)

當(dāng)重回界面的時候,是不會保存上一次繪制界面的內(nèi)容,必須存儲以備重繪時候繪制到界面

㈢簡單的縮放動畫

㈣自定義View實現(xiàn)繪制界面

㈤繪制完成時,清除界面繪制內(nèi)容,并且保證不連接重復(fù)圖片

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

2.自定義ViewGroup

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

?
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{
/**
* 每個點區(qū)域的寬度
*/
private int childWidth;
/***
* 上下文
*/
private Context context;
/***
* 保存圖片點的位置
*/
private List<LYJGesturePoint> list;
/***
* 創(chuàng)建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);
// 遍歷設(shè)置每個子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.自定義點類

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

?
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.實現(xiàn)自定義繪制類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;
/**
* 手指當(dāng)前在哪個Point內(nèi)
*/
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);// 創(chuàng)建一個畫筆
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); // 設(shè)置位圖的寬高
canvas = new Canvas();
canvas.setBitmap(bitmap);
paint.setStyle(Paint.Style.STROKE);// 設(shè)置非填充
paint.setStrokeWidth(20);// 筆寬20像素
paint.setColor(Color.rgb(245, 142, 33));// 設(shè)置默認連線顏色
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:
// 判斷當(dāng)前點擊的位置是處于哪個點之內(nèi)
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();
// 得到當(dāng)前移動位置是處于哪個點內(nèi)
LYJGesturePoint pointAt = getPointAt((int) event.getX(), (int) event.getY());
if (currentPoint == null && pointAt == null) {//你把手指按在屏幕滑動,如果終點與起點都不圖片那么返回
return true;
} else {// 代表用戶的手指移動到了點上
if (currentPoint == null) {// 先判斷當(dāng)前的point是不是為null
// 如果為空,那么把手指移動到的點賦值給currentPoint
currentPoint = pointAt;
// 把currentPoint這個點設(shè)置選中狀態(tài);
currentPoint.setPointState(Constants.POINT_STATE_SELECTED);
}
}
//如果移動到的點不為圖片區(qū)域或者移動到自己的地方,或者該圖片已經(jīng)為選中狀態(tài),直接畫直線就可以了
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{//其他情況畫兩點相連直線,并且保存繪制圓與直線,并調(diào)用按下圖片的縮放動畫
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;//設(shè)置選中點為當(dāng)前點。
}
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) {
//設(shè)置其為初始化不選中狀態(tài)
p.setPointState(Constants.POINT_STATE_NORMAL);
}
invalidate();
}
}
/**
* 通過點的位置去集合里面查找這個點是包含在哪個Point里面的
*
* @param x
* @param y
* @return 如果沒有找到,則返回null,代表用戶當(dāng)前移動的地方屬于點與點之間
*/
private LYJGesturePoint getPointAt(int x, int y) {
for (LYJGesturePoint point : list) {
// 先判斷點是否在圖片的X坐標內(nèi)
int leftX = point.getPointLeftTop().x;
int rightX = point.getPointRightBottom().x;
if (!(x >= leftX && x < rightX)) {
// 如果為假,則跳到下一個對比
continue;
}
//在判斷點是否在圖片的Y坐標內(nèi)
int topY = point.getPointLeftTop().y;
int bottomY = point.getPointRightBottom().y;
if (!(y >= topY && y < bottomY)) {
// 如果為假,則跳到下一個對比
continue;
}
// 如果執(zhí)行到這,那么說明當(dāng)前點擊的點的位置在遍歷到點的位置這個地方
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創(chuàng)建出來的畫布
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(bitmap, 0, 0, null);
}
}

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

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 午夜视频大全 | 成人一区二区三区四区 | 香蕉久久久久久 | 亚洲白嫩在线观看 | 欧美成人影院 | 午夜视频国产 | 国产精品毛片无码 | 黄色片在线观看网站 | 黄色网址免费在线 | 久久精品网址 | 色奇米 | 中国av免费在线观看 | 日韩视频高清 | 久久看视频 | 91九色论坛 | 澳门一级淫片免费视频 | 香蕉秀 | 色播一区 | 欧美成人国产va精品日本一级 | 在线观看中文字幕av | 国产精品视频2021 | 自拍亚洲伦理 | 亚洲午夜影院在线观看 | 欧美亚洲国产成人综合在线 | 一级黄色毛片播放 | a一级黄| 久久超| 99在线热播精品免费 | 国产久草视频在线 | 成人av一区二区免费播放 | 免费毛片电影 | 久久精品成人影院 | 91成人在线免费 | 在线观看网址av | 欧美性生活久久久 | 国产精品久久久久久久久久了 | 欧美高清第一页 | 成人黄色免费电影 | 在线看毛片的网站 | 久久99亚洲精品久久99果 | 亚洲码无人客一区二区三区 |