功能添加
This commit is contained in:
parent
0c81561074
commit
d021cdc9a9
@ -364,6 +364,12 @@ public class MainActivity extends AppCompatActivity {
|
||||
|
||||
binding.single.setEnabled(isFloatingShown == FLOATING_NONE);
|
||||
binding.multi.setEnabled(isFloatingShown == FLOATING_NONE);
|
||||
|
||||
if (isFloatingShown == FLOATING_NONE) {
|
||||
setVideo(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.bolangblue));
|
||||
} else {
|
||||
setVideo(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.bolangred));
|
||||
}
|
||||
}
|
||||
|
||||
private void setStartButtonEnabled(boolean enabled) {
|
||||
|
||||
@ -17,7 +17,6 @@ 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;
|
||||
|
||||
|
||||
@ -0,0 +1,410 @@
|
||||
package com.auto.clicker.autoclicker.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.text.InputType;
|
||||
import android.util.Log;
|
||||
import android.view.ContextThemeWrapper;
|
||||
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.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.PopupWindow;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.widget.SwitchCompat;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
|
||||
import com.auto.clicker.autoclicker.R;
|
||||
import com.auto.clicker.autoclicker.service.AutoClickService;
|
||||
|
||||
public class FloatingSettingDialogManager {
|
||||
|
||||
private static final String TAG = "FloatingSettingDialogManager";
|
||||
private final Context context;
|
||||
private final WindowManager windowManager;
|
||||
private ConstraintLayout floatingDialogView;
|
||||
private WindowManager.LayoutParams floatingDialogParams;
|
||||
|
||||
private FloatingViewManager floatingViewManager;
|
||||
|
||||
private static final int TYPE_INTERVAL = 0;
|
||||
private static final int TYPE_SWIPE_DURATION = 1;
|
||||
private static final int TYPE_REPEAT = 2;
|
||||
|
||||
private LinearLayout intervalSelectorContainer;
|
||||
private LinearLayout unitSelectorContainer;
|
||||
private SwitchCompat repeatSwitch;
|
||||
private LinearLayout repeatInput;
|
||||
private LinearLayout repeatSelectorContainer;
|
||||
private EditText etIntervalValue;
|
||||
private TextView intervalSelectedUnit;
|
||||
private EditText etDurationValue;
|
||||
private TextView tvSelectedUnit;
|
||||
private EditText etRepeatValue;
|
||||
private TextView repeatSelectedUnit;
|
||||
|
||||
public FloatingSettingDialogManager(Context context) {
|
||||
this.context = context;
|
||||
this.windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
}
|
||||
|
||||
public void setFloatingViewManager(FloatingViewManager manager) {
|
||||
this.floatingViewManager = manager;
|
||||
}
|
||||
|
||||
public void showFloatingTabDialog() {
|
||||
if (floatingDialogView != null) {
|
||||
removeFloatingTabDialog();
|
||||
}
|
||||
|
||||
Context themedContext = new ContextThemeWrapper(context, R.style.Theme_AutoClicker);
|
||||
|
||||
floatingDialogView = (ConstraintLayout) LayoutInflater.from(themedContext).inflate(R.layout.floating_setting_dialog, null);
|
||||
floatingDialogParams = createFloatingDialogParams();
|
||||
|
||||
intervalSelectorContainer = floatingDialogView.findViewById(R.id.dialog_interval_selector_container);
|
||||
unitSelectorContainer = floatingDialogView.findViewById(R.id.dialog_unit_selector_container);
|
||||
repeatSwitch = floatingDialogView.findViewById(R.id.dialog_repeat_switch);
|
||||
repeatInput = floatingDialogView.findViewById(R.id.dialog_repeat_input);
|
||||
repeatSelectorContainer = floatingDialogView.findViewById(R.id.dialog_repeat_selector_container);
|
||||
etIntervalValue = floatingDialogView.findViewById(R.id.dialog_et_interval_value);
|
||||
intervalSelectedUnit = floatingDialogView.findViewById(R.id.dialog_interval_selected_unit);
|
||||
etDurationValue = floatingDialogView.findViewById(R.id.dialog_et_duration_value);
|
||||
tvSelectedUnit = floatingDialogView.findViewById(R.id.dialog_tv_selected_unit);
|
||||
etRepeatValue = floatingDialogView.findViewById(R.id.dialog_et_repeat_value);
|
||||
repeatSelectedUnit = floatingDialogView.findViewById(R.id.dialog_repeat_selected_unit);
|
||||
|
||||
intervalSelectorContainer.setOnClickListener(v -> showUnitSelection(v, TYPE_INTERVAL));
|
||||
unitSelectorContainer.setOnClickListener(v -> showUnitSelection(v, TYPE_SWIPE_DURATION));
|
||||
|
||||
setupRepeatMode();
|
||||
|
||||
floatingDialogView.setOnTouchListener((v, event) -> {
|
||||
if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
|
||||
// 如果是外部点击事件,就关闭对话框
|
||||
removeFloatingTabDialog();
|
||||
Log.d(TAG, "检测到外部点击,浮动标签页弹窗已关闭。");
|
||||
return true; // 消费此事件
|
||||
}
|
||||
return false; // 其他事件不处理
|
||||
});
|
||||
|
||||
try {
|
||||
windowManager.addView(floatingDialogView, floatingDialogParams);
|
||||
Log.d(TAG, "浮动标签页弹窗已显示");
|
||||
} catch (WindowManager.BadTokenException e) {
|
||||
Log.e(TAG, "无法添加浮动标签页弹窗,可能是权限问题或上下文无效", e);
|
||||
showToastOnUi(context, "显示弹窗失败,请检查权限。");
|
||||
} catch (SecurityException e) {
|
||||
Log.e(TAG, "需要悬浮窗权限才能显示浮动弹窗", e);
|
||||
showToastOnUi(context, "请授予悬浮窗权限以便显示。");
|
||||
}
|
||||
}
|
||||
|
||||
public void removeFloatingTabDialog() {
|
||||
if (floatingDialogView != null) {
|
||||
try {
|
||||
windowManager.removeView(floatingDialogView);
|
||||
floatingDialogView = null;
|
||||
intervalSelectorContainer = null;
|
||||
unitSelectorContainer = null;
|
||||
repeatSwitch = null;
|
||||
repeatInput = null;
|
||||
repeatSelectorContainer = null;
|
||||
etIntervalValue = null;
|
||||
intervalSelectedUnit = null;
|
||||
etDurationValue = null;
|
||||
tvSelectedUnit = null;
|
||||
etRepeatValue = null;
|
||||
repeatSelectedUnit = null;
|
||||
|
||||
Log.d(TAG, "浮动标签页弹窗已移除");
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.w(TAG, "尝试移除不存在的视图", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private WindowManager.LayoutParams createFloatingDialogParams() {
|
||||
int overlayType = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ?
|
||||
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY :
|
||||
WindowManager.LayoutParams.TYPE_PHONE;
|
||||
|
||||
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
|
||||
WindowManager.LayoutParams.WRAP_CONTENT,
|
||||
WindowManager.LayoutParams.WRAP_CONTENT,
|
||||
overlayType,
|
||||
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
|
||||
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
|
||||
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL // 允许将触摸事件传递到其下方窗口
|
||||
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, // 监听外部触摸事件
|
||||
PixelFormat.TRANSLUCENT
|
||||
);
|
||||
params.gravity = Gravity.CENTER;
|
||||
return params;
|
||||
}
|
||||
|
||||
private void setupRepeatMode() {
|
||||
if (repeatSwitch == null || repeatInput == null || repeatSelectorContainer == null ||
|
||||
repeatSelectedUnit == null || etRepeatValue == null) {
|
||||
Log.e(TAG, "repeat mode UI components not found. Skipping setupRepeatMode.");
|
||||
return;
|
||||
}
|
||||
|
||||
repeatSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
if (isChecked) {
|
||||
repeatInput.setVisibility(View.VISIBLE);
|
||||
repeatSelectorContainer.setVisibility(View.VISIBLE);
|
||||
repeatSelectedUnit.setText(context.getString(R.string.infinitely_unit));
|
||||
etRepeatValue.setText("");
|
||||
etRepeatValue.setEnabled(false);
|
||||
etRepeatValue.setInputType(InputType.TYPE_NULL);
|
||||
} else {
|
||||
repeatInput.setVisibility(View.GONE);
|
||||
repeatSelectorContainer.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
|
||||
// 根据初始状态设置可见性
|
||||
if (!repeatSwitch.isChecked()) {
|
||||
repeatInput.setVisibility(View.GONE);
|
||||
repeatSelectorContainer.setVisibility(View.GONE);
|
||||
} else {
|
||||
repeatSelectedUnit.setText(context.getString(R.string.infinitely_unit));
|
||||
etRepeatValue.setText("");
|
||||
etRepeatValue.setEnabled(false);
|
||||
etRepeatValue.setInputType(InputType.TYPE_NULL);
|
||||
}
|
||||
|
||||
repeatSelectorContainer.setOnClickListener(v -> showUnitSelection(v, TYPE_REPEAT));
|
||||
}
|
||||
|
||||
private void showUnitSelection(View anchorView, int type) {
|
||||
View popupView = LayoutInflater.from(context).inflate(R.layout.dialog_unit_selection, null);
|
||||
PopupWindow popupWindow = new PopupWindow(
|
||||
popupView,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
true
|
||||
);
|
||||
|
||||
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
popupWindow.setOutsideTouchable(true);
|
||||
|
||||
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);
|
||||
TextView tvInfinitely = popupView.findViewById(R.id.tv_unit_infinitely);
|
||||
TextView tvDuration = popupView.findViewById(R.id.tv_unit_duration);
|
||||
TextView tvCycle = popupView.findViewById(R.id.tv_unit_cycle);
|
||||
|
||||
switch (type) {
|
||||
case TYPE_INTERVAL:
|
||||
tvMs.setVisibility(View.VISIBLE);
|
||||
tvSec.setVisibility(View.VISIBLE);
|
||||
tvMin.setVisibility(View.VISIBLE);
|
||||
tvInfinitely.setVisibility(View.GONE);
|
||||
tvDuration.setVisibility(View.GONE);
|
||||
tvCycle.setVisibility(View.GONE);
|
||||
break;
|
||||
case TYPE_SWIPE_DURATION:
|
||||
tvMs.setVisibility(View.VISIBLE);
|
||||
tvSec.setVisibility(View.VISIBLE);
|
||||
tvMin.setVisibility(View.GONE);
|
||||
tvInfinitely.setVisibility(View.GONE);
|
||||
tvDuration.setVisibility(View.GONE);
|
||||
tvCycle.setVisibility(View.GONE);
|
||||
break;
|
||||
case TYPE_REPEAT:
|
||||
tvMs.setVisibility(View.GONE);
|
||||
tvSec.setVisibility(View.GONE);
|
||||
tvMin.setVisibility(View.GONE);
|
||||
tvInfinitely.setVisibility(View.VISIBLE);
|
||||
tvDuration.setVisibility(View.VISIBLE);
|
||||
tvCycle.setVisibility(View.VISIBLE);
|
||||
Log.d(TAG, "TYPE_REPEAT: infinitely, duration, cycle visible.");
|
||||
break;
|
||||
}
|
||||
|
||||
if (type == TYPE_INTERVAL || type == TYPE_SWIPE_DURATION) {
|
||||
tvMs.setOnClickListener(v -> {
|
||||
String unitText = context.getString(R.string.milliseconds_unit);
|
||||
if (type == TYPE_INTERVAL) {
|
||||
intervalSelectedUnit.setText(unitText);
|
||||
showInputValue("Interval", etIntervalValue.getText().toString(), unitText);
|
||||
} else {
|
||||
tvSelectedUnit.setText(unitText);
|
||||
showInputValue("Swipe Duration", etDurationValue.getText().toString(), unitText);
|
||||
}
|
||||
popupWindow.dismiss();
|
||||
});
|
||||
|
||||
tvSec.setOnClickListener(v -> {
|
||||
String unitText = context.getString(R.string.seconds_unit);
|
||||
if (type == TYPE_INTERVAL) {
|
||||
intervalSelectedUnit.setText(unitText);
|
||||
showInputValue("Interval", etIntervalValue.getText().toString(), unitText);
|
||||
} else {
|
||||
tvSelectedUnit.setText(unitText);
|
||||
showInputValue("Swipe Duration", etDurationValue.getText().toString(), unitText);
|
||||
}
|
||||
popupWindow.dismiss();
|
||||
});
|
||||
|
||||
if (type == TYPE_INTERVAL) {
|
||||
tvMin.setOnClickListener(v -> {
|
||||
String unitText = context.getString(R.string.minutes_unit);
|
||||
intervalSelectedUnit.setText(unitText);
|
||||
popupWindow.dismiss();
|
||||
showInputValue("Interval", etIntervalValue.getText().toString(), unitText);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (type == TYPE_REPEAT) {
|
||||
tvInfinitely.setOnClickListener(v -> {
|
||||
repeatSelectedUnit.setText(context.getString(R.string.infinitely_unit));
|
||||
etRepeatValue.setText("");
|
||||
etRepeatValue.setEnabled(false);
|
||||
etRepeatValue.setInputType(InputType.TYPE_NULL);
|
||||
popupWindow.dismiss();
|
||||
showInputValue("Repeat", etRepeatValue.getText().toString(), context.getString(R.string.infinitely_unit));
|
||||
});
|
||||
|
||||
tvDuration.setOnClickListener(v -> {
|
||||
repeatSelectedUnit.setText(context.getString(R.string.duration_unit));
|
||||
etRepeatValue.setText("");
|
||||
etRepeatValue.setEnabled(true);
|
||||
etRepeatValue.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||
popupWindow.dismiss();
|
||||
showInputValue("Repeat", etRepeatValue.getText().toString(), context.getString(R.string.duration_unit));
|
||||
});
|
||||
|
||||
tvCycle.setOnClickListener(v -> {
|
||||
repeatSelectedUnit.setText(context.getString(R.string.cycle_unit));
|
||||
etRepeatValue.setText("");
|
||||
etRepeatValue.setEnabled(true);
|
||||
etRepeatValue.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||
popupWindow.dismiss();
|
||||
showInputValue("Repeat", etRepeatValue.getText().toString(), context.getString(R.string.cycle_unit));
|
||||
});
|
||||
}
|
||||
|
||||
if (type == TYPE_REPEAT) {
|
||||
popupWindow.showAsDropDown(anchorView, 0, -500);
|
||||
} else {
|
||||
popupWindow.showAsDropDown(anchorView);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void showInputValue(String type, String value, String unit) {
|
||||
String message = type + " 值: " + (value.isEmpty() ? "未输入" : value) + ", 单位: " + unit;
|
||||
showToastOnUi(context, message);
|
||||
|
||||
AutoClickService service = AutoClickService.getInstance();
|
||||
|
||||
switch (type) {
|
||||
case "Interval":
|
||||
long intervalValue = 0;
|
||||
if (!value.isEmpty()) {
|
||||
try {
|
||||
intervalValue = Long.parseLong(value);
|
||||
// 根据 unit 进行单位转换
|
||||
if (unit.equals(context.getString(R.string.seconds_unit))) {
|
||||
intervalValue *= 1000; // 如果单位是秒,转换为毫秒
|
||||
}
|
||||
if (service != null) {
|
||||
service.setClickInterval(intervalValue);
|
||||
} else {
|
||||
Log.e(TAG, "AutoClickService 实例为空,无法设置点击间隔。");
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
Log.e(TAG, "点击间隔值解析错误: " + value, e);
|
||||
showToastOnUi(context, "点击间隔值无效,请输入有效数字。");
|
||||
}
|
||||
}
|
||||
// 你可以在这里将 intervalValue 保存到你的数据模型或 SharedPreferences
|
||||
break;
|
||||
|
||||
case "Swipe Duration":
|
||||
int slideDurationValue = 0;
|
||||
if (!value.isEmpty()) {
|
||||
try {
|
||||
slideDurationValue = Integer.parseInt(value);
|
||||
if (unit.equals(context.getString(R.string.seconds_unit))) {
|
||||
slideDurationValue *= 1000; // 如果单位是秒,转换为毫秒
|
||||
}
|
||||
if (service != null) {
|
||||
service.setSlideDuration(slideDurationValue);
|
||||
} else {
|
||||
Log.e(TAG, "AutoClickService 实例为空,无法设置滑动时长。");
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
Log.e(TAG, "滑动时长值解析错误: " + value, e);
|
||||
showToastOnUi(context, "滑动时长值无效,请输入有效数字。");
|
||||
}
|
||||
}
|
||||
// 你可以在这里将 slideDurationValue 保存到你的数据模型或 SharedPreferences
|
||||
break;
|
||||
|
||||
case "Repeat":
|
||||
if (unit.equals(context.getString(R.string.infinitely_unit))) {
|
||||
// Repeat 为无限次,不需要处理输入值
|
||||
// 确保 etRepeatValue 是禁用的
|
||||
etRepeatValue.setText("");
|
||||
etRepeatValue.setEnabled(false);
|
||||
etRepeatValue.setInputType(InputType.TYPE_NULL);
|
||||
showToastOnUi(context, "重复模式: 无限次");
|
||||
// AutoClickService 内部已是循环执行,无限次意味着一直运行直到用户停止。
|
||||
// 如果需要更明确的无限次模式,可以在 AutoClickService 中设置一个标志位。
|
||||
} else if (unit.equals(context.getString(R.string.duration_unit))) {
|
||||
// Repeat 为时长,处理时间格式的输入 (例如 "HH:mm:ss" -> 毫秒)
|
||||
String durationValueStr = value.isEmpty() ? "0" : value;
|
||||
// TODO: 你需要在这里添加解析时间格式的逻辑,例如:
|
||||
// long parsedDuration = parseDurationString(durationValueStr); // 自定义方法解析时间
|
||||
// 如果 AutoClickService 需要总运行时间限制,你需要修改 AutoClickService 来支持。
|
||||
// 否则,你可能需要在悬浮窗管理类中实现一个计时器,当达到设定时长时调用 service.stopClicking()。
|
||||
etRepeatValue.setEnabled(true);
|
||||
etRepeatValue.setInputType(InputType.TYPE_CLASS_NUMBER); // 这里暂时设置为数字,如果需要特定时间输入,需要更复杂的实现
|
||||
showToastOnUi(context, "重复时长: " + durationValueStr);
|
||||
} else if (unit.equals(context.getString(R.string.cycle_unit))) {
|
||||
// Repeat 为次数,处理整数输入
|
||||
int repeatCount = 0;
|
||||
if (!value.isEmpty()) {
|
||||
try {
|
||||
repeatCount = Integer.parseInt(value);
|
||||
// TODO: 如果 AutoClickService 需要总循环次数限制,你需要修改 AutoClickService 来支持。
|
||||
// 可以在 AutoClickService 中添加一个变量来跟踪剩余循环次数,并在每次事件队列执行完毕后递减。
|
||||
// 当次数为 0 时,调用 stopClicking()。
|
||||
} catch (NumberFormatException e) {
|
||||
Log.e(TAG, "重复次数值解析错误: " + value, e);
|
||||
showToastOnUi(context, "重复次数值无效,请输入有效数字。");
|
||||
}
|
||||
}
|
||||
etRepeatValue.setEnabled(true);
|
||||
etRepeatValue.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||
showToastOnUi(context, "重复次数: " + repeatCount);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static void showToastOnUi(Context context, String msg) {
|
||||
new Handler(Looper.getMainLooper()).post(() ->
|
||||
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,6 +1,5 @@
|
||||
package com.auto.clicker.autoclicker.view;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@ -12,7 +11,6 @@ import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.provider.Settings;
|
||||
import android.text.InputType;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
@ -21,15 +19,12 @@ 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;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import com.auto.clicker.autoclicker.R;
|
||||
@ -80,6 +75,7 @@ public class FloatingViewManager {
|
||||
private boolean areEventsVisible = true;
|
||||
|
||||
private final FloatingTabDialogManager floatingTabDialogManager;
|
||||
private final FloatingSettingDialogManager floatingSettingDialogManager;
|
||||
|
||||
private final EventRepository eventRepository;
|
||||
|
||||
@ -97,7 +93,9 @@ public class FloatingViewManager {
|
||||
this.screenWidth = screenSize.x;
|
||||
this.screenHeight = screenSize.y;
|
||||
this.floatingTabDialogManager = new FloatingTabDialogManager(context);
|
||||
this.floatingSettingDialogManager = new FloatingSettingDialogManager(context);
|
||||
this.floatingTabDialogManager.setFloatingViewManager(this);
|
||||
this.floatingSettingDialogManager.setFloatingViewManager(this);
|
||||
this.eventRepository = new EventRepository(context.getApplicationContext());
|
||||
this.touchPointSize = 100;
|
||||
|
||||
@ -238,6 +236,7 @@ public class FloatingViewManager {
|
||||
addButton.setVisibility(View.GONE);
|
||||
removeButton.setVisibility(View.GONE);
|
||||
slideButton.setVisibility(View.GONE);
|
||||
addPointEvent();
|
||||
}
|
||||
|
||||
playButton.setOnClickListener(v -> toggleMultipleClicking());
|
||||
@ -259,7 +258,9 @@ public class FloatingViewManager {
|
||||
}
|
||||
});
|
||||
|
||||
settingButton.setOnClickListener(v -> showInputDialog());
|
||||
settingButton.setOnClickListener(v -> {
|
||||
floatingSettingDialogManager.showFloatingTabDialog();
|
||||
});
|
||||
closeButton.setOnClickListener(v -> closeFloatingViews());
|
||||
}
|
||||
|
||||
@ -413,7 +414,7 @@ public class FloatingViewManager {
|
||||
PrefUtils.setFloatingShown(context, 0);
|
||||
|
||||
Intent intent = new Intent("com.auto.clicker.autoclicker.FLOATING_WINDOW_STATE_CHANGED");
|
||||
intent.putExtra("isShown", false);
|
||||
intent.putExtra("isShown", 0);
|
||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
||||
}
|
||||
|
||||
@ -459,6 +460,10 @@ public class FloatingViewManager {
|
||||
floatingTabDialogManager.removeFloatingTabDialog();
|
||||
}
|
||||
|
||||
if (floatingSettingDialogManager != null) {
|
||||
floatingSettingDialogManager.removeFloatingTabDialog();
|
||||
}
|
||||
|
||||
Log.d(TAG, "所有浮动视图(包括控制栏和事件)已移除");
|
||||
}
|
||||
|
||||
@ -535,55 +540,6 @@ public class FloatingViewManager {
|
||||
}
|
||||
}
|
||||
|
||||
public void showInputDialog() {
|
||||
EditText input = new EditText(context);
|
||||
input.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||
input.setHint("输入点击间隔(ms)");
|
||||
input.setFocusableInTouchMode(true);
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle("设置点击间隔")
|
||||
.setView(input)
|
||||
.setPositiveButton("确定", (dialog, which) -> {
|
||||
String value = input.getText().toString();
|
||||
try {
|
||||
long interval = Long.parseLong(value);
|
||||
AutoClickService service = AutoClickService.getInstance();
|
||||
if (service != null) {
|
||||
service.setClickInterval(interval);
|
||||
} else {
|
||||
Log.w("InputDialog", "AutoClickService 未初始化");
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
Toast.makeText(context, "无效输入", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
dialog.dismiss();
|
||||
})
|
||||
.setNegativeButton("取消", (dialog, which) -> dialog.dismiss());
|
||||
|
||||
AlertDialog dialog = builder.create();
|
||||
|
||||
if (!(context instanceof Activity)) {
|
||||
if (dialog.getWindow() != null) {
|
||||
dialog.getWindow().setType(
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ?
|
||||
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY :
|
||||
WindowManager.LayoutParams.TYPE_PHONE
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
dialog.show();
|
||||
|
||||
input.requestFocus();
|
||||
input.post(() -> {
|
||||
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
if (imm != null) {
|
||||
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void flashTouchPoint(int index) {
|
||||
if (index >= 0 && index < runtimeEvents.size()) {
|
||||
Event event = runtimeEvents.get(index).getEvent();
|
||||
|
||||
9
app/src/main/res/drawable/green_ring.xml
Normal file
9
app/src/main/res/drawable/green_ring.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="47dp"
|
||||
android:height="47dp"
|
||||
android:viewportWidth="47"
|
||||
android:viewportHeight="47">
|
||||
<path
|
||||
android:pathData="M23.5,0C10.522,0 0,10.522 0,23.5C0,36.478 10.522,47 23.5,47C36.478,47 47,36.478 47,23.5C47,10.522 36.478,0 23.5,0ZM23.743,44.908C23.743,44.908 23.788,44.786 23.788,44.726V40.177C23.788,39.601 23.318,39.146 22.757,39.146C22.196,39.146 21.726,39.617 21.726,40.177V44.726C21.726,44.726 21.741,44.802 21.741,44.832C11.098,43.953 2.653,35.265 2.138,24.531H6.08C6.656,24.531 7.111,24.061 7.111,23.5C7.111,22.939 6.641,22.469 6.08,22.469H2.123C2.638,11.72 11.083,3.047 21.726,2.168C21.726,2.214 21.711,2.244 21.711,2.274V6.823C21.711,7.399 22.181,7.854 22.742,7.854C23.303,7.854 23.773,7.384 23.773,6.823V2.274C23.773,2.274 23.743,2.153 23.727,2.092C35.083,2.214 44.317,11.219 44.862,22.469H40.92C40.344,22.469 39.889,22.939 39.889,23.5C39.889,24.061 40.359,24.531 40.92,24.531H44.862C44.317,35.781 35.083,44.786 23.727,44.908H23.743Z"
|
||||
android:fillColor="#57FC0B"/>
|
||||
</vector>
|
||||
@ -1,9 +1,6 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M502.7,448a56,56 0,1 0,0 112,56 56,0 0,0 0,-112zM502.7,96C277.3,96 94.6,278.7 94.6,504S277.3,912 502.6,912C728,912 910.7,729.3 910.7,504S728,96 502.7,96zM544,829.3L544,688h-80v141.3C320,811.1 195.5,688 177.3,544L320,544v-80h-142.7C195.5,320 320,196.8 464,178.7L464,320h80v-141.3C688,196.8 809.8,320 828,464L688,464v80h140C809.8,688 688,811.2 544,829.3z"
|
||||
android:fillColor="#FF0057"/>
|
||||
</vector>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/blue_ring_bg" />
|
||||
|
||||
<item android:drawable="@drawable/green_ring" />
|
||||
</layer-list>
|
||||
288
app/src/main/res/layout/floating_setting_dialog.xml
Normal file
288
app/src/main/res/layout/floating_setting_dialog.xml
Normal file
@ -0,0 +1,288 @@
|
||||
<?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"
|
||||
android:layout_width="321dp"
|
||||
android:layout_height="386dp"
|
||||
android:background="@drawable/bg_rounded_rect"
|
||||
android:paddingBottom="25dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_default_actions_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="35dp"
|
||||
android:layout_marginTop="23dp"
|
||||
android:text="Default Actions"
|
||||
android:textColor="@color/text_gray"
|
||||
android:textSize="15sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_interval_icon"
|
||||
android:layout_width="11dp"
|
||||
android:layout_height="12dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:src="@drawable/hourglass"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/tv_interval_label"
|
||||
app:layout_constraintEnd_toStartOf="@+id/tv_interval_label"
|
||||
app:layout_constraintTop_toTopOf="@+id/tv_interval_label" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_interval_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="56dp"
|
||||
android:layout_marginTop="9dp"
|
||||
android:text="Interval between actions"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_default_actions_title" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/input_interval"
|
||||
android:layout_width="287dp"
|
||||
android:layout_height="42dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginTop="9dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:background="@drawable/rounded_edittext_background"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="12dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_interval_label">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/dialog_et_interval_value"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:background="@null"
|
||||
android:inputType="number"
|
||||
android:padding="8dp"
|
||||
android:textColor="@color/white"
|
||||
android:textColorHint="@color/gray" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/dialog_interval_selector_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="4dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialog_interval_selected_unit"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingEnd="4dp"
|
||||
android:text="milliseconds"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/interval_unit_dropdown"
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="8dp"
|
||||
android:src="@drawable/blue_arrow_down" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/duration_icon"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="11dp"
|
||||
android:src="@drawable/left_swipe"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/tv_swipe_duration_label"
|
||||
app:layout_constraintEnd_toEndOf="@id/iv_interval_icon"
|
||||
app:layout_constraintTop_toTopOf="@id/tv_swipe_duration_label" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_swipe_duration_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:text="Swipe duration"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintStart_toStartOf="@+id/tv_interval_label"
|
||||
app:layout_constraintTop_toBottomOf="@id/input_interval" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_preview_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="41dp"
|
||||
android:text="@string/preview"
|
||||
android:textColor="@color/blue"
|
||||
android:textSize="12sp"
|
||||
app:layout_constraintBottom_toBottomOf="@id/tv_swipe_duration_label"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/tv_swipe_duration_label" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/input_with_unit_container"
|
||||
android:layout_width="287dp"
|
||||
android:layout_height="42dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:background="@drawable/rounded_edittext_background"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="12dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_swipe_duration_label">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/dialog_et_duration_value"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:background="@null"
|
||||
android:inputType="number"
|
||||
android:padding="8dp"
|
||||
android:textColor="@color/white"
|
||||
android:textColorHint="@color/gray" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/dialog_unit_selector_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="4dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialog_tv_selected_unit"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingEnd="4dp"
|
||||
android:text="milliseconds"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_unit_dropdown"
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="8dp"
|
||||
android:src="@drawable/blue_arrow_down" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/default_cycle_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="35dp"
|
||||
android:layout_marginTop="23dp"
|
||||
android:text="Default cycle"
|
||||
android:textColor="@color/text_gray"
|
||||
android:textSize="15sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/input_with_unit_container" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/repeat_icon"
|
||||
android:layout_width="12dp"
|
||||
android:layout_height="12dp"
|
||||
android:layout_marginEnd="9dp"
|
||||
android:src="@drawable/cycle"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/repeat_text"
|
||||
app:layout_constraintEnd_toStartOf="@+id/repeat_text"
|
||||
app:layout_constraintTop_toTopOf="@+id/repeat_text" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/repeat_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="56dp"
|
||||
android:layout_marginTop="9dp"
|
||||
android:text="Repeat mode"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/default_cycle_title" />
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/dialog_repeat_switch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="32dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/repeat_text"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/repeat_text"
|
||||
app:layout_constraintVertical_bias="0.31"
|
||||
app:thumbTint="@color/switch_thumb_selector"
|
||||
app:trackTint="@color/switch_track_selector" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/dialog_repeat_input"
|
||||
android:layout_width="287dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingEnd="12dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/repeat_text">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/dialog_et_repeat_value"
|
||||
android:layout_width="123dp"
|
||||
android:layout_height="42dp"
|
||||
android:background="@drawable/rounded_edittext_background"
|
||||
android:inputType="number"
|
||||
android:padding="8dp"
|
||||
android:textColor="@color/white"
|
||||
android:textColorHint="@color/gray" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/dialog_repeat_selector_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="62dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="4dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialog_repeat_selected_unit"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingEnd="4dp"
|
||||
android:text="infinitely"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/repeat_unit_dropdown"
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="8dp"
|
||||
android:src="@drawable/blue_arrow_down" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
Loading…
Reference in New Issue
Block a user