android桌面懸浮窗顯示錄屏?xí)r間控制效果
本文實(shí)例為大家分享了android桌面懸浮窗,實(shí)現(xiàn)錄屏?xí)r間控制顯示效果的具體代碼,供大家參考,具體內(nèi)容如下
懸浮窗效果如上圖所示:
很簡(jiǎn)單的一個(gè)布局直接上代碼
懸浮窗布局如下record_screen_time_float.xml
<?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="結(jié)束" android:textColor="#ffffff" android:textSize="10dp" /> </LinearLayout> </LinearLayout> </LinearLayout>
懸浮窗是在service中拉起可以根據(jù)個(gè)人需要修改
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; //已經(jīng)錄制多少秒了 private int mRecordSeconds = 0; private static final int MSG_TYPE_COUNT_DOWN = 110; /** * 定義浮動(dòng)窗口布局 */ LinearLayout mlayout; TextView recordTime; /** * 懸浮窗控件 */ ImageView recordHintButton; LinearLayout stopRecord; /** * 懸浮窗的布局 */ WindowManager.LayoutParams wmParams; LayoutInflater inflater; /** * 創(chuàng)建浮動(dòng)窗口設(shè)置布局參數(shù)的對(duì)象 */ WindowManager mWindowManager; //觸摸監(jiān)聽器 GestureDetector mGestureDetector; FloatingListener mFloatingListener; @Override public void onCreate() { super.onCreate(); initWindow();//設(shè)置窗口的參數(shù) initFloating();//設(shè)置懸浮窗圖標(biāo) } @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);//設(shè)置好懸浮窗的參數(shù) // 懸浮窗默認(rèn)顯示以左上角為起始坐標(biāo) wmParams.gravity = Gravity.LEFT | Gravity.TOP; //懸浮窗的開始位置,因?yàn)樵O(shè)置的是從左上角開始,所以屏幕左上角是x=0;y=0 wmParams.x = 0; wmParams.y = 0; //得到容器,通過這個(gè)inflater來獲得懸浮窗控件 if (inflater == null) { inflater = LayoutInflater.from(getApplication()); } // 獲取浮動(dòng)窗口視圖所在布局 if (mlayout == null) { mlayout = (LinearLayout) inflater.inflate(R.layout.record_screen_time_float, null); } // 添加懸浮窗的視圖 mWindowManager.addView(mlayout, wmParams); } /** * 對(duì)windowManager進(jìn)行設(shè)置 * * @param wmParams * @return */ public WindowManager.LayoutParams getParams(WindowManager.LayoutParams wmParams) { if (wmParams == null) { wmParams = new WindowManager.LayoutParams(); } //設(shè)置window type 下面變量2002是在屏幕區(qū)域顯示,2003則可以顯示在狀態(tài)欄之上 //wmParams.type = LayoutParams.TYPE_PHONE; //wmParams.type = LayoutParams.TYPE_SYSTEM_ALERT; wmParams.type = LayoutParams.TYPE_SYSTEM_ERROR; //設(shè)置圖片格式,效果為背景透明 wmParams.format = PixelFormat.RGBA_8888; //設(shè)置浮動(dòng)窗口不可聚焦(實(shí)現(xiàn)操作除浮動(dòng)窗口外的其他可見窗口的操作) //wmParams.flags = LayoutParams.FLAG_NOT_FOCUSABLE; //設(shè)置可以顯示在狀態(tài)欄上 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; //設(shè)置懸浮窗口長(zhǎng)寬數(shù)據(jù) wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT; wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT; return wmParams; } /** * 找到懸浮窗的圖標(biāo),并且設(shè)置事件 * 設(shè)置懸浮窗的點(diǎn)擊、滑動(dòng)事件 */ 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){ //設(shè)置監(jiān)聽器 mFloatingListener = new FloatingListener(); } mlayout.setOnTouchListener(mFloatingListener); stopRecord.setOnTouchListener(mFloatingListener); } /× ×錄屏狀態(tài)顯示(閃爍效果) ×/ 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); } //開始觸控的坐標(biāo),移動(dòng)時(shí)的坐標(biāo)(相對(duì)于屏幕左上角的坐標(biāo)) private int mTouchStartX, mTouchStartY, mTouchCurrentX, mTouchCurrentY; //開始時(shí)的坐標(biāo)和結(jié)束時(shí)的坐標(biāo)(相對(duì)于自身控件的坐標(biāo)) private int mStartX, mStartY, mStopX, mStopY; private boolean isMove;//判斷懸浮窗是否移動(dòng) /** * 懸浮窗監(jiān)聽器 */ 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獲取不到監(jiān)聽 } } /** * 自定義的手勢(shì)監(jiān)聽類 */ class MyOnGestureListener extends SimpleOnGestureListener { @Override public boolean onSingleTapConfirmed(MotionEvent e) { if (!isMove) { System.out.println("onclick"); } return super.onSingleTapConfirmed(e); } } }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android實(shí)現(xiàn)粒子中心擴(kuò)散動(dòng)畫效果
粒子動(dòng)畫效果相比其他動(dòng)畫來說是非常復(fù)雜了的,主要涉及三個(gè)方面,粒子初始化、粒子位移、粒子回收等問題,本篇將實(shí)現(xiàn)兩種動(dòng)畫效果,代碼基本相同,只是旋轉(zhuǎn)速度不一樣,需要的朋友可以參考下2024-02-02基于Android SQLiteOpenHelper && CRUD 的使用
本篇文章小編為大家介紹,基于Android SQLiteOpenHelper && CRUD的使用。需要的朋友可以參考一下2013-04-04Android中ShapeableImageView使用實(shí)例詳解(告別shape、三方庫(kù))
之前Google推送了文章,Android?Material組件1.2.0里面就有ShapeableImageView,不用像以前再寫shape,下面這篇文章主要給大家介紹了關(guān)于Android中ShapeableImageView使用的相關(guān)資料,需要的朋友可以參考下2022-09-09玩轉(zhuǎn)Kotlin 徹底弄懂Lambda和高階函數(shù)
這篇文章主要幫助大家徹底弄懂Lambda和高階函數(shù),玩轉(zhuǎn)Kotlin,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10Flutter學(xué)習(xí)之SliverList和SliverGird的使用詳解
Sliver的組件一般都用在CustomScrollView中,除了SliverAppBar之外,我們還可以為CustomScrollView添加List或者Grid來實(shí)現(xiàn)更加復(fù)雜的組合效果。本文就來聊聊SliverList和SliverGird的使用吧2023-02-02Android RecycleView和線型布局制作聊天布局
大家好,本篇文章主要講的是Android RecycleView和線型布局制作聊天布局,感興趣的同學(xué)趕緊來看一看吧,對(duì)你有幫助的話記得收藏一下2022-01-01Android 圖片處理避免出現(xiàn)oom的方法詳解
本篇文章主要介紹了Android 圖片處理避免出現(xiàn)oom的方法詳解,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09android如何設(shè)置小區(qū)廣播默認(rèn)信道(50與60并支持雙卡)
置小區(qū)廣播默認(rèn)信道50與60,并支持雙卡主要是印度市場(chǎng),具體的實(shí)現(xiàn)如下,感興趣的朋友可以參考下哈2013-06-06Android Bluetooth藍(lán)牙技術(shù)使用流程詳解
這篇文章主要介紹了Android Bluetooth藍(lán)牙技術(shù)使用流程詳解的相關(guān)資料,需要的朋友可以參考下2016-02-02