From 17e202a5b1ef886ea42a1a900aae286107431b2a Mon Sep 17 00:00:00 2001 From: SuperMonster003 Date: Thu, 13 Mar 2025 17:48:29 +0800 Subject: [PATCH] =?UTF-8?q?6.6.2=20-=20Alpha4=20-=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E9=83=A8=E5=88=86=E6=8E=A7=E4=BB=B6=E4=B8=BB=E9=A2=98=E8=89=B2?= =?UTF-8?q?=E4=B8=8E=E8=83=8C=E6=99=AF=E8=89=B2=E5=AF=B9=E6=AF=94=E5=BA=A6?= =?UTF-8?q?=E8=BF=87=E4=BD=8E=E6=97=B6=E7=9A=84=E8=A7=86=E8=A7=89=E4=BD=93?= =?UTF-8?q?=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changelog/lang_zh-Hans.json | 1 + .../autojs/runtime/api/augment/ui/UI.kt | 2 +- .../org/autojs/autojs/theme/ThemeColor.kt | 22 +-- .../autojs/autojs/theme/ThemeColorHelper.java | 53 ++++++-- .../ThemeColorPreferenceCategory.kt | 8 +- .../preference/ThemeColorSwitchPreference.kt | 41 +++--- .../ThemeColorFloatingActionButton.java | 5 +- .../java/org/autojs/autojs/ui/BaseActivity.kt | 2 +- .../autojs/autojs/ui/explorer/ExplorerView.kt | 23 ++-- .../filechooser/ExplorerItemViewHolder.java | 38 +++++- .../ui/main/task/TaskListRecyclerView.java | 18 ++- .../autojs/autojs/ui/widget/FirstCharView.kt | 9 +- .../autojs/autojs/ui/widget/PrefSwitch.java | 2 +- .../java/org/autojs/autojs/util/ColorUtils.kt | 101 ++++++++++++++ app/src/main/res/layout/explorer_file.xml | 6 +- .../main/res/layout/file_choose_list_file.xml | 127 +++++++++++------- version.properties | 6 +- 17 files changed, 335 insertions(+), 129 deletions(-) diff --git a/.changelog/lang_zh-Hans.json b/.changelog/lang_zh-Hans.json index 4e89b853..989f2745 100644 --- a/.changelog/lang_zh-Hans.json +++ b/.changelog/lang_zh-Hans.json @@ -19,6 +19,7 @@ "打包页面支持 Pinyin 库选项", "打包应用主活动页面优化状态栏背景及文字颜色", "控件的文字及图标根据主题色亮度值自动切换合适的颜色", + "部分控件主题色与背景色对比度过低时的视觉体验", "应用内页面导航栏设置为透明或半透明以增强视觉体验", "长按应用主页 \"文件\" 标签可切换浮动按钮可见状态", "日志页面浮动按钮可见状态与列表滚动操作联动", diff --git a/app/src/main/java/org/autojs/autojs/runtime/api/augment/ui/UI.kt b/app/src/main/java/org/autojs/autojs/runtime/api/augment/ui/UI.kt index c03b42b2..d912bd91 100644 --- a/app/src/main/java/org/autojs/autojs/runtime/api/augment/ui/UI.kt +++ b/app/src/main/java/org/autojs/autojs/runtime/api/augment/ui/UI.kt @@ -767,7 +767,7 @@ class UI(private val scriptRuntime: ScriptRuntime) : AugmentableProxy(scriptRunt private fun attrValueConvert(o: Any?): Any? = when (o) { is String -> o is ColorNativeObject -> Colors.toHexRhino(o) - is ThemeColor -> o.getColorPrimary() + is ThemeColor -> o.colorPrimary is NativeWith -> attrValueConvert(o.prototype) else -> o } diff --git a/app/src/main/java/org/autojs/autojs/theme/ThemeColor.kt b/app/src/main/java/org/autojs/autojs/theme/ThemeColor.kt index 29d5d4e3..92e91b96 100644 --- a/app/src/main/java/org/autojs/autojs/theme/ThemeColor.kt +++ b/app/src/main/java/org/autojs/autojs/theme/ThemeColor.kt @@ -17,16 +17,10 @@ import org.autojs.autojs6.R * Modified by SuperMonster003 as of Mar 30, 2023. * Transformed by SuperMonster003 on Mar 30, 2023. */ -class ThemeColor { +class ThemeColor(@JvmField var colorPrimary: Int, @JvmField var colorPrimaryDark: Int, @JvmField var colorAccent: Int) { - @JvmField - var colorPrimary = 0 - - @JvmField - var colorAccent = 0 - - @JvmField - var colorPrimaryDark = 0 + @JvmOverloads + constructor(color: Int = 0) : this(color, color, color) @ScriptInterface fun getColorPrimary() = colorPrimary @@ -41,16 +35,6 @@ class ThemeColor { fun isLuminanceDark() = ColorUtils.isLuminanceDark(colorPrimary) - constructor() - - constructor(color: Int) : this(color, color, color) - - constructor(colorPrimary: Int, colorPrimaryDark: Int, colorAccent: Int) { - this.colorPrimary = colorPrimary - this.colorPrimaryDark = colorPrimaryDark - this.colorAccent = colorAccent - } - fun colorPrimary(colorPrimary: Int) = also { this.colorPrimary = colorPrimary } fun colorPrimaryDark(colorPrimaryDark: Int) = also { this.colorPrimaryDark = colorPrimaryDark } diff --git a/app/src/main/java/org/autojs/autojs/theme/ThemeColorHelper.java b/app/src/main/java/org/autojs/autojs/theme/ThemeColorHelper.java index acb939ce..44b2f6e6 100644 --- a/app/src/main/java/org/autojs/autojs/theme/ThemeColorHelper.java +++ b/app/src/main/java/org/autojs/autojs/theme/ThemeColorHelper.java @@ -19,6 +19,8 @@ import androidx.appcompat.widget.SwitchCompat; import androidx.core.graphics.drawable.DrawableCompat; import org.autojs.autojs.theme.internal.ScrollingViewEdgeGlowColorHelper; +import org.autojs.autojs.util.ColorUtils; +import org.autojs.autojs6.R; /** * Created by Stardust on Oct 24, 2016. @@ -27,8 +29,8 @@ public class ThemeColorHelper { private static final String TAG = "ThemeColorHelper"; private static final int[][] SWITCH_STATES = new int[][]{ - new int[]{-android.R.attr.state_checked}, new int[]{android.R.attr.state_checked}, + new int[]{-android.R.attr.state_checked}, }; private static void setColorPrimary(View v, int themeColor) { @@ -44,36 +46,67 @@ public class ThemeColorHelper { } private static void setColorPrimary(ViewGroup viewGroup, int themeColor) { + setColorPrimary(viewGroup, themeColor, false); + } + + private static void setColorPrimary(ViewGroup viewGroup, int themeColor, boolean contrastMatters) { + if (contrastMatters) themeColor = ColorUtils.adjustColorForContrast(viewGroup.getContext().getColor(R.color.window_background), themeColor, 2.3); for (int i = 0; i < viewGroup.getChildCount(); i++) { setColorPrimary(viewGroup.getChildAt(i), themeColor); } } public static void setColorPrimary(SwitchCompat switchCompat, int color) { - setThumbDrawableTintList(switchCompat.getThumbDrawable(), color); - setTrackDrawableTintList(switchCompat.getTrackDrawable(), color); + setColorPrimary(switchCompat, color, false); + } + + public static void setColorPrimary(SwitchCompat switchCompat, int color, boolean contrastMatters) { + int adjustedThumbColor = contrastMatters + ? ColorUtils.adjustColorForContrast(switchCompat.getContext().getColor(R.color.window_background), color, 2.3) + : color; + int adjustedTrackColor = contrastMatters + ? ColorUtils.adjustColorForContrast(switchCompat.getContext().getColor(R.color.window_background), color, 3.6) + : color; + + setThumbDrawableTintList(switchCompat.getThumbDrawable(), adjustedThumbColor); + setTrackDrawableTintList(switchCompat.getTrackDrawable(), adjustedTrackColor, true); } public static void setColorPrimary(Switch sw, int color) { - setThumbDrawableTintList(sw.getThumbDrawable(), color); - setTrackDrawableTintList(sw.getTrackDrawable(), color); + setColorPrimary(sw, color, false); + } + + public static void setColorPrimary(Switch sw, int color, boolean contrastMatters) { + int adjustedThumbColor = contrastMatters + ? ColorUtils.adjustColorForContrast(sw.getContext().getColor(R.color.window_background), color, 2.3) + : color; + int adjustedTrackColor = contrastMatters + ? ColorUtils.adjustColorForContrast(sw.getContext().getColor(R.color.window_background), color, 3.6) + : color; + + setThumbDrawableTintList(sw.getThumbDrawable(), adjustedThumbColor); + setTrackDrawableTintList(sw.getTrackDrawable(), adjustedTrackColor, false); } private static void setThumbDrawableTintList(Drawable drawable, int color) { + int unselectedColor = ColorUtils.isLuminanceLight(color) + ? Color.parseColor("#616161") // R.color.md_grey_700 + : Color.DKGRAY; int[] thumbColors = new int[]{ - Color.DKGRAY, color, + unselectedColor, }; DrawableCompat.setTintList(DrawableCompat.wrap(drawable), new ColorStateList(SWITCH_STATES, thumbColors)); } - private static void setTrackDrawableTintList(Drawable drawable, int color) { + private static void setTrackDrawableTintList(Drawable drawable, int color, boolean isCompat) { + int alpha = isCompat ? 0x29 : 0x66; int[] trackColors = new int[]{ - Color.GRAY, - makeAlpha(0x66, color) + makeAlpha(alpha, color), + makeAlpha(alpha, Color.BLACK), }; - DrawableCompat.setTintList(DrawableCompat.wrap(drawable), new ColorStateList(SWITCH_STATES, trackColors)); + DrawableCompat.setTintList(drawable, new ColorStateList(SWITCH_STATES, trackColors)); } private static int makeAlpha(int alpha, int color) { diff --git a/app/src/main/java/org/autojs/autojs/theme/preference/ThemeColorPreferenceCategory.kt b/app/src/main/java/org/autojs/autojs/theme/preference/ThemeColorPreferenceCategory.kt index f651a6ca..65524c75 100644 --- a/app/src/main/java/org/autojs/autojs/theme/preference/ThemeColorPreferenceCategory.kt +++ b/app/src/main/java/org/autojs/autojs/theme/preference/ThemeColorPreferenceCategory.kt @@ -10,6 +10,8 @@ import androidx.preference.PreferenceViewHolder import org.autojs.autojs.theme.ThemeColor import org.autojs.autojs.theme.ThemeColorManager import org.autojs.autojs.theme.ThemeColorMutable +import org.autojs.autojs.util.ColorUtils +import org.autojs.autojs6.R /** * Created by Stardust on Aug 8, 2016. @@ -35,9 +37,9 @@ class ThemeColorPreferenceCategory : PreferenceCategory, ThemeColorMutable { fun setTitleTextColor(titleTextColor: Int) = setThemeColor(ThemeColor(titleTextColor)) override fun setThemeColor(color: ThemeColor) { - color.colorPrimary.let { - mColor = it - mTitleTextView?.setTextColor(it) + ColorUtils.adjustColorForContrast(context.getColor(R.color.window_background), color.colorPrimary, 3.2).let { contrastColor -> + mColor = contrastColor + mTitleTextView?.setTextColor(contrastColor) } } diff --git a/app/src/main/java/org/autojs/autojs/theme/preference/ThemeColorSwitchPreference.kt b/app/src/main/java/org/autojs/autojs/theme/preference/ThemeColorSwitchPreference.kt index 5be31dac..7b83d848 100644 --- a/app/src/main/java/org/autojs/autojs/theme/preference/ThemeColorSwitchPreference.kt +++ b/app/src/main/java/org/autojs/autojs/theme/preference/ThemeColorSwitchPreference.kt @@ -1,5 +1,6 @@ package org.autojs.autojs.theme.preference +import android.annotation.SuppressLint import android.content.Context import android.content.res.Resources import android.content.res.TypedArray @@ -32,6 +33,27 @@ class ThemeColorSwitchPreference : SwitchPreference, ThemeColorMutable, LongClic override var longClickPromptMore: CharSequence? = null constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) { + init(context, attrs, defStyleAttr, defStyleRes) + } + + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { + init(context, attrs, defStyleAttr, 0) + } + + @SuppressLint("RestrictedApi") + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { + init(context, attrs, 0, 0) + } + + constructor(context: Context) : super(context) { + init(context, null, 0, 0) + } + + init { + ThemeColorManager.add(this) + } + + private fun init(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) { obtainStyledAttrs(context, attrs, R.styleable.MaterialPreference, defStyleAttr, defStyleRes) .let { a -> getAttrString(a, R.styleable.MaterialPreference_longClickPrompt)?.also { longClickPrompt = it } @@ -40,20 +62,6 @@ class ThemeColorSwitchPreference : SwitchPreference, ThemeColorMutable, LongClic } } - constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : this(context, attrs, defStyleAttr, 0) - - constructor(context: Context, attrs: AttributeSet?) : this( - context, attrs, TypedArrayUtils.getAttr( - context, androidx.preference.R.attr.switchPreferenceStyle, android.R.attr.switchPreferenceStyle - ) - ) - - constructor(context: Context) : this(context, null) - - init { - ThemeColorManager.add(this) - } - override fun onBindViewHolder(holder: PreferenceViewHolder) { super.onBindViewHolder(holder) mCheckableView = holder.findViewById(Resources.getSystem().getIdentifier("switch_widget", "id", "android")) @@ -70,10 +78,10 @@ class ThemeColorSwitchPreference : SwitchPreference, ThemeColorMutable, LongClic private fun applyColor() { if (mCheckableView is Switch) { - ThemeColorHelper.setColorPrimary(mCheckableView as Switch?, mColor) + ThemeColorHelper.setColorPrimary(mCheckableView as Switch, mColor, true) } if (mCheckableView is SwitchCompat) { - ThemeColorHelper.setColorPrimary(mCheckableView as SwitchCompat?, mColor) + ThemeColorHelper.setColorPrimary(mCheckableView as SwitchCompat, mColor, true) } } @@ -81,6 +89,7 @@ class ThemeColorSwitchPreference : SwitchPreference, ThemeColorMutable, LongClic return context.obtainStyledAttributes(set, styleableRes, defStyleAttr, defStyleRes) } + @SuppressLint("RestrictedApi") private fun getAttrString(a: TypedArray, index: Int): String? = TypedArrayUtils.getString(a, index, index) } \ No newline at end of file diff --git a/app/src/main/java/org/autojs/autojs/theme/widget/ThemeColorFloatingActionButton.java b/app/src/main/java/org/autojs/autojs/theme/widget/ThemeColorFloatingActionButton.java index c2eb1d29..c76f4a97 100644 --- a/app/src/main/java/org/autojs/autojs/theme/widget/ThemeColorFloatingActionButton.java +++ b/app/src/main/java/org/autojs/autojs/theme/widget/ThemeColorFloatingActionButton.java @@ -39,8 +39,9 @@ public class ThemeColorFloatingActionButton extends FloatingActionButton impleme @Override public void setThemeColor(ThemeColor color) { int colorAccent = color.colorAccent; - setBackgroundTintList(ColorStateList.valueOf(colorAccent)); - var tintColorRes = ColorUtils.isLuminanceLight(colorAccent) + int colorForContrast = ColorUtils.adjustColorForContrast(getContext().getColor(R.color.window_background), colorAccent, 1.15); + setBackgroundTintList(ColorStateList.valueOf(colorForContrast)); + var tintColorRes = ColorUtils.isLuminanceLight(colorForContrast) ? R.color.fab_tint_dark : R.color.fab_tint_light; var tintColor = getResources().getColor(tintColorRes, null); diff --git a/app/src/main/java/org/autojs/autojs/ui/BaseActivity.kt b/app/src/main/java/org/autojs/autojs/ui/BaseActivity.kt index 97e4ab32..3afee440 100644 --- a/app/src/main/java/org/autojs/autojs/ui/BaseActivity.kt +++ b/app/src/main/java/org/autojs/autojs/ui/BaseActivity.kt @@ -72,8 +72,8 @@ abstract class BaseActivity : AppCompatActivity() { initThemeColors() if (handleStatusBarThemeColorAutomatically && !BuildConfig.isInrt) { ThemeColorManager.addActivityStatusBar(this) + setUpStatusBarIconLightByThemeColor() } - setUpStatusBarIconLightByThemeColor() } override fun onResume() { diff --git a/app/src/main/java/org/autojs/autojs/ui/explorer/ExplorerView.kt b/app/src/main/java/org/autojs/autojs/ui/explorer/ExplorerView.kt index 3c0040f8..33da624a 100644 --- a/app/src/main/java/org/autojs/autojs/ui/explorer/ExplorerView.kt +++ b/app/src/main/java/org/autojs/autojs/ui/explorer/ExplorerView.kt @@ -44,6 +44,7 @@ import org.autojs.autojs.model.script.Scripts import org.autojs.autojs.pio.PFile import org.autojs.autojs.pio.PFiles import org.autojs.autojs.project.ProjectConfig +import org.autojs.autojs.theme.ThemeColorManagerCompat import org.autojs.autojs.theme.widget.ThemeColorSwipeRefreshLayout import org.autojs.autojs.ui.common.ScriptLoopDialog import org.autojs.autojs.ui.common.ScriptOperations @@ -54,6 +55,7 @@ import org.autojs.autojs.ui.project.BuildActivity import org.autojs.autojs.ui.viewmodel.ExplorerItemManager import org.autojs.autojs.ui.widget.BindableViewHolder import org.autojs.autojs.ui.widget.FirstCharView +import org.autojs.autojs.util.ColorUtils import org.autojs.autojs.util.EnvironmentUtils.externalStoragePath import org.autojs.autojs.util.FileUtils import org.autojs.autojs.util.IntentUtils @@ -715,14 +717,19 @@ open class ExplorerView : ThemeColorSwipeRefreshLayout, SwipeRefreshLayout.OnRef private fun setFirstChar(item: ExplorerItem) { mFirstChar.setIcon(ExplorerViewHelper.getIcon(item)) when (item.type) { - FileUtils.TYPE.JAVASCRIPT, FileUtils.TYPE.AUTO -> mFirstChar - .setIconTextColorByThemeColorLuminance() - .setStrokeThemeColor() - .setFillThemeColor() - else -> mFirstChar - .setIconTextColorDayNight() - .setStrokeColorDayNight() - .setFillTransparent() + FileUtils.TYPE.JAVASCRIPT, FileUtils.TYPE.AUTO -> { + val themeColorForContrast = ColorUtils.adjustColorForContrast(context.getColor(R.color.item_background_dark), ThemeColorManagerCompat.getColorPrimary(), 1.15) + mFirstChar + .setIconTextColorByThemeColorLuminance() + .setStrokeColor(themeColorForContrast) + .setFillColor(themeColorForContrast) + } + else -> { + mFirstChar + .setIconTextColorDayNight() + .setStrokeColorDayNight() + .setFillTransparent() + } } } diff --git a/app/src/main/java/org/autojs/autojs/ui/filechooser/ExplorerItemViewHolder.java b/app/src/main/java/org/autojs/autojs/ui/filechooser/ExplorerItemViewHolder.java index 07f8d5ba..c7b2d196 100644 --- a/app/src/main/java/org/autojs/autojs/ui/filechooser/ExplorerItemViewHolder.java +++ b/app/src/main/java/org/autojs/autojs/ui/filechooser/ExplorerItemViewHolder.java @@ -1,13 +1,20 @@ package org.autojs.autojs.ui.filechooser; +import android.content.Context; +import android.content.res.ColorStateList; import android.view.View; import androidx.annotation.NonNull; +import org.autojs.autojs.core.ui.widget.JsCheckBox; import org.autojs.autojs.model.explorer.ExplorerItem; +import org.autojs.autojs.pio.PFile; import org.autojs.autojs.pio.PFiles; +import org.autojs.autojs.theme.ThemeColorManagerCompat; import org.autojs.autojs.ui.explorer.ExplorerViewHelper; import org.autojs.autojs.ui.widget.BindableViewHolder; +import org.autojs.autojs.util.ColorUtils; +import org.autojs.autojs6.R; import org.autojs.autojs6.databinding.ExplorerFirstCharIconBinding; import org.autojs.autojs6.databinding.FileChooseListFileBinding; @@ -33,22 +40,39 @@ class ExplorerItemViewHolder extends BindableViewHolder { public void bind(Object item, int position) { if (!(item instanceof ExplorerItem explorerItem)) return; mExplorerItem = explorerItem; - listFileBinding.name.setText(ExplorerViewHelper.getDisplayName(fileChooseListView.getContext(), explorerItem)); - listFileBinding.item.setOnClickListener(view -> listFileBinding.checkbox.toggle()); - listFileBinding.checkbox.setOnCheckedChangeListener((buttonView, isChecked) -> { - if (listFileBinding.checkbox.isChecked()) { + + Context context = fileChooseListView.getContext(); + JsCheckBox checkbox = listFileBinding.checkbox; + + int itemBackgroundDarkColor = context.getColor(R.color.item_background_dark); + int themePrimaryColor = ThemeColorManagerCompat.getColorPrimary(); + + int checkBoxCheckedThemeColorForContrast = ColorUtils.adjustColorForContrast(itemBackgroundDarkColor, themePrimaryColor, 1.9); + int checkBoxUncheckedCheckedThemeColorForContrast = ColorUtils.adjustColorForContrast(itemBackgroundDarkColor, themePrimaryColor, 1.4); + int itemIconThemeColorForContrast = ColorUtils.adjustColorForContrast(itemBackgroundDarkColor, themePrimaryColor, 1.15); + + checkbox.setButtonTintList(new ColorStateList( + new int[][]{new int[]{android.R.attr.state_checked}, new int[]{}}, + new int[]{checkBoxCheckedThemeColorForContrast, checkBoxUncheckedCheckedThemeColorForContrast} + )); + + listFileBinding.name.setText(ExplorerViewHelper.getDisplayName(context, explorerItem)); + listFileBinding.item.setOnClickListener(view -> checkbox.toggle()); + checkbox.setOnCheckedChangeListener((buttonView, isChecked) -> { + if (checkbox.isChecked()) { fileChooseListView.check(mExplorerItem.toScriptFile(), getAdapterPosition()); } else { fileChooseListView.getSelectedFiles().remove(mExplorerItem.toScriptFile()); } }); listFileBinding.scriptFileSize.setText(PFiles.getHumanReadableSize(explorerItem.getSize())); + listFileBinding.scriptFileDate.setText(PFile.getFullDateString(explorerItem.lastModified())); switch (explorerItem.getType()) { case JAVASCRIPT, AUTO -> firstCharIconBinding.firstChar .setIconTextColorByThemeColorLuminance() - .setStrokeThemeColor() - .setFillColorDayNight(); + .setStrokeColor(itemIconThemeColorForContrast) + .setFillColor(itemIconThemeColorForContrast); default -> firstCharIconBinding.firstChar .setIconTextColorDayNight() .setStrokeColorDayNight() @@ -57,7 +81,7 @@ class ExplorerItemViewHolder extends BindableViewHolder { firstCharIconBinding.firstChar.setIcon(ExplorerViewHelper.getIcon(explorerItem)); - listFileBinding.checkbox.setChecked(fileChooseListView.getSelectedFiles().containsKey(mExplorerItem.toScriptFile()), false); + checkbox.setChecked(fileChooseListView.getSelectedFiles().containsKey(mExplorerItem.toScriptFile()), false); } } diff --git a/app/src/main/java/org/autojs/autojs/ui/main/task/TaskListRecyclerView.java b/app/src/main/java/org/autojs/autojs/ui/main/task/TaskListRecyclerView.java index bf04c023..02f53d19 100644 --- a/app/src/main/java/org/autojs/autojs/ui/main/task/TaskListRecyclerView.java +++ b/app/src/main/java/org/autojs/autojs/ui/main/task/TaskListRecyclerView.java @@ -25,9 +25,12 @@ import org.autojs.autojs.execution.ScriptExecutionListener; import org.autojs.autojs.execution.SimpleScriptExecutionListener; import org.autojs.autojs.groundwork.WrapContentLinearLayoutManager; import org.autojs.autojs.script.AutoFileSource; +import org.autojs.autojs.script.JavaScriptFileSource; import org.autojs.autojs.storage.database.ModelChange; +import org.autojs.autojs.theme.ThemeColorManagerCompat; import org.autojs.autojs.timing.TimedTaskManager; import org.autojs.autojs.ui.timing.TimedTaskSettingActivity; +import org.autojs.autojs.util.ColorUtils; import org.autojs.autojs.util.FileUtils; import org.autojs.autojs6.R; import org.autojs.autojs6.databinding.ExplorerFirstCharIconBinding; @@ -232,10 +235,19 @@ public class TaskListRecyclerView extends ThemeColorRecyclerView { public void bind(Task task) { mTask = task; + int itemIconThemeColorForContrast = ColorUtils.adjustColorForContrast(getContext().getColor(R.color.window_background), ThemeColorManagerCompat.getColorPrimary(), 2.3); + FileUtils.TYPE.Icon icon; + if (JavaScriptFileSource.ENGINE.equals(mTask.getEngineName())) { + icon = FileUtils.TYPE.JAVASCRIPT.icon; + } else if (AutoFileSource.ENGINE.equals(mTask.getEngineName())) { + icon = FileUtils.TYPE.AUTO.icon; + } else { + icon = FileUtils.TYPE.UNKNOWN.icon; + } firstCharIconBinding.firstChar - .setIcon(AutoFileSource.ENGINE.equals(mTask.getEngineName()) ? FileUtils.TYPE.AUTO.icon : FileUtils.TYPE.JAVASCRIPT.icon) - .setIconTextThemeColor() - .setStrokeThemeColor() + .setIcon(icon) + .setIconTextColor(itemIconThemeColorForContrast) + .setStrokeColor(itemIconThemeColorForContrast) .setFillTransparent(); itemBinding.name.setText(task.getName()); itemBinding.taskListFilePath.setText(task.getDesc()); diff --git a/app/src/main/java/org/autojs/autojs/ui/widget/FirstCharView.kt b/app/src/main/java/org/autojs/autojs/ui/widget/FirstCharView.kt index 350daa79..d55daa28 100644 --- a/app/src/main/java/org/autojs/autojs/ui/widget/FirstCharView.kt +++ b/app/src/main/java/org/autojs/autojs/ui/widget/FirstCharView.kt @@ -11,6 +11,7 @@ import androidx.annotation.ColorInt import androidx.annotation.ColorRes import org.autojs.autojs.theme.ThemeColorManager import org.autojs.autojs.theme.ThemeColorManagerCompat +import org.autojs.autojs.util.ColorUtils import org.autojs.autojs.util.FileUtils import org.autojs.autojs6.R import kotlin.math.roundToInt @@ -50,8 +51,6 @@ class FirstCharView : TextView { return privateBackground!! } - private fun convertColorResToInt(@ColorRes colorRes: Int) = context.getColor(colorRes) - fun setIconText(text: CharSequence?) = also { setText(text) } fun setIcon(icon: FileUtils.TYPE.Icon): FirstCharView { @@ -70,7 +69,7 @@ class FirstCharView : TextView { fun setIconTextColor(@ColorInt color: Int) = also { setTextColor(color) } - fun setIconTextColorRes(@ColorRes colorRes: Int) = also { setTextColor(convertColorResToInt(colorRes)) } + fun setIconTextColorRes(@ColorRes colorRes: Int) = also { setTextColor(context.getColor(colorRes)) } fun setIconTextColorByThemeColorLuminance() = also { setIconTextColorRes(ThemeColorManager.getDayOrNightColorResByLuminance()) } @@ -82,7 +81,7 @@ class FirstCharView : TextView { fun setStrokeColor(@ColorInt color: Int) = also { background().setStroke(strokeWidth, color) } - fun setStrokeColorRes(@ColorRes colorRes: Int): FirstCharView = setStrokeColor(convertColorResToInt(colorRes)) + fun setStrokeColorRes(@ColorRes colorRes: Int): FirstCharView = setStrokeColor(context.getColor(colorRes)) fun setStrokeThemeColor() = setStrokeColor(ThemeColorManagerCompat.getColorPrimary()) @@ -92,7 +91,7 @@ class FirstCharView : TextView { fun setFillColor(@ColorInt color: Int) = also { background().setColor(color) } - fun setFillColorRes(@ColorRes colorRes: Int) = setFillColor(convertColorResToInt(colorRes)) + fun setFillColorRes(@ColorRes colorRes: Int) = setFillColor(context.getColor(colorRes)) fun setFillThemeColor() = setFillColor(ThemeColorManagerCompat.getColorPrimary()) diff --git a/app/src/main/java/org/autojs/autojs/ui/widget/PrefSwitch.java b/app/src/main/java/org/autojs/autojs/ui/widget/PrefSwitch.java index b310b8bd..7e901d15 100644 --- a/app/src/main/java/org/autojs/autojs/ui/widget/PrefSwitch.java +++ b/app/src/main/java/org/autojs/autojs/ui/widget/PrefSwitch.java @@ -55,7 +55,7 @@ public class PrefSwitch extends JsSwitch implements SharedPreferences.OnSharedPr @Override public void setThemeColor(ThemeColor color) { - ThemeColorHelper.setColorPrimary(this, color.colorPrimary); + ThemeColorHelper.setColorPrimary(this, color.colorPrimary, true); } private void readInitialState() { diff --git a/app/src/main/java/org/autojs/autojs/util/ColorUtils.kt b/app/src/main/java/org/autojs/autojs/util/ColorUtils.kt index 1e2386d1..ba11fc9b 100644 --- a/app/src/main/java/org/autojs/autojs/util/ColorUtils.kt +++ b/app/src/main/java/org/autojs/autojs/util/ColorUtils.kt @@ -632,4 +632,105 @@ object ColorUtils { @JvmStatic fun equals(c1: String?, c2: String?) = equals(parseColor(c1), parseColor(c2)) + /** + * Adjust the reference color to achieve better contrast on the background color, while remaining as close as possible to the reference color. + * + * zh-CN: 调整参考色, 使其在背景色上具有更好的对比度, 同时尽量接近参考色. + * + * @param background The background color. (zh-CN: 背景颜色.) + * @param reference The reference color. (zh-CN: 参考颜色.) + * @param minimumContrast The minimum contrast ratio, typically between 1.0 and 21.0 (1 being the lowest contrast, 21 being the highest contrast). + * (zh-CN: 最小对比度, 通常值为 1.0 - 21.0 (1 为最低对比度, 21 为最高对比度).) + * - 4.5: Minimum contrast ratio for normal use cases (Standard AA) + * - 7.0: High contrast ratio for better readability (Standard AAA) + * - < 4.5 (e.g. 3.0): Lower contrast ratio (< 4.5, e.g., 3.0) is acceptable for decorative or less significant elements + * - zh-CN: + * - 4.5: 普通场景的最低对比度标准 (AA 标准) + * - 7.0: 高对比度场景标准 (AAA 标准) + * - < 4.5 (如 3.0): 装饰性或次要元素可用的较低标准 + * @return The adjusted color. (zh-CN: 调整后的颜色.) + */ + @JvmStatic + fun adjustColorForContrast( + @ColorInt background: Int, + @ColorInt reference: Int, + minimumContrast: Double = 4.5, + ): Int { + // 如果已经满足对比度要求, 直接返回参考色 + if (calculateContrast(background, reference) >= minimumContrast) { + return reference + } + + // 转为 HSL 以便调整亮度 + val hsl = FloatArray(3) + ColorUtils.colorToHSL(reference, hsl) + + // 提高亮度, 尝试达到目标对比度 + val lighterColor = findAdjustableHSLColor(hsl, background, minimumContrast, lighten = true) + if (lighterColor != null) { + return lighterColor + } + + // 降低亮度, 尝试达到目标对比度 + val darkerColor = findAdjustableHSLColor(hsl, background, minimumContrast, lighten = false) + if (darkerColor != null) { + return darkerColor + } + + // 如果两种情况下都无法满足, 返回原始颜色 (极端情况) + return reference + } + + /** + * Calculate the contrast ratio between two colors using the W3C WCAG formula. + * + * zh-CN: 计算两种颜色的对比度, 使用 W3C WCAG 公式. + */ + private fun calculateContrast(color1: Int, color2: Int): Double { + return ColorUtils.calculateContrast(color1, color2) + } + + /** + * Adjust the lightness of a color in HSL format to meet the minimum contrast ratio. + * + * zh-CN: 调整颜色的亮度, 尝试找到满足最小对比度的颜色. + * + * @param hsl The color value in HSL format, including Hue, Saturation, and Lightness. + * (zh-CN: HSL 格式颜色值, 包括色相 (Hue), 饱和度 (Saturation), 亮度 (Lightness).) + * @param background The background color. (zh-CN: 背景颜色.) + * @param minimumContrast minimum contrast ratio. (zh-CN: 最小对比度值.) + * @param lighten Whether to increase brightness (true) or decrease brightness (false). + * (zh-CN: 是否提高亮度 (true 为提高亮度, false 为降低亮度).) + * @return The adjusted color, or null if no suitable color can be found. + * (zh-CN: 调整后的颜色, 若无法找到满足条件的颜色, 返回 null.) + */ + @ColorInt + private fun findAdjustableHSLColor( + hsl: FloatArray, + @ColorInt background: Int, + minimumContrast: Double, + lighten: Boolean, + ): Int? { + val step = 0.02f // 每次调整亮度的步长 + val maxSteps = 50 // 最大调整次数 (防止死循环) + + val adjustedHSL = hsl.copyOf() + for (i in 0 until maxSteps) { + // 根据 lighten 参数, 增加或减少亮度 + adjustedHSL[2] = (adjustedHSL[2] + (if (lighten) step else -step)) + .coerceIn(0f, 1f) // 防止超出合法范围 [0, 1] + + // 将调整后的 HSL 转回 RGB + val adjustedColor = ColorUtils.HSLToColor(adjustedHSL) + + // 重新计算对比度, 如果满足条件即可返回 + if (calculateContrast(background, adjustedColor) >= minimumContrast) { + return adjustedColor + } + } + + // 无法找到合适的亮度调整 + return null + } + } \ No newline at end of file diff --git a/app/src/main/res/layout/explorer_file.xml b/app/src/main/res/layout/explorer_file.xml index 53c9629d..315aed6e 100644 --- a/app/src/main/res/layout/explorer_file.xml +++ b/app/src/main/res/layout/explorer_file.xml @@ -17,13 +17,13 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/item_background_dark" + android:baselineAligned="false" android:clickable="true" + android:focusable="true" android:foreground="?selectableItemBackground" android:orientation="horizontal" android:paddingVertical="9dp" - android:paddingStart="8dp" - android:baselineAligned="false" - android:focusable="true"> + android:paddingStart="8dp"> - + + android:layout_width="match_parent" + android:layout_height="1px" + android:background="?android:divider" /> + android:id="@+id/item" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@color/item_background_dark" + android:clickable="true" + android:focusable="true" + android:foreground="?selectableItemBackground" + android:orientation="horizontal" + android:paddingVertical="9dp" + android:paddingStart="8dp"> + android:id="@+id/checkbox" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:gravity="center" /> + layout="@layout/explorer_first_char_icon" + android:layout_gravity="center_vertical" + android:layout_height="wrap_content" + android:layout_width="wrap_content" /> + + + android:ellipsize="end" + android:gravity="center_vertical" + android:maxLines="1" + android:textColor="?android:textColorPrimary" + android:textSize="14sp" + tools:text="@string/text_sample_name" /> - + + + android:textColor="?android:textColorSecondary" + android:textSize="11sp" + tools:text="@string/text_sample_file_date" /> - + + + + + android:layout_width="match_parent" + android:layout_height="1px" + android:background="#EDEEEF" /> diff --git a/version.properties b/version.properties index 4e6e49a5..145046f9 100644 --- a/version.properties +++ b/version.properties @@ -1,5 +1,5 @@ -#Thu Mar 13 12:06:20 CST 2025 -BUILD_TIME=1741838780961 +#Thu Mar 13 17:43:40 CST 2025 +BUILD_TIME=1741859020501 COMPILE_SDK_VERSION=35 JAVA_VERSION=23 JAVA_VERSION_MIN_RADICAL=0 @@ -17,6 +17,6 @@ RAPID_OCR_OPENCV_MOBILE_LABEL_VERSION=13 RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3 TARGET_SDK_VERSION=35 TARGET_SDK_VERSION_INRT=29 -VERSION_BUILD=3023 +VERSION_BUILD=3025 VERSION_NAME=6.6.2 Alpha4 VSCODE_EXT_REQUIRED_VERSION=1.0.8