加入設定功能

This commit is contained in:
Raymond Yang 2023-07-03 15:54:04 +08:00
parent ea629e45a7
commit f00517ddd2
9 changed files with 286 additions and 74 deletions

View File

@ -16,10 +16,14 @@
android:supportsRtl="true"
android:theme="@style/Theme.EasyWindowTest"
tools:targetApi="31">
<activity
android:name=".SettingActivity"
android:exported="false"
android:screenOrientation="landscape" />
<activity
android:name=".MainActivity"
android:screenOrientation="landscape"
android:exported="true">
android:exported="true"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

View File

@ -3,6 +3,7 @@ package com.ray650128.easywindowtest
import android.view.Gravity
import android.view.MotionEvent
import android.view.WindowManager
import androidx.core.view.GravityCompat
import com.hjq.window.EasyWindow
object FloatingWindowHelper {
@ -11,11 +12,22 @@ object FloatingWindowHelper {
val isShowing: Boolean
get() = _isShowing
private var xOffset = PreferenceUtil.xOffset
private var yOffset = PreferenceUtil.yOffset
private var windowGravity = GravityType.fromInt(PreferenceUtil.gravity)
private val window by lazy {
EasyWindow<EasyWindow<*>>(MyApp.instance).apply {
setContentView(R.layout.window_hint)
setGravity(Gravity.START or Gravity.TOP)
setYOffset(100)
setGravity(when (windowGravity) {
GravityType.TOP_LEFT -> Gravity.TOP or Gravity.START
GravityType.BOTTOM_LEFT -> Gravity.BOTTOM or Gravity.START
GravityType.TOP_RIGHT -> Gravity.TOP or Gravity.END
GravityType.BOTTOM_RIGHT -> Gravity.BOTTOM or Gravity.END
})
setXOffset(xOffset)
setYOffset(yOffset)
setImageDrawable(android.R.id.icon, R.drawable.ic_chicken)
setOnTouchListener { window, view, event ->
var touch = false
@ -66,4 +78,33 @@ object FloatingWindowHelper {
window.setYOffset(value)
window.update()
}
fun setGravity(value: GravityType) {
when (value) {
GravityType.TOP_LEFT -> {
window.setGravity(Gravity.TOP or Gravity.START)
}
GravityType.BOTTOM_LEFT -> {
window.setGravity(Gravity.BOTTOM or Gravity.START)
}
GravityType.TOP_RIGHT -> {
window.setGravity(Gravity.TOP or Gravity.END)
}
GravityType.BOTTOM_RIGHT -> {
window.setGravity(Gravity.BOTTOM or Gravity.END)
}
}
window.update()
}
enum class GravityType(val type: Int) {
TOP_LEFT(0),
BOTTOM_LEFT(1),
TOP_RIGHT(2),
BOTTOM_RIGHT(3);
companion object {
fun fromInt(value: Int) = GravityType.values().first { it.type == value }
}
}
}

View File

@ -31,6 +31,7 @@ class MainActivity : AppCompatActivity() {
binding.btnStep1.isEnabled = !Settings.canDrawOverlays(mContext)
binding.btnStep2.isEnabled = Settings.canDrawOverlays(mContext)
binding.btnStep3.isEnabled = FloatingWindowHelper.isShowing
binding.btnSetting.isEnabled = FloatingWindowHelper.isShowing
return@registerForActivityResult
}
showOverlayWindow()
@ -56,6 +57,11 @@ class MainActivity : AppCompatActivity() {
btnStep3.setOnClickListener {
hideOverlayWindow()
}
btnSetting.setOnClickListener {
val intent = Intent(mContext, SettingActivity::class.java)
startActivity(intent)
}
}
}
@ -66,6 +72,7 @@ class MainActivity : AppCompatActivity() {
btnStep1.isEnabled = !Settings.canDrawOverlays(mContext)
btnStep2.isEnabled = Settings.canDrawOverlays(mContext) && !FloatingWindowHelper.isShowing
btnStep3.isEnabled = FloatingWindowHelper.isShowing
btnSetting.isEnabled = FloatingWindowHelper.isShowing
}
}
@ -73,11 +80,13 @@ class MainActivity : AppCompatActivity() {
FloatingWindowHelper.show()
binding.btnStep2.isEnabled = !FloatingWindowHelper.isShowing
binding.btnStep3.isEnabled = FloatingWindowHelper.isShowing
binding.btnSetting.isEnabled = FloatingWindowHelper.isShowing
}
private fun hideOverlayWindow() {
FloatingWindowHelper.hide()
binding.btnStep2.isEnabled = !FloatingWindowHelper.isShowing
binding.btnStep3.isEnabled = FloatingWindowHelper.isShowing
binding.btnSetting.isEnabled = FloatingWindowHelper.isShowing
}
}

View File

@ -1,68 +0,0 @@
package com.ray650128.easywindowtest
import android.annotation.SuppressLint
import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
import com.hjq.window.EasyWindow
import com.hjq.window.draggable.BaseDraggable
/**
* author : Raymond Yang
* time : 2023/07/03
* desc : 移動拖曳處理實現類別
*/
class MovingDraggable(private val window: EasyWindow<*>) : BaseDraggable() {
/** 手指按下的座標 */
private var mViewDownX = 0f
private var mViewDownY = 0f
/** 觸控移動標記 */
private var mMoveTouch = false
@SuppressLint("ClickableViewAccessibility")
override fun onTouch(v: View, event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
window.setWindowFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS or
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH)
window.update()
// 記錄按下的位置(相對 View 的座標)
mViewDownX = event.x
mViewDownY = event.y
mMoveTouch = false
}
MotionEvent.ACTION_MOVE -> {
// 記錄移動的位置(相對螢幕的座標)
val rawMoveX = event.rawX - windowInvisibleWidth
val rawMoveY = event.rawY - windowInvisibleHeight
var newX = rawMoveX - mViewDownX
var newY = rawMoveY - mViewDownY
if (newX < 0) {
newX = 0f
}
if (newY < 0) {
newY = 0f
}
// 更新移動的位置
updateLocation(newX, newY)
if (!mMoveTouch && isFingerMove(mViewDownX, event.x, mViewDownY, event.y)) {
// 如果使用者移動了手指,那麼就攔截本次觸控事件,從而不讓點選事件生效
mMoveTouch = true
}
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> return mMoveTouch
MotionEvent.ACTION_OUTSIDE -> {
window.setWindowFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS or
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH)
window.update()
}
else -> {}
}
return true
}
}

