Legit Material3 Theming 1/5 (style/colors.xml)

Chnage Source code Icon (Touches #127)
Some code cleanups
etc... (Sry I forgot what all I did)
This commit is contained in:
LooKeR
2021-12-03 00:37:13 +05:30
parent 74d3ec194c
commit 848c5ce863
24 changed files with 393 additions and 319 deletions

View File

@ -74,7 +74,7 @@ class InstallerService : Service() {
.setAutoCancel(true)
.setColor(
ContextThemeWrapper(this, R.style.Theme_Main_Light)
.getColorFromAttr(android.R.attr.colorAccent).defaultColor
.getColorFromAttr(R.attr.colorPrimary).defaultColor
)
when (status) {

View File

@ -93,7 +93,8 @@ class EditRepositoryFragment() : ScreenFragment() {
syncConnection.bind(requireContext())
screenActivity.onToolbarCreated(toolbar)
toolbar.setTitle(if (repositoryId != null) R.string.edit_repository else R.string.add_repository)
collapsingToolbar.title =
getString(if (repositoryId != null) R.string.edit_repository else R.string.add_repository)
saveMenuItem = toolbar.menu.add(R.string.save)
.setIcon(Utils.getToolbarIcon(toolbar.context, R.drawable.ic_save))
@ -179,7 +180,7 @@ class EditRepositoryFragment() : ScreenFragment() {
} catch (e: Exception) {
Pair(null, null)
}
layout.address.setText(addressText?.nullIfEmpty() ?: layout.address.hint)
layout.address.setText(addressText)
layout.fingerprint.setText(fingerprintText)
} else {
layout.address.setText(repository.address)

View File

@ -3,10 +3,15 @@ package com.looker.droidify.screen
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.switchmaterial.SwitchMaterial
import coil.load
import com.google.android.material.card.MaterialCardView
import com.google.android.material.imageview.ShapeableImageView
import com.google.android.material.textview.MaterialTextView
import com.looker.droidify.R
import com.looker.droidify.database.Database
import com.looker.droidify.entity.Repository
import com.looker.droidify.utility.extension.resources.clear
import com.looker.droidify.utility.extension.resources.getColorFromAttr
import com.looker.droidify.utility.extension.resources.inflate
import com.looker.droidify.widget.CursorRecyclerAdapter
@ -18,9 +23,12 @@ class RepositoriesAdapter(
enum class ViewType { REPOSITORY }
private class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val switch = itemView.findViewById<SwitchMaterial>(R.id.repository_switch)!!
val item = itemView.findViewById<MaterialCardView>(R.id.repository_item)!!
val checkMark = itemView.findViewById<ShapeableImageView>(R.id.repository_state)!!
val repoName = itemView.findViewById<MaterialTextView>(R.id.repository_name)!!
val repoDesc = itemView.findViewById<MaterialTextView>(R.id.repository_description)!!
var listenSwitch = true
var isEnabled = true
}
override val viewTypeClass: Class<ViewType>
@ -39,15 +47,13 @@ class RepositoriesAdapter(
viewType: ViewType,
): RecyclerView.ViewHolder {
return ViewHolder(parent.inflate(R.layout.repository_item)).apply {
itemView.setOnClickListener { onClick(getRepository(adapterPosition)) }
switch.setOnCheckedChangeListener { _, isChecked ->
if (listenSwitch) {
if (!onSwitch(getRepository(adapterPosition), isChecked)) {
listenSwitch = false
switch.isChecked = !isChecked
listenSwitch = true
}
}
itemView.setOnLongClickListener {
onClick(getRepository(adapterPosition))
true
}
itemView.setOnClickListener {
isEnabled = !isEnabled
onSwitch(getRepository(adapterPosition), isEnabled)
}
}
}
@ -55,10 +61,26 @@ class RepositoriesAdapter(
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
holder as ViewHolder
val repository = getRepository(position)
val lastListenSwitch = holder.listenSwitch
holder.listenSwitch = false
holder.switch.isChecked = repository.enabled
holder.listenSwitch = lastListenSwitch
holder.switch.text = repository.name
holder.repoName.text = repository.name
holder.repoDesc.text = repository.description.trim()
if (repository.enabled) {
holder.isEnabled = true
holder.item.setCardBackgroundColor(
holder.item.context.getColorFromAttr(R.attr.colorPrimaryContainer)
)
holder.repoName.setTextColor(holder.repoName.context.getColorFromAttr(R.attr.colorOnPrimaryContainer))
holder.repoDesc.setTextColor(holder.repoDesc.context.getColorFromAttr(R.attr.colorOnPrimaryContainer))
holder.checkMark.load(R.drawable.ic_check)
holder.checkMark.imageTintList =
holder.checkMark.context.getColorFromAttr(R.attr.colorOnPrimaryContainer)
} else {
holder.isEnabled = false
holder.item.setCardBackgroundColor(holder.item.context.getColorFromAttr(android.R.attr.colorBackground))
holder.repoName.setTextColor(holder.repoName.context.getColorFromAttr(R.attr.colorOnBackground))
holder.repoDesc.setTextColor(holder.repoDesc.context.getColorFromAttr(R.attr.colorOnBackground))
holder.checkMark.clear()
holder.checkMark.imageTintList =
holder.checkMark.context.getColorFromAttr(R.attr.colorOnBackground)
}
}
}

View File

@ -13,6 +13,7 @@ import com.looker.droidify.database.CursorOwner
import com.looker.droidify.service.Connection
import com.looker.droidify.service.SyncService
import com.looker.droidify.utility.Utils
import com.looker.droidify.widget.RecyclerFastScroller
class RepositoriesFragment : ScreenFragment(), CursorOwner.Callback {
private var recyclerView: RecyclerView? = null
@ -37,9 +38,11 @@ class RepositoriesFragment : ScreenFragment(), CursorOwner.Callback {
syncConnection.binder?.setEnabled(repository, isEnabled) == true
})
recyclerView = this
RecyclerFastScroller(this)
})
}
this.toolbar = fragmentBinding.toolbar
this.collapsingToolbar = fragmentBinding.collapsingToolbar
return view
}
@ -49,18 +52,15 @@ class RepositoriesFragment : ScreenFragment(), CursorOwner.Callback {
syncConnection.bind(requireContext())
screenActivity.cursorOwner.attach(this, CursorOwner.Request.Repositories)
toolbar.apply {
screenActivity.onToolbarCreated(this)
setTitle(R.string.repositories)
menu.add(R.string.add_repository)
.setIcon(Utils.getToolbarIcon(this.context, R.drawable.ic_add))
.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS)
.setOnMenuItemClickListener {
view.post { screenActivity.navigateAddRepository() }
true
}
}
screenActivity.onToolbarCreated(toolbar)
toolbar.menu.add(R.string.add_repository)
.setIcon(Utils.getToolbarIcon(toolbar.context, R.drawable.ic_add))
.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS)
.setOnMenuItemClickListener {
view.post { screenActivity.navigateAddRepository() }
true
}
collapsingToolbar.title = getString(R.string.repositories)
}
override fun onDestroyView() {

View File

@ -19,7 +19,6 @@ import com.looker.droidify.service.SyncService
import com.looker.droidify.utility.Utils
import com.looker.droidify.utility.extension.resources.getColorFromAttr
import com.looker.droidify.utility.extension.resources.sizeScaled
import io.reactivex.rxjava3.disposables.Disposable
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.util.*
@ -44,7 +43,6 @@ class RepositoryFragment() : ScreenFragment() {
private var layout: LinearLayoutCompat? = null
private val syncConnection = Connection(SyncService::class.java)
private var repositoryDisposable: Disposable? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@ -54,7 +52,7 @@ class RepositoryFragment() : ScreenFragment() {
lifecycleScope.launch(Dispatchers.Main) { updateRepositoryView() }
screenActivity.onToolbarCreated(toolbar)
toolbar.setTitle(R.string.repository)
collapsingToolbar.title = getString(R.string.repository)
toolbar.menu.apply {
add(R.string.edit_repository)
@ -98,8 +96,6 @@ class RepositoryFragment() : ScreenFragment() {
layout = null
titleBinding = null
syncConnection.unbind(requireContext())
repositoryDisposable?.dispose()
repositoryDisposable = null
}
private fun updateRepositoryView() {
@ -111,7 +107,7 @@ class RepositoryFragment() : ScreenFragment() {
} else {
layout.addTitleText(R.string.address, repository.address)
if (repository.updated > 0L) {
toolbar.title = repository.name
collapsingToolbar.title = repository.name
layout.addTitleText(R.string.name, repository.name)
layout.addTitleText(R.string.description, repository.description.replace('\n', ' '))
layout.addTitleText(R.string.recently_updated, run {

View File

@ -14,6 +14,7 @@ import com.looker.droidify.R
import com.looker.droidify.content.Preferences
import com.looker.droidify.database.CursorOwner
import com.looker.droidify.installer.AppInstaller
import com.looker.droidify.ui.appDetail.AppDetailFragment
import com.looker.droidify.utility.KParcelable
import com.looker.droidify.utility.extension.resources.getDrawableFromAttr
import com.looker.droidify.utility.extension.text.nullIfEmpty
@ -235,7 +236,7 @@ abstract class ScreenActivity : AppCompatActivity() {
val packageName = intent.packageName
if (!packageName.isNullOrEmpty()) {
val fragment = currentFragment
if (fragment !is ProductFragment || fragment.packageName != packageName) {
if (fragment !is AppDetailFragment || fragment.packageName != packageName) {
navigateProduct(packageName)
}
}
@ -243,7 +244,7 @@ abstract class ScreenActivity : AppCompatActivity() {
}
}
internal fun navigateProduct(packageName: String) = pushFragment(ProductFragment(packageName))
internal fun navigateProduct(packageName: String) = pushFragment(AppDetailFragment(packageName))
internal fun navigateRepositories() = pushFragment(RepositoriesFragment())
internal fun navigatePreferences() = pushFragment(SettingsFragment())
internal fun navigateAddRepository() = pushFragment(EditRepositoryFragment(null))

View File

@ -4,18 +4,16 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.Toolbar
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.appbar.CollapsingToolbarLayout
import com.google.android.material.appbar.MaterialToolbar
import com.looker.droidify.databinding.FragmentBinding
open class ScreenFragment : BaseFragment() {
private var _fragmentBinding: FragmentBinding? = null
val fragmentBinding get() = _fragmentBinding!!
lateinit var toolbar: Toolbar
lateinit var toolbar: MaterialToolbar
lateinit var collapsingToolbar: CollapsingToolbarLayout
lateinit var appBar: AppBarLayout
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -29,7 +27,6 @@ open class ScreenFragment : BaseFragment() {
): View? {
this.toolbar = fragmentBinding.toolbar
this.collapsingToolbar = fragmentBinding.collapsingToolbar
this.appBar = fragmentBinding.appbarLayout
return fragmentBinding.root
}

View File

@ -48,7 +48,6 @@ class ScreenshotsAdapter(private val onClick: (Product.Screenshot) -> Unit) :
.setAllCornerSizes(radius)
.build()
image.shapeAppearanceModel = shapeAppearanceModel
image.setBackgroundColor(surfaceColor)
itemView.addView(image)
itemView.layoutParams = RecyclerView.LayoutParams(
RecyclerView.LayoutParams.WRAP_CONTENT,

View File

@ -45,7 +45,7 @@ class SettingsFragment : ScreenFragment() {
super.onViewCreated(view, savedInstanceState)
preferenceBinding = PreferenceItemBinding.inflate(layoutInflater)
screenActivity.onToolbarCreated(toolbar)
toolbar.setTitle(R.string.settings)
collapsingToolbar.title = getString(R.string.settings)
val content = fragmentBinding.fragmentContent
val scroll = NestedScrollView(content.context)
@ -202,8 +202,10 @@ class SettingsFragment : ScreenFragment() {
preferences[Preferences.Key.ProxyPort]?.setEnabled(enabled)
}
if (key == Preferences.Key.RootPermission) {
preferences[Preferences.Key.RootPermission]?.setEnabled(Shell.getCachedShell()?.isRoot
?: Shell.getShell().isRoot)
preferences[Preferences.Key.RootPermission]?.setEnabled(
Shell.getCachedShell()?.isRoot
?: Shell.getShell().isRoot
)
}
if (key == Preferences.Key.Theme) {
requireActivity().recreate()
@ -217,7 +219,7 @@ class SettingsFragment : ScreenFragment() {
val text = MaterialTextView(context)
text.typeface = TypefaceExtra.medium
text.setTextSizeScaled(14)
text.setTextColor(text.context.getColorFromAttr(R.attr.colorAccent))
text.setTextColor(text.context.getColorFromAttr(R.attr.colorPrimary))
text.text = title
resources.sizeScaled(16).let { text.setPadding(it, it, it, 0) }
addView(

View File

@ -115,7 +115,7 @@ class TabsFragment : ScreenFragment() {
syncConnection.bind(requireContext())
screenActivity.onToolbarCreated(toolbar)
toolbar.setTitle(R.string.application_name)
collapsingToolbar.title = getString(R.string.application_name)
// Move focus from SearchView to Toolbar
toolbar.isFocusableInTouchMode = true
@ -136,7 +136,7 @@ class TabsFragment : ScreenFragment() {
return true
}
})
setOnSearchClickListener { appBar.setExpanded(false, true) }
setOnSearchClickListener { fragmentBinding.appbarLayout.setExpanded(false, true) }
}
toolbar.menu.apply {
@ -340,16 +340,6 @@ class TabsFragment : ScreenFragment() {
}
}
override fun onAttachFragment(childFragment: Fragment) {
super.onAttachFragment(childFragment)
if (view != null && childFragment is AppListFragment) {
childFragment.setSearchQuery(searchQuery)
childFragment.setSection(section)
childFragment.setOrder(Preferences[Preferences.Key.SortOrder].order)
}
}
override fun onBackPressed(): Boolean {
return when {
searchMenuItem?.isActionViewExpanded == true -> {

View File

@ -220,7 +220,7 @@ class DownloadService : ConnectionService<DownloadService.Binder>() {
.setSmallIcon(android.R.drawable.stat_sys_warning)
.setColor(
ContextThemeWrapper(this, R.style.Theme_Main_Light)
.getColorFromAttr(R.attr.colorAccent).defaultColor
.getColorFromAttr(R.attr.colorPrimary).defaultColor
)
.setContentIntent(
PendingIntent.getBroadcast(
@ -286,7 +286,7 @@ class DownloadService : ConnectionService<DownloadService.Binder>() {
.setSmallIcon(android.R.drawable.stat_sys_download_done)
.setColor(
ContextThemeWrapper(this, R.style.Theme_Main_Light)
.getColorFromAttr(android.R.attr.colorAccent).defaultColor
.getColorFromAttr(R.attr.colorPrimary).defaultColor
)
.setContentIntent(installIntent(task))
.setContentTitle(getString(R.string.downloaded_FORMAT, task.name))

View File

@ -1,4 +1,4 @@
package com.looker.droidify.screen
package com.looker.droidify.ui.appDetail
import android.annotation.SuppressLint
import android.content.ClipData
@ -21,7 +21,6 @@ import android.view.Gravity
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.appcompat.widget.LinearLayoutCompat
@ -47,6 +46,7 @@ import com.looker.droidify.content.Preferences
import com.looker.droidify.content.ProductPreferences
import com.looker.droidify.entity.*
import com.looker.droidify.network.CoilDownloader
import com.looker.droidify.screen.ScreenshotsAdapter
import com.looker.droidify.utility.KParcelable
import com.looker.droidify.utility.PackageItemResolver
import com.looker.droidify.utility.Utils
@ -59,8 +59,8 @@ import java.lang.ref.WeakReference
import java.util.*
import kotlin.math.*
class ProductAdapter(private val callbacks: Callbacks) :
StableRecyclerAdapter<ProductAdapter.ViewType, RecyclerView.ViewHolder>() {
class AppDetailAdapter(private val callbacks: Callbacks) :
StableRecyclerAdapter<AppDetailAdapter.ViewType, RecyclerView.ViewHolder>() {
interface Callbacks {
fun onActionClick(action: Action)
@ -96,11 +96,11 @@ class ProductAdapter(private val callbacks: Callbacks) :
private enum class SectionType(val titleResId: Int, val colorAttrResId: Int) {
ANTI_FEATURES(R.string.anti_features, R.attr.colorError),
CHANGES(R.string.changes, R.attr.colorAccent),
LINKS(R.string.links, R.attr.colorAccent),
DONATE(R.string.donate, R.attr.colorAccent),
PERMISSIONS(R.string.permissions, R.attr.colorAccent),
VERSIONS(R.string.versions, R.attr.colorAccent)
CHANGES(R.string.changes, R.attr.colorPrimary),
LINKS(R.string.links, R.attr.colorPrimary),
DONATE(R.string.donate, R.attr.colorPrimary),
PERMISSIONS(R.string.permissions, R.attr.colorPrimary),
VERSIONS(R.string.versions, R.attr.colorPrimary)
}
internal enum class ExpandType {
@ -129,8 +129,7 @@ class ProductAdapter(private val callbacks: Callbacks) :
class AppInfoItem(
val repository: Repository,
val product: Product,
val packageName: String,
val product: Product
) : Item() {
override val descriptor: String
get() = "app_info.${product.name}"
@ -329,9 +328,9 @@ class ProductAdapter(private val callbacks: Callbacks) :
val progressIcon: Drawable
val defaultIcon: Drawable
val actionTintNormal = action.context.getColorFromAttr(R.attr.colorSurface)
val actionTintNormal = action.context.getColorFromAttr(R.attr.colorPrimary)
val actionTintOnNormal = action.context.getColorFromAttr(R.attr.colorOnPrimary)
val actionTintCancel = action.context.getColorFromAttr(R.attr.colorError)
val actionTintOnNormal = action.context.getColorFromAttr(R.attr.colorOnSurface)
val actionTintOnCancel = action.context.getColorFromAttr(R.attr.colorOnError)
init {
@ -362,7 +361,7 @@ class ProductAdapter(private val callbacks: Callbacks) :
}
private class SwitchViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val enabled = itemView.findViewById<SwitchMaterial>(R.id.enabled)!!
val enabled = itemView.findViewById<SwitchMaterial>(R.id.update_state_switch)!!
val statefulViews: Sequence<View>
get() = sequenceOf(itemView, enabled)
@ -404,7 +403,7 @@ class ProductAdapter(private val callbacks: Callbacks) :
private class TextViewHolder(context: Context) :
RecyclerView.ViewHolder(MaterialTextView(context)) {
val text: TextView
val text: MaterialTextView
get() = itemView as MaterialTextView
init {
@ -481,7 +480,7 @@ class ProductAdapter(private val callbacks: Callbacks) :
val dateFormat = DateFormat.getDateFormat(itemView.context)!!
val version = itemView.findViewById<MaterialTextView>(R.id.version)!!
val status = itemView.findViewById<MaterialTextView>(R.id.status)!!
val status = itemView.findViewById<MaterialTextView>(R.id.installation_status)!!
val source = itemView.findViewById<MaterialTextView>(R.id.source)!!
val added = itemView.findViewById<MaterialTextView>(R.id.added)!!
val size = itemView.findViewById<MaterialTextView>(R.id.size)!!
@ -499,21 +498,6 @@ class ProductAdapter(private val callbacks: Callbacks) :
signature,
compatibility
)
init {
status.apply {
background =
ResourcesCompat.getDrawable(
itemView.resources,
R.drawable.background_border,
itemView.context.theme
)
backgroundTintList = itemView.context.getColorFromAttr(R.attr.colorSurface)
typeface = TypefaceExtra.bold
setPadding(15, 5, 15, 5)
setTextColor(itemView.context.getColorFromAttr(R.attr.colorPrimary))
}
}
}
private class EmptyViewHolder(context: Context) :
@ -568,8 +552,7 @@ class ProductAdapter(private val callbacks: Callbacks) :
if (productRepository != null) {
items += Item.AppInfoItem(
productRepository.second,
productRepository.first,
packageName
productRepository.first
)
items += Item.ScreenshotItem(
productRepository.first.screenshots,
@ -709,8 +692,7 @@ class ProductAdapter(private val callbacks: Callbacks) :
)
}
author.email.nullIfEmpty()?.let {
linkItems += Item.LinkItem
.Typed(LinkType.EMAIL, "", Uri.parse("mailto:$it"))
linkItems += Item.LinkItem.Typed(LinkType.EMAIL, "", Uri.parse("mailto:$it"))
}
linkItems += licenses.asSequence().map {
Item.LinkItem.Typed(
@ -887,7 +869,7 @@ class ProductAdapter(private val callbacks: Callbacks) :
val from = items.indexOfFirst { it is Item.ReleaseItem }
val to = items.indexOfLast { it is Item.ReleaseItem }
if (from in 0..to) {
notifyItemRangeChanged(from, to - from + 1)
notifyItemRangeChanged(0, 1)
}
} else {
notifyItemChanged(index, Payload.STATUS)
@ -909,7 +891,7 @@ class ProductAdapter(private val callbacks: Callbacks) :
): RecyclerView.ViewHolder {
return when (viewType) {
ViewType.APP_INFO -> AppInfoViewHolder(parent.inflate(R.layout.item_app_info_x)).apply {
action.setOnClickListener { this@ProductAdapter.action?.let(callbacks::onActionClick) }
action.setOnClickListener { this@AppDetailAdapter.action?.let(callbacks::onActionClick) }
}
ViewType.SCREENSHOT -> ScreenShotViewHolder(parent.inflate(R.layout.screenshot_scrollview))
ViewType.SWITCH -> SwitchViewHolder(parent.inflate(R.layout.switch_item)).apply {
@ -1118,14 +1100,12 @@ class ProductAdapter(private val callbacks: Callbacks) :
if (status.total != null) {
holder.progress.progress =
(holder.progress.max.toFloat() * status.read / status.total).roundToInt()
}
Unit
} else Unit
}
}::class
}
}
val imageSource = product?.source?.trimAfter('/', 4).plus(".png").toUri()
val sdk = product?.displayRelease?.targetSdkVersion
holder.version.doOnPreDraw {
@ -1143,13 +1123,9 @@ class ProductAdapter(private val callbacks: Callbacks) :
}
val devName = product?.source?.trimAfter('/', 4).trimBefore('/', 3)
holder.devName.text = if (author.isNullOrEmpty()) devName else author
when {
imageSource.toString()
.contains("kde.org") -> holder.devIcon.setImageResource(R.drawable.ic_kde)
imageSource.toString()
.contains("gitlab") -> holder.devIcon.setImageResource(R.drawable.ic_gitlab)
imageSource.toString().contains("github") -> holder.devIcon.load(imageSource)
}
holder.devIcon.load(R.drawable.ic_code)
holder.dev.setOnClickListener {
product?.source?.let { link ->
if (link.isNotEmpty()) {
@ -1334,30 +1310,46 @@ class ProductAdapter(private val callbacks: Callbacks) :
installedItem?.signature == item.release.signature
val suggested =
incompatibility == null && item.release.selected && item.selectedRepository
val olderOrSignature = installedItem?.let {
it.versionCode > item.release.versionCode ||
it.signature != item.release.signature
} == true
val grayOut = incompatibility != null || olderOrSignature
val primarySecondaryColor = context.getColorFromAttr(
if (grayOut)
android.R.attr.textColorSecondary else android.R.attr.textColor
)
if (suggested) {
holder.itemView.apply {
background = ResourcesCompat.getDrawable(
holder.itemView.resources,
R.drawable.background_border,
holder.itemView.context.theme
)
backgroundTintList =
holder.itemView.context.getColorFromAttr(R.attr.colorSurface)
}
} else {
holder.itemView.background = null
}
holder.version.text =
context.getString(R.string.version_FORMAT, item.release.version)
holder.version.setTextColor(primarySecondaryColor)
holder.status.visibility = if (installed || suggested) View.VISIBLE else View.GONE
holder.status.setText(
when {
installed -> R.string.installed
suggested -> R.string.suggested
else -> R.string.unknown
}
)
holder.status.apply {
visibility = if (installed || suggested) View.VISIBLE else View.GONE
setText(
when {
installed -> R.string.installed
suggested -> R.string.suggested
else -> R.string.unknown
}
)
background =
ResourcesCompat.getDrawable(
holder.itemView.resources,
R.drawable.background_border,
context.theme
)
setPadding(15, 15, 15, 15)
backgroundTintList =
context.getColorFromAttr(R.attr.colorSecondaryContainer)
setTextColor(context.getColorFromAttr(R.attr.colorOnSecondaryContainer))
}
holder.source.text =
context.getString(R.string.provided_by_FORMAT, item.repository.name)
holder.added.text = holder.dateFormat.format(item.release.added)
holder.added.setTextColor(primarySecondaryColor)
holder.size.text = item.release.size.formatSize()
holder.signature.visibility =
if (item.showSignature && item.release.signature.isNotEmpty())
@ -1466,7 +1458,7 @@ class ProductAdapter(private val callbacks: Callbacks) :
Snackbar.make(view, R.string.link_copied_to_clipboard, Snackbar.LENGTH_SHORT).show()
}
private class LinkSpan(private val url: String, productAdapter: ProductAdapter) :
private class LinkSpan(private val url: String, productAdapter: AppDetailAdapter) :
ClickableSpan() {
private val productAdapterReference = WeakReference(productAdapter)

View File

@ -1,4 +1,4 @@
package com.looker.droidify.screen
package com.looker.droidify.ui.appDetail
import android.content.ActivityNotFoundException
import android.content.ComponentName
@ -20,6 +20,9 @@ import com.looker.droidify.content.ProductPreferences
import com.looker.droidify.database.Database
import com.looker.droidify.entity.*
import com.looker.droidify.installer.AppInstaller
import com.looker.droidify.screen.MessageDialog
import com.looker.droidify.screen.ScreenFragment
import com.looker.droidify.screen.ScreenshotsFragment
import com.looker.droidify.service.Connection
import com.looker.droidify.service.DownloadService
import com.looker.droidify.utility.RxUtils
@ -35,7 +38,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class ProductFragment() : ScreenFragment(), ProductAdapter.Callbacks {
class AppDetailFragment() : ScreenFragment(), AppDetailAdapter.Callbacks {
companion object {
private const val EXTRA_PACKAGE_NAME = "packageName"
private const val STATE_LAYOUT_MANAGER = "layoutManager"
@ -52,14 +55,14 @@ class ProductFragment() : ScreenFragment(), ProductAdapter.Callbacks {
private enum class Action(
val id: Int,
val adapterAction: ProductAdapter.Action,
val adapterAction: AppDetailAdapter.Action,
) {
INSTALL(1, ProductAdapter.Action.INSTALL),
UPDATE(2, ProductAdapter.Action.UPDATE),
LAUNCH(3, ProductAdapter.Action.LAUNCH),
DETAILS(4, ProductAdapter.Action.DETAILS),
UNINSTALL(5, ProductAdapter.Action.UNINSTALL),
SHARE(6, ProductAdapter.Action.SHARE)
INSTALL(1, AppDetailAdapter.Action.INSTALL),
UPDATE(2, AppDetailAdapter.Action.UPDATE),
LAUNCH(3, AppDetailAdapter.Action.LAUNCH),
DETAILS(4, AppDetailAdapter.Action.DETAILS),
UNINSTALL(5, AppDetailAdapter.Action.UNINSTALL),
SHARE(6, AppDetailAdapter.Action.SHARE)
}
private class Installed(
@ -114,10 +117,10 @@ class ProductFragment() : ScreenFragment(), ProductAdapter.Callbacks {
this.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
isMotionEventSplittingEnabled = false
isVerticalScrollBarEnabled = false
val adapter = ProductAdapter(this@ProductFragment)
val adapter = AppDetailAdapter(this@AppDetailFragment)
this.adapter = adapter
addOnScrollListener(scrollListener)
savedInstanceState?.getParcelable<ProductAdapter.SavedState>(STATE_ADAPTER)
savedInstanceState?.getParcelable<AppDetailAdapter.SavedState>(STATE_ADAPTER)
?.let(adapter::restoreState)
layoutManagerState = savedInstanceState?.getParcelable(STATE_LAYOUT_MANAGER)
recyclerView = this
@ -213,7 +216,7 @@ class ProductFragment() : ScreenFragment(), ProductAdapter.Callbacks {
}
}
val recyclerView = recyclerView!!
val adapter = recyclerView.adapter as ProductAdapter
val adapter = recyclerView.adapter as AppDetailAdapter
if (firstChanged || productChanged || installedItemChanged) {
adapter.setProducts(
recyclerView.context,
@ -246,7 +249,7 @@ class ProductFragment() : ScreenFragment(), ProductAdapter.Callbacks {
val layoutManagerState =
layoutManagerState ?: recyclerView?.layoutManager?.onSaveInstanceState()
layoutManagerState?.let { outState.putParcelable(STATE_LAYOUT_MANAGER, it) }
val adapterState = (recyclerView?.adapter as? ProductAdapter)?.saveState()
val adapterState = (recyclerView?.adapter as? AppDetailAdapter)?.saveState()
adapterState?.let { outState.putParcelable(STATE_ADAPTER, it) }
}
@ -297,8 +300,8 @@ class ProductFragment() : ScreenFragment(), ProductAdapter.Callbacks {
}
val adapterAction =
if (downloading) ProductAdapter.Action.CANCEL else primaryAction?.adapterAction
(recyclerView?.adapter as? ProductAdapter)?.setAction(adapterAction)
if (downloading) AppDetailAdapter.Action.CANCEL else primaryAction?.adapterAction
(recyclerView?.adapter as? AppDetailAdapter)?.setAction(adapterAction)
for (action in sequenceOf(
Action.INSTALL,
@ -344,9 +347,9 @@ class ProductFragment() : ScreenFragment(), ProductAdapter.Callbacks {
private suspend fun updateDownloadState(state: DownloadService.State?) {
val status = when (state) {
is DownloadService.State.Pending -> ProductAdapter.Status.Pending
is DownloadService.State.Connecting -> ProductAdapter.Status.Connecting
is DownloadService.State.Downloading -> ProductAdapter.Status.Downloading(
is DownloadService.State.Pending -> AppDetailAdapter.Status.Pending
is DownloadService.State.Connecting -> AppDetailAdapter.Status.Connecting
is DownloadService.State.Downloading -> AppDetailAdapter.Status.Downloading(
state.read,
state.total
)
@ -357,7 +360,7 @@ class ProductFragment() : ScreenFragment(), ProductAdapter.Callbacks {
this.downloading = downloading
updateButtons()
}
(recyclerView?.adapter as? ProductAdapter)?.setStatus(status)
(recyclerView?.adapter as? AppDetailAdapter)?.setStatus(status)
if (state is DownloadService.State.Success && isResumed) {
withContext(Dispatchers.Default) {
state.consume()
@ -383,10 +386,10 @@ class ProductFragment() : ScreenFragment(), ProductAdapter.Callbacks {
}
}
override fun onActionClick(action: ProductAdapter.Action) {
override fun onActionClick(action: AppDetailAdapter.Action) {
when (action) {
ProductAdapter.Action.INSTALL,
ProductAdapter.Action.UPDATE,
AppDetailAdapter.Action.INSTALL,
AppDetailAdapter.Action.UPDATE,
-> {
val installedItem = installed?.installedItem
lifecycleScope.launch {
@ -399,7 +402,7 @@ class ProductFragment() : ScreenFragment(), ProductAdapter.Callbacks {
}
Unit
}
ProductAdapter.Action.LAUNCH -> {
AppDetailAdapter.Action.LAUNCH -> {
val launcherActivities = installed?.launcherActivities.orEmpty()
if (launcherActivities.size >= 2) {
LaunchDialog(launcherActivities).show(
@ -411,25 +414,25 @@ class ProductFragment() : ScreenFragment(), ProductAdapter.Callbacks {
}
Unit
}
ProductAdapter.Action.DETAILS -> {
AppDetailAdapter.Action.DETAILS -> {
startActivity(
Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
.setData(Uri.parse("package:$packageName"))
)
}
ProductAdapter.Action.UNINSTALL -> {
AppDetailAdapter.Action.UNINSTALL -> {
lifecycleScope.launch {
AppInstaller.getInstance(context)?.defaultInstaller?.uninstall(packageName)
}
Unit
}
ProductAdapter.Action.CANCEL -> {
AppDetailAdapter.Action.CANCEL -> {
val binder = downloadConnection.binder
if (downloading && binder != null) {
binder.cancel(packageName)
} else Unit
}
ProductAdapter.Action.SHARE -> {
AppDetailAdapter.Action.SHARE -> {
val sendIntent: Intent = Intent().apply {
this.action = Intent.ACTION_SEND
putExtra(
@ -552,7 +555,7 @@ class ProductFragment() : ScreenFragment(), ProductAdapter.Callbacks {
return MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.launch)
.setItems(labels.toTypedArray()) { _, position ->
(parentFragment as ProductFragment)
(parentFragment as AppDetailFragment)
.startLauncherActivity(names[position])
}
.setNegativeButton(R.string.cancel, null)

View File

@ -2,11 +2,11 @@ package com.looker.droidify.ui.appsList
import android.content.Context
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.view.animation.AnimationUtils
import androidx.core.content.res.ResourcesCompat
import androidx.recyclerview.widget.RecyclerView
import coil.load
import coil.transform.RoundedCornersTransformation
@ -163,16 +163,16 @@ class AppListAdapter(private val onClick: (ProductItem) -> Unit) :
if (productItem.canUpdate) {
text = productItem.version
if (background == null) {
resources.sizeScaled(4).let { setPadding(it, 0, it, 0) }
setTextColor(holder.status.context.getColorFromAttr(android.R.attr.colorBackground))
background = GradientDrawable(
GradientDrawable.Orientation.TOP_BOTTOM,
null
).apply {
color =
holder.status.context.getColorFromAttr(R.attr.colorAccent)
cornerRadius = holder.status.resources.sizeScaled(2).toFloat()
}
background =
ResourcesCompat.getDrawable(
holder.itemView.resources,
R.drawable.background_border,
context.theme
)
setPadding(8, 15, 1, 15)
backgroundTintList =
context.getColorFromAttr(R.attr.colorSecondaryContainer)
setTextColor(context.getColorFromAttr(R.attr.colorSecondary))
}
} else {
text = productItem.installedVersion.nullIfEmpty() ?: productItem.version