6.6.2 - Alpha5 - 主题色设置页面增加新布局支持 (初步)

This commit is contained in:
SuperMonster003
2025-03-24 19:57:31 +08:00
parent fb93e169cb
commit 9dd763644d
24 changed files with 538 additions and 303 deletions

View File

@@ -4,7 +4,8 @@
"released_date": "2025/01/03",
"feature": [
"ui.statusBarAppearanceLight/statusBarAppearanceLightBy/navigationBarColor 等方法",
"设置页面增加 \"文件扩展名\" 设置选项"
"设置页面增加 \"文件扩展名\" 设置选项",
"主题色设置页面增加新布局支持"
],
"fix": [
"Android 15 状态栏背景颜色与主题色不一致的问题",

View File

@@ -258,8 +258,7 @@
<activity android:name="org.autojs.autojs.ui.project.ProjectConfigActivity" />
<activity
android:name="org.autojs.autojs.ui.keystore.ManageKeyStoreActivity" />
<activity android:name="org.autojs.autojs.ui.keystore.ManageKeyStoreActivity" />
<activity
android:name="org.autojs.autojs.ui.log.LogActivity"
@@ -574,6 +573,10 @@
<!-- </intent-filter>-->
<!--</receiver>-->
<activity
android:name="org.autojs.autojs.theme.app.ColorSelectLegacyActivity"
android:theme="@style/MtAppTheme.FullScreen" />
<activity
android:name="org.autojs.autojs.theme.app.ColorSelectActivity"
android:theme="@style/MtAppTheme.FullScreen" />

View File

@@ -78,10 +78,10 @@ object ThemeColorManager {
}
@JvmStatic
fun getDayOrNightColorByLuminance(context: Context): Int = context.getColor(getDayOrNightColorResByLuminance())
fun getDayOrNightColorByLuminance(context: Context): Int = ViewUtils.getDayOrNightColorByLuminance(context, colorPrimary)
@JvmStatic
fun getDayOrNightColorResByLuminance(): Int = if (isThemeColorLuminanceLight()) R.color.day else R.color.night
fun getDayOrNightColorResByLuminance(): Int = ViewUtils.getDayOrNightColorResByLuminance(colorPrimary)
private object BackgroundColorManager {

View File

@@ -1,183 +1,48 @@
package org.autojs.autojs.theme.app
import android.content.Context
import android.content.Intent
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
import android.os.Bundle
import android.view.View
import android.view.ViewAnimationUtils
import com.google.android.material.appbar.AppBarLayout
import org.autojs.autojs.core.pref.Pref
import org.autojs.autojs.theme.ThemeChangeNotifier
import org.autojs.autojs.theme.ThemeColor
import org.autojs.autojs.theme.ThemeColorManager
import org.autojs.autojs.ui.BaseActivity
import org.autojs.autojs.util.ColorUtils
import org.autojs.autojs.util.StringUtils.key
import org.autojs.autojs.util.ViewUtils
import android.view.Menu
import android.view.MenuItem
import org.autojs.autojs6.R
import org.autojs.autojs6.databinding.MtActivityColorSelectBinding
import kotlin.math.hypot
/**
* Created by Stardust on Mar 5, 2017.
* Modified by SuperMonster003 as of Sep 22, 2022.
* Transformed by SuperMonster003 on Sep 22, 2022.
* Created by SuperMonster003 on Mar 20, 2025.
*/
class ColorSelectActivity : BaseActivity() {
override val handleStatusBarThemeColorAutomatically = false
class ColorSelectActivity : ColorSelectBaseActivity() {
private lateinit var binding: MtActivityColorSelectBinding
private lateinit var mAppBarLayout: AppBarLayout
private lateinit var mTitle: String
private lateinit var mColorSettingRecyclerView: ColorSettingRecyclerView
private var mCurrentColor = 0
private val mOnItemClickListener = object : OnItemClickListener {
override fun onItemClick(v: View?, position: Int) {
mColorSettingRecyclerView.selectedThemeColor?.let {
setColorWithAnimation(mAppBarLayout, it.colorPrimary)
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
handleIntent()
MtActivityColorSelectBinding.inflate(layoutInflater).also {
binding = it
setUpUI(it)
ViewUtils.excludePaddingClippableViewFromNavigationBar(it.colorSettingRecyclerView)
setContentView(it.root)
setUpToolbar(it.toolbar)
setUpColorSettingRecyclerView(it.colorSettingRecyclerView)
setUpAppBar(it.appBar, it.appBarContainer)
}
}
private fun handleIntent() {
mTitle = intent.getStringExtra("title") ?: getString(R.string.mt_color_picker_title)
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_color_select, menu)
return super.onCreateOptionsMenu(menu)
}
private fun setUpUI(binding: MtActivityColorSelectBinding) {
setContentView(binding.root)
mCurrentColor = ThemeColorManager.colorPrimary
mAppBarLayout = binding.appBar.apply { setBackgroundColor(mCurrentColor) }
setUpToolbar(binding)
setUpColorSettingRecyclerView(binding)
}
private fun setUpToolbar(binding: MtActivityColorSelectBinding) {
binding.toolbar.also { toolbar ->
toolbar.title = mTitle
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
toolbar.setNavigationOnClickListener { finish() }
}
}
private fun setUpColorSettingRecyclerView(binding: MtActivityColorSelectBinding) {
mColorSettingRecyclerView = binding.colorSettingRecyclerView.apply {
setCustomColor()
setSelectedColor(mCurrentColor)
setOnItemClickListener(mOnItemClickListener)
}
}
override fun finish() {
mColorSettingRecyclerView.selectedThemeColor?.let {
ThemeColorManager.setThemeColor(it.colorPrimary)
Pref.putString(key(R.string.key_theme_color), getColorString(this))
ThemeChangeNotifier.notifyThemeChanged()
}
super.finish()
}
override fun initThemeColors() {
super.initThemeColors()
setUpToolbarColors()
setUpStatusBarAppearanceLight()
}
private fun setUpToolbarColors() {
val toolbar = binding.toolbar
val aimColor = when {
ColorUtils.isLuminanceLight(mCurrentColor) -> getColor(R.color.day)
else -> getColor(R.color.night)
}
toolbar.setTitleTextColor(aimColor)
toolbar.setSubtitleTextColor(aimColor)
toolbar.navigationIcon?.let { navigationIcon ->
navigationIcon.colorFilter = PorterDuffColorFilter(aimColor, PorterDuff.Mode.SRC_IN)
}
}
private fun setUpStatusBarAppearanceLight() {
ViewUtils.setStatusBarAppearanceLight(this, ColorUtils.isLuminanceDark(mCurrentColor))
}
private fun setColorWithAnimation(view: View, colorTo: Int) {
binding.appBarContainer.setBackgroundColor(mCurrentColor)
view.setBackgroundColor(colorTo)
mCurrentColor = colorTo
initThemeColors()
ViewAnimationUtils.createCircularReveal(
/* view = */ view,
/* centerX = */ view.left,
/* centerY = */ view.bottom,
/* startRadius = */ 0f,
/* endRadius = */ hypot(view.width.toDouble(), view.height.toDouble()).toFloat()
).apply {
duration = 500L
start()
}
}
class ColorItem(var name: String, var themeColor: ThemeColor) {
constructor(name: String, color: Int) : this(name, ThemeColor(color))
}
interface OnItemClickListener {
fun onItemClick(v: View?, position: Int)
}
companion object {
const val SELECT_NONE = -1
val KEY_CUSTOM_COLOR = "${ColorSettingRecyclerView::class.java.name}.COLOR_SETTING_CUSTOM_COLOR"
val KEY_SELECTED_COLOR_INDEX = "${ColorSettingRecyclerView::class.java.name}.SELECTED_COLOR_INDEX"
val customColorPosition: Int
get() = /* return mColors.size() - 1; */ 0
private val defaultColorPosition: Int
get() = customColorPosition + 1
@JvmStatic
fun startActivity(context: Context) {
Intent(context, ColorSelectActivity::class.java)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.putExtra("title", context.getString(R.string.mt_color_picker_title))
.let { context.startActivity(it) }
}
fun getColorString(context: Context): String {
val index = Pref.getInt(KEY_SELECTED_COLOR_INDEX, defaultColorPosition)
val colorItem = getColorItems(context)[index]
return "${colorItem.name} [${ColorUtils.toString(colorItem.themeColor.colorPrimary).uppercase()}]"
}
internal fun getColorItems(context: Context): List<ColorItem> = ArrayList<Pair</* nameRes */ Int, /* colorInt */ Int>>()
.apply {
add(customColorPosition, Pair(Pref.getInt(KEY_CUSTOM_COLOR, context.getColor(R.color.md_blue_grey_800)), R.string.mt_custom))
add(defaultColorPosition, Pair(context.getColor(R.color.theme_color_default), R.string.theme_color_default))
addAll(ColorUtils.MATERIAL_COLOR_ITEMS.map { pair -> Pair(context.getColor(pair.first), pair.second) })
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_toggle_color_select_layout -> {
isLegacyLayout = true
startActivity(this)
}
.map { (colorInt, nameRes) -> ColorItem(context.getString(nameRes), colorInt) }
R.id.action_locate_current_color -> {
}
R.id.action_search_color -> {
}
}
return true
}
}

View File

@@ -0,0 +1,190 @@
package org.autojs.autojs.theme.app
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.View
import android.view.ViewAnimationUtils
import androidx.appcompat.widget.Toolbar
import com.google.android.material.appbar.AppBarLayout
import io.codetail.widget.RevealFrameLayout
import org.autojs.autojs.core.pref.Pref
import org.autojs.autojs.theme.ThemeChangeNotifier
import org.autojs.autojs.theme.ThemeColor
import org.autojs.autojs.theme.ThemeColorManager
import org.autojs.autojs.ui.BaseActivity
import org.autojs.autojs.util.ColorUtils
import org.autojs.autojs.util.StringUtils.key
import org.autojs.autojs.util.ViewUtils
import org.autojs.autojs.util.ViewUtils.setMenuIconsColorByColorLuminance
import org.autojs.autojs.util.ViewUtils.setNavigationIconColorByColorLuminance
import org.autojs.autojs.util.ViewUtils.setTitlesTextColorByColorLuminance
import org.autojs.autojs6.R
import kotlin.math.hypot
import kotlin.properties.Delegates
/**
* Created by Stardust on Mar 5, 2017.
* Modified by SuperMonster003 as of Sep 22, 2022.
* Transformed by SuperMonster003 on Sep 22, 2022.
*/
abstract class ColorSelectBaseActivity : BaseActivity() {
override val handleStatusBarThemeColorAutomatically = false
private lateinit var mToolbar: Toolbar
private lateinit var mAppBarLayout: AppBarLayout
private lateinit var mAppBarContainer: RevealFrameLayout
private lateinit var mColorSettingRecyclerView: ColorSettingRecyclerView
private lateinit var mTitle: String
private val mOnItemClickListener = object : OnItemClickListener {
override fun onItemClick(v: View?, position: Int) {
mColorSettingRecyclerView.selectedThemeColor?.let {
setColorWithAnimation(mAppBarLayout, it.colorPrimary)
}
}
}
private var currentColor by Delegates.notNull<Int>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mTitle = this.intent.getStringExtra("title") ?: this.getString(R.string.mt_color_picker_title)
currentColor = this.intent.getIntExtra("currentColor", ThemeColorManager.colorPrimary)
}
protected fun setUpToolbar(toolbar: Toolbar) {
toolbar.apply {
title = mTitle
setSupportActionBar(this)
setNavigationOnClickListener { finish() }
setTitleTextAppearance(this@ColorSelectBaseActivity, R.style.TextAppearanceMainTitle)
mToolbar = this
}
supportActionBar?.setDisplayHomeAsUpEnabled(true)
}
protected fun setUpColorSettingRecyclerView(colorSettingRecyclerView: ColorSettingRecyclerView) {
mColorSettingRecyclerView = colorSettingRecyclerView.apply {
setCustomColor()
setSelectedColor(currentColor)
setOnItemClickListener(mOnItemClickListener)
ViewUtils.excludePaddingClippableViewFromNavigationBar(this)
}
}
override fun finish() {
mColorSettingRecyclerView.selectedThemeColor?.let {
ThemeColorManager.setThemeColor(it.colorPrimary)
Pref.putString(key(R.string.key_theme_color), getColorString(this))
ThemeChangeNotifier.notifyThemeChanged()
}
super.finish()
}
protected fun finishWithoutSaving() {
super.finish()
}
override fun initThemeColors() {
super.initThemeColors()
mToolbar.setTitlesTextColorByColorLuminance(this, currentColor)
mToolbar.setNavigationIconColorByColorLuminance(this, currentColor)
ViewUtils.setStatusBarAppearanceLightByColorLuminance(this, currentColor)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
updateToolbarIconsColor()
return super.onCreateOptionsMenu(menu)
}
private fun updateToolbarIconsColor() {
mToolbar.setMenuIconsColorByColorLuminance(this, currentColor)
}
private fun setColorWithAnimation(view: View, colorTo: Int) {
mAppBarContainer.setBackgroundColor(currentColor)
view.setBackgroundColor(colorTo)
currentColor = colorTo
initThemeColors()
updateToolbarIconsColor()
ViewAnimationUtils.createCircularReveal(
/* view = */ view,
/* centerX = */ view.left,
/* centerY = */ view.bottom,
/* startRadius = */ 0f,
/* endRadius = */ hypot(view.width.toDouble(), view.height.toDouble()).toFloat()
).apply {
duration = 500L
start()
}
}
protected fun setUpAppBar(appBar: AppBarLayout, appBarContainer: RevealFrameLayout) {
mAppBarLayout = appBar.apply { setBackgroundColor(currentColor) }
mAppBarContainer = appBarContainer
}
class ColorItem(var name: String, var themeColor: ThemeColor) {
constructor(name: String, color: Int) : this(name, ThemeColor(color))
}
interface OnItemClickListener {
fun onItemClick(v: View?, position: Int)
}
companion object {
const val SELECT_NONE = -1
val KEY_CUSTOM_COLOR = "${ColorSettingRecyclerView::class.java.name}.COLOR_SETTING_CUSTOM_COLOR"
val KEY_SELECTED_COLOR_INDEX = "${ColorSettingRecyclerView::class.java.name}.SELECTED_COLOR_INDEX"
val customColorPosition: Int
get() = /* return mColors.size() - 1; */ 0
private val defaultColorPosition: Int
get() = customColorPosition + 1
var isLegacyLayout: Boolean
get() = Pref.getBoolean(R.string.key_color_select_activity_legacy_layout, false)
set(value) = Pref.putBoolean(R.string.key_color_select_activity_legacy_layout, value)
@JvmStatic
fun startActivity(context: Context) {
val cls = when (isLegacyLayout) {
true -> ColorSelectLegacyActivity::class.java
else -> ColorSelectActivity::class.java
}
val intent = Intent(context, cls).apply {
putExtra("title", context.getString(R.string.mt_color_picker_title))
}
if (context is ColorSelectBaseActivity) {
intent.putExtra("currentColor", context.currentColor)
context.finishWithoutSaving()
}
context.startActivity(intent)
}
fun getColorString(context: Context): String {
val index = Pref.getInt(KEY_SELECTED_COLOR_INDEX, defaultColorPosition)
val colorItem = getColorItems(context)[index]
return "${colorItem.name} [${ColorUtils.toString(colorItem.themeColor.colorPrimary).uppercase()}]"
}
internal fun getColorItems(context: Context): List<ColorItem> = ArrayList<Pair</* nameRes */ Int, /* colorInt */ Int>>()
.apply {
add(customColorPosition, Pair(Pref.getInt(KEY_CUSTOM_COLOR, context.getColor(R.color.md_blue_grey_800)), R.string.mt_custom))
add(defaultColorPosition, Pair(context.getColor(R.color.theme_color_default), R.string.theme_color_default))
addAll(ColorUtils.MATERIAL_COLOR_ITEMS.map { pair -> Pair(context.getColor(pair.first), pair.second) })
}
.map { (colorInt, nameRes) -> ColorItem(context.getString(nameRes), colorInt) }
}
}

View File

@@ -0,0 +1,42 @@
package org.autojs.autojs.theme.app
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import org.autojs.autojs6.R
import org.autojs.autojs6.databinding.MtActivityColorSelectLegacyBinding
/**
* Created by SuperMonster003 on Mar 20, 2025.
*/
class ColorSelectLegacyActivity : ColorSelectBaseActivity() {
private lateinit var binding: MtActivityColorSelectLegacyBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
MtActivityColorSelectLegacyBinding.inflate(layoutInflater).also {
binding = it
setContentView(it.root)
setUpToolbar(it.toolbar)
setUpColorSettingRecyclerView(it.colorSettingRecyclerView)
setUpAppBar(it.appBar, it.appBarContainer)
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_color_select_legacy, menu)
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_toggle_color_select_layout -> {
isLegacyLayout = false
startActivity(this)
}
}
return true
}
}

View File

@@ -6,7 +6,6 @@ import android.content.res.ColorStateList
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.View.OnClickListener
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
@@ -32,20 +31,20 @@ class ColorSettingRecyclerView : ThemeColorRecyclerView {
constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(context, attrs, defStyle)
private var mOnItemClickListener: ColorSelectActivity.OnItemClickListener? = null
private var mOnItemClickListener: ColorSelectBaseActivity.OnItemClickListener? = null
private var mSelectedPosition = ColorSelectActivity.SELECT_NONE
private var mSelectedPosition = ColorSelectBaseActivity.SELECT_NONE
val selectedThemeColor: ThemeColor?
get() = ColorSelectActivity.getColorItems(context)[mSelectedPosition].themeColor.takeUnless { mSelectedPosition < 0 }
get() = ColorSelectBaseActivity.getColorItems(context)[mSelectedPosition].themeColor.takeUnless { mSelectedPosition < 0 }
private val customColor: Int
get() = Pref.getInt(ColorSelectActivity.KEY_CUSTOM_COLOR, context.getColor(R.color.md_blue_grey_800))
get() = Pref.getInt(ColorSelectBaseActivity.KEY_CUSTOM_COLOR, context.getColor(R.color.md_blue_grey_800))
private val mActualOnItemClickListener = OnClickListener { v ->
getChildViewHolder(v)?.let { holder ->
val pos = holder.bindingAdapterPosition
if (pos == ColorSelectActivity.customColorPosition) {
if (pos == ColorSelectBaseActivity.customColorPosition) {
showColorPicker(v)
} else {
setSelectedPosition(pos)
@@ -62,7 +61,7 @@ class ColorSettingRecyclerView : ThemeColorRecyclerView {
@SuppressLint("NotifyDataSetChanged")
fun setSelectedPosition(currentPosition: Int) {
if (mSelectedPosition != ColorSelectActivity.SELECT_NONE) {
if (mSelectedPosition != ColorSelectBaseActivity.SELECT_NONE) {
adapter!!.notifyItemChanged(mSelectedPosition)
mSelectedPosition = currentPosition
adapter!!.notifyItemChanged(currentPosition)
@@ -70,21 +69,21 @@ class ColorSettingRecyclerView : ThemeColorRecyclerView {
mSelectedPosition = currentPosition
adapter!!.notifyDataSetChanged()
}
Pref.putInt(ColorSelectActivity.KEY_SELECTED_COLOR_INDEX, mSelectedPosition)
Pref.putInt(ColorSelectBaseActivity.KEY_SELECTED_COLOR_INDEX, mSelectedPosition)
}
fun setSelectedColor(colorPrimary: Int) {
for ((i, colorItem) in ColorSelectActivity.getColorItems(context).withIndex()) {
for ((i, colorItem) in ColorSelectBaseActivity.getColorItems(context).withIndex()) {
if (colorItem.themeColor.colorPrimary == colorPrimary) {
setSelectedPosition(i)
return
}
}
mSelectedPosition = ColorSelectActivity.SELECT_NONE
mSelectedPosition = ColorSelectBaseActivity.SELECT_NONE
}
private fun setCustomColor(color: Int) {
ColorSelectActivity.getColorItems(context)[ColorSelectActivity.customColorPosition].themeColor.colorPrimary = color
ColorSelectBaseActivity.getColorItems(context)[ColorSelectBaseActivity.customColorPosition].themeColor.colorPrimary = color
}
fun setCustomColor() {
@@ -104,10 +103,10 @@ class ColorSettingRecyclerView : ThemeColorRecyclerView {
setColorPickerDialogListener(object : ColorPickerDialogListener {
override fun onColorSelected(dialogId: Int, @ColorInt color: Int) {
val c = color or -0x1000000
Pref.putInt(ColorSelectActivity.KEY_CUSTOM_COLOR, c)
Pref.putInt(ColorSelectBaseActivity.KEY_CUSTOM_COLOR, c)
setCustomColor(c)
setSelectedPosition(ColorSelectActivity.customColorPosition)
mOnItemClickListener?.onItemClick(v, ColorSelectActivity.customColorPosition)
setSelectedPosition(ColorSelectBaseActivity.customColorPosition)
mOnItemClickListener?.onItemClick(v, ColorSelectBaseActivity.customColorPosition)
}
override fun onDialogDismissed(dialogId: Int) {}
@@ -116,7 +115,7 @@ class ColorSettingRecyclerView : ThemeColorRecyclerView {
.show((context as FragmentActivity).supportFragmentManager, "Tag")
}
fun setOnItemClickListener(onItemClickListener: ColorSelectActivity.OnItemClickListener?) {
fun setOnItemClickListener(onItemClickListener: ColorSelectBaseActivity.OnItemClickListener?) {
mOnItemClickListener = onItemClickListener
}
@@ -127,7 +126,7 @@ class ColorSettingRecyclerView : ThemeColorRecyclerView {
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = ColorSelectActivity.getColorItems(context)[position]
val item = ColorSelectBaseActivity.getColorItems(context)[position]
holder.apply {
setColor(item.themeColor.colorPrimary)
nameView.text = item.name
@@ -136,7 +135,7 @@ class ColorSettingRecyclerView : ThemeColorRecyclerView {
}
}
override fun getItemCount() = ColorSelectActivity.getColorItems(context).size
override fun getItemCount() = ColorSelectBaseActivity.getColorItems(context).size
}

View File

@@ -1,6 +1,5 @@
package org.autojs.autojs.theme.preference
import android.annotation.SuppressLint
import android.content.Context
import android.content.res.Resources
import android.content.res.TypedArray
@@ -39,7 +38,6 @@ class ThemeColorSwitchPreference : SwitchPreference, ThemeColorMutable, LongClic
init(context, attrs, defStyleAttr, 0)
}
@SuppressLint("RestrictedApi")
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
init(context, attrs, 0, 0)
}
@@ -87,7 +85,6 @@ class ThemeColorSwitchPreference : SwitchPreference, ThemeColorMutable, LongClic
return context.obtainStyledAttributes(set, styleableRes, defStyleAttr, defStyleRes)
}
@SuppressLint("RestrictedApi")
private fun getAttrString(a: TypedArray, index: Int): String? = a.getString(index)
}

View File

@@ -1,76 +0,0 @@
package org.autojs.autojs.theme.widget;
import android.content.Context;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import org.autojs.autojs.theme.ThemeColor;
import org.autojs.autojs.theme.ThemeColorManager;
import org.autojs.autojs.theme.ThemeColorMutable;
import org.autojs.autojs6.R;
/**
* Created by Stardust on Mar 5, 2017.
* Modified by SuperMonster003 as of Dec 1, 2021.
*/
public class ThemeColorToolbar extends Toolbar implements ThemeColorMutable {
public ThemeColorToolbar(Context context) {
super(context);
init();
}
public ThemeColorToolbar(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public ThemeColorToolbar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
ThemeColorManager.add(this);
setContentInsetStartWithNavigation(getContext().getResources().getDimensionPixelSize(R.dimen.toolbar_content_inset_start_with_navigation));
setTitleTextAppearance(getContext(), R.style.TextAppearanceMainTitle);
}
@Override
public void setThemeColor(ThemeColor color) {
getViewTreeObserver().addOnGlobalLayoutListener(() -> applyThemeColor(color));
}
private void applyThemeColor(ThemeColor color) {
int colorPrimary = color.colorPrimary;
setBackgroundColor(colorPrimary);
int aimColor = ThemeColorManager.getDayOrNightColorByLuminance(getContext());
int popupTheme = ThemeColorManager.isThemeColorLuminanceLight() ? R.style.PopupMenuThemeLight : R.style.PopupMenuThemeDark;
setTitleTextColor(aimColor);
setSubtitleTextColor(aimColor);
Drawable navigationIcon = getNavigationIcon();
if (navigationIcon != null) {
navigationIcon.setColorFilter(new PorterDuffColorFilter(aimColor, PorterDuff.Mode.SRC_IN));
setNavigationIcon(navigationIcon);
}
Drawable collapseIcon = getCollapseIcon();
if (collapseIcon != null) {
collapseIcon.setColorFilter(new PorterDuffColorFilter(aimColor, PorterDuff.Mode.SRC_IN));
setCollapseIcon(collapseIcon);
}
Drawable overflowIcon = getOverflowIcon();
if (overflowIcon != null) {
overflowIcon.setColorFilter(new PorterDuffColorFilter(aimColor, PorterDuff.Mode.SRC_IN));
setOverflowIcon(overflowIcon);
}
setPopupTheme(popupTheme);
}
}

View File

@@ -0,0 +1,56 @@
package org.autojs.autojs.theme.widget
import android.content.Context
import android.util.AttributeSet
import android.view.ViewTreeObserver.OnGlobalLayoutListener
import androidx.appcompat.widget.Toolbar
import org.autojs.autojs.theme.ThemeColor
import org.autojs.autojs.theme.ThemeColorManager.add
import org.autojs.autojs.theme.ThemeColorManager.getDayOrNightColorByLuminance
import org.autojs.autojs.theme.ThemeColorManager.isThemeColorLuminanceLight
import org.autojs.autojs.theme.ThemeColorMutable
import org.autojs.autojs.util.ViewUtils.applyColorFilterWith
import org.autojs.autojs6.R
/**
* Created by Stardust on Mar 5, 2017.
* Modified by SuperMonster003 as of Dec 1, 2021.
*/
open class ThemeColorToolbar : Toolbar, ThemeColorMutable {
constructor(context: Context) : super(context) {
init()
}
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
init()
}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
init()
}
private fun init() {
add(this)
setContentInsetStartWithNavigation(context.resources.getDimensionPixelSize(R.dimen.toolbar_content_inset_start_with_navigation))
setTitleTextAppearance(context, R.style.TextAppearanceMainTitle)
}
override fun setThemeColor(color: ThemeColor) {
viewTreeObserver.addOnGlobalLayoutListener(OnGlobalLayoutListener { applyThemeColor(color) })
}
private fun applyThemeColor(color: ThemeColor) {
val aimColor = getDayOrNightColorByLuminance(context)
setBackgroundColor(color.colorPrimary)
setTitleTextColor(aimColor)
setSubtitleTextColor(aimColor)
navigationIcon?.let { navigationIcon = it.applyColorFilterWith(aimColor) }
collapseIcon?.let { collapseIcon = it.applyColorFilterWith(aimColor) }
overflowIcon?.let { overflowIcon = it.applyColorFilterWith(aimColor) }
popupTheme = if (isThemeColorLuminanceLight()) R.style.PopupMenuThemeLight else R.style.PopupMenuThemeDark
}
}

View File

@@ -23,6 +23,7 @@ import org.autojs.autojs.ui.BaseActivity
import org.autojs.autojs.ui.keystore.NewKeyStoreDialog.NewKeyStoreConfigs
import org.autojs.autojs.ui.viewmodel.KeyStoreViewModel
import org.autojs.autojs.util.ViewUtils
import org.autojs.autojs.util.ViewUtils.setMenuIconsColorByThemeColorLuminance
import org.autojs.autojs6.R
import org.autojs.autojs6.databinding.ActivityManageKeyStoreBinding
import java.io.File
@@ -118,7 +119,7 @@ class ManageKeyStoreActivity : BaseActivity() {
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_manage_key_store, menu)
ViewUtils.setToolbarMenuIconsColorByThemeColorLuminance(this)
binding.toolbar.setMenuIconsColorByThemeColorLuminance(this)
return true
}

View File

@@ -29,7 +29,7 @@ import org.autojs.autojs.pluginclient.JsonSocketServer
import org.autojs.autojs.service.AccessibilityService
import org.autojs.autojs.service.ForegroundService
import org.autojs.autojs.service.NotificationService
import org.autojs.autojs.theme.app.ColorSelectActivity
import org.autojs.autojs.theme.app.ColorSelectBaseActivity
import org.autojs.autojs.ui.floating.CircularMenu
import org.autojs.autojs.ui.floating.FloatyWindowManger
import org.autojs.autojs.ui.fragment.BindingDelegates.viewBinding
@@ -366,7 +366,7 @@ open class DrawerFragment : Fragment() {
)
mThemeColorItem = DrawerMenuShortcutItem(R.drawable.ic_personalize, R.string.text_theme_color)
.setAction(Runnable { ColorSelectActivity.startActivity(mContext) })
.setAction(Runnable { ColorSelectBaseActivity.startActivity(mContext) })
mAboutAppAndDevItem = DrawerMenuShortcutItem(R.drawable.ic_about, R.string.text_about_app_and_developer)
.setAction(Runnable { AboutActivity.startActivity(mContext) })

View File

@@ -31,7 +31,7 @@ class NightModePreference : MaterialListPreference {
prefContext.getString(R.string.entry_night_mode_follow_system) -> {
ViewUtils.setDefaultNightMode(ViewUtils.MODE.FOLLOW)
Pref.putBoolean(R.string.key_auto_night_mode_enabled, true)
Pref.putBoolean(R.string.key_night_mode_enabled, ViewUtils.isNightModeYes(prefContext))
Pref.putBoolean(R.string.key_night_mode_enabled, ViewUtils.isSystemDarkModeEnabled(prefContext))
}
prefContext.getString(R.string.entry_night_mode_always_on) -> {
ViewUtils.setDefaultNightMode(ViewUtils.MODE.NIGHT)

View File

@@ -3,9 +3,8 @@ package org.autojs.autojs.ui.settings
import android.content.Context
import android.content.SharedPreferences
import android.util.AttributeSet
import androidx.preference.Preference.SummaryProvider
import org.autojs.autojs.core.pref.Pref
import org.autojs.autojs.theme.app.ColorSelectActivity
import org.autojs.autojs.theme.app.ColorSelectBaseActivity
import org.autojs.autojs.theme.preference.MaterialPreference
class ThemeColorPreference : MaterialPreference, SharedPreferences.OnSharedPreferenceChangeListener {
@@ -20,12 +19,12 @@ class ThemeColorPreference : MaterialPreference, SharedPreferences.OnSharedPrefe
init {
Pref.registerOnSharedPreferenceChangeListener(this)
summaryProvider = SummaryProvider<ThemeColorPreference> { ColorSelectActivity.getColorString(prefContext) }
summaryProvider = SummaryProvider<ThemeColorPreference> { ColorSelectBaseActivity.getColorString(prefContext) }
}
override fun onClick() {
super.onClick()
ColorSelectActivity.startActivity(prefContext)
ColorSelectBaseActivity.startActivity(prefContext)
}
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) = notifyChanged()

View File

@@ -18,7 +18,7 @@ import org.autojs.autojs6.databinding.ToolbarMenuItemBinding
*/
class ToolbarMenuItem : LinearLayout {
private lateinit var mImageView: ImageView
private var mImageView: ImageView
private var mTextView: TextView
private val enabledDrawable by lazy {

View File

@@ -29,6 +29,9 @@ object DisplayUtils {
@JvmStatic
fun dpToPx(dp: Float) = TypedValue.applyDimension(COMPLEX_UNIT_DIP, dp, displayMetrics)
@JvmStatic
fun spToPx(sp: Float) = TypedValue.applyDimension(COMPLEX_UNIT_SP, sp, displayMetrics)
/**
* This method converts device-specific pixels to density independent pixels.
*

View File

@@ -10,9 +10,11 @@ import android.content.ContextWrapper
import android.content.res.Configuration
import android.content.res.Configuration.UI_MODE_NIGHT_MASK
import android.content.res.Configuration.UI_MODE_NIGHT_YES
import android.graphics.ColorFilter
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.os.Build
import android.os.Looper
import android.util.DisplayMetrics
@@ -187,6 +189,11 @@ object ViewUtils {
}
}
fun setStatusBarAppearanceLightByColorLuminance(activity: Activity, aimColor: Int) {
val shouldBeLight = ColorUtils.isLuminanceDark(aimColor)
setStatusBarAppearanceLight(activity, shouldBeLight)
}
fun setStatusBarBackgroundColor(activity: Activity, color: Int) {
val window = activity.window
val decorView = window.decorView
@@ -347,15 +354,16 @@ object ViewUtils {
@JvmStatic
fun setToolbarAsBack(activity: AppCompatActivity, title: String?) {
val toolbar = activity.findViewById<Toolbar>(R.id.toolbar)
toolbar.title = title
val toolbar = activity.findViewById<Toolbar>(R.id.toolbar)?.apply {
this.title = title
} ?: return
activity.setSupportActionBar(toolbar)
activity.supportActionBar?.let { actionBar ->
toolbar.setNavigationOnClickListener { activity.finish() }
actionBar.setDisplayHomeAsUpEnabled(true)
}
setToolbarMenuIconsColorByThemeColorLuminance(activity, toolbar)
setToolbarNavigationIconColorByThemeColorLuminance(activity, toolbar)
toolbar.setMenuIconsColorByThemeColorLuminance(activity)
toolbar.setNavigationIconColorByThemeColorLuminance(activity)
}
@JvmStatic
@@ -363,24 +371,73 @@ object ViewUtils {
setToolbarAsBack(activity, activity.getString(titleRes))
}
@JvmStatic
@JvmOverloads
fun setToolbarMenuIconsColorByThemeColorLuminance(activity: Activity, toolbar: Toolbar? = null) {
val toolbarView = toolbar ?: activity.findViewById(R.id.toolbar) ?: return
val aimColor = ThemeColorManager.getDayOrNightColorByLuminance(activity)
toolbarView.menu.forEach { menuItem ->
menuItem.icon?.colorFilter = PorterDuffColorFilter(aimColor, PorterDuff.Mode.SRC_IN)
}
fun Toolbar.setMenuIconsColorByThemeColorLuminance(context: Context) {
this.setMenuIconsColorByColorLuminance(context, ThemeColorManager.colorPrimary)
}
@JvmStatic
@JvmOverloads
fun setToolbarNavigationIconColorByThemeColorLuminance(activity: Activity, toolbar: Toolbar? = null) {
val toolbarView = toolbar ?: activity.findViewById(R.id.toolbar) ?: return
val aimColor = ThemeColorManager.getDayOrNightColorByLuminance(activity)
toolbarView.navigationIcon?.let { navigationIcon ->
navigationIcon.colorFilter = PorterDuffColorFilter(aimColor, PorterDuff.Mode.SRC_IN)
fun setToolbarMenuIconsColorByThemeColorLuminance(context: Context, toolbar: Toolbar) {
toolbar.setMenuIconsColorByThemeColorLuminance(context)
}
fun Toolbar.setMenuIconsColorByColorLuminance(context: Context, aimColor: Int) {
val color = getDayOrNightColorByLuminance(context, aimColor)
this.menu.forEach { menu ->
menu.icon?.let { ic -> menu.icon = ic.applyColorFilterWith(color) }
}
this.collapseIcon?.let { this.collapseIcon = it.applyColorFilterWith(color) }
this.overflowIcon?.let { this.overflowIcon = it.applyColorFilterWith(color) }
}
@JvmStatic
fun setToolbarMenuIconsColorByColorLuminance(context: Context, toolbar: Toolbar, aimColor: Int) {
toolbar.setMenuIconsColorByColorLuminance(context, aimColor)
}
fun Toolbar.setNavigationIconColorByThemeColorLuminance(context: Context) {
this.setNavigationIconColorByColorLuminance(context, ThemeColorManager.colorPrimary)
}
@JvmStatic
fun setToolbarNavigationIconColorByThemeColorLuminance(context: Context, toolbar: Toolbar) {
toolbar.setNavigationIconColorByThemeColorLuminance(context)
}
fun Toolbar.setNavigationIconColorByColorLuminance(context: Context, aimColor: Int) {
val color = getDayOrNightColorByLuminance(context, aimColor)
this.navigationIcon?.let { this.navigationIcon = it.applyColorFilterWith(color) }
}
fun Drawable.applyColorFilterWith(color: Int): Drawable {
return this.applyColorFilterWith(PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN))
}
fun Drawable.applyColorFilterWith(colorFilter: ColorFilter): Drawable {
return this.also { this.colorFilter = colorFilter }
}
@JvmStatic
fun setToolbarNavigationIconColorByColorLuminance(context: Context, toolbar: Toolbar, aimColor: Int) {
toolbar.setNavigationIconColorByColorLuminance(context, aimColor)
}
fun Toolbar.setTitlesTextColorByColorLuminance(context: Context, aimColor: Int) {
val color = getDayOrNightColorByLuminance(context, aimColor)
setTitleTextColor(color)
setSubtitleTextColor(color)
}
@JvmStatic
fun setToolbarTitlesTextColorByColorLuminance(context: Context, toolbar: Toolbar, aimColor: Int) {
toolbar.setTitlesTextColorByColorLuminance(context, aimColor)
}
@JvmStatic
fun getDayOrNightColorByLuminance(context: Context, aimColor: Int): Int = context.getColor(getDayOrNightColorResByLuminance(aimColor))
@JvmStatic
fun getDayOrNightColorResByLuminance(aimColor: Int): Int {
return if (ColorUtils.isLuminanceLight(aimColor)) R.color.day else R.color.night
}
@JvmStatic

View File

@@ -0,0 +1,15 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:fillColor="@android:color/transparent"
android:strokeColor="#09090b"
android:strokeWidth="1.8"
android:strokeLineCap="round"
android:strokeLineJoin="round"
android:pathData="M16,10c0,3.3137 -2.6863,6 -6,6m6,-6c0,-3.31371 -2.6863,-6 -6,-6m6,6h3m-9,6c-3.31371,0 -6,-2.6863 -6,-6m6,6v3m-6,-9c0,-3.31371 2.68629,-6 6,-6m-6,6h-3m9,-6v-3m2,9c0,1.1046 -0.8954,2 -2,2s-2,-0.8954 -2,-2 0.8954,-2 2,-2 2,0.8954 2,2z" />
</vector>

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
@@ -16,16 +17,14 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/MtAppTheme.AppBarOverlay"
android:clipToPadding="true"
android:fitsSystemWindows="true">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="center_vertical"
android:theme="@style/ToolBarStyle"
app:contentInsetStartWithNavigation="@dimen/toolbar_content_inset_start_with_navigation"
android:theme="@style/ToolBarStyle"
app:popupTheme="@style/MtAppTheme.PopupOverlay"
tools:title="@string/text_sample_string" />

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<io.codetail.widget.RevealFrameLayout
android:id="@+id/appBarContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/MtAppTheme.AppBarOverlay"
android:fitsSystemWindows="true">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:contentInsetStartWithNavigation="@dimen/toolbar_content_inset_start_with_navigation"
android:theme="@style/ToolBarStyle"
app:popupTheme="@style/MtAppTheme.PopupOverlay"
tools:title="@string/text_sample_string" />
</com.google.android.material.appbar.AppBarLayout>
</io.codetail.widget.RevealFrameLayout>
<view
android:id="@+id/color_setting_recycler_view"
class="org.autojs.autojs.theme.app.ColorSettingRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_locate_current_color"
android:title="@string/text_locate_current_color"
android:icon="@drawable/ic_locate"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_search_color"
android:title="@string/text_search_color"
android:icon="@drawable/ic_search_white_36dp"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_toggle_color_select_layout"
android:title="@string/text_switch_to_legacy_layout"
android:icon="@drawable/ic_swap_horiz_black_48dp"
app:showAsAction="never" />
</menu>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_toggle_color_select_layout"
android:title="@string/text_switch_to_new_layout"
android:icon="@drawable/ic_swap_horiz_black_48dp"
app:showAsAction="never" />
</menu>

View File

@@ -97,11 +97,14 @@
<item name="android:navigationBarColor">@android:color/transparent</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.DayNight.ActionBar" />
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.DayNight.ActionBar">
<item name="actionOverflowMenuStyle">@style/OverflowMenu</item>
</style>
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.DayNight.ActionBar">
<item name="android:textColorPrimary">@color/day_full</item>
<item name="android:textColorSecondary">@color/colorAccent</item>
<item name="actionOverflowMenuStyle">@style/OverflowMenu</item>
</style>
<style name="MtAppTheme.FullScreen" parent="Theme.AppCompat.DayNight.NoActionBar">
@@ -112,9 +115,11 @@
<item name="android:navigationBarColor">@android:color/transparent</item>
</style>
<style name="MtAppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.DayNight.ActionBar" />
<style name="MtAppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.DayNight.ActionBar">
<item name="actionOverflowMenuStyle">@style/OverflowMenu</item>
</style>
<style name="MtAppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.DayNight.ActionBar">
<style name="MtAppTheme.PopupOverlay" parent="OverflowMenu">
<item name="android:textColorPrimary">@color/day_full</item>
</style>
@@ -144,18 +149,18 @@
</style>
<style name="PopupMenuTheme" parent="AppTheme.PopupOverlay">
<item name="android:textColor">@color/day_night</item>
<item name="android:tint">@color/day_night</item>
<item name="android:textColor">@color/day_night_full</item>
<item name="android:tint">@color/day_night_full</item>
</style>
<style name="PopupMenuThemeLight" parent="AppTheme.PopupOverlay">
<item name="android:textColor">@color/day</item>
<item name="android:tint">@color/day</item>
<item name="android:textColor">@color/day_full</item>
<item name="android:tint">@color/day_full</item>
</style>
<style name="PopupMenuThemeDark" parent="AppTheme.PopupOverlay">
<item name="android:textColor">@color/dusk</item>
<item name="android:tint">@color/dusk</item>
<item name="android:textColor">@color/night_full</item>
<item name="android:tint">@color/night_full</item>
</style>
<style name="SearchViewActionBar" parent="@style/Widget.AppCompat.SearchView.ActionBar" />
@@ -164,8 +169,8 @@
<style name="TextAppearanceEditorTitle" parent="TextAppearance.Widget.AppCompat.Toolbar.Title">
<item name="android:textSize">@dimen/editor_title_text_size</item>
<item name="android:maxLines">2</item>
<item name="android:ellipsize">middle</item>
<item name="maxLines">2</item>
<item name="paddingStart">0dp</item>
</style>
<style name="TextAppearanceMainTitle" parent="TextAppearance.Widget.AppCompat.Toolbar.Title">
@@ -179,6 +184,8 @@
</style>
<style name="OverflowMenu" parent="Widget.AppCompat.PopupMenu.Overflow">
<item name="android:textColor">@color/day_night_full</item>
<item name="android:itemBackground">@color/item_background</item>
<item name="android:windowDisablePreview">true</item>
<item name="overlapAnchor">false</item>
<item name="android:dropDownVerticalOffset">5.0dp</item>

View File

@@ -1,5 +1,5 @@
#Mon Mar 24 19:37:17 CST 2025
BUILD_TIME=1742816237794
#Mon Mar 24 19:54:51 CST 2025
BUILD_TIME=1742817291092
COMPILE_SDK_VERSION=35
JAVA_VERSION=23
JAVA_VERSION_MIN_RADICAL=0