diff --git a/app/src/main/java/com/auto/clicker/autoclicker/service/ForegroundService.java b/app/src/main/java/com/auto/clicker/autoclicker/service/ForegroundService.java
index 520c614..fe659a0 100644
--- a/app/src/main/java/com/auto/clicker/autoclicker/service/ForegroundService.java
+++ b/app/src/main/java/com/auto/clicker/autoclicker/service/ForegroundService.java
@@ -24,11 +24,16 @@ public class ForegroundService extends Service {
private static final int NOTIFICATION_ID = 1;
private FloatingViewManager floatingViewManager;
private boolean isFloatingViewShown = false;
+ private static ForegroundService instance;
@Override
public void onCreate() {
super.onCreate();
+
+ instance = this;
+
createNotificationChannel();
+
try {
floatingViewManager = new FloatingViewManager(this);
} catch (Exception e) {
@@ -68,6 +73,14 @@ public class ForegroundService extends Service {
return START_STICKY;
}
+ public static ForegroundService getInstance() {
+ return instance;
+ }
+
+ public FloatingViewManager getFloatingViewManager() {
+ return floatingViewManager;
+ }
+
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
@@ -86,6 +99,9 @@ public class ForegroundService extends Service {
@Override
public void onDestroy() {
super.onDestroy();
+
+ instance = null;
+
if (floatingViewManager != null) {
floatingViewManager.removeAllFloatingViews();
isFloatingViewShown = false;
diff --git a/app/src/main/java/com/auto/clicker/autoclicker/ui/fragment/setting/ActionFragment.java b/app/src/main/java/com/auto/clicker/autoclicker/ui/fragment/setting/ActionFragment.java
index e9e7348..48d5a42 100644
--- a/app/src/main/java/com/auto/clicker/autoclicker/ui/fragment/setting/ActionFragment.java
+++ b/app/src/main/java/com/auto/clicker/autoclicker/ui/fragment/setting/ActionFragment.java
@@ -1,20 +1,137 @@
package com.auto.clicker.autoclicker.ui.fragment.setting;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.PopupWindow;
+import android.widget.TextView;
+import android.widget.Toast;
import androidx.fragment.app.Fragment;
import com.auto.clicker.autoclicker.R;
+import com.auto.clicker.autoclicker.databinding.FragmentActionBinding;
public class ActionFragment extends Fragment {
-
+ private FragmentActionBinding binding;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- return inflater.inflate(R.layout.fragment_action, container, false);
+ binding = FragmentActionBinding.inflate(inflater, container, false);
+
+ binding.intervalSelectorContainer.setOnClickListener(this::showIntervalUnitSelection);
+
+ binding.unitSelectorContainer.setOnClickListener(this::showSwipeDurationUnitSelection);
+
+ return binding.getRoot();
+ }
+
+ private void showIntervalUnitSelection(View anchorView) {
+ // 加载弹窗布局
+ View popupView = getLayoutInflater().inflate(R.layout.dialog_unit_selection, null);
+ PopupWindow popupWindow = new PopupWindow(
+ popupView,
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ true // 设置为 true,以便点击外部区域时自动关闭
+ );
+
+ // 设置背景,否则点击外部无法关闭
+ popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+ popupWindow.setOutsideTouchable(true);
+
+ // 获取弹窗中的TextViews
+ TextView tvMs = popupView.findViewById(R.id.tv_unit_ms);
+ TextView tvSec = popupView.findViewById(R.id.tv_unit_sec);
+ TextView tvMin = popupView.findViewById(R.id.tv_unit_min);
+
+ // Interval 单位有:毫秒,秒,分钟
+ tvMs.setVisibility(View.VISIBLE);
+ tvSec.setVisibility(View.VISIBLE);
+ tvMin.setVisibility(View.VISIBLE);
+
+ tvMs.setOnClickListener(v -> {
+ binding.intervalSelectedUnit.setText(getString(R.string.milliseconds_unit));
+ popupWindow.dismiss();
+ showInputValue("Interval", binding.etIntervalValue.getText().toString(), getString(R.string.milliseconds_unit));
+ });
+
+ tvSec.setOnClickListener(v -> {
+ binding.intervalSelectedUnit.setText(getString(R.string.seconds_unit));
+ popupWindow.dismiss();
+ showInputValue("Interval", binding.etIntervalValue.getText().toString(), getString(R.string.seconds_unit));
+ });
+
+ tvMin.setOnClickListener(v -> {
+ binding.intervalSelectedUnit.setText(getString(R.string.minutes_unit));
+ popupWindow.dismiss();
+ showInputValue("Interval", binding.etIntervalValue.getText().toString(), getString(R.string.minutes_unit));
+ });
+
+ // 显示弹窗,使其显示在anchorView下方
+ popupWindow.showAsDropDown(anchorView);
+ }
+
+ private void showSwipeDurationUnitSelection(View anchorView) {
+ // 加载弹窗布局
+ View popupView = getLayoutInflater().inflate(R.layout.dialog_unit_selection, null);
+ PopupWindow popupWindow = new PopupWindow(
+ popupView,
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ true // 设置为 true,以便点击外部区域时自动关闭
+ );
+
+ // 设置背景,否则点击外部无法关闭
+ popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+ popupWindow.setOutsideTouchable(true);
+
+ // 获取弹窗中的TextViews
+ TextView tvMs = popupView.findViewById(R.id.tv_unit_ms);
+ TextView tvSec = popupView.findViewById(R.id.tv_unit_sec);
+ TextView tvMin = popupView.findViewById(R.id.tv_unit_min);
+
+ // Swipe duration 单位只有:毫秒,秒
+ tvMs.setVisibility(View.VISIBLE);
+ tvSec.setVisibility(View.VISIBLE);
+ tvMin.setVisibility(View.GONE); // 隐藏分钟选项
+
+ tvMs.setOnClickListener(v -> {
+ binding.tvSelectedUnit.setText(getString(R.string.milliseconds_unit));
+ popupWindow.dismiss();
+ showInputValue("Swipe Duration", binding.etDurationValue.getText().toString(), getString(R.string.milliseconds_unit));
+ });
+
+ tvSec.setOnClickListener(v -> {
+ binding.tvSelectedUnit.setText(getString(R.string.seconds_unit));
+ popupWindow.dismiss();
+ showInputValue("Swipe Duration", binding.etDurationValue.getText().toString(), getString(R.string.seconds_unit));
+ });
+
+ // 显示弹窗,使其显示在anchorView下方
+ popupWindow.showAsDropDown(anchorView);
+ }
+
+ private void showInputValue(String type, String value, String unit) {
+ String message = type + " 值: " + (value.isEmpty() ? "未输入" : value) + ", 单位: " + unit;
+ Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
+
+ if (type.equals("Interval")) {
+ long intervalValue = value.isEmpty() ? 0 : Long.parseLong(value);
+ // 根据 unit 进行单位转换或保存
+ } else if (type.equals("Swipe Duration")) {
+ long durationValue = value.isEmpty() ? 0 : Long.parseLong(value);
+ // 根据 unit 进行单位转换或保存
+ }
+ }
+
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ binding = null;
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/auto/clicker/autoclicker/ui/fragment/setting/UISizeFragment.java b/app/src/main/java/com/auto/clicker/autoclicker/ui/fragment/setting/UISizeFragment.java
index bafd485..bf98384 100644
--- a/app/src/main/java/com/auto/clicker/autoclicker/ui/fragment/setting/UISizeFragment.java
+++ b/app/src/main/java/com/auto/clicker/autoclicker/ui/fragment/setting/UISizeFragment.java
@@ -1,20 +1,166 @@
package com.auto.clicker.autoclicker.ui.fragment.setting;
import android.os.Bundle;
+import android.util.Log;
+import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.SeekBar;
+import android.widget.Toast;
import androidx.fragment.app.Fragment;
-import com.auto.clicker.autoclicker.R;
+import com.auto.clicker.autoclicker.databinding.FragmentUISizeBinding;
+import com.auto.clicker.autoclicker.service.ForegroundService;
+import com.auto.clicker.autoclicker.view.FloatingViewManager;
public class UISizeFragment extends Fragment {
+ private static final String TAG = "UISizeFragment";
+ private FragmentUISizeBinding binding;
+ private FloatingViewManager floatingViewManager;
+
+ private static final int MIN_POINT_SIZE = 50;
+ private static final int MAX_POINT_SIZE = 200;
+
+ private static final int MIN_CONTROL_BAR_WIDTH_DP = 20;
+ private static final int MAX_CONTROL_BAR_WIDTH_DP = 80;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- return inflater.inflate(R.layout.fragment_u_i_size, container, false);
+ binding = FragmentUISizeBinding.inflate(inflater, container, false);
+
+ ForegroundService service = ForegroundService.getInstance();
+ if (service != null) {
+ floatingViewManager = service.getFloatingViewManager();
+ }
+
+ if (floatingViewManager != null) {
+ setupPointSizeControl();
+ setupControlBarSizeControl();
+ } else {
+ Toast.makeText(getContext(), "自动化服务未运行,UI大小设置功能不可用。", Toast.LENGTH_LONG).show();
+ disableAllControlUI();
+ }
+
+ return binding.getRoot();
+ }
+
+ private void setupPointSizeControl() {
+ binding.pointSeekbar.setMax(MAX_POINT_SIZE - MIN_POINT_SIZE);
+
+ int currentPointSize = floatingViewManager.getTouchPointSize();
+
+ currentPointSize = Math.max(MIN_POINT_SIZE, Math.min(MAX_POINT_SIZE, currentPointSize));
+ binding.pointSeekbar.setProgress(currentPointSize - MIN_POINT_SIZE);
+
+ updatePointSizeUI(currentPointSize);
+
+ binding.pointSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ int newSize = progress + MIN_POINT_SIZE;
+ updatePointSizeUI(newSize);
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ int finalSize = seekBar.getProgress() + MIN_POINT_SIZE;
+ floatingViewManager.setTouchPointSize(finalSize);
+ Log.d(TAG, "触摸点大小设置为: " + finalSize + "px");
+ Toast.makeText(getContext(), "触摸点大小已更新", Toast.LENGTH_SHORT).show();
+ }
+ });
+ }
+
+ private void setupControlBarSizeControl() {
+ int minControlBarWidthPx = dpToPx(MIN_CONTROL_BAR_WIDTH_DP);
+ int maxControlBarWidthPx = dpToPx(MAX_CONTROL_BAR_WIDTH_DP);
+
+ binding.barSeekbar.setMax(maxControlBarWidthPx - minControlBarWidthPx);
+
+ int currentBarWidthPx = floatingViewManager.getControlBarWidth();
+
+ currentBarWidthPx = Math.max(minControlBarWidthPx, Math.min(maxControlBarWidthPx, currentBarWidthPx));
+ binding.barSeekbar.setProgress(currentBarWidthPx - minControlBarWidthPx);
+
+ binding.currentBarSizeText.setText(String.valueOf(pxToDp(currentBarWidthPx)) + "dp");
+
+ binding.barSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ int newWidthPx = progress + minControlBarWidthPx;
+ binding.currentBarSizeText.setText(String.valueOf(pxToDp(newWidthPx)) + "dp");
+ updateControlBarPreview(newWidthPx);
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ int finalWidthPx = seekBar.getProgress() + minControlBarWidthPx;
+ floatingViewManager.setControlBarSize(finalWidthPx);
+ Log.d(TAG, "控制栏大小设置为: " + pxToDp(finalWidthPx) + "dp (" + finalWidthPx + "px)");
+ Toast.makeText(getContext(), "控制栏大小已更新", Toast.LENGTH_SHORT).show();
+ }
+ });
+ }
+
+ private int dpToPx(int dp) {
+ if (getContext() == null) return dp;
+ return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getContext().getResources().getDisplayMetrics());
+ }
+
+ private int pxToDp(int px) {
+ if (getContext() == null) return px;
+ return (int) (px / getContext().getResources().getDisplayMetrics().density);
+ }
+
+ private void updatePointSizeUI(int size) {
+ binding.currentPointSizeText.setText(String.valueOf(size) + "px");
+
+ ViewGroup.LayoutParams params = binding.ringPreview.getLayoutParams();
+ params.width = size;
+ params.height = size;
+ binding.ringPreview.setLayoutParams(params);
+
+ float textSize = (float) size / (MAX_POINT_SIZE / 19f);
+ binding.ringText.setTextSize(textSize);
+ }
+
+ private void updateControlBarPreview(int width) {
+ ViewGroup.LayoutParams params = binding.controlBar.getLayoutParams();
+ params.width = width;
+
+ params.height = (int) (width * (249f / 37f));
+ binding.controlBar.setLayoutParams(params);
+ }
+
+ private void disableAllControlUI() {
+ disablePointSizeControlUI();
+ binding.barSeekbar.setEnabled(false);
+ binding.barSizeContainer.setAlpha(0.5f);
+ }
+
+ private void disablePointSizeControlUI() {
+ binding.pointSeekbar.setEnabled(false);
+ binding.currentPointSizeText.setText("N/A");
+ binding.ringPreview.setVisibility(View.GONE);
+ binding.ringText.setVisibility(View.GONE);
+ binding.pointSizeContainer.setAlpha(0.5f);
+ }
+
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ binding = null;
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/auto/clicker/autoclicker/util/EventViewBinder.java b/app/src/main/java/com/auto/clicker/autoclicker/util/EventViewBinder.java
index b01f899..267d997 100644
--- a/app/src/main/java/com/auto/clicker/autoclicker/util/EventViewBinder.java
+++ b/app/src/main/java/com/auto/clicker/autoclicker/util/EventViewBinder.java
@@ -5,6 +5,7 @@ import android.graphics.Color;
import android.graphics.PixelFormat;
import android.os.Build;
import android.util.Log;
+import android.util.TypedValue;
import android.view.Gravity;
import android.view.WindowManager;
import android.widget.TextView;
@@ -23,7 +24,7 @@ public class EventViewBinder {
public static void bindPoint(Context context, WindowManager windowManager,
PointEvent pointEvent, int touchPointSize,
int screenWidth, int screenHeight,
- OnPositionChangedCallback callback,int order) {
+ OnPositionChangedCallback callback,int order,float initialTextSize) {
TextView pointView = createTouchPointView(context, String.valueOf(order));
Log.d("bind","id: " + order);
@@ -35,6 +36,8 @@ public class EventViewBinder {
pointEvent.setView(pointView);
pointEvent.setLayoutParams(params);
+ pointView.setTextSize(TypedValue.COMPLEX_UNIT_SP, initialTextSize);
+
DraggableHelper.makeDraggable(pointView, params, windowManager,
screenWidth, screenHeight,
(x, y) -> {
@@ -49,7 +52,7 @@ public class EventViewBinder {
public static void bindSlide(Context context, WindowManager windowManager,
SlideEvent slideEvent, int touchPointSize,
int screenWidth, int screenHeight,
- OnPositionChangedCallback callback,int order) {
+ OnPositionChangedCallback callback,int order,float initialTextSize) {
PointEvent start = slideEvent.getStartPoint();
PointEvent end = slideEvent.getEndPoint();
@@ -69,6 +72,9 @@ public class EventViewBinder {
end.setView(endView);
end.setLayoutParams(endParams);
+ startView.setTextSize(TypedValue.COMPLEX_UNIT_SP, initialTextSize);
+ endView.setTextSize(TypedValue.COMPLEX_UNIT_SP, initialTextSize);
+
ConnectingLineView lineView = new ConnectingLineView(context);
WindowManager.LayoutParams lineParams = createLineViewParams(context);
@@ -108,7 +114,6 @@ public class EventViewBinder {
touchPointView.setGravity(Gravity.CENTER);
touchPointView.setText(label);
touchPointView.setTextColor(Color.WHITE);
- touchPointView.setTextSize(19);
return touchPointView;
}
@@ -148,7 +153,7 @@ public class EventViewBinder {
return params;
}
- private static void updateLinePosition(SlideEvent slideEvent, int touchPointSize) {
+ public static void updateLinePosition(SlideEvent slideEvent, int touchPointSize) {
PointEvent start = slideEvent.getStartPoint();
PointEvent end = slideEvent.getEndPoint();
ConnectingLineView lineView = slideEvent.getLineView();
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 d642c97..44c49a8 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
@@ -5,6 +5,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.SharedPreferences;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.os.Build;
@@ -13,15 +14,18 @@ import android.os.Looper;
import android.provider.Settings;
import android.text.InputType;
import android.util.Log;
+import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
+import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
@@ -52,7 +56,10 @@ import java.util.List;
public class FloatingViewManager {
private static final String TAG = "FloatingViewManager";
public static final long DEBOUNCE_INTERVAL = 500;
- public static final int TOUCH_POINT_SIZE = 100;
+
+ private int touchPointSize;
+
+ private int controlBarWidth;
private final Context context;
private final WindowManager windowManager;
@@ -74,6 +81,13 @@ public class FloatingViewManager {
private final EventRepository eventRepository;
+ private static final String PREFS_NAME = "AutoClickerPrefs";
+ private static final String KEY_TOUCH_POINT_SIZE = "touch_point_size";
+ private static final String KEY_CONTROL_BAR_WIDTH = "control_bar_width";
+
+ private static final int DEFAULT_TOUCH_POINT_SIZE = 100;
+ private static final int DEFAULT_CONTROL_BAR_WIDTH_DP = 38;
+
public FloatingViewManager(Context context) {
this.context = context;
this.windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
@@ -83,6 +97,10 @@ public class FloatingViewManager {
this.floatingTabDialogManager = new FloatingTabDialogManager(context);
this.floatingTabDialogManager.setFloatingViewManager(this);
this.eventRepository = new EventRepository(context.getApplicationContext());
+ this.touchPointSize = 100;
+
+ loadSettings();
+
registerBroadcastReceiver();
}
@@ -112,16 +130,24 @@ public class FloatingViewManager {
}
private void initMultipleControlBar() {
+ if (multipleControlBarView != null) {
+ safeRemoveView(multipleControlBarView);
+ multipleControlBarView = null;
+ }
+
multipleControlBarView = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.multiple_control_bar, null);
multipleControlBarParams = createControlBarParams();
- setupDraggableView(multipleControlBarView, multipleControlBarParams, this::updateMoreControlBarPosition);
+ multipleControlBarParams.width = this.controlBarWidth;
+ multipleControlBarParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
+ setupDraggableView(multipleControlBarView, multipleControlBarParams, this::updateMoreControlBarPosition);
setupControlButtons(multipleControlBarView);
+
+ updateControlBarImageViews(multipleControlBarView, this.controlBarWidth);
}
private WindowManager.LayoutParams createControlBarParams() {
- // 创建控制栏的悬浮窗参数
int overlayType = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ?
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY :
WindowManager.LayoutParams.TYPE_PHONE;
@@ -257,12 +283,14 @@ public class FloatingViewManager {
return;
}
- PointEvent pointEvent = new PointEvent(eventOrderCounter, screenWidth / 2 - TOUCH_POINT_SIZE / 2,
- screenHeight / 2 - TOUCH_POINT_SIZE / 2);
+ PointEvent pointEvent = new PointEvent(eventOrderCounter, screenWidth / 2 - touchPointSize / 2,
+ screenHeight / 2 - touchPointSize / 2);
+
+ float currentTextSize = calculateTextSizeForPointSize(this.touchPointSize);
EventViewBinder.bindPoint(context, windowManager, pointEvent,
- TOUCH_POINT_SIZE, screenWidth, screenHeight,
- (x, y) -> updateServicePositions(), eventOrderCounter);
+ this.touchPointSize, screenWidth, screenHeight,
+ (x, y) -> updateServicePositions(), eventOrderCounter, currentTextSize);
runtimeEvents.add(new EventWrapper(EventWrapper.EventType.POINT, pointEvent, eventOrderCounter));
eventOrderCounter++;
@@ -278,9 +306,11 @@ public class FloatingViewManager {
PointEvent endPoint = new PointEvent(eventOrderCounter, screenWidth / 2 + 100, screenHeight / 2 - 50);
SlideEvent slideEvent = new SlideEvent(eventOrderCounter, startPoint, endPoint);
+ float currentTextSize = calculateTextSizeForPointSize(this.touchPointSize);
+
EventViewBinder.bindSlide(context, windowManager, slideEvent,
- TOUCH_POINT_SIZE, screenWidth, screenHeight,
- (x, y) -> updateServicePositions(), eventOrderCounter);
+ this.touchPointSize, screenWidth, screenHeight,
+ (x, y) -> updateServicePositions(), eventOrderCounter, currentTextSize);
runtimeEvents.add(new EventWrapper(EventWrapper.EventType.SLIDE, slideEvent, eventOrderCounter));
eventOrderCounter++;
@@ -649,11 +679,13 @@ public class FloatingViewManager {
if (clickPoint != null) {
PointEvent pointEvent = new PointEvent(eventEntity.orderInSolution, clickPoint.x, clickPoint.y);
+ float currentTextSize = calculateTextSizeForPointSize(FloatingViewManager.this.touchPointSize);
+
EventViewBinder.bindPoint(context, windowManager,
pointEvent,
- TOUCH_POINT_SIZE,
+ FloatingViewManager.this.touchPointSize,
screenWidth, screenHeight,
- (x, y) -> updateServicePositions(), eventEntity.orderInSolution);
+ (x, y) -> updateServicePositions(), eventEntity.orderInSolution, currentTextSize);
runtimeEvents.add(new EventWrapper(type, pointEvent, pointEvent.getId()));
}
@@ -667,11 +699,13 @@ public class FloatingViewManager {
SlideEvent slideEvent = new SlideEvent(eventEntity.orderInSolution, startPointEvent, endPointEvent);
+ float currentTextSize = calculateTextSizeForPointSize(FloatingViewManager.this.touchPointSize);
+
EventViewBinder.bindSlide(context, windowManager,
slideEvent,
- TOUCH_POINT_SIZE,
+ FloatingViewManager.this.touchPointSize,
screenWidth, screenHeight,
- (x, y) -> updateServicePositions(), eventEntity.orderInSolution);
+ (x, y) -> updateServicePositions(), eventEntity.orderInSolution, currentTextSize);
runtimeEvents.add(new EventWrapper(type, slideEvent, slideEvent.getId()));
}
@@ -715,4 +749,202 @@ public class FloatingViewManager {
lastToggleTime = currentTime;
return false;
}
+
+ private void loadSettings() {
+ SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
+ this.touchPointSize = prefs.getInt(KEY_TOUCH_POINT_SIZE, DEFAULT_TOUCH_POINT_SIZE);
+
+
+ int defaultControlBarWidthPx = dpToPx(DEFAULT_CONTROL_BAR_WIDTH_DP);
+ this.controlBarWidth = prefs.getInt(KEY_CONTROL_BAR_WIDTH, defaultControlBarWidthPx);
+
+ Log.d(TAG, "设置已加载:触摸点大小=" + this.touchPointSize + ", 控制栏宽度=" + this.controlBarWidth);
+ }
+
+ public void setTouchPointSize(int newSize) {
+ if (this.touchPointSize == newSize || newSize <= 0) {
+ return;
+ }
+ this.touchPointSize = newSize;
+ saveTouchPointSize(newSize);
+
+ for (EventWrapper wrapper : new ArrayList<>(runtimeEvents)) {
+ if (wrapper.getType() == EventWrapper.EventType.POINT) {
+ PointEvent pe = (PointEvent) wrapper.getEvent();
+ updatePointViewSize(pe);
+ } else if (wrapper.getType() == EventWrapper.EventType.SLIDE) {
+ SlideEvent se = (SlideEvent) wrapper.getEvent();
+ updateSlideViewSize(se);
+ }
+ }
+ }
+
+ private void updatePointViewSize(PointEvent pointEvent) {
+ if (pointEvent.getView() != null && pointEvent.getLayoutParams() != null) {
+ TextView pointView = pointEvent.getView();
+ WindowManager.LayoutParams params = pointEvent.getLayoutParams();
+
+ params.width = touchPointSize;
+ params.height = touchPointSize;
+
+ float newTextSize = calculateTextSizeForPointSize(touchPointSize);
+
+ pointView.setTextSize(TypedValue.COMPLEX_UNIT_SP, newTextSize);
+
+ try {
+ windowManager.updateViewLayout(pointView, params);
+ } catch (IllegalArgumentException e) {
+ Log.w(TAG, "尝试更新不存在的点击点视图", e);
+ }
+ }
+ }
+
+ private void updateSlideViewSize(SlideEvent slideEvent) {
+ float newTextSize = calculateTextSizeForPointSize(touchPointSize); // 调用新方法计算
+
+ if (slideEvent.getStartPoint().getView() != null && slideEvent.getStartPoint().getLayoutParams() != null) {
+ TextView startView = slideEvent.getStartPoint().getView();
+ WindowManager.LayoutParams startParams = slideEvent.getStartPoint().getLayoutParams();
+ startParams.width = touchPointSize;
+ startParams.height = touchPointSize;
+ startView.setTextSize(TypedValue.COMPLEX_UNIT_SP, newTextSize);
+ try {
+ windowManager.updateViewLayout(startView, startParams);
+ } catch (IllegalArgumentException e) {
+ Log.w(TAG, "尝试更新不存在的滑动起点视图", e);
+ }
+ }
+
+ if (slideEvent.getEndPoint().getView() != null && slideEvent.getEndPoint().getLayoutParams() != null) {
+ TextView endView = slideEvent.getEndPoint().getView();
+ WindowManager.LayoutParams endParams = slideEvent.getEndPoint().getLayoutParams();
+ endParams.width = touchPointSize;
+ endParams.height = touchPointSize;
+ endView.setTextSize(TypedValue.COMPLEX_UNIT_SP, newTextSize);
+ try {
+ windowManager.updateViewLayout(endView, endParams);
+ } catch (IllegalArgumentException e) {
+ Log.w(TAG, "尝试更新不存在的滑动终点视图", e);
+ }
+ }
+
+ EventViewBinder.updateLinePosition(slideEvent, touchPointSize);
+ }
+
+ private float calculateTextSizeForPointSize(int pointSize) {
+ final int MIN_POINT_SIZE_FOR_CALC = 50;
+ final int MAX_POINT_SIZE_FOR_CALC = 200;
+ final float MIN_TEXT_SIZE_SP = 10f;
+ final float MAX_TEXT_SIZE_SP = 30f;
+
+ float ratio = (float) (pointSize - MIN_POINT_SIZE_FOR_CALC) / (MAX_POINT_SIZE_FOR_CALC - MIN_POINT_SIZE_FOR_CALC);
+ return MIN_TEXT_SIZE_SP + (MAX_TEXT_SIZE_SP - MIN_TEXT_SIZE_SP) * ratio;
+ }
+
+ private void saveTouchPointSize(int size) {
+ SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
+ prefs.edit().putInt(KEY_TOUCH_POINT_SIZE, size).apply();
+ Log.d(TAG, "触摸点大小已保存: " + size);
+ }
+
+ private void saveControlBarWidth(int width) {
+ SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
+ prefs.edit().putInt(KEY_CONTROL_BAR_WIDTH, width).apply();
+ Log.d(TAG, "控制栏宽度已保存: " + width);
+ }
+
+ public int getTouchPointSize() {
+ return this.touchPointSize;
+ }
+
+ private void updateControlBarImageViews(ViewGroup parentView, int newBarWidthPx) {
+ float scaleFactor = (float) newBarWidthPx / dpToPx(DEFAULT_CONTROL_BAR_WIDTH_DP);
+
+ for (int i = 0; i < parentView.getChildCount(); i++) {
+ View child = parentView.getChildAt(i);
+ if (child instanceof ViewGroup) {
+ // 递归处理嵌套的 ViewGroup
+ updateControlBarImageViews((ViewGroup) child, newBarWidthPx);
+ } else if (child instanceof ImageView) {
+ ImageView imageView = (ImageView) child;
+ ViewGroup.LayoutParams params = imageView.getLayoutParams();
+
+ if (imageView.getId() == R.id.cut_off) {
+ params.width = ViewGroup.LayoutParams.MATCH_PARENT;
+ params.height = dpToPx(1);
+
+ imageView.setLayoutParams(params);
+ continue;
+ }
+
+ int originalImgWidthDp = 0;
+ int originalImgHeightDp = 0;
+
+ if (imageView.getId() == R.id.play_button || imageView.getId() == R.id.add_button || imageView.getId() == R.id.remove_button || imageView.getId() == R.id.close_button) {
+ originalImgWidthDp = 13;
+ if (imageView.getId() == R.id.remove_button) {
+ originalImgHeightDp = 2;
+ } else {
+ originalImgHeightDp = 13;
+ }
+ } else if (imageView.getId() == R.id.slide_button) {
+ originalImgWidthDp = 17;
+ originalImgHeightDp = 17;
+ } else if (imageView.getId() == R.id.save_button) {
+ originalImgWidthDp = 15;
+ originalImgHeightDp = 15;
+ } else if (imageView.getId() == R.id.eye_button) {
+ originalImgWidthDp = 16;
+ originalImgHeightDp = 9;
+ } else if (imageView.getId() == R.id.settings_button) {
+ originalImgWidthDp = 14;
+ originalImgHeightDp = 14;
+ }
+
+ if (originalImgWidthDp > 0) {
+ // 根据原始 dp 值和缩放因子计算新的像素尺寸
+ params.width = (int) (dpToPx(originalImgWidthDp) * scaleFactor);
+ params.height = (int) (dpToPx(originalImgHeightDp) * scaleFactor);
+ imageView.setLayoutParams(params);
+ } else {
+ if (params.width > 0) {
+ params.width = (int) (dpToPx(params.width) * scaleFactor);
+ }
+ if (params.height > 0) {
+ params.height = (int) (dpToPx(params.height) * scaleFactor);
+ }
+ imageView.setLayoutParams(params);
+ }
+ }
+ }
+ }
+
+ private int dpToPx(int dp) {
+ if (context == null) return dp;
+ return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());
+ }
+
+ public void setControlBarSize(int newWidth) {
+ if (this.controlBarWidth == newWidth || newWidth <= 0) {
+ return;
+ }
+ this.controlBarWidth = newWidth;
+ saveControlBarWidth(newWidth);
+
+ if (multipleControlBarView != null && multipleControlBarParams != null) {
+ multipleControlBarParams.width = this.controlBarWidth;
+ multipleControlBarParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
+
+ try {
+ windowManager.updateViewLayout(multipleControlBarView, multipleControlBarParams);
+ updateControlBarImageViews(multipleControlBarView, this.controlBarWidth);
+ } catch (IllegalArgumentException e) {
+ Log.w(TAG, "尝试更新不存在的控制栏视图", e);
+ }
+ }
+ }
+
+ public int getControlBarWidth() {
+ return controlBarWidth;
+ }
}
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_unit_selection.xml b/app/src/main/res/layout/dialog_unit_selection.xml
new file mode 100644
index 0000000..3b59649
--- /dev/null
+++ b/app/src/main/res/layout/dialog_unit_selection.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_u_i_size.xml b/app/src/main/res/layout/fragment_u_i_size.xml
index a6618c4..0112ec4 100644
--- a/app/src/main/res/layout/fragment_u_i_size.xml
+++ b/app/src/main/res/layout/fragment_u_i_size.xml
@@ -1,9 +1,9 @@
-
-
-
-
-
-
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent">
-
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ tools:text="100px" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/multiple_control_bar.xml b/app/src/main/res/layout/multiple_control_bar.xml
index 85780cb..a1cbe98 100644
--- a/app/src/main/res/layout/multiple_control_bar.xml
+++ b/app/src/main/res/layout/multiple_control_bar.xml
@@ -9,8 +9,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
- android:orientation="vertical"
- android:paddingHorizontal="10dp">
+ android:orientation="vertical">
Hello blank fragment
Preview
This service enables auto-clicking on the screen.
-
+ milliseconds
+ seconds
+ minutes
\ No newline at end of file