pull/32/head
Administrator 5 years ago
parent 3328980791
commit 27133a11c8
  1. 34
      app/src/main/java/io/legado/app/App.kt
  2. 6
      app/src/main/java/io/legado/app/base/BaseActivity.kt
  3. 38
      app/src/main/java/io/legado/app/lib/theme/ATH.kt
  4. 80
      app/src/main/java/io/legado/app/lib/theme/MaterialValueHelper.kt
  5. 3
      app/src/main/java/io/legado/app/ui/bookshelf/BookshelfAdapter.kt
  6. 30
      app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt
  7. 7
      app/src/main/java/io/legado/app/ui/main/MainActivity.kt
  8. 11
      app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt
  9. 1
      app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt
  10. 3
      app/src/main/java/io/legado/app/ui/sourcedebug/SourceDebugActivity.kt
  11. 3
      app/src/main/java/io/legado/app/ui/welcome/WelcomeActivity.kt
  12. 10
      app/src/main/java/io/legado/app/ui/widget/TitleBar.kt
  13. 63
      app/src/main/java/io/legado/app/utils/AnkoExtensions.kt
  14. 9
      app/src/main/java/io/legado/app/utils/ContextExtensions.kt
  15. 57
      app/src/main/java/io/legado/app/utils/FragmentExtensions.kt
  16. 3
      app/src/main/java/io/legado/app/utils/MenuExtensions.kt
  17. 257
      app/src/main/java/io/legado/app/utils/Snackbars.kt
  18. 80
      app/src/main/java/io/legado/app/utils/Toasts.kt
  19. 3
      app/src/main/java/io/legado/app/utils/ViewModelKt.kt