View File

@ -0,0 +1,28 @@
package com.ray650128.easywindowtest
import android.content.Context
/**
* Shared Preferences 工具類別
* @author Raymond Yang
*/
object PreferenceUtil {
private const val MAIN_KEY = "PcReDiveClanBattleFrameTool"
private const val X_AXIS_OFFSET = "X_AXIS_OFFSET"
private const val Y_AXIS_OFFSET = "Y_AXIS_OFFSET"
private const val GRAVITY = "GRAVITY"
private val sharedPreferences = MyApp.appContext.getSharedPreferences(MAIN_KEY, Context.MODE_PRIVATE)
var xOffset: Int
get() = sharedPreferences.getInt(X_AXIS_OFFSET, 0)
set(value) = sharedPreferences.edit().putInt(X_AXIS_OFFSET, value).apply()
var yOffset: Int
get() = sharedPreferences.getInt(Y_AXIS_OFFSET, 0)
set(value) = sharedPreferences.edit().putInt(Y_AXIS_OFFSET, value).apply()
var gravity: Int
get() = sharedPreferences.getInt(GRAVITY, 0)
set(value) = sharedPreferences.edit().putInt(GRAVITY, value).apply()
}

View File

@ -0,0 +1,74 @@
package com.ray650128.easywindowtest
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.AdapterView
import androidx.core.widget.addTextChangedListener
import com.ray650128.easywindowtest.databinding.ActivitySettingBinding
class SettingActivity : AppCompatActivity() {
private lateinit var binding: ActivitySettingBinding
private var xOffset = 0
private var yOffset = 0
private var windowGravity = FloatingWindowHelper.GravityType.TOP_LEFT
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySettingBinding.inflate(layoutInflater)
setContentView(binding.root)
xOffset = PreferenceUtil.xOffset
yOffset = PreferenceUtil.yOffset
windowGravity = FloatingWindowHelper.GravityType.fromInt(PreferenceUtil.gravity)
binding.apply {
spGravity.apply {
setSelection(PreferenceUtil.gravity)
onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
windowGravity = FloatingWindowHelper.GravityType.fromInt(position)
FloatingWindowHelper.setGravity(windowGravity)
}
override fun onNothingSelected(parent: AdapterView<*>?) {}
}
}
etXOffset.apply {
setText("$xOffset")
addTextChangedListener {
if (it.isNullOrEmpty()) return@addTextChangedListener
xOffset = it.toString().toIntOrNull() ?: return@addTextChangedListener
FloatingWindowHelper.setXOffset(xOffset)
}
}
etYOffset.apply {
setText("$yOffset")
addTextChangedListener {
if (it.isNullOrEmpty()) return@addTextChangedListener
yOffset = it.toString().toIntOrNull() ?: return@addTextChangedListener
FloatingWindowHelper.setYOffset(yOffset)
}
}
btnOk.setOnClickListener {
PreferenceUtil.xOffset = xOffset
PreferenceUtil.yOffset = yOffset
PreferenceUtil.gravity = windowGravity.type
finish()
}
btnCancel.setOnClickListener {
FloatingWindowHelper.setXOffset(PreferenceUtil.xOffset)
FloatingWindowHelper.setYOffset(PreferenceUtil.yOffset)
FloatingWindowHelper.setGravity(FloatingWindowHelper.GravityType.fromInt(PreferenceUtil.gravity))
finish()
}
}
}
}

