diff --git a/app/src/main/java/io/legado/app/App.kt b/app/src/main/java/io/legado/app/App.kt index c6e4f40bc..a6c6d9514 100644 --- a/app/src/main/java/io/legado/app/App.kt +++ b/app/src/main/java/io/legado/app/App.kt @@ -14,8 +14,8 @@ import io.legado.app.constant.AppConst.channelIdWeb import io.legado.app.data.AppDatabase import io.legado.app.lib.theme.ThemeStore import io.legado.app.utils.getCompatColor -import io.legado.app.utils.getPrefBoolean import io.legado.app.utils.getPrefInt +import io.legado.app.utils.isNightTheme @Suppress("DEPRECATION") class App : Application() { @@ -36,14 +36,18 @@ class App : Application() { override fun onCreate() { super.onCreate() INSTANCE = this + db = AppDatabase.createDatabase(INSTANCE) packageManager.getPackageInfo(packageName, 0)?.let { versionCode = it.versionCode versionName = it.versionName } - if (!ThemeStore.isConfigured(this, versionCode)) upThemeStore() + + if (!ThemeStore.isConfigured(this, versionCode)) applyTheme() initNightTheme() + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) createChannelId() + LiveEventBus.get() .config() .supportBroadcast(this) @@ -51,20 +55,11 @@ class App : Application() { .autoClear(false) } - fun initNightTheme() { - val targetMode = if (getPrefBoolean("isNightTheme")) { - AppCompatDelegate.MODE_NIGHT_YES - } else { - AppCompatDelegate.MODE_NIGHT_NO - } - AppCompatDelegate.setDefaultNightMode(targetMode) - } - /** * 更新主题 */ - fun upThemeStore() { - if (getPrefBoolean("isNightTheme")) { + fun applyTheme() { + if (isNightTheme) { ThemeStore.editTheme(this) .primaryColor(getPrefInt("colorPrimaryNight", getCompatColor(R.color.colorPrimary))) .accentColor(getPrefInt("colorAccentNight", getCompatColor(R.color.colorAccent))) @@ -80,10 +75,21 @@ class App : Application() { } fun applyDayNight() { - upThemeStore() + applyTheme() initNightTheme() } + + private fun initNightTheme() { + val targetMode = if (isNightTheme) { + AppCompatDelegate.MODE_NIGHT_YES + } else { + AppCompatDelegate.MODE_NIGHT_NO + } + AppCompatDelegate.setDefaultNightMode(targetMode) + } + + /** * 创建通知ID */ diff --git a/app/src/main/java/io/legado/app/base/BaseActivity.kt b/app/src/main/java/io/legado/app/base/BaseActivity.kt index 51f960788..c109d0e3b 100644 --- a/app/src/main/java/io/legado/app/base/BaseActivity.kt +++ b/app/src/main/java/io/legado/app/base/BaseActivity.kt @@ -8,8 +8,10 @@ import android.view.View import android.view.WindowManager import androidx.appcompat.app.AppCompatActivity import io.legado.app.R +import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ColorUtils import io.legado.app.lib.theme.ThemeStore +import io.legado.app.lib.theme.primaryColor import io.legado.app.utils.* import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.MainScope @@ -64,8 +66,8 @@ abstract class BaseActivity(private val layoutID: Int, private val fullScreen: B } private fun initTheme() { - window.decorView.setBackgroundColor(ThemeStore.backgroundColor(this)) - if (ColorUtils.isColorLight(ThemeStore.primaryColor(this))) { + ATH.applyBackgroundTint(window.decorView) + if (ColorUtils.isColorLight(primaryColor)) { setTheme(R.style.AppTheme_Light) } else { setTheme(R.style.AppTheme_Dark) diff --git a/app/src/main/java/io/legado/app/lib/theme/ATH.kt b/app/src/main/java/io/legado/app/lib/theme/ATH.kt index 62a8cad34..e59d87149 100644 --- a/app/src/main/java/io/legado/app/lib/theme/ATH.kt +++ b/app/src/main/java/io/legado/app/lib/theme/ATH.kt @@ -13,7 +13,12 @@ import androidx.annotation.ColorInt import androidx.appcompat.app.AlertDialog import androidx.recyclerview.widget.RecyclerView import androidx.viewpager.widget.ViewPager -import io.legado.app.utils.getPrefBoolean +import com.google.android.material.bottomnavigation.BottomNavigationView +import io.legado.app.R +import io.legado.app.utils.getCompatColor +import io.legado.app.utils.isTransparentStatusBar +import kotlinx.android.synthetic.main.activity_main.view.* +import org.jetbrains.anko.backgroundColor /** @@ -32,7 +37,7 @@ object ATH { fun setStatusbarColorAuto(activity: Activity) { setStatusbarColor( activity, - ThemeStore.statusBarColor(activity, activity.getPrefBoolean("transparentStatusBar")) + ThemeStore.statusBarColor(activity, activity.isTransparentStatusBar) ) } @@ -160,6 +165,35 @@ object ATH { } } + //**************************************************************Directly*************************************************************// + + fun applyBottomNavigationColor(bottomBar: BottomNavigationView?) { + bottomBar?.apply { + setBackgroundColor(ThemeStore.backgroundColor(context)) + val colorStateList = Selector.colorBuild() + .setDefaultColor(context.getCompatColor(R.color.btn_bg_press_tp)) + .setSelectedColor(ThemeStore.primaryColor(bottom_navigation_view.context)).create() + itemIconTintList = colorStateList + itemTextColor = colorStateList + } + } + + fun applyTint(view: View?) { + view?.apply { + setTint(this, context.accentColor) + } + } + + fun applyBackgroundTint(view: View?) { + view?.apply { + if (background == null) { + backgroundColor = context.backgroundColor + } else { + setBackgroundTint(this, context.backgroundColor) + } + } + } + fun applyEdgeEffectColor(view: View?) { when (view) { is RecyclerView -> view.edgeEffectFactory = DEFAULT_EFFECT_FACTORY diff --git a/app/src/main/java/io/legado/app/lib/theme/MaterialValueHelper.kt b/app/src/main/java/io/legado/app/lib/theme/MaterialValueHelper.kt index 1dc767f39..ea37c7b00 100644 --- a/app/src/main/java/io/legado/app/lib/theme/MaterialValueHelper.kt +++ b/app/src/main/java/io/legado/app/lib/theme/MaterialValueHelper.kt @@ -75,52 +75,56 @@ fun Fragment.getSecondaryDisabledTextColor(dark: Boolean): Int { } else ContextCompat.getColor(requireContext(), R.color.secondary_text_disabled_material_dark) } +val Context.primaryColor: Int + get() = ThemeStore.primaryColor(this) -@ColorInt -fun Context.getPrimaryTextColor(): Int { - return getPrimaryTextColor(isDarkTheme()) -} +val Context.primaryColorDark: Int + get() = ThemeStore.primaryColorDark(this) -@ColorInt -fun Context.getSecondaryTextColor(): Int { - return getSecondaryTextColor(isDarkTheme()) -} +val Context.accentColor: Int + get() = ThemeStore.accentColor(this) -@ColorInt -fun Context.getPrimaryDisabledTextColor(): Int { - return getPrimaryDisabledTextColor(isDarkTheme()) -} +val Context.backgroundColor: Int + get() = ThemeStore.backgroundColor(this) -@ColorInt -fun Context.getSecondaryDisabledTextColor(): Int { - return getSecondaryDisabledTextColor(isDarkTheme()) -} +val Context.primaryTextColor: Int + get() = getPrimaryTextColor(isDarkTheme) +val Context.secondaryTextColor: Int + get() = getSecondaryTextColor(isDarkTheme) -@ColorInt -fun Fragment.getPrimaryTextColor(): Int { - return getPrimaryTextColor(isDarkTheme()) -} +val Context.primaryDisabledTextColor: Int + get() = getPrimaryDisabledTextColor(isDarkTheme) -@ColorInt -fun Fragment.getSecondaryTextColor(): Int { - return getSecondaryTextColor(isDarkTheme()) -} +val Context.secondaryDisabledTextColor: Int + get() = getSecondaryDisabledTextColor(isDarkTheme) -@ColorInt -fun Fragment.getPrimaryDisabledTextColor(): Int { - return getPrimaryDisabledTextColor(isDarkTheme()) -} +val Fragment.primaryColor: Int + get() = ThemeStore.primaryColor(requireContext()) -@ColorInt -fun Fragment.getSecondaryDisabledTextColor(): Int { - return getSecondaryDisabledTextColor(isDarkTheme()) -} +val Fragment.primaryColorDark: Int + get() = ThemeStore.primaryColorDark(requireContext()) -fun Context.isDarkTheme(): Boolean { - return ColorUtils.isColorLight(ThemeStore.primaryColor(this)) -} +val Fragment.accentColor: Int + get() = ThemeStore.accentColor(requireContext()) + +val Fragment.backgroundColor: Int + get() = ThemeStore.backgroundColor(requireContext()) + +val Fragment.primaryTextColor: Int + get() = getPrimaryTextColor(isDarkTheme) + +val Fragment.secondaryTextColor: Int + get() = getSecondaryTextColor(isDarkTheme) + +val Fragment.primaryDisabledTextColor: Int + get() = getPrimaryDisabledTextColor(isDarkTheme) + +val Fragment.secondaryDisabledTextColor: Int + get() = getSecondaryDisabledTextColor(isDarkTheme) + +val Context.isDarkTheme: Boolean + get() = ColorUtils.isColorLight(ThemeStore.primaryColor(this)) -fun Fragment.isDarkTheme(): Boolean { - return requireContext().isDarkTheme() -} \ No newline at end of file +val Fragment.isDarkTheme: Boolean + get() = requireContext().isDarkTheme \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/bookshelf/BookshelfAdapter.kt b/app/src/main/java/io/legado/app/ui/bookshelf/BookshelfAdapter.kt index fa3a945b5..4f8a20e7f 100644 --- a/app/src/main/java/io/legado/app/ui/bookshelf/BookshelfAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/bookshelf/BookshelfAdapter.kt @@ -9,6 +9,7 @@ import androidx.recyclerview.widget.RecyclerView import io.legado.app.R import io.legado.app.data.entities.Book import io.legado.app.help.ImageLoader +import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ThemeStore import kotlinx.android.synthetic.main.item_bookshelf_list.view.* import kotlinx.android.synthetic.main.item_relace_rule.view.tv_name @@ -49,7 +50,7 @@ class BookshelfAdapter : PagedListAdapter(D class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) { init { - itemView.setBackgroundColor(ThemeStore.backgroundColor(itemView.context)) + ATH.applyBackgroundTint(itemView) } fun bind(book: Book, callBack: CallBack?) = with(itemView) { diff --git a/app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt b/app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt index 778e6e15e..1a2dad761 100644 --- a/app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt +++ b/app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt @@ -49,9 +49,9 @@ class ThemeConfigFragment : PreferenceFragmentCompat(), SharedPreferences.OnShar .setTitle("白天背景太暗") .setMessage("将会恢复默认背景?") .setPositiveButton(R.string.ok) { _, _ -> - App.INSTANCE.putPrefInt( + putPrefInt( "colorBackground", - App.INSTANCE.getCompatColor(R.color.md_grey_100) + getCompatColor(R.color.md_grey_100) ) upTheme(false) } @@ -69,9 +69,9 @@ class ThemeConfigFragment : PreferenceFragmentCompat(), SharedPreferences.OnShar .setTitle("夜间背景太亮") .setMessage("将会恢复默认背景?") .setPositiveButton(R.string.ok) { _, _ -> - App.INSTANCE.putPrefInt( + putPrefInt( "colorBackgroundNight", - App.INSTANCE.getCompatColor(R.color.md_grey_800) + getCompatColor(R.color.md_grey_800) ) upTheme(true) } @@ -95,14 +95,14 @@ class ThemeConfigFragment : PreferenceFragmentCompat(), SharedPreferences.OnShar .setMessage("是否确认恢复?") .setPositiveButton(R.string.ok) { _, _ -> preferenceManager.sharedPreferences.edit() - .putInt("colorPrimary", App.INSTANCE.getCompatColor(R.color.colorPrimary)) - .putInt("colorAccent", App.INSTANCE.getCompatColor(R.color.colorAccent)) - .putInt("colorBackground", App.INSTANCE.getCompatColor(R.color.md_grey_100)) - .putInt("colorPrimaryNight", App.INSTANCE.getCompatColor(R.color.colorPrimary)) - .putInt("colorAccentNight", App.INSTANCE.getCompatColor(R.color.colorAccent)) - .putInt("colorBackgroundNight", App.INSTANCE.getCompatColor(R.color.md_grey_800)) + .putInt("colorPrimary", getCompatColor(R.color.colorPrimary)) + .putInt("colorAccent", getCompatColor(R.color.colorAccent)) + .putInt("colorBackground", getCompatColor(R.color.md_grey_100)) + .putInt("colorPrimaryNight", getCompatColor(R.color.colorPrimary)) + .putInt("colorAccentNight", getCompatColor(R.color.colorAccent)) + .putInt("colorBackgroundNight", getCompatColor(R.color.md_grey_800)) .apply() - App.INSTANCE.upThemeStore() + App.INSTANCE.applyTheme() recreateActivities() } .setNegativeButton(R.string.cancel, null) @@ -117,7 +117,7 @@ class ThemeConfigFragment : PreferenceFragmentCompat(), SharedPreferences.OnShar return !ColorUtils.isColorLight( sharedPreferences.getInt( "colorBackground", - App.INSTANCE.getCompatColor(R.color.md_grey_100) + getCompatColor(R.color.md_grey_100) ) ) } @@ -126,14 +126,14 @@ class ThemeConfigFragment : PreferenceFragmentCompat(), SharedPreferences.OnShar return ColorUtils.isColorLight( sharedPreferences.getInt( "colorBackgroundNight", - App.INSTANCE.getCompatColor(R.color.md_grey_800) + getCompatColor(R.color.md_grey_800) ) ) } private fun upTheme(isNightTheme: Boolean) { - if (App.INSTANCE.getPrefBoolean("isNightTheme") == isNightTheme) { - App.INSTANCE.upThemeStore() + if (this.isNightTheme == isNightTheme) { + App.INSTANCE.applyTheme() recreateActivities() } } diff --git a/app/src/main/java/io/legado/app/ui/main/MainActivity.kt b/app/src/main/java/io/legado/app/ui/main/MainActivity.kt index bcb1d2fe3..774c6f329 100644 --- a/app/src/main/java/io/legado/app/ui/main/MainActivity.kt +++ b/app/src/main/java/io/legado/app/ui/main/MainActivity.kt @@ -35,12 +35,7 @@ class MainActivity : VMBaseActivity(R.layout.activity_main), override fun onActivityCreated(savedInstanceState: Bundle?) { ATH.applyEdgeEffectColor(view_pager_main) - bottom_navigation_view.setBackgroundColor(ThemeStore.backgroundColor(this)) - val colorStateList = Selector.colorBuild() - .setDefaultColor(getCompatColor(R.color.btn_bg_press_tp)) - .setSelectedColor(ThemeStore.primaryColor(bottom_navigation_view.context)).create() - bottom_navigation_view.itemIconTintList = colorStateList - bottom_navigation_view.itemTextColor = colorStateList + ATH.applyBottomNavigationColor(bottom_navigation_view) view_pager_main.offscreenPageLimit = 3 view_pager_main.adapter = TabFragmentPageAdapter(supportFragmentManager) view_pager_main.addOnPageChangeListener(this) diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt index a0aa86e4e..24b67a9f2 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt @@ -1,6 +1,7 @@ package io.legado.app.ui.main.bookshelf import android.os.Bundle +import android.util.Log import android.view.Menu import android.view.View import android.widget.EditText @@ -22,11 +23,13 @@ import io.legado.app.lib.dialogs.noButton import io.legado.app.lib.dialogs.yesButton import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ThemeStore +import io.legado.app.lib.theme.accentColor import io.legado.app.ui.bookshelf.BookshelfActivity import io.legado.app.ui.search.SearchActivity import io.legado.app.utils.applyTint import io.legado.app.utils.getViewModel import io.legado.app.utils.requestInputMethod +import io.legado.app.utils.visible import kotlinx.android.synthetic.main.dialog_edittext.view.* import kotlinx.android.synthetic.main.fragment_bookshelf.* import kotlinx.android.synthetic.main.view_title_bar.* @@ -58,7 +61,7 @@ class BookshelfFragment : VMBaseFragment(R.layout.fragment_b } private fun initSearchView() { - search_view.visibility = View.VISIBLE + search_view.visible() search_view.onActionViewExpanded() search_view.isSubmitButtonEnabled = true search_view.queryHint = getString(R.string.search_book_key) @@ -68,11 +71,11 @@ class BookshelfFragment : VMBaseFragment(R.layout.fragment_b private fun initRecyclerView() { ATH.applyEdgeEffectColor(rv_bookshelf) - refresh_layout.setColorSchemeColors(ThemeStore.accentColor(refresh_layout.context)) + refresh_layout.setColorSchemeColors(accentColor) refresh_layout.setOnRefreshListener { refresh_layout.isRefreshing = false } - tv_recent_reading.textColor = ThemeStore.accentColor(tv_recent_reading.context) + tv_recent_reading.textColor = accentColor rv_book_group.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) bookGroupAdapter = BookGroupAdapter() rv_book_group.adapter = bookGroupAdapter @@ -118,7 +121,7 @@ class BookshelfFragment : VMBaseFragment(R.layout.fragment_b customView { layoutInflater.inflate(R.layout.dialog_edittext, null).apply { editText = edit_view.apply { - ATH.setTint(this, ThemeStore.accentColor(ctx)) + ATH.applyTint(this) hint = "分组名称" } } diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt index d47080cb4..1bb9a3b64 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt @@ -7,7 +7,6 @@ import io.legado.app.data.entities.BookGroup class BookshelfViewModel(application: Application) : BaseViewModel(application) { - fun saveBookGroup(group: String?) { if (!group.isNullOrBlank()) { execute { diff --git a/app/src/main/java/io/legado/app/ui/sourcedebug/SourceDebugActivity.kt b/app/src/main/java/io/legado/app/ui/sourcedebug/SourceDebugActivity.kt index a6345fe13..609689873 100644 --- a/app/src/main/java/io/legado/app/ui/sourcedebug/SourceDebugActivity.kt +++ b/app/src/main/java/io/legado/app/ui/sourcedebug/SourceDebugActivity.kt @@ -10,6 +10,7 @@ import io.legado.app.constant.Bus import io.legado.app.help.EventMessage import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ThemeStore +import io.legado.app.lib.theme.accentColor import io.legado.app.utils.getViewModel import io.legado.app.utils.observeEvent import kotlinx.android.synthetic.main.activity_source_debug.* @@ -34,7 +35,7 @@ class SourceDebugActivity : VMBaseActivity(R.layout.activity_s adapter = SourceDebugAdapter(this) recycler_view.layoutManager = LinearLayoutManager(this) recycler_view.adapter = adapter - rotate_loading.loadingColor = ThemeStore.accentColor(this) + rotate_loading.loadingColor = accentColor } private fun initSearchView() { diff --git a/app/src/main/java/io/legado/app/ui/welcome/WelcomeActivity.kt b/app/src/main/java/io/legado/app/ui/welcome/WelcomeActivity.kt index 3295cb766..efe7a36ff 100644 --- a/app/src/main/java/io/legado/app/ui/welcome/WelcomeActivity.kt +++ b/app/src/main/java/io/legado/app/ui/welcome/WelcomeActivity.kt @@ -6,6 +6,7 @@ import android.os.Bundle import io.legado.app.R import io.legado.app.base.BaseActivity import io.legado.app.lib.theme.ThemeStore +import io.legado.app.lib.theme.accentColor import io.legado.app.ui.main.MainActivity import kotlinx.android.synthetic.main.activity_welcome.* import org.jetbrains.anko.startActivity @@ -13,7 +14,7 @@ import org.jetbrains.anko.startActivity class WelcomeActivity : BaseActivity(R.layout.activity_welcome) { override fun onActivityCreated(savedInstanceState: Bundle?) { - iv_bg.setColorFilter(ThemeStore.accentColor(this)) + iv_bg.setColorFilter(accentColor) val welAnimator = ValueAnimator.ofFloat(1f, 0f).setDuration(800) welAnimator.startDelay = 100 welAnimator.addUpdateListener { animation -> diff --git a/app/src/main/java/io/legado/app/ui/widget/TitleBar.kt b/app/src/main/java/io/legado/app/ui/widget/TitleBar.kt index 0ce45791b..0a36b6a58 100644 --- a/app/src/main/java/io/legado/app/ui/widget/TitleBar.kt +++ b/app/src/main/java/io/legado/app/ui/widget/TitleBar.kt @@ -16,10 +16,11 @@ import androidx.core.graphics.drawable.DrawableCompat import com.google.android.material.appbar.AppBarLayout import io.legado.app.R import io.legado.app.lib.theme.DrawableUtils -import io.legado.app.lib.theme.ThemeStore -import io.legado.app.lib.theme.getPrimaryTextColor +import io.legado.app.lib.theme.primaryColor +import io.legado.app.lib.theme.primaryTextColor import io.legado.app.utils.getNavigationBarHeight import io.legado.app.utils.getStatusBarHeight +import org.jetbrains.anko.backgroundColor import org.jetbrains.anko.bottomPadding import org.jetbrains.anko.topPadding @@ -48,7 +49,6 @@ class TitleBar(context: Context, attrs: AttributeSet?) : AppBarLayout(context, a init { inflate(context, R.layout.view_title_bar, this) - setBackgroundColor(ThemeStore.primaryColor(context)) toolbar = findViewById(R.id.toolbar) val a = context.obtainStyledAttributes( attrs, R.styleable.TitleBar, @@ -124,6 +124,8 @@ class TitleBar(context: Context, attrs: AttributeSet?) : AppBarLayout(context, a if (!subtitleText.isNullOrBlank()) { this.subtitle = subtitleText } + + backgroundColor = context.primaryColor } if (a.getBoolean(R.styleable.TitleBar_fitStatusBar, true)) { @@ -174,7 +176,7 @@ class TitleBar(context: Context, attrs: AttributeSet?) : AppBarLayout(context, a } private fun wrapAppTheme() { - val primaryTextColor = if (isInEditMode) Color.BLACK else context.getPrimaryTextColor() + val primaryTextColor = if (isInEditMode) Color.BLACK else context.primaryTextColor DrawableUtils.setTint(toolbar.overflowIcon, primaryTextColor) toolbar.setTitleTextColor(primaryTextColor) diff --git a/app/src/main/java/io/legado/app/utils/AnkoExtensions.kt b/app/src/main/java/io/legado/app/utils/AnkoExtensions.kt deleted file mode 100644 index 44bdf4f15..000000000 --- a/app/src/main/java/io/legado/app/utils/AnkoExtensions.kt +++ /dev/null @@ -1,63 +0,0 @@ -package io.legado.app.utils - -import android.content.res.ColorStateList -import android.graphics.drawable.Drawable -import android.view.View -import androidx.annotation.ColorRes -import androidx.annotation.DrawableRes -import androidx.annotation.StringRes -import androidx.fragment.app.Fragment -import com.google.android.material.snackbar.Snackbar -import org.jetbrains.anko.dip -import org.jetbrains.anko.longToast -import org.jetbrains.anko.toast - - -/** - * Display the Snackbar with the [Snackbar.LENGTH_SHORT] duration. - * - * @param message the message text resource. - */ -@JvmName("snackbar2") -fun View.snackbar(@StringRes message: Int) = Snackbar - .make(this, message, Snackbar.LENGTH_SHORT) - .apply { show() } - -/** - * Display Snackbar with the [Snackbar.LENGTH_LONG] duration. - * - * @param message the message text resource. - */ -@JvmName("longSnackbar2") -fun View.longSnackbar(@StringRes message: Int) = Snackbar - .make(this, message, Snackbar.LENGTH_LONG) - .apply { show() } - -/** - * Display Snackbar with the [Snackbar.LENGTH_LONG] duration. - * - * @param message the message text resource. - */ -@JvmName("longSnackbar2") -fun View.longSnackbar(@StringRes message: Int, @StringRes actionText: Int, action: (View) -> Unit) = Snackbar - .make(this, message, Snackbar.LENGTH_LONG) - .setAction(actionText, action) - .apply { show() } - -fun Fragment.toast(textResource: Int) = requireActivity().toast(textResource) - -fun Fragment.toast(text: CharSequence) = requireActivity().toast(text) - -fun Fragment.longToast(textResource: Int) = requireActivity().longToast(textResource) - -fun Fragment.longToast(text: CharSequence) = requireActivity().longToast(text) - -fun Fragment.dip(value: Int): Int = requireActivity().dip(value) - -fun Fragment.dip(value: Float): Int = requireActivity().dip(value) - -fun Fragment.getCompatColor(@ColorRes id: Int): Int = requireContext().getCompatColor(id) - -fun Fragment.getCompatDrawable(@DrawableRes id: Int): Drawable? = requireContext().getCompatDrawable(id) - -fun Fragment.getCompatColorStateList(@ColorRes id: Int): ColorStateList? = requireContext().getCompatColorStateList(id) \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/utils/ContextExtensions.kt b/app/src/main/java/io/legado/app/utils/ContextExtensions.kt index d5a4e74e3..7de826fbb 100644 --- a/app/src/main/java/io/legado/app/utils/ContextExtensions.kt +++ b/app/src/main/java/io/legado/app/utils/ContextExtensions.kt @@ -8,6 +8,7 @@ import androidx.annotation.DrawableRes import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import androidx.core.content.edit +import androidx.fragment.app.Fragment import com.jeremyliao.liveeventbus.LiveEventBus import io.legado.app.R import org.jetbrains.anko.connectivityManager @@ -64,4 +65,10 @@ fun Context.getStatusBarHeight(): Int { fun Context.getNavigationBarHeight(): Int { val resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android") return resources.getDimensionPixelSize(resourceId) -} \ No newline at end of file +} + +val Context.isNightTheme: Boolean + get() = getPrefBoolean("isNightTheme") + +val Context.isTransparentStatusBar: Boolean + get() = getPrefBoolean("transparentStatusBar") \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/utils/FragmentExtensions.kt b/app/src/main/java/io/legado/app/utils/FragmentExtensions.kt new file mode 100644 index 000000000..c81c734ad --- /dev/null +++ b/app/src/main/java/io/legado/app/utils/FragmentExtensions.kt @@ -0,0 +1,57 @@ +package io.legado.app.utils + +import android.content.res.ColorStateList +import android.graphics.drawable.Drawable +import androidx.annotation.ColorRes +import androidx.annotation.DrawableRes +import androidx.core.content.edit +import androidx.fragment.app.Fragment +import org.jetbrains.anko.connectivityManager +import org.jetbrains.anko.defaultSharedPreferences + +fun Fragment.isOnline() = requireContext().connectivityManager.activeNetworkInfo?.isConnected == true + +fun Fragment.getPrefBoolean(key: String, defValue: Boolean = false) = + requireContext().defaultSharedPreferences.getBoolean(key, defValue) + +fun Fragment.putPrefBoolean(key: String, value: Boolean = false) = + requireContext().defaultSharedPreferences.edit { putBoolean(key, value) } + +fun Fragment.getPrefInt(key: String, defValue: Int = 0) = + requireContext().defaultSharedPreferences.getInt(key, defValue) + +fun Fragment.putPrefInt(key: String, value: Int) = + requireContext().defaultSharedPreferences.edit { putInt(key, value) } + +fun Fragment.getPrefLong(key: String, defValue: Long = 0L) = + requireContext().defaultSharedPreferences.getLong(key, defValue) + +fun Fragment.putPrefLong(key: String, value: Long) = + requireContext().defaultSharedPreferences.edit { putLong(key, value) } + +fun Fragment.getPrefString(key: String, defValue: String? = null) = + requireContext().defaultSharedPreferences.getString(key, defValue) + +fun Fragment.putPrefString(key: String, value: String) = + requireContext().defaultSharedPreferences.edit { putString(key, value) } + +fun Fragment.getPrefStringSet(key: String, defValue: MutableSet? = null) = + requireContext().defaultSharedPreferences.getStringSet(key, defValue) + +fun Fragment.putPrefStringSet(key: String, value: MutableSet) = + requireContext().defaultSharedPreferences.edit { putStringSet(key, value) } + +fun Fragment.removePref(key: String) = + requireContext().defaultSharedPreferences.edit { remove(key) } + +fun Fragment.getCompatColor(@ColorRes id: Int): Int = requireContext().getCompatColor(id) + +fun Fragment.getCompatDrawable(@DrawableRes id: Int): Drawable? = requireContext().getCompatDrawable(id) + +fun Fragment.getCompatColorStateList(@ColorRes id: Int): ColorStateList? = requireContext().getCompatColorStateList(id) + +val Fragment.isNightTheme: Boolean + get() = getPrefBoolean("isNightTheme") + +val Fragment.isTransparentStatusBar: Boolean + get() = getPrefBoolean("transparentStatusBar") \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/utils/MenuExtensions.kt b/app/src/main/java/io/legado/app/utils/MenuExtensions.kt index 881d87867..8d97321af 100644 --- a/app/src/main/java/io/legado/app/utils/MenuExtensions.kt +++ b/app/src/main/java/io/legado/app/utils/MenuExtensions.kt @@ -8,12 +8,13 @@ import androidx.core.view.forEach import io.legado.app.R import io.legado.app.lib.theme.DrawableUtils import io.legado.app.lib.theme.getPrimaryTextColor +import io.legado.app.lib.theme.primaryTextColor fun Menu.setIconColor(context: Context): Menu = this.let { menu -> if (menu is MenuBuilder) { menu.setOptionalIconsVisible(true) } - val primaryTextColor = context.getPrimaryTextColor() + val primaryTextColor = context.primaryTextColor val defaultTextColor = context.getCompatColor(R.color.tv_text_default) menu.forEach { item -> (item as MenuItemImpl).let { impl -> diff --git a/app/src/main/java/io/legado/app/utils/Snackbars.kt b/app/src/main/java/io/legado/app/utils/Snackbars.kt new file mode 100644 index 000000000..f60def01f --- /dev/null +++ b/app/src/main/java/io/legado/app/utils/Snackbars.kt @@ -0,0 +1,257 @@ +package io.legado.app.utils + +import android.view.View +import androidx.annotation.StringRes +import com.google.android.material.snackbar.Snackbar + +/** + * Display the Snackbar with the [Snackbar.LENGTH_SHORT] duration. + * + * @param message the message text resource. + */ +@Deprecated("Use 'View.snackbar(Int)' instead.", ReplaceWith("view.snackbar(message)")) +inline fun snackbar(view: View, message: Int) = Snackbar + .make(view, message, Snackbar.LENGTH_SHORT) + .apply { show() } + +/** + * Display Snackbar with the [Snackbar.LENGTH_LONG] duration. + * + * @param message the message text resource. + */ +@Deprecated("Use 'View.longSnackbar(Int)' instead.", ReplaceWith("view.longSnackbar(message)")) +inline fun longSnackbar(view: View, message: Int) = Snackbar + .make(view, message, Snackbar.LENGTH_LONG) + .apply { show() } + +/** + * Display Snackbar with the [Snackbar.LENGTH_INDEFINITE] duration. + * + * @param message the message text resource. + */ +@Deprecated("Use 'View.indefiniteSnackbar(Int)' instead.", ReplaceWith("view.indefiniteSnackbar(message)")) +inline fun indefiniteSnackbar(view: View, message: Int) = Snackbar + .make(view, message, Snackbar.LENGTH_INDEFINITE) + .apply { show() } + +/** + * Display the Snackbar with the [Snackbar.LENGTH_SHORT] duration. + * + * @param message the message text. + */ +@Deprecated("Use 'View.snackbar(CharSequence)' instead.", ReplaceWith("view.snackbar(message)")) +inline fun snackbar(view: View, message: CharSequence) = Snackbar + .make(view, message, Snackbar.LENGTH_SHORT) + .apply { show() } + +/** + * Display Snackbar with the [Snackbar.LENGTH_LONG] duration. + * + * @param message the message text. + */ +@Deprecated("Use 'View.longSnackbar(CharSequence)' instead.", ReplaceWith("view.longSnackbar(message)")) +inline fun longSnackbar(view: View, message: CharSequence) = Snackbar + .make(view, message, Snackbar.LENGTH_LONG) + .apply { show() } + +/** + * Display Snackbar with the [Snackbar.LENGTH_INDEFINITE] duration. + * + * @param message the message text. + */ +@Deprecated("Use 'View.indefiniteSnackbar(CharSequence)' instead.", ReplaceWith("view.indefiniteSnackbar(message)")) +inline fun indefiniteSnackbar(view: View, message: CharSequence) = Snackbar + .make(view, message, Snackbar.LENGTH_INDEFINITE) + .apply { show() } + +/** + * Display the Snackbar with the [Snackbar.LENGTH_SHORT] duration. + * + * @param message the message text resource. + */ +@Deprecated("Use 'View.snackbar(Int, Int, (View) -> Unit)' instead.", ReplaceWith("view.snackbar(message, actionText, action)")) +inline fun snackbar(view: View, message: Int, actionText: Int, noinline action: (View) -> Unit) = Snackbar + .make(view, message, Snackbar.LENGTH_SHORT) + .setAction(actionText, action) + .apply { show() } + +/** + * Display Snackbar with the [Snackbar.LENGTH_LONG] duration. + * + * @param message the message text resource. + */ +@Deprecated("Use 'View.longSnackbar(Int, Int, (View) -> Unit)' instead.", ReplaceWith("view.longSnackbar(message, actionText, action)")) +inline fun longSnackbar(view: View, message: Int, actionText: Int, noinline action: (View) -> Unit) = Snackbar + .make(view, message, Snackbar.LENGTH_LONG) + .setAction(actionText, action) + .apply { show() } + +/** + * Display Snackbar with the [Snackbar.LENGTH_INDEFINITE] duration. + * + * @param message the message text resource. + */ +@Deprecated("Use 'View.indefiniteSnackbar(Int, Int, (View) -> Unit)' instead.", ReplaceWith("view.indefiniteSnackbar(message, actionText, action)")) +inline fun indefiniteSnackbar(view: View, message: Int, actionText: Int, noinline action: (View) -> Unit) = Snackbar + .make(view, message, Snackbar.LENGTH_INDEFINITE) + .setAction(actionText, action) + .apply { show() } + +/** + * Display the Snackbar with the [Snackbar.LENGTH_SHORT] duration. + * + * @param message the message text. + */ +@Deprecated("Use 'View.snackbar(CharSequence, CharSequence, (View) -> Unit)' instead.", ReplaceWith("view.snackbar(message, actionText, action)")) +inline fun snackbar(view: View, message: CharSequence, actionText: CharSequence, noinline action: (View) -> Unit) = Snackbar + .make(view, message, Snackbar.LENGTH_SHORT) + .setAction(actionText, action) + .apply { show() } + +/** + * Display Snackbar with the [Snackbar.LENGTH_LONG] duration. + * + * @param message the message text. + */ +@Deprecated("Use 'View.longSnackbar(CharSequence, CharSequence, (View) -> Unit)' instead.", ReplaceWith("view.longSnackbar(message, actionText, action)")) +inline fun longSnackbar(view: View, message: CharSequence, actionText: CharSequence, noinline action: (View) -> Unit) = Snackbar + .make(view, message, Snackbar.LENGTH_LONG) + .setAction(actionText, action) + .apply { show() } + +/** + * Display Snackbar with the [Snackbar.LENGTH_INDEFINITE] duration. + * + * @param message the message text. + */ +@Deprecated("Use 'View.indefiniteSnackbar(CharSequence, CharSequence, (View) -> Unit)' instead.", ReplaceWith("view.indefiniteSnackbar(message, actionText, action)")) +inline fun indefiniteSnackbar(view: View, message: CharSequence, actionText: CharSequence, noinline action: (View) -> Unit) = Snackbar + .make(view, message, Snackbar.LENGTH_INDEFINITE) + .setAction(actionText, action) + .apply { show() } + +/** + * Display the Snackbar with the [Snackbar.LENGTH_SHORT] duration. + * + * @param message the message text resource. + */ +@JvmName("snackbar2") +inline fun View.snackbar(@StringRes message: Int) = Snackbar + .make(this, message, Snackbar.LENGTH_SHORT) + .apply { show() } + +/** + * Display Snackbar with the [Snackbar.LENGTH_LONG] duration. + * + * @param message the message text resource. + */ +@JvmName("longSnackbar2") +inline fun View.longSnackbar(@StringRes message: Int) = Snackbar + .make(this, message, Snackbar.LENGTH_LONG) + .apply { show() } + +/** + * Display Snackbar with the [Snackbar.LENGTH_INDEFINITE] duration. + * + * @param message the message text resource. + */ +@JvmName("indefiniteSnackbar2") +inline fun View.indefiniteSnackbar(@StringRes message: Int) = Snackbar + .make(this, message, Snackbar.LENGTH_INDEFINITE) + .apply { show() } + +/** + * Display the Snackbar with the [Snackbar.LENGTH_SHORT] duration. + * + * @param message the message text. + */ +@JvmName("snackbar2") +inline fun View.snackbar(message: CharSequence) = Snackbar + .make(this, message, Snackbar.LENGTH_SHORT) + .apply { show() } + +/** + * Display Snackbar with the [Snackbar.LENGTH_LONG] duration. + * + * @param message the message text. + */ +@JvmName("longSnackbar2") +inline fun View.longSnackbar(message: CharSequence) = Snackbar + .make(this, message, Snackbar.LENGTH_LONG) + .apply { show() } + +/** + * Display Snackbar with the [Snackbar.LENGTH_INDEFINITE] duration. + * + * @param message the message text. + */ +@JvmName("indefiniteSnackbar2") +inline fun View.indefiniteSnackbar(message: CharSequence) = Snackbar + .make(this, message, Snackbar.LENGTH_INDEFINITE) + .apply { show() } + +/** + * Display the Snackbar with the [Snackbar.LENGTH_SHORT] duration. + * + * @param message the message text resource. + */ +@JvmName("snackbar2") +inline fun View.snackbar(message: Int, @StringRes actionText: Int, noinline action: (View) -> Unit) = Snackbar + .make(this, message, Snackbar.LENGTH_SHORT) + .setAction(actionText, action) + .apply { show() } + +/** + * Display Snackbar with the [Snackbar.LENGTH_LONG] duration. + * + * @param message the message text resource. + */ +@JvmName("longSnackbar2") +inline fun View.longSnackbar(@StringRes message: Int, @StringRes actionText: Int, noinline action: (View) -> Unit) = Snackbar + .make(this, message, Snackbar.LENGTH_LONG) + .setAction(actionText, action) + .apply { show() } + +/** + * Display Snackbar with the [Snackbar.LENGTH_INDEFINITE] duration. + * + * @param message the message text resource. + */ +@JvmName("indefiniteSnackbar2") +inline fun View.indefiniteSnackbar(@StringRes message: Int, @StringRes actionText: Int, noinline action: (View) -> Unit) = Snackbar + .make(this, message, Snackbar.LENGTH_INDEFINITE) + .setAction(actionText, action) + .apply { show() } + +/** + * Display the Snackbar with the [Snackbar.LENGTH_SHORT] duration. + * + * @param message the message text. + */ +@JvmName("snackbar2") +inline fun View.snackbar(message: CharSequence, actionText: CharSequence, noinline action: (View) -> Unit) = Snackbar + .make(this, message, Snackbar.LENGTH_SHORT) + .setAction(actionText, action) + .apply { show() } + +/** + * Display Snackbar with the [Snackbar.LENGTH_LONG] duration. + * + * @param message the message text. + */ +@JvmName("longSnackbar2") +inline fun View.longSnackbar(message: CharSequence, actionText: CharSequence, noinline action: (View) -> Unit) = Snackbar + .make(this, message, Snackbar.LENGTH_LONG) + .setAction(actionText, action) + .apply { show() } + +/** + * Display Snackbar with the [Snackbar.LENGTH_INDEFINITE] duration. + * + * @param message the message text. + */ +@JvmName("indefiniteSnackbar2") +inline fun View.indefiniteSnackbar(message: CharSequence, actionText: CharSequence, noinline action: (View) -> Unit) = Snackbar + .make(this, message, Snackbar.LENGTH_INDEFINITE) + .setAction(actionText, action) + .apply { show() } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/utils/Toasts.kt b/app/src/main/java/io/legado/app/utils/Toasts.kt new file mode 100644 index 000000000..5fea5ad08 --- /dev/null +++ b/app/src/main/java/io/legado/app/utils/Toasts.kt @@ -0,0 +1,80 @@ +package io.legado.app.utils + +import android.content.Context +import android.widget.Toast +import androidx.fragment.app.Fragment +import org.jetbrains.anko.longToast +import org.jetbrains.anko.toast + + +/** + * Display the simple Toast message with the [Toast.LENGTH_SHORT] duration. + * + * @param message the message text resource. + */ +inline fun Fragment.toast(message: Int) = requireActivity().toast(message) + +/** + * Display the simple Toast message with the [Toast.LENGTH_SHORT] duration. + * + * @param message the message text resource. + */ +inline fun Context.toast(message: Int): Toast = Toast + .makeText(this, message, Toast.LENGTH_SHORT) + .apply { + show() + } + +/** + * Display the simple Toast message with the [Toast.LENGTH_SHORT] duration. + * + * @param message the message text. + */ +inline fun Fragment.toast(message: CharSequence) = requireActivity().toast(message) + +/** + * Display the simple Toast message with the [Toast.LENGTH_SHORT] duration. + * + * @param message the message text. + */ +inline fun Context.toast(message: CharSequence): Toast = Toast + .makeText(this, message, Toast.LENGTH_SHORT) + .apply { + show() + } + +/** + * Display the simple Toast message with the [Toast.LENGTH_LONG] duration. + * + * @param message the message text resource. + */ +inline fun Fragment.longToast(message: Int) = requireActivity().longToast(message) + +/** + * Display the simple Toast message with the [Toast.LENGTH_LONG] duration. + * + * @param message the message text resource. + */ +inline fun Context.longToast(message: Int): Toast = Toast + .makeText(this, message, Toast.LENGTH_LONG) + .apply { + show() + } + +/** + * Display the simple Toast message with the [Toast.LENGTH_LONG] duration. + * + * @param message the message text. + */ +inline fun Fragment.longToast(message: CharSequence) = requireActivity().longToast(message) + +/** + * Display the simple Toast message with the [Toast.LENGTH_LONG] duration. + * + * @param message the message text. + */ +inline fun Context.longToast(message: CharSequence): Toast = Toast + .makeText(this, message, Toast.LENGTH_LONG) + .apply { + show() + } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/utils/ViewModelKt.kt b/app/src/main/java/io/legado/app/utils/ViewModelKt.kt index c2ef64e53..b777c8bbf 100644 --- a/app/src/main/java/io/legado/app/utils/ViewModelKt.kt +++ b/app/src/main/java/io/legado/app/utils/ViewModelKt.kt @@ -9,5 +9,8 @@ fun AppCompatActivity.getViewModel(clazz: Class) = ViewModelP fun Fragment.getViewModel(clazz: Class) = ViewModelProviders.of(this).get(clazz) +/** + * 与activity数据同步 + */ fun Fragment.getViewModelOfActivity(clazz: Class) = ViewModelProviders.of(requireActivity()).get(clazz) \ No newline at end of file