@ -14,8 +14,8 @@ import io.legado.app.constant.AppConst.channelIdWeb
import io.legado.app.data.AppDatabase import io.legado.app.data.AppDatabase
import io.legado.app.lib.theme.ThemeStore import io.legado.app.lib.theme.ThemeStore
import io.legado.app.utils.getCompatColor import io.legado.app.utils.getCompatColor
import io.legado.app.utils.getPrefBoolean
import io.legado.app.utils.getPrefInt import io.legado.app.utils.getPrefInt
import io.legado.app.utils.isNightTheme
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
class App : Application() { class App : Application() {
@ -36,14 +36,18 @@ class App : Application() {
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
INSTANCE = this INSTANCE = this
db = AppDatabase.createDatabase(INSTANCE) db = AppDatabase.createDatabase(INSTANCE)
packageManager.getPackageInfo(packageName, 0)?.let { packageManager.getPackageInfo(packageName, 0)?.let {
versionCode = it.versionCode versionCode = it.versionCode
versionName = it.versionName versionName = it.versionName
} }
if (!ThemeStore.isConfigured(this, versionCode)) upThemeStore()
if (!ThemeStore.isConfigured(this, versionCode)) applyTheme()
initNightTheme() initNightTheme()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) createChannelId() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) createChannelId()
LiveEventBus.get() LiveEventBus.get()
.config() .config()
.supportBroadcast(this) .supportBroadcast(this)
@ -51,20 +55,11 @@ class App : Application() {
.autoClear(false) .autoClear(false)
} }
fun initNightTheme() {
val targetMode = if (getPrefBoolean("isNightTheme")) {
AppCompatDelegate.MODE_NIGHT_YES
} else {
AppCompatDelegate.MODE_NIGHT_NO
}
AppCompatDelegate.setDefaultNightMode(targetMode)
}
/** /**
* 更新主题 * 更新主题
*/ */
fun upThemeStore() { fun applyTheme() {
if (getPrefBoolean("isNightTheme")) { if (isNightTheme) {
ThemeStore.editTheme(this) ThemeStore.editTheme(this)
.primaryColor(getPrefInt("colorPrimaryNight", getCompatColor(R.color.colorPrimary))) .primaryColor(getPrefInt("colorPrimaryNight", getCompatColor(R.color.colorPrimary)))
.accentColor(getPrefInt("colorAccentNight", getCompatColor(R.color.colorAccent))) .accentColor(getPrefInt("colorAccentNight", getCompatColor(R.color.colorAccent)))
@ -80,10 +75,21 @@ class App : Application() {
} }
fun applyDayNight() { fun applyDayNight() {
upThemeStore() applyTheme()
initNightTheme() initNightTheme()
} }
private fun initNightTheme() {
val targetMode = if (isNightTheme) {
AppCompatDelegate.MODE_NIGHT_YES
} else {
AppCompatDelegate.MODE_NIGHT_NO
}
AppCompatDelegate.setDefaultNightMode(targetMode)
}
/** /**
* 创建通知ID * 创建通知ID
*/ */

@ -8,8 +8,10 @@ import android.view.View
import android.view.WindowManager import android.view.WindowManager
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import io.legado.app.R 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.ColorUtils
import io.legado.app.lib.theme.ThemeStore import io.legado.app.lib.theme.ThemeStore
import io.legado.app.lib.theme.primaryColor
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.MainScope import kotlinx.coroutines.MainScope
@ -64,8 +66,8 @@ abstract class BaseActivity(private val layoutID: Int, private val fullScreen: B
} }
private fun initTheme() { private fun initTheme() {
window.decorView.setBackgroundColor(ThemeStore.backgroundColor(this)) ATH.applyBackgroundTint(window.decorView)
if (ColorUtils.isColorLight(ThemeStore.primaryColor(this))) { if (ColorUtils.isColorLight(primaryColor)) {
setTheme(R.style.AppTheme_Light) setTheme(R.style.AppTheme_Light)
} else { } else {
setTheme(R.style.AppTheme_Dark) setTheme(R.style.AppTheme_Dark)

@ -13,7 +13,12 @@ import androidx.annotation.ColorInt
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager.widget.ViewPager 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) { fun setStatusbarColorAuto(activity: Activity) {
setStatusbarColor( setStatusbarColor(
activity, 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?) { fun applyEdgeEffectColor(view: View?) {
when (view) { when (view) {
is RecyclerView -> view.edgeEffectFactory = DEFAULT_EFFECT_FACTORY is RecyclerView -> view.edgeEffectFactory = DEFAULT_EFFECT_FACTORY

@ -75,52 +75,56 @@ fun Fragment.getSecondaryDisabledTextColor(dark: Boolean): Int {
} else ContextCompat.getColor(requireContext(), R.color.secondary_text_disabled_material_dark) } else ContextCompat.getColor(requireContext(), R.color.secondary_text_disabled_material_dark)
} }
val Context.primaryColor: Int
get() = ThemeStore.primaryColor(this)
@ColorInt val Context.primaryColorDark: Int
fun Context.getPrimaryTextColor(): Int { get() = ThemeStore.primaryColorDark(this)
return getPrimaryTextColor(isDarkTheme())
}
@ColorInt val Context.accentColor: Int
fun Context.getSecondaryTextColor(): Int { get() = ThemeStore.accentColor(this)
return getSecondaryTextColor(isDarkTheme())
}
@ColorInt val Context.backgroundColor: Int
fun Context.getPrimaryDisabledTextColor(): Int { get() = ThemeStore.backgroundColor(this)
return getPrimaryDisabledTextColor(isDarkTheme())
}
@ColorInt val Context.primaryTextColor: Int
fun Context.getSecondaryDisabledTextColor(): Int { get() = getPrimaryTextColor(isDarkTheme)
return getSecondaryDisabledTextColor(isDarkTheme())
}
val Context.secondaryTextColor: Int
get() = getSecondaryTextColor(isDarkTheme)
@ColorInt val Context.primaryDisabledTextColor: Int
fun Fragment.getPrimaryTextColor(): Int { get() = getPrimaryDisabledTextColor(isDarkTheme)
return getPrimaryTextColor(isDarkTheme())
}
@ColorInt val Context.secondaryDisabledTextColor: Int
fun Fragment.getSecondaryTextColor(): Int { get() = getSecondaryDisabledTextColor(isDarkTheme)
return getSecondaryTextColor(isDarkTheme())
}
@ColorInt val Fragment.primaryColor: Int
fun Fragment.getPrimaryDisabledTextColor(): Int { get() = ThemeStore.primaryColor(requireContext())
return getPrimaryDisabledTextColor(isDarkTheme())
}
@ColorInt val Fragment.primaryColorDark: Int
fun Fragment.getSecondaryDisabledTextColor(): Int { get() = ThemeStore.primaryColorDark(requireContext())
return getSecondaryDisabledTextColor(isDarkTheme())
}
fun Context.isDarkTheme(): Boolean { val Fragment.accentColor: Int
return ColorUtils.isColorLight(ThemeStore.primaryColor(this)) 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 { val Fragment.isDarkTheme: Boolean
return requireContext().isDarkTheme() get() = requireContext().isDarkTheme
}

@ -9,6 +9,7 @@ import androidx.recyclerview.widget.RecyclerView
import io.legado.app.R import io.legado.app.R
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.help.ImageLoader import io.legado.app.help.ImageLoader
import io.legado.app.lib.theme.ATH
import io.legado.app.lib.theme.ThemeStore import io.legado.app.lib.theme.ThemeStore
import kotlinx.android.synthetic.main.item_bookshelf_list.view.* import kotlinx.android.synthetic.main.item_bookshelf_list.view.*
import kotlinx.android.synthetic.main.item_relace_rule.view.tv_name import kotlinx.android.synthetic.main.item_relace_rule.view.tv_name
@ -49,7 +50,7 @@ class BookshelfAdapter : PagedListAdapter<Book, BookshelfAdapter.MyViewHolder>(D
class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) { class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
init { init {
itemView.setBackgroundColor(ThemeStore.backgroundColor(itemView.context)) ATH.applyBackgroundTint(itemView)
} }
fun bind(book: Book, callBack: CallBack?) = with(itemView) { fun bind(book: Book, callBack: CallBack?) = with(itemView) {

@ -49,9 +49,9 @@ class ThemeConfigFragment : PreferenceFragmentCompat(), SharedPreferences.OnShar
.setTitle("白天背景太暗") .setTitle("白天背景太暗")
.setMessage("将会恢复默认背景?") .setMessage("将会恢复默认背景?")
.setPositiveButton(R.string.ok) { _, _ -> .setPositiveButton(R.string.ok) { _, _ ->
App.INSTANCE.putPrefInt( putPrefInt(
"colorBackground", "colorBackground",
App.INSTANCE.getCompatColor(R.color.md_grey_100) getCompatColor(R.color.md_grey_100)
) )
upTheme(false) upTheme(false)
} }
@ -69,9 +69,9 @@ class ThemeConfigFragment : PreferenceFragmentCompat(), SharedPreferences.OnShar
.setTitle("夜间背景太亮") .setTitle("夜间背景太亮")
.setMessage("将会恢复默认背景?") .setMessage("将会恢复默认背景?")
.setPositiveButton(R.string.ok) { _, _ -> .setPositiveButton(R.string.ok) { _, _ ->
App.INSTANCE.putPrefInt( putPrefInt(
"colorBackgroundNight", "colorBackgroundNight",
App.INSTANCE.getCompatColor(R.color.md_grey_800) getCompatColor(R.color.md_grey_800)
) )
upTheme(true) upTheme(true)
} }
@ -95,14 +95,14 @@ class ThemeConfigFragment : PreferenceFragmentCompat(), SharedPreferences.OnShar
.setMessage("是否确认恢复?") .setMessage("是否确认恢复?")
.setPositiveButton(R.string.ok) { _, _ -> .setPositiveButton(R.string.ok) { _, _ ->
preferenceManager.sharedPreferences.edit() preferenceManager.sharedPreferences.edit()
.putInt("colorPrimary", App.INSTANCE.getCompatColor(R.color.colorPrimary)) .putInt("colorPrimary", getCompatColor(R.color.colorPrimary))
.putInt("colorAccent", App.INSTANCE.getCompatColor(R.color.colorAccent)) .putInt("colorAccent", getCompatColor(R.color.colorAccent))
.putInt("colorBackground", App.INSTANCE.getCompatColor(R.color.md_grey_100)) .putInt("colorBackground", getCompatColor(R.color.md_grey_100))
.putInt("colorPrimaryNight", App.INSTANCE.getCompatColor(R.color.colorPrimary)) .putInt("colorPrimaryNight", getCompatColor(R.color.colorPrimary))
.putInt("colorAccentNight", App.INSTANCE.getCompatColor(R.color.colorAccent)) .putInt("colorAccentNight", getCompatColor(R.color.colorAccent))
.putInt("colorBackgroundNight", App.INSTANCE.getCompatColor(R.color.md_grey_800)) .putInt("colorBackgroundNight", getCompatColor(R.color.md_grey_800))
.apply() .apply()
App.INSTANCE.upThemeStore() App.INSTANCE.applyTheme()
recreateActivities() recreateActivities()
} }
.setNegativeButton(R.string.cancel, null) .setNegativeButton(R.string.cancel, null)
@ -117,7 +117,7 @@ class ThemeConfigFragment : PreferenceFragmentCompat(), SharedPreferences.OnShar
return !ColorUtils.isColorLight( return !ColorUtils.isColorLight(
sharedPreferences.getInt( sharedPreferences.getInt(
"colorBackground", "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( return ColorUtils.isColorLight(
sharedPreferences.getInt( sharedPreferences.getInt(
"colorBackgroundNight", "colorBackgroundNight",
App.INSTANCE.getCompatColor(R.color.md_grey_800) getCompatColor(R.color.md_grey_800)
) )
) )
} }
private fun upTheme(isNightTheme: Boolean) { private fun upTheme(isNightTheme: Boolean) {
if (App.INSTANCE.getPrefBoolean("isNightTheme") == isNightTheme) { if (this.isNightTheme == isNightTheme) {
App.INSTANCE.upThemeStore() App.INSTANCE.applyTheme()
recreateActivities() recreateActivities()
} }
} }

@ -35,12 +35,7 @@ class MainActivity : VMBaseActivity<MainViewModel>(R.layout.activity_main),
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
ATH.applyEdgeEffectColor(view_pager_main) ATH.applyEdgeEffectColor(view_pager_main)
bottom_navigation_view.setBackgroundColor(ThemeStore.backgroundColor(this)) ATH.applyBottomNavigationColor(bottom_navigation_view)
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
view_pager_main.offscreenPageLimit = 3 view_pager_main.offscreenPageLimit = 3
view_pager_main.adapter = TabFragmentPageAdapter(supportFragmentManager) view_pager_main.adapter = TabFragmentPageAdapter(supportFragmentManager)
view_pager_main.addOnPageChangeListener(this) view_pager_main.addOnPageChangeListener(this)

@ -1,6 +1,7 @@
package io.legado.app.ui.main.bookshelf package io.legado.app.ui.main.bookshelf
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.Menu import android.view.Menu
import android.view.View import android.view.View
import android.widget.EditText 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.dialogs.yesButton
import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ATH
import io.legado.app.lib.theme.ThemeStore 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.bookshelf.BookshelfActivity
import io.legado.app.ui.search.SearchActivity import io.legado.app.ui.search.SearchActivity
import io.legado.app.utils.applyTint import io.legado.app.utils.applyTint
import io.legado.app.utils.getViewModel import io.legado.app.utils.getViewModel
import io.legado.app.utils.requestInputMethod 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.dialog_edittext.view.*
import kotlinx.android.synthetic.main.fragment_bookshelf.* import kotlinx.android.synthetic.main.fragment_bookshelf.*
import kotlinx.android.synthetic.main.view_title_bar.* import kotlinx.android.synthetic.main.view_title_bar.*
@ -58,7 +61,7 @@ class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_b
} }
private fun initSearchView() { private fun initSearchView() {
search_view.visibility = View.VISIBLE search_view.visible()
search_view.onActionViewExpanded() search_view.onActionViewExpanded()
search_view.isSubmitButtonEnabled = true search_view.isSubmitButtonEnabled = true
search_view.queryHint = getString(R.string.search_book_key) search_view.queryHint = getString(R.string.search_book_key)
@ -68,11 +71,11 @@ class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_b
private fun initRecyclerView() { private fun initRecyclerView() {
ATH.applyEdgeEffectColor(rv_bookshelf) ATH.applyEdgeEffectColor(rv_bookshelf)
refresh_layout.setColorSchemeColors(ThemeStore.accentColor(refresh_layout.context)) refresh_layout.setColorSchemeColors(accentColor)
refresh_layout.setOnRefreshListener { refresh_layout.setOnRefreshListener {
refresh_layout.isRefreshing = false 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) rv_book_group.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
bookGroupAdapter = BookGroupAdapter() bookGroupAdapter = BookGroupAdapter()
rv_book_group.adapter = bookGroupAdapter rv_book_group.adapter = bookGroupAdapter
@ -118,7 +121,7 @@ class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_b
customView { customView {
layoutInflater.inflate(R.layout.dialog_edittext, null).apply { layoutInflater.inflate(R.layout.dialog_edittext, null).apply {
editText = edit_view.apply { editText = edit_view.apply {
ATH.setTint(this, ThemeStore.accentColor(ctx)) ATH.applyTint(this)
hint = "分组名称" hint = "分组名称"
} }
} }

@ -7,7 +7,6 @@ import io.legado.app.data.entities.BookGroup
class BookshelfViewModel(application: Application) : BaseViewModel(application) { class BookshelfViewModel(application: Application) : BaseViewModel(application) {
fun saveBookGroup(group: String?) { fun saveBookGroup(group: String?) {
if (!group.isNullOrBlank()) { if (!group.isNullOrBlank()) {
execute { execute {

@ -10,6 +10,7 @@ import io.legado.app.constant.Bus
import io.legado.app.help.EventMessage import io.legado.app.help.EventMessage
import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ATH
import io.legado.app.lib.theme.ThemeStore 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.getViewModel
import io.legado.app.utils.observeEvent import io.legado.app.utils.observeEvent
import kotlinx.android.synthetic.main.activity_source_debug.* import kotlinx.android.synthetic.main.activity_source_debug.*
@ -34,7 +35,7 @@ class SourceDebugActivity : VMBaseActivity<SourceDebugModel>(R.layout.activity_s
adapter = SourceDebugAdapter(this) adapter = SourceDebugAdapter(this)
recycler_view.layoutManager = LinearLayoutManager(this) recycler_view.layoutManager = LinearLayoutManager(this)
recycler_view.adapter = adapter recycler_view.adapter = adapter
rotate_loading.loadingColor = ThemeStore.accentColor(this) rotate_loading.loadingColor = accentColor
} }
private fun initSearchView() { private fun initSearchView() {

@ -6,6 +6,7 @@ import android.os.Bundle
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseActivity import io.legado.app.base.BaseActivity
import io.legado.app.lib.theme.ThemeStore import io.legado.app.lib.theme.ThemeStore
import io.legado.app.lib.theme.accentColor
import io.legado.app.ui.main.MainActivity import io.legado.app.ui.main.MainActivity
import kotlinx.android.synthetic.main.activity_welcome.* import kotlinx.android.synthetic.main.activity_welcome.*
import org.jetbrains.anko.startActivity import org.jetbrains.anko.startActivity
@ -13,7 +14,7 @@ import org.jetbrains.anko.startActivity
class WelcomeActivity : BaseActivity(R.layout.activity_welcome) { class WelcomeActivity : BaseActivity(R.layout.activity_welcome) {
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
iv_bg.setColorFilter(ThemeStore.accentColor(this)) iv_bg.setColorFilter(accentColor)
val welAnimator = ValueAnimator.ofFloat(1f, 0f).setDuration(800) val welAnimator = ValueAnimator.ofFloat(1f, 0f).setDuration(800)
welAnimator.startDelay = 100 welAnimator.startDelay = 100
welAnimator.addUpdateListener { animation -> welAnimator.addUpdateListener { animation ->

@ -16,10 +16,11 @@ import androidx.core.graphics.drawable.DrawableCompat
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import io.legado.app.R import io.legado.app.R
import io.legado.app.lib.theme.DrawableUtils import io.legado.app.lib.theme.DrawableUtils
import io.legado.app.lib.theme.ThemeStore import io.legado.app.lib.theme.primaryColor
import io.legado.app.lib.theme.getPrimaryTextColor import io.legado.app.lib.theme.primaryTextColor
import io.legado.app.utils.getNavigationBarHeight import io.legado.app.utils.getNavigationBarHeight
import io.legado.app.utils.getStatusBarHeight import io.legado.app.utils.getStatusBarHeight
import org.jetbrains.anko.backgroundColor
import org.jetbrains.anko.bottomPadding import org.jetbrains.anko.bottomPadding
import org.jetbrains.anko.topPadding import org.jetbrains.anko.topPadding
@ -48,7 +49,6 @@ class TitleBar(context: Context, attrs: AttributeSet?) : AppBarLayout(context, a
init { init {
inflate(context, R.layout.view_title_bar, this) inflate(context, R.layout.view_title_bar, this)
setBackgroundColor(ThemeStore.primaryColor(context))
toolbar = findViewById(R.id.toolbar) toolbar = findViewById(R.id.toolbar)
val a = context.obtainStyledAttributes( val a = context.obtainStyledAttributes(
attrs, R.styleable.TitleBar, attrs, R.styleable.TitleBar,
@ -124,6 +124,8 @@ class TitleBar(context: Context, attrs: AttributeSet?) : AppBarLayout(context, a
if (!subtitleText.isNullOrBlank()) { if (!subtitleText.isNullOrBlank()) {
this.subtitle = subtitleText this.subtitle = subtitleText
} }
backgroundColor = context.primaryColor
} }
if (a.getBoolean(R.styleable.TitleBar_fitStatusBar, true)) { if (a.getBoolean(R.styleable.TitleBar_fitStatusBar, true)) {
@ -174,7 +176,7 @@ class TitleBar(context: Context, attrs: AttributeSet?) : AppBarLayout(context, a
} }
private fun wrapAppTheme() { 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) DrawableUtils.setTint(toolbar.overflowIcon, primaryTextColor)
toolbar.setTitleTextColor(primaryTextColor) toolbar.setTitleTextColor(primaryTextColor)

@ -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)

@ -8,6 +8,7 @@ import androidx.annotation.DrawableRes
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.content.edit import androidx.core.content.edit
import androidx.fragment.app.Fragment
import com.jeremyliao.liveeventbus.LiveEventBus import com.jeremyliao.liveeventbus.LiveEventBus
import io.legado.app.R import io.legado.app.R
import org.jetbrains.anko.connectivityManager import org.jetbrains.anko.connectivityManager
@ -64,4 +65,10 @@ fun Context.getStatusBarHeight(): Int {
fun Context.getNavigationBarHeight(): Int { fun Context.getNavigationBarHeight(): Int {
val resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android") val resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android")
return resources.getDimensionPixelSize(resourceId) return resources.getDimensionPixelSize(resourceId)
} }
val Context.isNightTheme: Boolean
get() = getPrefBoolean("isNightTheme")
val Context.isTransparentStatusBar: Boolean
get() = getPrefBoolean("transparentStatusBar")

@ -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<String>? = null) =
requireContext().defaultSharedPreferences.getStringSet(key, defValue)
fun Fragment.putPrefStringSet(key: String, value: MutableSet<String>) =
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")

@ -8,12 +8,13 @@ import androidx.core.view.forEach
import io.legado.app.R import io.legado.app.R
import io.legado.app.lib.theme.DrawableUtils import io.legado.app.lib.theme.DrawableUtils
import io.legado.app.lib.theme.getPrimaryTextColor import io.legado.app.lib.theme.getPrimaryTextColor
import io.legado.app.lib.theme.primaryTextColor
fun Menu.setIconColor(context: Context): Menu = this.let { menu -> fun Menu.setIconColor(context: Context): Menu = this.let { menu ->
if (menu is MenuBuilder) { if (menu is MenuBuilder) {
menu.setOptionalIconsVisible(true) menu.setOptionalIconsVisible(true)
} }
val primaryTextColor = context.getPrimaryTextColor() val primaryTextColor = context.primaryTextColor
val defaultTextColor = context.getCompatColor(R.color.tv_text_default) val defaultTextColor = context.getCompatColor(R.color.tv_text_default)
menu.forEach { item -> menu.forEach { item ->
(item as MenuItemImpl).let { impl -> (item as MenuItemImpl).let { impl ->

@ -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() }

@ -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()
}

@ -9,5 +9,8 @@ fun <T : ViewModel> AppCompatActivity.getViewModel(clazz: Class<T>) = ViewModelP
fun <T : ViewModel> Fragment.getViewModel(clazz: Class<T>) = ViewModelProviders.of(this).get(clazz) fun <T : ViewModel> Fragment.getViewModel(clazz: Class<T>) = ViewModelProviders.of(this).get(clazz)
/**
* 与activity数据同步
*/
fun <T : ViewModel> Fragment.getViewModelOfActivity(clazz: Class<T>) = fun <T : ViewModel> Fragment.getViewModelOfActivity(clazz: Class<T>) =
ViewModelProviders.of(requireActivity()).get(clazz) ViewModelProviders.of(requireActivity()).get(clazz)
Loading…
Cancel
Save