功能添加
This commit is contained in:
parent
5a78b467fc
commit
427f0b12c4
@ -30,8 +30,6 @@ public class AutoClickService extends AccessibilityService {
|
|||||||
|
|
||||||
private static final long MIN_CLICK_INTERVAL = 40;
|
private static final long MIN_CLICK_INTERVAL = 40;
|
||||||
private static final long MAX_CLICK_INTERVAL = 10000;
|
private static final long MAX_CLICK_INTERVAL = 10000;
|
||||||
private static final int MIN_CLICK_DURATION = 50;
|
|
||||||
private static final int MAX_CLICK_DURATION = 1000;
|
|
||||||
private static final int MIN_SLIDE_DURATION = 100;
|
private static final int MIN_SLIDE_DURATION = 100;
|
||||||
private static final int MAX_SLIDE_DURATION = 2000;
|
private static final int MAX_SLIDE_DURATION = 2000;
|
||||||
|
|
||||||
@ -109,15 +107,6 @@ public class AutoClickService extends AccessibilityService {
|
|||||||
logDebug("设置点击间隔: " + interval + "ms");
|
logDebug("设置点击间隔: " + interval + "ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClickDuration(int duration) {
|
|
||||||
if (duration < MIN_CLICK_DURATION || duration > MAX_CLICK_DURATION) {
|
|
||||||
Log.w(TAG, "点击时长超出范围: " + duration + "ms");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.clickDuration = duration;
|
|
||||||
logDebug("设置点击时长: " + duration + "ms");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSlideDuration(int duration) {
|
public void setSlideDuration(int duration) {
|
||||||
if (duration < MIN_SLIDE_DURATION || duration > MAX_SLIDE_DURATION) {
|
if (duration < MIN_SLIDE_DURATION || duration > MAX_SLIDE_DURATION) {
|
||||||
Log.w(TAG, "滑动时长超出范围: " + duration + "ms");
|
Log.w(TAG, "滑动时长超出范围: " + duration + "ms");
|
||||||
@ -127,11 +116,6 @@ public class AutoClickService extends AccessibilityService {
|
|||||||
logDebug("设置滑动时长: " + duration + "ms");
|
logDebug("设置滑动时长: " + duration + "ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置事件队列的循环次数。
|
|
||||||
*
|
|
||||||
* @param count 循环次数。设置为0表示无限循环,设置为1表示不循环(执行一次)。
|
|
||||||
*/
|
|
||||||
public void setLoopCount(int count) {
|
public void setLoopCount(int count) {
|
||||||
if (count < 0) {
|
if (count < 0) {
|
||||||
Log.w(TAG, "循环次数不能为负数,已设置为默认值 1");
|
Log.w(TAG, "循环次数不能为负数,已设置为默认值 1");
|
||||||
@ -140,18 +124,12 @@ public class AutoClickService extends AccessibilityService {
|
|||||||
this.loopCount = count;
|
this.loopCount = count;
|
||||||
}
|
}
|
||||||
logDebug("设置循环次数: " + loopCount + " 次");
|
logDebug("设置循环次数: " + loopCount + " 次");
|
||||||
// 如果设置了循环次数,则重置循环时间为0,确保两种模式不冲突
|
|
||||||
if (this.loopCount > 0) {
|
if (this.loopCount > 0) {
|
||||||
this.loopTimeMillis = 0;
|
this.loopTimeMillis = 0;
|
||||||
logDebug("已重置循环时间为 0ms");
|
logDebug("已重置循环时间为 0ms");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置事件队列的循环总时间。
|
|
||||||
*
|
|
||||||
* @param timeMillis 循环总时间,单位毫秒。设置为0表示不按时间循环。
|
|
||||||
*/
|
|
||||||
public void setLoopTime(long timeMillis) {
|
public void setLoopTime(long timeMillis) {
|
||||||
if (timeMillis < 0) {
|
if (timeMillis < 0) {
|
||||||
Log.w(TAG, "循环时间不能为负数,已设置为默认值 0ms");
|
Log.w(TAG, "循环时间不能为负数,已设置为默认值 0ms");
|
||||||
@ -160,7 +138,6 @@ public class AutoClickService extends AccessibilityService {
|
|||||||
this.loopTimeMillis = timeMillis;
|
this.loopTimeMillis = timeMillis;
|
||||||
}
|
}
|
||||||
logDebug("设置循环时间: " + loopTimeMillis + "ms");
|
logDebug("设置循环时间: " + loopTimeMillis + "ms");
|
||||||
// 如果设置了循环时间,则重置循环次数为0,确保两种模式不冲突
|
|
||||||
if (this.loopTimeMillis > 0) {
|
if (this.loopTimeMillis > 0) {
|
||||||
this.loopCount = 0;
|
this.loopCount = 0;
|
||||||
logDebug("已重置循环次数为 0");
|
logDebug("已重置循环次数为 0");
|
||||||
@ -203,10 +180,9 @@ public class AutoClickService extends AccessibilityService {
|
|||||||
|
|
||||||
EventViewBinder.setAllTouchPointsDraggable(true);
|
EventViewBinder.setAllTouchPointsDraggable(true);
|
||||||
|
|
||||||
// 重置循环状态
|
currentEventIndex = 0;
|
||||||
currentEventIndex = 0; // 停止时重置事件索引
|
currentLoop = 0;
|
||||||
currentLoop = 0; // 停止时重置循环计数
|
startTimeMillis = 0;
|
||||||
startTimeMillis = 0; // 停止时重置开始时间
|
|
||||||
|
|
||||||
logDebug("停止执行事件");
|
logDebug("停止执行事件");
|
||||||
}
|
}
|
||||||
@ -224,29 +200,26 @@ public class AutoClickService extends AccessibilityService {
|
|||||||
|
|
||||||
if (runtimeEvents.isEmpty()) {
|
if (runtimeEvents.isEmpty()) {
|
||||||
logDebug("跳过执行:事件队列为空");
|
logDebug("跳过执行:事件队列为空");
|
||||||
stopClicking(); // 如果事件队列为空,则停止服务
|
stopClicking();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 在每一轮循环开始前排序,确保顺序正确
|
|
||||||
runtimeEvents.sort(Comparator.comparingInt(EventWrapper::getOrder));
|
runtimeEvents.sort(Comparator.comparingInt(EventWrapper::getOrder));
|
||||||
|
|
||||||
// 检查是否完成了一轮事件列表
|
|
||||||
if (currentEventIndex >= runtimeEvents.size()) {
|
if (currentEventIndex >= runtimeEvents.size()) {
|
||||||
currentEventIndex = 0; // 重置事件索引,准备开始新一轮循环
|
currentEventIndex = 0;
|
||||||
currentLoop++; // 完成一轮,增加循环计数
|
currentLoop++;
|
||||||
logDebug("完成第 " + currentLoop + " 轮事件执行。");
|
logDebug("完成第 " + currentLoop + " 轮事件执行。");
|
||||||
|
|
||||||
// 判断是否继续循环
|
|
||||||
boolean continueLoop = false;
|
boolean continueLoop = false;
|
||||||
if (loopCount > 0) { // 按次数循环模式
|
if (loopCount > 0) {
|
||||||
if (currentLoop < loopCount) {
|
if (currentLoop < loopCount) {
|
||||||
continueLoop = true;
|
continueLoop = true;
|
||||||
logDebug("继续第 " + (currentLoop + 1) + " 轮循环 (共 " + loopCount + " 轮)");
|
logDebug("继续第 " + (currentLoop + 1) + " 轮循环 (共 " + loopCount + " 轮)");
|
||||||
} else {
|
} else {
|
||||||
logDebug("已达到设定的循环次数 (" + loopCount + " 次),停止循环。");
|
logDebug("已达到设定的循环次数 (" + loopCount + " 次),停止循环。");
|
||||||
}
|
}
|
||||||
} else if (loopTimeMillis > 0) { // 按时间循环模式
|
} else if (loopTimeMillis > 0) {
|
||||||
long elapsedTime = System.currentTimeMillis() - startTimeMillis;
|
long elapsedTime = System.currentTimeMillis() - startTimeMillis;
|
||||||
if (elapsedTime < loopTimeMillis) {
|
if (elapsedTime < loopTimeMillis) {
|
||||||
continueLoop = true;
|
continueLoop = true;
|
||||||
@ -254,13 +227,13 @@ public class AutoClickService extends AccessibilityService {
|
|||||||
} else {
|
} else {
|
||||||
logDebug("已达到设定的循环时间 (" + (loopTimeMillis / 1000) + "s),停止循环。");
|
logDebug("已达到设定的循环时间 (" + (loopTimeMillis / 1000) + "s),停止循环。");
|
||||||
}
|
}
|
||||||
} else { // 无限循环模式 (loopCount == 0 && loopTimeMillis == 0)
|
} else {
|
||||||
continueLoop = true;
|
continueLoop = true;
|
||||||
logDebug("无限循环模式,继续下一轮循环。");
|
logDebug("无限循环模式,继续下一轮循环。");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!continueLoop) {
|
if (!continueLoop) {
|
||||||
stopClicking(); // 不再继续循环,则停止服务
|
stopClicking();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -274,8 +247,8 @@ public class AutoClickService extends AccessibilityService {
|
|||||||
performSlide((SlideEvent) event);
|
performSlide((SlideEvent) event);
|
||||||
} else {
|
} else {
|
||||||
logDebug("未知或不匹配的事件类型,跳过执行: " + wrapper.getType());
|
logDebug("未知或不匹配的事件类型,跳过执行: " + wrapper.getType());
|
||||||
currentEventIndex++; // 跳过当前事件
|
currentEventIndex++;
|
||||||
handler.postDelayed(this::executeEventsByType, clickInterval); // 立即尝试下一个事件
|
handler.postDelayed(this::executeEventsByType, clickInterval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import android.graphics.Color;
|
|||||||
import android.graphics.drawable.ColorDrawable;
|
import android.graphics.drawable.ColorDrawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.InputType;
|
import android.text.InputType;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@ -12,18 +13,35 @@ import android.widget.TextView;
|
|||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.widget.AppCompatButton;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
import com.auto.clicker.autoclicker.R;
|
import com.auto.clicker.autoclicker.R;
|
||||||
import com.auto.clicker.autoclicker.databinding.FragmentActionBinding;
|
import com.auto.clicker.autoclicker.databinding.FragmentActionBinding;
|
||||||
|
import com.auto.clicker.autoclicker.service.AutoClickService;
|
||||||
|
|
||||||
public class ActionFragment extends Fragment {
|
public class ActionFragment extends Fragment {
|
||||||
|
private static final String TAG = "ActionFragment";
|
||||||
private FragmentActionBinding binding;
|
private FragmentActionBinding binding;
|
||||||
|
|
||||||
private static final int TYPE_INTERVAL = 0;
|
private static final int TYPE_INTERVAL = 0;
|
||||||
private static final int TYPE_SWIPE_DURATION = 1;
|
private static final int TYPE_SWIPE_DURATION = 1;
|
||||||
private static final int TYPE_REPEAT = 2;
|
private static final int TYPE_REPEAT = 2;
|
||||||
|
|
||||||
|
private enum UnitType {
|
||||||
|
MS, SEC, MIN, INFINITELY, DURATION, CYCLE, UNKNOWN
|
||||||
|
}
|
||||||
|
|
||||||
|
private UnitType currentIntervalUnit = UnitType.MS;
|
||||||
|
private UnitType currentSwipeDurationUnit = UnitType.MS;
|
||||||
|
private UnitType currentRepeatUnit = UnitType.INFINITELY;
|
||||||
|
private String currentIntervalValue = "";
|
||||||
|
private String currentDurationValue = "";
|
||||||
|
private String currentRepeatValue = "";
|
||||||
|
private boolean isRepeatSwitchChecked = false;
|
||||||
|
|
||||||
|
private AppCompatButton saveSettingsButton;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
@ -33,38 +51,61 @@ public class ActionFragment extends Fragment {
|
|||||||
binding.unitSelectorContainer.setOnClickListener(v -> showUnitSelection(v, TYPE_SWIPE_DURATION));
|
binding.unitSelectorContainer.setOnClickListener(v -> showUnitSelection(v, TYPE_SWIPE_DURATION));
|
||||||
|
|
||||||
setupRepeatMode();
|
setupRepeatMode();
|
||||||
|
|
||||||
setupAdvancedMode();
|
setupAdvancedMode();
|
||||||
|
restoreUIState();
|
||||||
|
|
||||||
|
saveSettingsButton = binding.save;
|
||||||
|
saveSettingsButton.setOnClickListener(v -> {
|
||||||
|
applySettingsToService();
|
||||||
|
Toast.makeText(getContext(), "设置已保存并应用!", Toast.LENGTH_SHORT).show();
|
||||||
|
});
|
||||||
|
|
||||||
return binding.getRoot();
|
return binding.getRoot();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
restoreUIState();
|
||||||
|
}
|
||||||
|
|
||||||
private void setupRepeatMode() {
|
private void setupRepeatMode() {
|
||||||
|
binding.repeatSwitch.setChecked(isRepeatSwitchChecked);
|
||||||
|
updateRepeatUI(isRepeatSwitchChecked);
|
||||||
|
|
||||||
binding.repeatSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
binding.repeatSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||||
|
isRepeatSwitchChecked = isChecked;
|
||||||
|
updateRepeatUI(isChecked);
|
||||||
|
});
|
||||||
|
|
||||||
|
binding.repeatSelectorContainer.setOnClickListener(v -> showUnitSelection(v, TYPE_REPEAT));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateRepeatUI(boolean isChecked) {
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
binding.repeatInput.setVisibility(View.VISIBLE);
|
binding.repeatInput.setVisibility(View.VISIBLE);
|
||||||
binding.repeatSelectorContainer.setVisibility(View.VISIBLE);
|
binding.repeatSelectorContainer.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
if (currentRepeatUnit == UnitType.INFINITELY) {
|
||||||
binding.repeatSelectedUnit.setText(getString(R.string.infinitely_unit));
|
binding.repeatSelectedUnit.setText(getString(R.string.infinitely_unit));
|
||||||
binding.etRepeatValue.setText("");
|
binding.etRepeatValue.setText("");
|
||||||
binding.etRepeatValue.setEnabled(false);
|
binding.etRepeatValue.setEnabled(false);
|
||||||
binding.etRepeatValue.setInputType(InputType.TYPE_NULL);
|
binding.etRepeatValue.setInputType(InputType.TYPE_NULL);
|
||||||
|
} else if (currentRepeatUnit == UnitType.DURATION) {
|
||||||
|
binding.repeatSelectedUnit.setText(getString(R.string.duration_unit));
|
||||||
|
binding.etRepeatValue.setText(currentRepeatValue);
|
||||||
|
binding.etRepeatValue.setEnabled(true);
|
||||||
|
binding.etRepeatValue.setInputType(InputType.TYPE_CLASS_DATETIME | InputType.TYPE_DATETIME_VARIATION_TIME);
|
||||||
|
} else if (currentRepeatUnit == UnitType.CYCLE) {
|
||||||
|
binding.repeatSelectedUnit.setText(getString(R.string.cycle_unit));
|
||||||
|
binding.etRepeatValue.setText(currentRepeatValue);
|
||||||
|
binding.etRepeatValue.setEnabled(true);
|
||||||
|
binding.etRepeatValue.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
binding.repeatInput.setVisibility(View.GONE);
|
binding.repeatInput.setVisibility(View.GONE);
|
||||||
binding.repeatSelectorContainer.setVisibility(View.GONE);
|
binding.repeatSelectorContainer.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
if (!binding.repeatSwitch.isChecked()) {
|
|
||||||
binding.repeatInput.setVisibility(View.GONE);
|
|
||||||
binding.repeatSelectorContainer.setVisibility(View.GONE);
|
|
||||||
} else {
|
|
||||||
binding.repeatSelectedUnit.setText(getString(R.string.infinitely_unit));
|
|
||||||
binding.etRepeatValue.setText("");
|
|
||||||
binding.etRepeatValue.setEnabled(false);
|
|
||||||
binding.etRepeatValue.setInputType(InputType.TYPE_NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.repeatSelectorContainer.setOnClickListener(v -> showUnitSelection(v, TYPE_REPEAT));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupAdvancedMode() {
|
private void setupAdvancedMode() {
|
||||||
@ -72,9 +113,9 @@ public class ActionFragment extends Fragment {
|
|||||||
|
|
||||||
binding.advancedSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
binding.advancedSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
Toast.makeText(getContext(), "Anti-Detection mode is ON", Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), "防检测模式已开启", Toast.LENGTH_SHORT).show();
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(getContext(), "Anti-Detection mode is OFF", Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), "防检测模式已关闭", Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -98,132 +139,251 @@ public class ActionFragment extends Fragment {
|
|||||||
TextView tvDuration = popupView.findViewById(R.id.tv_unit_duration);
|
TextView tvDuration = popupView.findViewById(R.id.tv_unit_duration);
|
||||||
TextView tvCycle = popupView.findViewById(R.id.tv_unit_cycle);
|
TextView tvCycle = popupView.findViewById(R.id.tv_unit_cycle);
|
||||||
|
|
||||||
|
tvMs.setVisibility(View.GONE);
|
||||||
|
tvSec.setVisibility(View.GONE);
|
||||||
|
tvMin.setVisibility(View.GONE);
|
||||||
|
tvInfinitely.setVisibility(View.GONE);
|
||||||
|
tvDuration.setVisibility(View.GONE);
|
||||||
|
tvCycle.setVisibility(View.GONE);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case TYPE_INTERVAL:
|
case TYPE_INTERVAL:
|
||||||
tvMs.setVisibility(View.VISIBLE);
|
tvMs.setVisibility(View.VISIBLE);
|
||||||
tvSec.setVisibility(View.VISIBLE);
|
tvSec.setVisibility(View.VISIBLE);
|
||||||
tvMin.setVisibility(View.VISIBLE);
|
tvMin.setVisibility(View.VISIBLE);
|
||||||
tvInfinitely.setVisibility(View.GONE);
|
|
||||||
tvDuration.setVisibility(View.GONE);
|
|
||||||
tvCycle.setVisibility(View.GONE);
|
|
||||||
break;
|
break;
|
||||||
case TYPE_SWIPE_DURATION:
|
case TYPE_SWIPE_DURATION:
|
||||||
tvMs.setVisibility(View.VISIBLE);
|
tvMs.setVisibility(View.VISIBLE);
|
||||||
tvSec.setVisibility(View.VISIBLE);
|
tvSec.setVisibility(View.VISIBLE);
|
||||||
tvMin.setVisibility(View.GONE);
|
|
||||||
tvInfinitely.setVisibility(View.GONE);
|
|
||||||
tvDuration.setVisibility(View.GONE);
|
|
||||||
tvCycle.setVisibility(View.GONE);
|
|
||||||
break;
|
break;
|
||||||
case TYPE_REPEAT:
|
case TYPE_REPEAT:
|
||||||
tvMs.setVisibility(View.GONE);
|
|
||||||
tvSec.setVisibility(View.GONE);
|
|
||||||
tvMin.setVisibility(View.GONE);
|
|
||||||
tvInfinitely.setVisibility(View.VISIBLE);
|
tvInfinitely.setVisibility(View.VISIBLE);
|
||||||
tvDuration.setVisibility(View.VISIBLE);
|
tvDuration.setVisibility(View.VISIBLE);
|
||||||
tvCycle.setVisibility(View.VISIBLE);
|
tvCycle.setVisibility(View.VISIBLE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == TYPE_INTERVAL || type == TYPE_SWIPE_DURATION) {
|
|
||||||
tvMs.setOnClickListener(v -> {
|
tvMs.setOnClickListener(v -> {
|
||||||
|
UnitType selectedUnitType = UnitType.MS;
|
||||||
String unitText = getString(R.string.milliseconds_unit);
|
String unitText = getString(R.string.milliseconds_unit);
|
||||||
if (type == TYPE_INTERVAL) {
|
updateUIAndSaveSettings(type, selectedUnitType, unitText);
|
||||||
binding.intervalSelectedUnit.setText(unitText);
|
|
||||||
showInputValue("Interval", binding.etIntervalValue.getText().toString(), unitText);
|
|
||||||
} else {
|
|
||||||
binding.tvSelectedUnit.setText(unitText);
|
|
||||||
showInputValue("Swipe Duration", binding.etDurationValue.getText().toString(), unitText);
|
|
||||||
}
|
|
||||||
popupWindow.dismiss();
|
popupWindow.dismiss();
|
||||||
});
|
});
|
||||||
|
|
||||||
tvSec.setOnClickListener(v -> {
|
tvSec.setOnClickListener(v -> {
|
||||||
|
UnitType selectedUnitType = UnitType.SEC;
|
||||||
String unitText = getString(R.string.seconds_unit);
|
String unitText = getString(R.string.seconds_unit);
|
||||||
if (type == TYPE_INTERVAL) {
|
updateUIAndSaveSettings(type, selectedUnitType, unitText);
|
||||||
binding.intervalSelectedUnit.setText(unitText);
|
|
||||||
showInputValue("Interval", binding.etIntervalValue.getText().toString(), unitText);
|
|
||||||
} else {
|
|
||||||
binding.tvSelectedUnit.setText(unitText);
|
|
||||||
showInputValue("Swipe Duration", binding.etDurationValue.getText().toString(), unitText);
|
|
||||||
}
|
|
||||||
popupWindow.dismiss();
|
popupWindow.dismiss();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (type == TYPE_INTERVAL) {
|
if (type == TYPE_INTERVAL) {
|
||||||
tvMin.setOnClickListener(v -> {
|
tvMin.setOnClickListener(v -> {
|
||||||
|
UnitType selectedUnitType = UnitType.MIN;
|
||||||
String unitText = getString(R.string.minutes_unit);
|
String unitText = getString(R.string.minutes_unit);
|
||||||
binding.intervalSelectedUnit.setText(unitText);
|
updateUIAndSaveSettings(type, selectedUnitType, unitText);
|
||||||
popupWindow.dismiss();
|
popupWindow.dismiss();
|
||||||
showInputValue("Interval", binding.etIntervalValue.getText().toString(), unitText);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (type == TYPE_REPEAT) {
|
if (type == TYPE_REPEAT) {
|
||||||
tvInfinitely.setOnClickListener(v -> {
|
tvInfinitely.setOnClickListener(v -> {
|
||||||
binding.repeatSelectedUnit.setText(getString(R.string.infinitely_unit));
|
UnitType selectedUnitType = UnitType.INFINITELY;
|
||||||
binding.etRepeatValue.setText("");
|
String unitText = getString(R.string.infinitely_unit);
|
||||||
binding.etRepeatValue.setEnabled(false);
|
updateUIAndSaveSettings(type, selectedUnitType, unitText);
|
||||||
binding.etRepeatValue.setInputType(InputType.TYPE_NULL);
|
updateRepeatUI(true);
|
||||||
popupWindow.dismiss();
|
popupWindow.dismiss();
|
||||||
showInputValue("Repeat", binding.etRepeatValue.getText().toString(), getString(R.string.infinitely_unit));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
tvDuration.setOnClickListener(v -> {
|
tvDuration.setOnClickListener(v -> {
|
||||||
binding.repeatSelectedUnit.setText(getString(R.string.duration_unit));
|
UnitType selectedUnitType = UnitType.DURATION;
|
||||||
binding.etRepeatValue.setText("");
|
String unitText = getString(R.string.duration_unit);
|
||||||
binding.etRepeatValue.setEnabled(true);
|
updateUIAndSaveSettings(type, selectedUnitType, unitText);
|
||||||
binding.etRepeatValue.setInputType(InputType.TYPE_CLASS_DATETIME | InputType.TYPE_DATETIME_VARIATION_TIME); // 设置为时间格式
|
updateRepeatUI(true);
|
||||||
popupWindow.dismiss();
|
popupWindow.dismiss();
|
||||||
showInputValue("Repeat", binding.etRepeatValue.getText().toString(), getString(R.string.duration_unit));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
tvCycle.setOnClickListener(v -> {
|
tvCycle.setOnClickListener(v -> {
|
||||||
binding.repeatSelectedUnit.setText(getString(R.string.cycle_unit));
|
UnitType selectedUnitType = UnitType.CYCLE;
|
||||||
binding.etRepeatValue.setText("");
|
String unitText = getString(R.string.cycle_unit);
|
||||||
binding.etRepeatValue.setEnabled(true);
|
updateUIAndSaveSettings(type, selectedUnitType, unitText);
|
||||||
binding.etRepeatValue.setInputType(InputType.TYPE_CLASS_NUMBER);
|
updateRepeatUI(true);
|
||||||
popupWindow.dismiss();
|
popupWindow.dismiss();
|
||||||
showInputValue("Repeat", binding.etRepeatValue.getText().toString(), getString(R.string.cycle_unit));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
popupWindow.showAsDropDown(anchorView);
|
popupWindow.showAsDropDown(anchorView);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showInputValue(String type, String value, String unit) {
|
private void updateUIAndSaveSettings(int type, UnitType selectedUnitType, String unitText) {
|
||||||
String message = type + " 值: " + (value.isEmpty() ? "未输入" : value) + ", 单位: " + unit;
|
switch (type) {
|
||||||
Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
|
case TYPE_INTERVAL:
|
||||||
|
binding.intervalSelectedUnit.setText(unitText);
|
||||||
if (type.equals("Interval")) {
|
currentIntervalUnit = selectedUnitType;
|
||||||
long intervalValue = value.isEmpty() ? 0 : Long.parseLong(value);
|
break;
|
||||||
// 根据 unit 进行单位转换或保存 Interval 值
|
case TYPE_SWIPE_DURATION:
|
||||||
// 例如:if (unit.equals(getString(R.string.seconds_unit))) { ... }
|
binding.tvSelectedUnit.setText(unitText);
|
||||||
} else if (type.equals("Swipe Duration")) {
|
currentSwipeDurationUnit = selectedUnitType;
|
||||||
long durationValue = value.isEmpty() ? 0 : Long.parseLong(value);
|
break;
|
||||||
// 根据 unit 进行单位转换或保存 Swipe Duration 值
|
case TYPE_REPEAT:
|
||||||
} else if (type.equals("Repeat")) {
|
binding.repeatSelectedUnit.setText(unitText);
|
||||||
if (unit.equals(getString(R.string.infinitely_unit))) {
|
currentRepeatUnit = selectedUnitType;
|
||||||
// Repeat 为无限次,不需要处理输入值
|
break;
|
||||||
} else if (unit.equals(getString(R.string.duration_unit))) {
|
|
||||||
// Repeat 为时长,处理时间格式的输入
|
|
||||||
// 您需要在这里添加解析时间格式的逻辑
|
|
||||||
String durationValue = value.isEmpty() ? "0" : value;
|
|
||||||
// long parsedDuration = parseDurationString(durationValue); // 自定义方法解析时间
|
|
||||||
Toast.makeText(getContext(), "Repeat Duration: " + durationValue, Toast.LENGTH_SHORT).show();
|
|
||||||
} else if (unit.equals(getString(R.string.cycle_unit))) {
|
|
||||||
// Repeat 为次数,处理整数输入
|
|
||||||
int repeatCount = value.isEmpty() ? 0 : Integer.parseInt(value);
|
|
||||||
Toast.makeText(getContext(), "Repeat Cycles: " + repeatCount, Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
}
|
||||||
|
saveCurrentInputValues();
|
||||||
|
showInputValue(type, getEditTextValue(type), unitText);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getEditTextValue(int type) {
|
||||||
|
switch (type) {
|
||||||
|
case TYPE_INTERVAL: return binding.etIntervalValue.getText().toString();
|
||||||
|
case TYPE_SWIPE_DURATION: return binding.etDurationValue.getText().toString();
|
||||||
|
case TYPE_REPEAT: return binding.etRepeatValue.getText().toString();
|
||||||
|
default: return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showInputValue(int type, String value, String unitText) {
|
||||||
|
String typeName = "";
|
||||||
|
switch (type) {
|
||||||
|
case TYPE_INTERVAL: typeName = "点击间隔"; break;
|
||||||
|
case TYPE_SWIPE_DURATION: typeName = "滑动时长"; break;
|
||||||
|
case TYPE_REPEAT: typeName = "循环模式"; break;
|
||||||
|
}
|
||||||
|
String message = typeName + " 值: " + (value.isEmpty() ? "未输入" : value) + ", 单位: " + unitText;
|
||||||
|
Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveCurrentInputValues() {
|
||||||
|
currentIntervalValue = binding.etIntervalValue.getText().toString();
|
||||||
|
currentDurationValue = binding.etDurationValue.getText().toString();
|
||||||
|
currentRepeatValue = binding.etRepeatValue.getText().toString();
|
||||||
|
isRepeatSwitchChecked = binding.repeatSwitch.isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void restoreUIState() {
|
||||||
|
binding.etIntervalValue.setText(currentIntervalValue);
|
||||||
|
binding.intervalSelectedUnit.setText(getUnitString(currentIntervalUnit));
|
||||||
|
|
||||||
|
binding.etDurationValue.setText(currentDurationValue);
|
||||||
|
binding.tvSelectedUnit.setText(getUnitString(currentSwipeDurationUnit));
|
||||||
|
|
||||||
|
binding.repeatSwitch.setChecked(isRepeatSwitchChecked);
|
||||||
|
updateRepeatUI(isRepeatSwitchChecked);
|
||||||
|
|
||||||
|
if (isRepeatSwitchChecked) {
|
||||||
|
binding.repeatSelectedUnit.setText(getUnitString(currentRepeatUnit));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getUnitString(UnitType unitType) {
|
||||||
|
switch (unitType) {
|
||||||
|
case MS: return getString(R.string.milliseconds_unit);
|
||||||
|
case SEC: return getString(R.string.seconds_unit);
|
||||||
|
case MIN: return getString(R.string.minutes_unit);
|
||||||
|
case INFINITELY: return getString(R.string.infinitely_unit);
|
||||||
|
case DURATION: return getString(R.string.duration_unit);
|
||||||
|
case CYCLE: return getString(R.string.cycle_unit);
|
||||||
|
default: return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void applySettingsToService() {
|
||||||
|
saveCurrentInputValues();
|
||||||
|
|
||||||
|
AutoClickService service = AutoClickService.getInstance();
|
||||||
|
if (service == null) {
|
||||||
|
Toast.makeText(getContext(), "自动点击服务未运行,无法应用设置。", Toast.LENGTH_SHORT).show();
|
||||||
|
Log.e(TAG, "AutoClickService 实例为空,无法应用设置。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
long intervalValue = 0;
|
||||||
|
if (!currentIntervalValue.isEmpty()) {
|
||||||
|
try {
|
||||||
|
intervalValue = Long.parseLong(currentIntervalValue);
|
||||||
|
if (currentIntervalUnit == UnitType.SEC) {
|
||||||
|
intervalValue *= 1000;
|
||||||
|
} else if (currentIntervalUnit == UnitType.MIN) {
|
||||||
|
intervalValue *= 60 * 1000;
|
||||||
|
}
|
||||||
|
service.setClickInterval(intervalValue);
|
||||||
|
Log.d(TAG, "应用点击间隔到服务: " + intervalValue + "ms");
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
Log.e(TAG, "点击间隔值解析错误: " + currentIntervalValue, e);
|
||||||
|
Toast.makeText(getContext(), "点击间隔值无效,请输入有效数字。", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "点击间隔值为空,未应用到服务。");
|
||||||
|
}
|
||||||
|
|
||||||
|
long slideDurationValue = 0;
|
||||||
|
if (!currentDurationValue.isEmpty()) {
|
||||||
|
try {
|
||||||
|
slideDurationValue = Long.parseLong(currentDurationValue);
|
||||||
|
if (currentSwipeDurationUnit == UnitType.SEC) {
|
||||||
|
slideDurationValue *= 1000;
|
||||||
|
}
|
||||||
|
service.setSlideDuration((int) slideDurationValue);
|
||||||
|
Log.d(TAG, "应用滑动时长到服务: " + slideDurationValue + "ms");
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
Log.e(TAG, "滑动时长值解析错误: " + currentDurationValue, e);
|
||||||
|
Toast.makeText(getContext(), "滑动时长值无效,请输入有效数字。", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "滑动时长值为空,未应用到服务。");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isRepeatSwitchChecked) {
|
||||||
|
if (currentRepeatUnit == UnitType.INFINITELY) {
|
||||||
|
service.setLoopCount(0);
|
||||||
|
Log.d(TAG, "应用重复模式: 无限次。");
|
||||||
|
} else if (currentRepeatUnit == UnitType.DURATION) {
|
||||||
|
long repeatDurationMillis = 0;
|
||||||
|
if (!currentRepeatValue.isEmpty()) {
|
||||||
|
try {
|
||||||
|
repeatDurationMillis = Long.parseLong(currentRepeatValue);
|
||||||
|
service.setLoopTime(repeatDurationMillis);
|
||||||
|
Log.d(TAG, "应用重复时长: " + repeatDurationMillis + "ms。");
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
Log.e(TAG, "重复时长值解析错误: " + currentRepeatValue, e);
|
||||||
|
Toast.makeText(getContext(), "重复时长值无效,请输入有效数字或正确的时间格式。", Toast.LENGTH_SHORT).show();
|
||||||
|
service.setLoopTime(0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
service.setLoopTime(0);
|
||||||
|
Log.d(TAG, "重复时长值为空,取消时间循环。");
|
||||||
|
}
|
||||||
|
service.setLoopCount(0);
|
||||||
|
} else if (currentRepeatUnit == UnitType.CYCLE) {
|
||||||
|
int repeatCount = 0;
|
||||||
|
if (!currentRepeatValue.isEmpty()) {
|
||||||
|
try {
|
||||||
|
repeatCount = Integer.parseInt(currentRepeatValue);
|
||||||
|
service.setLoopCount(repeatCount);
|
||||||
|
Log.d(TAG, "应用重复次数: " + repeatCount + "次。");
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
Log.e(TAG, "重复次数值解析错误: " + currentRepeatValue, e);
|
||||||
|
Toast.makeText(getContext(), "重复次数值无效,请输入有效数字。", Toast.LENGTH_SHORT).show();
|
||||||
|
service.setLoopCount(1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
service.setLoopCount(1);
|
||||||
|
Log.d(TAG, "重复次数值为空,设置为执行一次。");
|
||||||
|
}
|
||||||
|
service.setLoopTime(0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
service.setLoopCount(1);
|
||||||
|
service.setLoopTime(0);
|
||||||
|
Log.d(TAG, "重复开关关闭,服务设置为执行一次。");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroyView() {
|
public void onDestroyView() {
|
||||||
super.onDestroyView();
|
super.onDestroyView();
|
||||||
|
saveCurrentInputValues();
|
||||||
binding = null;
|
binding = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -22,14 +22,12 @@ import java.util.Map;
|
|||||||
|
|
||||||
public class EventViewBinder {
|
public class EventViewBinder {
|
||||||
|
|
||||||
// 存储每个视图及其对应的 OnTouchListener 实例,用于启用/禁用拖动
|
|
||||||
private static final Map<View, View.OnTouchListener> activeDragListeners = new HashMap<>();
|
private static final Map<View, View.OnTouchListener> activeDragListeners = new HashMap<>();
|
||||||
|
|
||||||
public interface OnPositionChangedCallback {
|
public interface OnPositionChangedCallback {
|
||||||
void onPositionChanged(int x, int y);
|
void onPositionChanged(int x, int y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- bindPoint 方法 ---
|
|
||||||
public static void bindPoint(Context context, WindowManager windowManager,
|
public static void bindPoint(Context context, WindowManager windowManager,
|
||||||
PointEvent pointEvent, int touchPointSize,
|
PointEvent pointEvent, int touchPointSize,
|
||||||
int screenWidth, int screenHeight,
|
int screenWidth, int screenHeight,
|
||||||
@ -47,7 +45,6 @@ public class EventViewBinder {
|
|||||||
|
|
||||||
pointView.setTextSize(TypedValue.COMPLEX_UNIT_SP, initialTextSize);
|
pointView.setTextSize(TypedValue.COMPLEX_UNIT_SP, initialTextSize);
|
||||||
|
|
||||||
// 创建并保存 OnTouchListener
|
|
||||||
View.OnTouchListener touchListener = createTouchListener(
|
View.OnTouchListener touchListener = createTouchListener(
|
||||||
pointView, params, windowManager, screenWidth, screenHeight,
|
pointView, params, windowManager, screenWidth, screenHeight,
|
||||||
(x, y) -> {
|
(x, y) -> {
|
||||||
@ -57,12 +54,11 @@ public class EventViewBinder {
|
|||||||
});
|
});
|
||||||
|
|
||||||
pointView.setOnTouchListener(touchListener);
|
pointView.setOnTouchListener(touchListener);
|
||||||
activeDragListeners.put(pointView, touchListener); // 保存监听器到 Map
|
activeDragListeners.put(pointView, touchListener);
|
||||||
|
|
||||||
windowManager.addView(pointView, params);
|
windowManager.addView(pointView, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- bindSlide 方法 ---
|
|
||||||
public static void bindSlide(Context context, WindowManager windowManager,
|
public static void bindSlide(Context context, WindowManager windowManager,
|
||||||
SlideEvent slideEvent, int touchPointSize,
|
SlideEvent slideEvent, int touchPointSize,
|
||||||
int screenWidth, int screenHeight,
|
int screenWidth, int screenHeight,
|
||||||
@ -126,15 +122,13 @@ public class EventViewBinder {
|
|||||||
updateLinePosition(slideEvent, touchPointSize);
|
updateLinePosition(slideEvent, touchPointSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- 从 DraggableHelper 移动过来的 OnTouchListener 创建逻辑 ---
|
|
||||||
// 这个方法创建并返回一个 View.OnTouchListener 实例
|
|
||||||
private static View.OnTouchListener createTouchListener(
|
private static View.OnTouchListener createTouchListener(
|
||||||
View view, WindowManager.LayoutParams params, WindowManager windowManager,
|
View view, WindowManager.LayoutParams params, WindowManager windowManager,
|
||||||
int screenWidth, int screenHeight, DraggableHelper.DragCallback callback) { // 仍然使用 DraggableHelper.DragCallback 接口
|
int screenWidth, int screenHeight, DraggableHelper.DragCallback callback) {
|
||||||
return new View.OnTouchListener() {
|
return new View.OnTouchListener() {
|
||||||
private float lastX, lastY;
|
private float lastX, lastY;
|
||||||
private float paramX, paramY;
|
private float paramX, paramY;
|
||||||
private boolean isDragging = false; // 标记是否正在拖动
|
private boolean isDragging = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onTouch(View v, MotionEvent event) {
|
public boolean onTouch(View v, MotionEvent event) {
|
||||||
@ -144,7 +138,7 @@ public class EventViewBinder {
|
|||||||
lastY = event.getRawY();
|
lastY = event.getRawY();
|
||||||
paramX = params.x;
|
paramX = params.x;
|
||||||
paramY = params.y;
|
paramY = params.y;
|
||||||
isDragging = false; // 重置拖动状态
|
isDragging = false;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case MotionEvent.ACTION_MOVE:
|
case MotionEvent.ACTION_MOVE:
|
||||||
@ -169,7 +163,7 @@ public class EventViewBinder {
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
case MotionEvent.ACTION_UP:
|
case MotionEvent.ACTION_UP:
|
||||||
if (!isDragging) { // 如果没有拖动,才视为点击
|
if (!isDragging) {
|
||||||
v.performClick();
|
v.performClick();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -179,42 +173,25 @@ public class EventViewBinder {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- 新增方法:统一控制所有触摸点的拖动状态 ---
|
|
||||||
public static void setAllTouchPointsDraggable(boolean draggable) {
|
public static void setAllTouchPointsDraggable(boolean draggable) {
|
||||||
for (Map.Entry<View, View.OnTouchListener> entry : activeDragListeners.entrySet()) {
|
for (Map.Entry<View, View.OnTouchListener> entry : activeDragListeners.entrySet()) {
|
||||||
View view = entry.getKey();
|
View view = entry.getKey();
|
||||||
View.OnTouchListener listener = entry.getValue();
|
View.OnTouchListener listener = entry.getValue();
|
||||||
if (draggable) {
|
if (draggable) {
|
||||||
// 启用拖动:重新设置保存的监听器
|
|
||||||
view.setOnTouchListener(listener);
|
view.setOnTouchListener(listener);
|
||||||
} else {
|
} else {
|
||||||
// 禁用拖动:将监听器设置为 null,阻止触摸事件
|
|
||||||
view.setOnTouchListener(null);
|
view.setOnTouchListener(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- 新增方法:移除不再需要的视图及其监听器 ---
|
|
||||||
public static void removeBoundView(WindowManager windowManager, View view) {
|
|
||||||
if (view != null) {
|
|
||||||
try {
|
|
||||||
windowManager.removeView(view);
|
|
||||||
activeDragListeners.remove(view); // 从 Map 中移除
|
|
||||||
Log.d("EventViewBinder", "移除视图并清理监听器: " + view.getTag());
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
Log.e("EventViewBinder", "尝试移除不存在的视图: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- 辅助方法 (保持不变) ---
|
|
||||||
public static TextView createTouchPointView(Context context, String label) {
|
public static TextView createTouchPointView(Context context, String label) {
|
||||||
TextView touchPointView = new TextView(context);
|
TextView touchPointView = new TextView(context);
|
||||||
touchPointView.setBackgroundResource(R.drawable.ring_has_bg);
|
touchPointView.setBackgroundResource(R.drawable.ring_has_bg);
|
||||||
touchPointView.setGravity(Gravity.CENTER);
|
touchPointView.setGravity(Gravity.CENTER);
|
||||||
touchPointView.setText(label);
|
touchPointView.setText(label);
|
||||||
touchPointView.setTextColor(Color.WHITE);
|
touchPointView.setTextColor(Color.WHITE);
|
||||||
touchPointView.setTag(label); // 添加一个Tag,方便日志识别
|
touchPointView.setTag(label);
|
||||||
return touchPointView;
|
return touchPointView;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,7 +222,7 @@ public class EventViewBinder {
|
|||||||
overlayType,
|
overlayType,
|
||||||
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
|
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
|
||||||
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
|
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
|
||||||
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, // 线条通常不可触摸
|
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
|
||||||
PixelFormat.TRANSLUCENT
|
PixelFormat.TRANSLUCENT
|
||||||
);
|
);
|
||||||
params.gravity = Gravity.TOP | Gravity.START;
|
params.gravity = Gravity.TOP | Gravity.START;
|
||||||
|
|||||||
@ -96,7 +96,6 @@ public class FloatingSettingDialogManager {
|
|||||||
unitSelectorContainer.setOnClickListener(v -> showUnitSelection(v, TYPE_SWIPE_DURATION));
|
unitSelectorContainer.setOnClickListener(v -> showUnitSelection(v, TYPE_SWIPE_DURATION));
|
||||||
|
|
||||||
setupRepeatMode();
|
setupRepeatMode();
|
||||||
// --- 恢复UI状态 ---
|
|
||||||
restoreUIState();
|
restoreUIState();
|
||||||
|
|
||||||
// floatingDialogView.setOnTouchListener((v, event) -> {
|
// floatingDialogView.setOnTouchListener((v, event) -> {
|
||||||
@ -179,8 +178,8 @@ public class FloatingSettingDialogManager {
|
|||||||
overlayType,
|
overlayType,
|
||||||
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
|
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
|
||||||
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
|
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
|
||||||
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL // 允许将触摸事件传递到其下方窗口
|
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
|
||||||
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, // 监听外部触摸事件
|
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
|
||||||
PixelFormat.TRANSLUCENT
|
PixelFormat.TRANSLUCENT
|
||||||
);
|
);
|
||||||
params.gravity = Gravity.CENTER;
|
params.gravity = Gravity.CENTER;
|
||||||
@ -195,7 +194,7 @@ public class FloatingSettingDialogManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
repeatSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
repeatSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||||
isRepeatSwitchChecked = isChecked; // 保存开关状态
|
isRepeatSwitchChecked = isChecked;
|
||||||
updateRepeatUI(isChecked);
|
updateRepeatUI(isChecked);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -206,16 +205,14 @@ public class FloatingSettingDialogManager {
|
|||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
repeatInput.setVisibility(View.VISIBLE);
|
repeatInput.setVisibility(View.VISIBLE);
|
||||||
repeatSelectorContainer.setVisibility(View.VISIBLE);
|
repeatSelectorContainer.setVisibility(View.VISIBLE);
|
||||||
// 只有当单位是“无限次”时才禁用输入框
|
|
||||||
if (currentRepeatUnit.equals(context.getString(R.string.infinitely_unit)) || repeatSelectedUnit.getText().toString().equals(context.getString(R.string.infinitely_unit))) {
|
if (currentRepeatUnit.equals(context.getString(R.string.infinitely_unit)) || repeatSelectedUnit.getText().toString().equals(context.getString(R.string.infinitely_unit))) {
|
||||||
etRepeatValue.setText("");
|
etRepeatValue.setText("");
|
||||||
etRepeatValue.setEnabled(false);
|
etRepeatValue.setEnabled(false);
|
||||||
etRepeatValue.setInputType(InputType.TYPE_NULL);
|
etRepeatValue.setInputType(InputType.TYPE_NULL);
|
||||||
repeatSelectedUnit.setText(context.getString(R.string.infinitely_unit)); // 确保显示无限次
|
repeatSelectedUnit.setText(context.getString(R.string.infinitely_unit));
|
||||||
} else {
|
} else {
|
||||||
etRepeatValue.setEnabled(true);
|
etRepeatValue.setEnabled(true);
|
||||||
etRepeatValue.setInputType(InputType.TYPE_CLASS_NUMBER); // 默认设置为数字输入
|
etRepeatValue.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||||
// 恢复之前的输入值和单位
|
|
||||||
etRepeatValue.setText(currentRepeatValue);
|
etRepeatValue.setText(currentRepeatValue);
|
||||||
repeatSelectedUnit.setText(currentRepeatUnit.isEmpty() ? context.getString(R.string.cycle_unit) : currentRepeatUnit);
|
repeatSelectedUnit.setText(currentRepeatUnit.isEmpty() ? context.getString(R.string.cycle_unit) : currentRepeatUnit);
|
||||||
}
|
}
|
||||||
@ -383,8 +380,6 @@ public class FloatingSettingDialogManager {
|
|||||||
showToastOnUi(context, "点击间隔值无效,请输入有效数字。");
|
showToastOnUi(context, "点击间隔值无效,请输入有效数字。");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 如果为空,设置一个默认值或不设置,这取决于你的业务逻辑
|
|
||||||
// service.setClickInterval(默认值);
|
|
||||||
Log.d(TAG, "点击间隔值为空,未应用到服务。");
|
Log.d(TAG, "点击间隔值为空,未应用到服务。");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,12 +397,9 @@ public class FloatingSettingDialogManager {
|
|||||||
showToastOnUi(context, "滑动时长值无效,请输入有效数字。");
|
showToastOnUi(context, "滑动时长值无效,请输入有效数字。");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 如果为空,设置一个默认值或不设置
|
|
||||||
// service.setSlideDuration(默认值);
|
|
||||||
Log.d(TAG, "滑动时长值为空,未应用到服务。");
|
Log.d(TAG, "滑动时长值为空,未应用到服务。");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 应用重复设置
|
|
||||||
if (isRepeatSwitchChecked) {
|
if (isRepeatSwitchChecked) {
|
||||||
if (currentRepeatUnit.equals(context.getString(R.string.infinitely_unit))) {
|
if (currentRepeatUnit.equals(context.getString(R.string.infinitely_unit))) {
|
||||||
service.setLoopCount(0); // 无限循环
|
service.setLoopCount(0); // 无限循环
|
||||||
@ -417,8 +409,6 @@ public class FloatingSettingDialogManager {
|
|||||||
if (!currentRepeatValue.isEmpty()) {
|
if (!currentRepeatValue.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
repeatDurationMillis = Long.parseLong(currentRepeatValue);
|
repeatDurationMillis = Long.parseLong(currentRepeatValue);
|
||||||
// 根据你的UI单位,这里可能需要进一步转换,例如用户输入的是秒
|
|
||||||
// repeatDurationMillis *= 1000L;
|
|
||||||
service.setLoopTime(repeatDurationMillis);
|
service.setLoopTime(repeatDurationMillis);
|
||||||
Log.d(TAG, "应用重复时长: " + repeatDurationMillis + "ms。");
|
Log.d(TAG, "应用重复时长: " + repeatDurationMillis + "ms。");
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
|
|||||||
@ -24,7 +24,6 @@ import android.widget.LinearLayout;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
|
|
||||||
import com.auto.clicker.autoclicker.R;
|
import com.auto.clicker.autoclicker.R;
|
||||||
@ -87,6 +86,13 @@ public class FloatingViewManager {
|
|||||||
private static final int DEFAULT_CONTROL_BAR_WIDTH_DP = 50;
|
private static final int DEFAULT_CONTROL_BAR_WIDTH_DP = 50;
|
||||||
|
|
||||||
private ImageView playButton;
|
private ImageView playButton;
|
||||||
|
private ImageView addButton;
|
||||||
|
private ImageView removeButton;
|
||||||
|
private ImageView slideButton;
|
||||||
|
private ImageView saveButton;
|
||||||
|
private ImageView eyeButton;
|
||||||
|
private ImageView settingButton;
|
||||||
|
private ImageView closeButton;
|
||||||
|
|
||||||
public FloatingViewManager(Context context) {
|
public FloatingViewManager(Context context) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
@ -225,13 +231,13 @@ public class FloatingViewManager {
|
|||||||
|
|
||||||
private void setupControlButtons(LinearLayout controlBar, int mode) {
|
private void setupControlButtons(LinearLayout controlBar, int mode) {
|
||||||
playButton = controlBar.findViewById(R.id.play_button);
|
playButton = controlBar.findViewById(R.id.play_button);
|
||||||
ImageView addButton = controlBar.findViewById(R.id.add_button);
|
addButton = controlBar.findViewById(R.id.add_button);
|
||||||
ImageView removeButton = controlBar.findViewById(R.id.remove_button);
|
removeButton = controlBar.findViewById(R.id.remove_button);
|
||||||
ImageView slideButton = controlBar.findViewById(R.id.slide_button);
|
slideButton = controlBar.findViewById(R.id.slide_button);
|
||||||
ImageView saveButton = controlBar.findViewById(R.id.save_button);
|
saveButton = controlBar.findViewById(R.id.save_button);
|
||||||
ImageView eyeButton = controlBar.findViewById(R.id.eye_button);
|
eyeButton = controlBar.findViewById(R.id.eye_button);
|
||||||
ImageView settingButton = controlBar.findViewById(R.id.settings_button);
|
settingButton = controlBar.findViewById(R.id.settings_button);
|
||||||
ImageView closeButton = controlBar.findViewById(R.id.close_button);
|
closeButton = controlBar.findViewById(R.id.close_button);
|
||||||
|
|
||||||
if (mode == 1) {
|
if (mode == 1) {
|
||||||
addButton.setVisibility(View.GONE);
|
addButton.setVisibility(View.GONE);
|
||||||
@ -336,57 +342,88 @@ public class FloatingViewManager {
|
|||||||
|
|
||||||
public void toggleEventsVisibility(boolean show) {
|
public void toggleEventsVisibility(boolean show) {
|
||||||
for (EventWrapper wrapper : new ArrayList<>(runtimeEvents)) {
|
for (EventWrapper wrapper : new ArrayList<>(runtimeEvents)) {
|
||||||
// 获取事件的视图
|
WindowManager.LayoutParams params = null;
|
||||||
View viewToToggle = null;
|
|
||||||
if (wrapper.getType() == EventWrapper.EventType.POINT) {
|
if (wrapper.getType() == EventWrapper.EventType.POINT) {
|
||||||
viewToToggle = EventViewBinder.createTouchPointView(context, String.valueOf(wrapper.getEvent().getId()));
|
PointEvent pointEvent = (PointEvent) wrapper.getEvent();
|
||||||
|
View pointView = pointEvent.getView();
|
||||||
|
|
||||||
|
if (pointView != null) {
|
||||||
|
params = (WindowManager.LayoutParams) pointView.getLayoutParams();
|
||||||
|
if (params != null) {
|
||||||
|
if (show) {
|
||||||
|
pointView.setAlpha(1.0f);
|
||||||
|
params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
|
||||||
|
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
|
||||||
|
} else {
|
||||||
|
pointView.setAlpha(0.0f);
|
||||||
|
params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
|
||||||
|
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
|
||||||
|
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
|
||||||
|
}
|
||||||
|
windowManager.updateViewLayout(pointView, params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else if (wrapper.getType() == EventWrapper.EventType.SLIDE) {
|
} else if (wrapper.getType() == EventWrapper.EventType.SLIDE) {
|
||||||
View startPointView = getView(show, wrapper, context);
|
|
||||||
|
|
||||||
WindowManager.LayoutParams startParams = (WindowManager.LayoutParams) startPointView.getLayoutParams();
|
|
||||||
if (show) {
|
|
||||||
startParams.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
|
|
||||||
} else {
|
|
||||||
startParams.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
|
|
||||||
}
|
|
||||||
windowManager.updateViewLayout(startPointView, startParams);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (viewToToggle != null) {
|
|
||||||
if (show) {
|
|
||||||
viewToToggle.setAlpha(1.0f);
|
|
||||||
} else {
|
|
||||||
viewToToggle.setAlpha(0.0f);
|
|
||||||
}
|
|
||||||
WindowManager.LayoutParams params = (WindowManager.LayoutParams) viewToToggle.getLayoutParams();
|
|
||||||
if (show) {
|
|
||||||
params.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
|
|
||||||
} else {
|
|
||||||
params.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
|
|
||||||
}
|
|
||||||
windowManager.updateViewLayout(viewToToggle, params);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
private View getView(boolean show, EventWrapper wrapper, Context context) {
|
|
||||||
SlideEvent slideEvent = (SlideEvent) wrapper.getEvent();
|
SlideEvent slideEvent = (SlideEvent) wrapper.getEvent();
|
||||||
View startPointView = EventViewBinder.createTouchPointView(context, String.valueOf(slideEvent.getStartPoint().getId()));
|
|
||||||
View endPointView = EventViewBinder.createTouchPointView(context, String.valueOf(slideEvent.getEndPoint().getId()));
|
|
||||||
View lineView = new ConnectingLineView(context);
|
|
||||||
|
|
||||||
|
View startPointView = slideEvent.getStartPoint().getView();
|
||||||
|
if (startPointView != null) {
|
||||||
|
params = (WindowManager.LayoutParams) startPointView.getLayoutParams();
|
||||||
|
if (params != null) {
|
||||||
if (show) {
|
if (show) {
|
||||||
startPointView.setAlpha(1.0f);
|
startPointView.setAlpha(1.0f);
|
||||||
endPointView.setAlpha(1.0f);
|
params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
|
||||||
lineView.setAlpha(1.0f);
|
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
|
||||||
} else {
|
} else {
|
||||||
startPointView.setAlpha(0.0f);
|
startPointView.setAlpha(0.0f);
|
||||||
endPointView.setAlpha(0.0f);
|
params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
|
||||||
lineView.setAlpha(0.0f);
|
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
|
||||||
|
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
|
||||||
|
}
|
||||||
|
windowManager.updateViewLayout(startPointView, params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
View endPointView = slideEvent.getEndPoint().getView();
|
||||||
|
if (endPointView != null) {
|
||||||
|
params = (WindowManager.LayoutParams) endPointView.getLayoutParams();
|
||||||
|
if (params != null) {
|
||||||
|
if (show) {
|
||||||
|
endPointView.setAlpha(1.0f);
|
||||||
|
params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
|
||||||
|
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
|
||||||
|
} else {
|
||||||
|
endPointView.setAlpha(0.0f);
|
||||||
|
params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
|
||||||
|
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
|
||||||
|
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
|
||||||
|
}
|
||||||
|
windowManager.updateViewLayout(endPointView, params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
View lineView = slideEvent.getLineView();
|
||||||
|
if (lineView != null) {
|
||||||
|
params = (WindowManager.LayoutParams) lineView.getLayoutParams();
|
||||||
|
if (params != null) {
|
||||||
|
if (show) {
|
||||||
|
lineView.setAlpha(1.0f);
|
||||||
|
params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
|
||||||
|
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
|
||||||
|
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
|
||||||
|
} else {
|
||||||
|
lineView.setAlpha(0.0f);
|
||||||
|
params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
|
||||||
|
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
|
||||||
|
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
|
||||||
|
}
|
||||||
|
windowManager.updateViewLayout(lineView, params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return startPointView;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeLastEvent() {
|
private void removeLastEvent() {
|
||||||
@ -433,6 +470,8 @@ public class FloatingViewManager {
|
|||||||
Toast.makeText(context, "多点点击开始", Toast.LENGTH_SHORT).show();
|
Toast.makeText(context, "多点点击开始", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
updateTouchPointsBackground(R.drawable.touch_point);
|
updateTouchPointsBackground(R.drawable.touch_point);
|
||||||
|
|
||||||
|
setControlButtonsEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stopMultiClicking(AutoClickService service) {
|
private void stopMultiClicking(AutoClickService service) {
|
||||||
@ -440,6 +479,25 @@ public class FloatingViewManager {
|
|||||||
Toast.makeText(context, "多点点击停止", Toast.LENGTH_SHORT).show();
|
Toast.makeText(context, "多点点击停止", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
updateTouchPointsBackground(R.drawable.ring_has_bg);
|
updateTouchPointsBackground(R.drawable.ring_has_bg);
|
||||||
|
|
||||||
|
setControlButtonsEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setControlButtonsEnabled(boolean enabled) {
|
||||||
|
if (addButton != null) addButton.setEnabled(enabled);
|
||||||
|
if (removeButton != null) removeButton.setEnabled(enabled);
|
||||||
|
if (slideButton != null) slideButton.setEnabled(enabled);
|
||||||
|
if (saveButton != null) saveButton.setEnabled(enabled);
|
||||||
|
if (eyeButton != null) eyeButton.setEnabled(enabled);
|
||||||
|
if (settingButton != null) settingButton.setEnabled(enabled);
|
||||||
|
|
||||||
|
float alpha = enabled ? 1.0f : 0.5f;
|
||||||
|
if (addButton != null) addButton.setAlpha(alpha);
|
||||||
|
if (removeButton != null) removeButton.setAlpha(alpha);
|
||||||
|
if (slideButton != null) slideButton.setAlpha(alpha);
|
||||||
|
if (saveButton != null) saveButton.setAlpha(alpha);
|
||||||
|
if (eyeButton != null) eyeButton.setAlpha(alpha);
|
||||||
|
if (settingButton != null) settingButton.setAlpha(alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeEvent(Event event) {
|
private void removeEvent(Event event) {
|
||||||
|
|||||||
@ -14,11 +14,12 @@
|
|||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/default_actions_container"
|
android:id="@+id/default_actions_container"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="223dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="20dp"
|
android:layout_marginStart="20dp"
|
||||||
android:layout_marginTop="14dp"
|
android:layout_marginTop="14dp"
|
||||||
android:layout_marginEnd="20dp"
|
android:layout_marginEnd="20dp"
|
||||||
android:background="@drawable/bg_rounded_rect"
|
android:background="@drawable/bg_rounded_rect"
|
||||||
|
android:paddingBottom="10dp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
@ -112,6 +113,18 @@
|
|||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_interval_range_hint"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="36dp"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:text="范围: 40ms - 10000ms"
|
||||||
|
android:textColor="@color/gray"
|
||||||
|
android:textSize="12sp"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/input_interval" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/duration_icon"
|
android:id="@+id/duration_icon"
|
||||||
android:layout_width="20dp"
|
android:layout_width="20dp"
|
||||||
@ -130,7 +143,7 @@
|
|||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
app:layout_constraintStart_toStartOf="@+id/tv_interval_label"
|
app:layout_constraintStart_toStartOf="@+id/tv_interval_label"
|
||||||
app:layout_constraintTop_toBottomOf="@id/input_interval" />
|
app:layout_constraintTop_toBottomOf="@id/tv_interval_range_hint" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tv_preview_label"
|
android:id="@+id/tv_preview_label"
|
||||||
@ -140,6 +153,7 @@
|
|||||||
android:text="@string/preview"
|
android:text="@string/preview"
|
||||||
android:textColor="@color/blue"
|
android:textColor="@color/blue"
|
||||||
android:textSize="12sp"
|
android:textSize="12sp"
|
||||||
|
android:visibility="gone"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/tv_swipe_duration_label"
|
app:layout_constraintBottom_toBottomOf="@id/tv_swipe_duration_label"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="@id/tv_swipe_duration_label" />
|
app:layout_constraintTop_toTopOf="@id/tv_swipe_duration_label" />
|
||||||
@ -199,6 +213,17 @@
|
|||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_duration_range_hint"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="36dp"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:text="范围: 100ms - 2000ms"
|
||||||
|
android:textColor="@color/gray"
|
||||||
|
android:textSize="12sp"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/input_with_unit_container" />
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
@ -375,6 +400,20 @@
|
|||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/save"
|
||||||
|
android:layout_width="150dp"
|
||||||
|
android:layout_height="54dp"
|
||||||
|
android:layout_marginTop="18dp"
|
||||||
|
android:background="@drawable/btn_border_background"
|
||||||
|
android:backgroundTint="#0BC4FC"
|
||||||
|
android:text="Save"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="21sp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/default_advanced_container" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|||||||
@ -1,68 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="38dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@drawable/control_bar_bg"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center_horizontal"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingHorizontal="10dp">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/play_button"
|
|
||||||
android:layout_width="13dp"
|
|
||||||
android:layout_height="13dp"
|
|
||||||
android:layout_marginTop="15dp"
|
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/save_button"
|
|
||||||
android:layout_width="15dp"
|
|
||||||
android:layout_height="15dp"
|
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
android:src="@drawable/save" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/eye_button"
|
|
||||||
android:layout_width="16dp"
|
|
||||||
android:layout_height="9dp"
|
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
android:src="@drawable/eye" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/settings_button"
|
|
||||||
android:layout_width="14dp"
|
|
||||||
android:layout_height="14dp"
|
|
||||||
android:layout_marginBottom="9dp"
|
|
||||||
android:src="@drawable/control_setting" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/cut_off"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="1dp"
|
|
||||||
android:layout_marginBottom="10dp"
|
|
||||||
android:scaleType="fitXY"
|
|
||||||
android:src="@drawable/cut_off_line" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center_horizontal"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingHorizontal="10dp">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/close_button"
|
|
||||||
android:layout_width="10dp"
|
|
||||||
android:layout_height="10dp"
|
|
||||||
android:layout_marginBottom="11dp"
|
|
||||||
android:src="@drawable/cancel" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
Loading…
Reference in New Issue
Block a user