From 0b20d1a01a43bab43914aa214d71db7779a53011 Mon Sep 17 00:00:00 2001 From: lihongwei Date: Wed, 18 Jun 2025 14:29:45 +0800 Subject: [PATCH] =?UTF-8?q?UI=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/activity/main/MainActivity.java | 25 +++++-- .../autoclicker/view/FloatingViewManager.java | 75 +++++++++++-------- app/src/main/res/layout/activity_main.xml | 4 +- .../main/res/layout/single_control_bar.xml | 68 +++++++++++++++++ app/src/main/res/values/colors.xml | 3 + 5 files changed, 138 insertions(+), 37 deletions(-) create mode 100644 app/src/main/res/layout/single_control_bar.xml diff --git a/app/src/main/java/com/auto/clicker/autoclicker/ui/activity/main/MainActivity.java b/app/src/main/java/com/auto/clicker/autoclicker/ui/activity/main/MainActivity.java index 7831edf..58d7b7c 100644 --- a/app/src/main/java/com/auto/clicker/autoclicker/ui/activity/main/MainActivity.java +++ b/app/src/main/java/com/auto/clicker/autoclicker/ui/activity/main/MainActivity.java @@ -21,6 +21,7 @@ import androidx.activity.EdgeToEdge; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.appcompat.app.AppCompatActivity; +import androidx.core.content.ContextCompat; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; @@ -140,18 +141,25 @@ public class MainActivity extends AppCompatActivity { binding.animatedView.setOnClickListener(v -> onToggleFloatingWindowClicked()); binding.single.setOnClickListener(v -> { + if (isFloatingShown != FLOATING_NONE) { + Toast.makeText(this, "请先关闭悬浮窗再切换模式", Toast.LENGTH_SHORT).show(); + return; + } selectedFloatingMode = FLOATING_SINGLE; updateSelectionButtons(); - logDebug("选择单点模式. selectedFloatingMode=" + selectedFloatingMode); }); binding.multi.setOnClickListener(v -> { + if (isFloatingShown != FLOATING_NONE) { + Toast.makeText(this, "请先关闭悬浮窗再切换模式", Toast.LENGTH_SHORT).show(); + return; + } selectedFloatingMode = FLOATING_MULTI; updateSelectionButtons(); - logDebug("选择多点模式. selectedFloatingMode=" + selectedFloatingMode); }); + } private void checkPermissions() { @@ -205,7 +213,6 @@ public class MainActivity extends AppCompatActivity { } } - private void showPermissionRequest(Intent intent, String toastMessage, String errorMessage) { try { permissionLauncher.launch(intent); @@ -270,7 +277,6 @@ public class MainActivity extends AppCompatActivity { return FLOATING_NONE; } - public void onToggleFloatingWindowClicked() { long currentTime = System.currentTimeMillis(); if (currentTime - lastClickTime < DEBOUNCE_INTERVAL) { @@ -341,13 +347,23 @@ public class MainActivity extends AppCompatActivity { private void updateSelectionButtons() { logDebug("更新选择按钮UI: selectedFloatingMode=" + selectedFloatingMode); + if (selectedFloatingMode == FLOATING_SINGLE) { binding.single.setSelected(true); binding.multi.setSelected(false); + + binding.single.setBackgroundTintList(ContextCompat.getColorStateList(this, R.color.button_selected)); + binding.multi.setBackgroundTintList(ContextCompat.getColorStateList(this, R.color.button_unselected)); } else if (selectedFloatingMode == FLOATING_MULTI) { binding.single.setSelected(false); binding.multi.setSelected(true); + + binding.single.setBackgroundTintList(ContextCompat.getColorStateList(this, R.color.button_unselected)); + binding.multi.setBackgroundTintList(ContextCompat.getColorStateList(this, R.color.button_selected)); } + + binding.single.setEnabled(isFloatingShown == FLOATING_NONE); + binding.multi.setEnabled(isFloatingShown == FLOATING_NONE); } private void setStartButtonEnabled(boolean enabled) { @@ -363,7 +379,6 @@ public class MainActivity extends AppCompatActivity { binding.animatedVideo.start(); } - @Override protected void onDestroy() { super.onDestroy(); diff --git a/app/src/main/java/com/auto/clicker/autoclicker/view/FloatingViewManager.java b/app/src/main/java/com/auto/clicker/autoclicker/view/FloatingViewManager.java index de6b4e1..390582d 100644 --- a/app/src/main/java/com/auto/clicker/autoclicker/view/FloatingViewManager.java +++ b/app/src/main/java/com/auto/clicker/autoclicker/view/FloatingViewManager.java @@ -77,14 +77,15 @@ public class FloatingViewManager { throw new SecurityException("需要悬浮窗许可"); } - removeFloatingViews(); - showMultipleModeViews(mode); + removeFloatingViews(); // 移除已有悬浮窗 + showMultipleModeViews(mode); // 显示新模式悬浮窗 Log.d(TAG, "添加悬浮窗, 模式 = " + mode); } public void removeFloatingViews() { try { + // 移除点事件视图 for (EventWrapper wrapper : new ArrayList<>(runtimeEvents)) { if (wrapper.getType() == EventWrapper.EventType.POINT) { PointEvent pe = (PointEvent) wrapper.getEvent(); @@ -92,6 +93,7 @@ public class FloatingViewManager { } } + // 移除滑动事件视图 for (EventWrapper wrapper : new ArrayList<>(runtimeEvents)) { if (wrapper.getType() == EventWrapper.EventType.SLIDE) { SlideEvent se = (SlideEvent) wrapper.getEvent(); @@ -103,8 +105,6 @@ public class FloatingViewManager { runtimeEvents.clear(); - Log.d(TAG, "remove runtimeEvents: " + runtimeEvents.size() + " eventOrderCounter :" + eventOrderCounter); - if (multipleControlBarView != null) { safeRemoveView(multipleControlBarView); multipleControlBarView = null; @@ -127,6 +127,7 @@ public class FloatingViewManager { } private void closeFloatingViews() { + // 停止自动点击服务 AutoClickService service = AutoClickService.getInstance(); if (service != null) { service.stopClicking(); @@ -135,31 +136,30 @@ public class FloatingViewManager { Toast.makeText(context, "请同意无障碍服务权限", Toast.LENGTH_SHORT).show(); } - updateTouchPointsBackground(R.drawable.un_touch_point); - removeFloatingViews(); + updateTouchPointsBackground(R.drawable.ring_has_bg); + removeFloatingViews(); // 移除所有悬浮窗 context.stopService(new Intent(context, ForegroundService.class)); PrefUtils.setFloatingShown(context, 0); + // 发送浮窗关闭广播 Intent intent = new Intent("com.auto.autoclicker.FLOATING_WINDOW_STATE_CHANGED"); intent.putExtra("isShown", false); LocalBroadcastManager.getInstance(context).sendBroadcast(intent); } private void showMultipleModeViews(int mode) { - initMultipleTouchPointView(); - initMultipleControlBar(); + initMultipleTouchPointView(); // 初始化点击点数据 + initMultipleControlBar(); // 初始化控制栏视图 if (multipleControlBarView != null) { - windowManager.addView(multipleControlBarView, multipleControlBarParams); + windowManager.addView(multipleControlBarView, multipleControlBarParams); // 显示控制栏 } } private void initMultipleTouchPointView() { runtimeEvents.clear(); eventOrderCounter = 1; - - Log.d(TAG, "init runtimeEvents: " + runtimeEvents.size() + " eventOrderCounter :" + eventOrderCounter); } @SuppressLint("ClickableViewAccessibility") @@ -167,9 +167,9 @@ public class FloatingViewManager { multipleControlBarView = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.multiple_control_bar, null); multipleControlBarParams = createControlBarParams(); - setupDraggableView(multipleControlBarView, multipleControlBarParams, this::updateMoreControlBarPosition); + setupDraggableView(multipleControlBarView, multipleControlBarParams, this::updateMoreControlBarPosition); // 可拖动 - setupControlButtons(multipleControlBarView); + setupControlButtons(multipleControlBarView); // 初始化按钮功能 } private void setupControlButtons(LinearLayout controlBar) { @@ -180,6 +180,7 @@ public class FloatingViewManager { ImageView closeButton = controlBar.findViewById(R.id.close_button); ImageView settingButton = controlBar.findViewById(R.id.settings_button); + // 按钮点击事件绑定 playButton.setOnClickListener(v -> toggleMultipleClicking()); addButton.setOnClickListener(v -> addPointEvent()); removeButton.setOnClickListener(v -> removeLastEvent()); @@ -188,17 +189,8 @@ public class FloatingViewManager { settingButton.setOnClickListener(v -> showInputDialog()); } - private TextView createTouchPointView(String label) { - TextView touchPointView = new TextView(context); - touchPointView.setBackgroundResource(R.drawable.un_touch_point); - touchPointView.setGravity(Gravity.CENTER); - touchPointView.setText(label); - touchPointView.setTextColor(Color.BLACK); - touchPointView.setTextSize(16); - return touchPointView; - } - private WindowManager.LayoutParams createTouchPointParams() { + // 创建点击点的布局参数 int overlayType = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : WindowManager.LayoutParams.TYPE_PHONE; @@ -215,6 +207,7 @@ public class FloatingViewManager { } private WindowManager.LayoutParams createControlBarParams() { + // 创建控制栏的悬浮窗参数 int overlayType = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : WindowManager.LayoutParams.TYPE_PHONE; @@ -234,6 +227,7 @@ public class FloatingViewManager { } private WindowManager.LayoutParams createLineViewParams() { + // 创建连接线(滑动路径)的参数,全屏不可点击 int overlayType = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : WindowManager.LayoutParams.TYPE_PHONE; @@ -260,19 +254,22 @@ public class FloatingViewManager { return; } + // 创建点击点视图 TextView point = createTouchPointView(String.valueOf(eventOrderCounter)); + // 设置位置居中 WindowManager.LayoutParams params = createTouchPointParams(); params.x = screenWidth / 2 - TOUCH_POINT_SIZE / 2; params.y = screenHeight / 2 - TOUCH_POINT_SIZE / 2; + // 包装为事件对象 PointEvent pointEvent = new PointEvent(eventOrderCounter, params.x, params.y, point, params); - runtimeEvents.add(new EventWrapper(EventWrapper.EventType.POINT, pointEvent, eventOrderCounter)); eventOrderCounter++; Log.d(TAG, "addPoint runtimeEvents: " + runtimeEvents.size() + " eventOrderCounter :" + eventOrderCounter); + // 设置拖动功能并添加到窗口 setupDraggablePoint(point, params, pointEvent); windowManager.addView(point, params); updateServicePositions(); @@ -285,36 +282,40 @@ public class FloatingViewManager { return; } + // 创建起点 TextView startPoint = createTouchPointView(String.valueOf(eventOrderCounter)); WindowManager.LayoutParams startParams = createTouchPointParams(); startParams.x = screenWidth / 2 - 100; startParams.y = screenHeight / 2 - 50; PointEvent startPointEvent = new PointEvent(eventOrderCounter, startParams.x, startParams.y, startPoint, startParams); + // 创建终点 TextView endPoint = createTouchPointView(String.valueOf(eventOrderCounter)); WindowManager.LayoutParams endParams = createTouchPointParams(); endParams.x = screenWidth / 2 + 100; endParams.y = screenHeight / 2 - 50; PointEvent endPointEvent = new PointEvent(eventOrderCounter, endParams.x, endParams.y, endPoint, endParams); + // 创建滑动连线 ConnectingLineView lineView = new ConnectingLineView(context); WindowManager.LayoutParams lineParams = createLineViewParams(); SlideEvent slideEvent = new SlideEvent(eventOrderCounter, startPointEvent, endPointEvent, lineView, lineParams); - runtimeEvents.add(new EventWrapper(EventWrapper.EventType.SLIDE, slideEvent, eventOrderCounter)); eventOrderCounter++; Log.d(TAG, "addSlide runtimeEvents: " + runtimeEvents.size() + " eventOrderCounter :" + eventOrderCounter); + // 设置滑动点可拖动 setupDraggableSlidePoint(startPoint, startParams, startPointEvent, slideEvent); setupDraggableSlidePoint(endPoint, endParams, endPointEvent, slideEvent); + // 添加视图到窗口 windowManager.addView(lineView, lineParams); windowManager.addView(startPoint, startParams); windowManager.addView(endPoint, endParams); - updateLinePosition(slideEvent); + updateLinePosition(slideEvent); // 更新线的位置 updateServicePositions(); } @@ -329,6 +330,7 @@ public class FloatingViewManager { return; } + // 移除最后一个事件 Event lastEvent = runtimeEvents.remove(runtimeEvents.size() - 1).getEvent(); removeEvent(lastEvent); eventOrderCounter--; @@ -337,6 +339,7 @@ public class FloatingViewManager { private void removeEvent(Event event) { try { + // 判断类型并移除相关视图 if (event instanceof PointEvent) { PointEvent pointEvent = (PointEvent) event; windowManager.removeView(pointEvent.getView()); @@ -352,6 +355,7 @@ public class FloatingViewManager { } private void updateServicePositions() { + // 更新服务中记录的位置 AutoClickService service = AutoClickService.getInstance(); if (service != null) { service.addMultipleClickEvents(runtimeEvents); @@ -363,7 +367,7 @@ public class FloatingViewManager { AutoClickService service = AutoClickService.getInstance(); if (service == null) { - handleMissingService(); + handleMissingService(); // 无障碍服务未开启 return; } @@ -373,9 +377,9 @@ public class FloatingViewManager { } if (isMultipleRunning) { - stopMultiClicking(service); + stopMultiClicking(service); // 停止点击 } else { - startMultiClicking(service); + startMultiClicking(service); // 开始点击 } isMultipleRunning = !isMultipleRunning; @@ -396,7 +400,7 @@ public class FloatingViewManager { service.stopClicking(); Toast.makeText(context, "多点点击停止", Toast.LENGTH_SHORT).show(); - updateTouchPointsBackground(R.drawable.un_touch_point); + updateTouchPointsBackground(R.drawable.ring_has_bg); } private void updateTouchPointsBackground(int resourceId) { @@ -594,6 +598,17 @@ public class FloatingViewManager { lineView.setPoints(startCenterX, startCenterY, endCenterX, endCenterY); } + private TextView createTouchPointView(String label) { + // 创建一个圆形点击点视图 + TextView touchPointView = new TextView(context); + touchPointView.setBackgroundResource(R.drawable.ring_has_bg); + touchPointView.setGravity(Gravity.CENTER); + touchPointView.setText(label); + touchPointView.setTextColor(Color.WHITE); + touchPointView.setTextSize(19); + return touchPointView; + } + public void showInputDialog() { EditText input = new EditText(context); input.setInputType(InputType.TYPE_CLASS_NUMBER); diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 490936c..4f66822 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -61,8 +61,8 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 83c7a0d..2e305d9 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,10 +1,13 @@ #FF000000 + #171717 #FFFFFFFF #0BC4FC #616161 #113945 #8DA5A7 #446672 + #1A546B + #171717 \ No newline at end of file