本文實例為大家分享了android桌面懸浮窗,實現錄屏時間控制顯示效果的具體代碼,供大家參考,具體內容如下
懸浮窗效果如上圖所示:
很簡單的一個布局直接上代碼
懸浮窗布局如下record_screen_time_float.xml
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
|
<? xml version = "1.0" encoding = "utf-8" ?> < LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android" android:layout_width = "wrap_content" android:layout_height = "wrap_content" > < LinearLayout android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:background = "@drawable/corners_bg" android:paddingBottom = "3dp" android:paddingTop = "3dp" android:paddingLeft = "15dp" android:paddingRight = "8dp" android:layout_gravity = "center" android:gravity = "center" android:orientation = "horizontal" > < TextView android:id = "@+id/record_time" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "00:00" android:textColor = "#ffffff" android:textSize = "10dp" /> < View android:layout_width = "2dp" android:layout_height = "match_parent" android:layout_marginLeft = "5dp" android:layout_marginRight = "5dp" android:textColor = "#ffffff" /> < LinearLayout android:id = "@+id/stop_record" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_gravity = "center" android:gravity = "center" android:orientation = "horizontal" > < ImageView android:id = "@+id/record_hint_button" android:layout_width = "10dp" android:layout_height = "10dp" android:layout_marginRight = "5dp" android:background = "#FF4040" /> < TextView android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "結束" android:textColor = "#ffffff" android:textSize = "10dp" /> </ LinearLayout > </ LinearLayout > </ LinearLayout > |
懸浮窗是在service中拉起可以根據個人需要修改
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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
|
package com.android.systemui; import android.annotation.TargetApi; import android.app.Service; import android.content.Context; import android.content.Intent; import android.os.Binder; import android.os.Build; import android.os.Environment; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.support.annotation.RequiresApi; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.animation.LinearInterpolator; import android.graphics.PixelFormat; import android.view.GestureDetector; import android.view.GestureDetector.SimpleOnGestureListener; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.widget.LinearLayout; import android.widget.TextView; import android.view.View.OnTouchListener; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.Toast; import com.android.systemui.R; import android.util.Log; import java.io.File; import java.io.IOException; public class ScreenRecordService extends Service implements Handler.Callback { private final String TAG = "ScreenRecordService" ; private Handler mHandler; //已經錄制多少秒了 private int mRecordSeconds = 0 ; private static final int MSG_TYPE_COUNT_DOWN = 110 ; /** * 定義浮動窗口布局 */ LinearLayout mlayout; TextView recordTime; /** * 懸浮窗控件 */ ImageView recordHintButton; LinearLayout stopRecord; /** * 懸浮窗的布局 */ WindowManager.LayoutParams wmParams; LayoutInflater inflater; /** * 創建浮動窗口設置布局參數的對象 */ WindowManager mWindowManager; //觸摸監聽器 GestureDetector mGestureDetector; FloatingListener mFloatingListener; @Override public void onCreate() { super .onCreate(); initWindow(); //設置窗口的參數 initFloating(); //設置懸浮窗圖標 } @Override public void onDestroy() { super .onDestroy(); try { if (mlayout != null ) { // 移除懸浮窗口 mWindowManager.removeView(mlayout); } } catch (Exception e) { Log.e(TAG, "not attached to window manager" ); } } @RequiresApi (api = Build.VERSION_CODES.LOLLIPOP) @Override public boolean handleMessage(Message msg) { switch (msg.what) { case MSG_TYPE_COUNT_DOWN: { mRecordSeconds++; int minute = 0 , second = 0 ; if (mRecordSeconds >= 60 ) { minute = mRecordSeconds / 60 ; second = mRecordSeconds % 60 ; } else { second = mRecordSeconds; } String timeTip = "" +minute+ ":" +second; recordTime.setText(timeTip); } break ; } } return true ; } /** * 初始化windowManager */ private void initWindow() { if (mWindowManager == null ) { mWindowManager = (WindowManager) getApplication().getSystemService(Context.WINDOW_SERVICE); } wmParams = getParams(wmParams); //設置好懸浮窗的參數 // 懸浮窗默認顯示以左上角為起始坐標 wmParams.gravity = Gravity.LEFT | Gravity.TOP; //懸浮窗的開始位置,因為設置的是從左上角開始,所以屏幕左上角是x=0;y=0 wmParams.x = 0 ; wmParams.y = 0 ; //得到容器,通過這個inflater來獲得懸浮窗控件 if (inflater == null ) { inflater = LayoutInflater.from(getApplication()); } // 獲取浮動窗口視圖所在布局 if (mlayout == null ) { mlayout = (LinearLayout) inflater.inflate(R.layout.record_screen_time_float, null ); } // 添加懸浮窗的視圖 mWindowManager.addView(mlayout, wmParams); } /** * 對windowManager進行設置 * * @param wmParams * @return */ public WindowManager.LayoutParams getParams(WindowManager.LayoutParams wmParams) { if (wmParams == null ) { wmParams = new WindowManager.LayoutParams(); } //設置window type 下面變量2002是在屏幕區域顯示,2003則可以顯示在狀態欄之上 //wmParams.type = LayoutParams.TYPE_PHONE; //wmParams.type = LayoutParams.TYPE_SYSTEM_ALERT; wmParams.type = LayoutParams.TYPE_SYSTEM_ERROR; //設置圖片格式,效果為背景透明 wmParams.format = PixelFormat.RGBA_8888; //設置浮動窗口不可聚焦(實現操作除浮動窗口外的其他可見窗口的操作) //wmParams.flags = LayoutParams.FLAG_NOT_FOCUSABLE; //設置可以顯示在狀態欄上 wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH; //設置懸浮窗口長寬數據 wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT; wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT; return wmParams; } /** * 找到懸浮窗的圖標,并且設置事件 * 設置懸浮窗的點擊、滑動事件 */ private void initFloating() { recordTime = (TextView) mlayout.findViewById(R.id.record_time); recordHintButton = (ImageView) mlayout.findViewById(R.id.record_hint_button); setFlickerAnimation(recordHintButton); stopRecord = (LinearLayout) mlayout.findViewById(R.id.stop_record); mlayout.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Log.d(TAG, "OnClickListener" ); ScreenUtil.stopScreenRecord(ScreenRecordService. this ); } }); if (mGestureDetector == null ) { mGestureDetector = new GestureDetector( this , new MyOnGestureListener()); } if (mFloatingListener == null ){ //設置監聽器 mFloatingListener = new FloatingListener(); } mlayout.setOnTouchListener(mFloatingListener); stopRecord.setOnTouchListener(mFloatingListener); } /× ×錄屏狀態顯示(閃爍效果) ×/ private void setFlickerAnimation(ImageView iv_chat_head) { final Animation animation = new AlphaAnimation( 1 , 0 ); // Change alpha from fully visible to invisible animation.setDuration( 500 ); // duration - half a second animation.setInterpolator( new LinearInterpolator()); // do not alter animation rate animation.setRepeatCount(Animation.INFINITE); // Repeat animation infinitely animation.setRepeatMode(Animation.REVERSE); // iv_chat_head.setAnimation(animation); } //開始觸控的坐標,移動時的坐標(相對于屏幕左上角的坐標) private int mTouchStartX, mTouchStartY, mTouchCurrentX, mTouchCurrentY; //開始時的坐標和結束時的坐標(相對于自身控件的坐標) private int mStartX, mStartY, mStopX, mStopY; private boolean isMove; //判斷懸浮窗是否移動 /** * 懸浮窗監聽器 */ private class FloatingListener implements OnTouchListener { @Override public boolean onTouch(View arg0, MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: isMove = false ; mTouchStartX = ( int ) event.getRawX(); mTouchStartY = ( int ) event.getRawY(); mStartX = ( int ) event.getX(); mStartY = ( int ) event.getY(); break ; case MotionEvent.ACTION_MOVE: mTouchCurrentX = ( int ) event.getRawX(); mTouchCurrentY = ( int ) event.getRawY(); wmParams.x += mTouchCurrentX - mTouchStartX; wmParams.y += mTouchCurrentY - mTouchStartY; if (mlayout != null ) { mWindowManager.updateViewLayout(mlayout, wmParams); } mTouchStartX = mTouchCurrentX; mTouchStartY = mTouchCurrentY; break ; case MotionEvent.ACTION_UP: mStopX = ( int ) event.getX(); mStopY = ( int ) event.getY(); if (Math.abs(mStartX - mStopX) >= 1 || Math.abs(mStartY - mStopY) >= 1 ) { isMove = true ; } break ; } return mGestureDetector.onTouchEvent(event); //此處必須返回false,否則OnClickListener獲取不到監聽 } } /** * 自定義的手勢監聽類 */ class MyOnGestureListener extends SimpleOnGestureListener { @Override public boolean onSingleTapConfirmed(MotionEvent e) { if (!isMove) { System.out.println( "onclick" ); } return super .onSingleTapConfirmed(e); } } } |
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/zhuxingchong/article/details/80760179