View File

@ -49,7 +49,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="關閉懸浮窗"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toTopOf="@+id/btnSetting"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnStep2" />
@ -63,4 +63,13 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/btnSetting"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="設定懸浮窗"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SettingActivity">
<TextView
android:id="@+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="螢幕吸附位置"
app:layout_constraintBottom_toBottomOf="@+id/spGravity"
app:layout_constraintEnd_toStartOf="@+id/spGravity"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/spGravity" />
<Spinner
android:id="@+id/spGravity"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:entries="@array/item_edge_position"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/textView6"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="水平偏移像素"
app:layout_constraintBottom_toBottomOf="@+id/etXOffset"
app:layout_constraintEnd_toStartOf="@+id/etXOffset"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/etXOffset" />
<EditText
android:id="@+id/etXOffset"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:ems="10"
android:inputType="number"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/textView4"
app:layout_constraintTop_toBottomOf="@+id/spGravity" />
<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="垂直偏移像素"
app:layout_constraintBottom_toBottomOf="@+id/etYOffset"
app:layout_constraintEnd_toStartOf="@+id/etYOffset"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/etYOffset" />
<EditText
android:id="@+id/etYOffset"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:ems="10"
android:inputType="number"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/textView5"
app:layout_constraintTop_toBottomOf="@+id/etXOffset" />
<Button
android:id="@+id/btnOk"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:text="確定"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/btnCancel"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/etYOffset" />
<Button
android:id="@+id/btnCancel"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:text="取消"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/btnOk"
app:layout_constraintTop_toBottomOf="@+id/etYOffset" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,3 +1,10 @@
<resources>
<string name="app_name">懸浮視窗 by 楓小夜</string>
<array name="item_edge_position">
<item>左上角</item>
<item>左下角</item>
<item>右上角</item>
<item>右下角</item>
</array>
</resources>