Skip to content

Commit 6315532

Browse files
committed
Allow creating multiple accents
Accents can also be disabled, removed (swipe left)
1 parent 03b1067 commit 6315532

22 files changed

+755
-347
lines changed

app/build.gradle

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ apply plugin: 'kotlin-android'
44

55
apply plugin: 'kotlin-android-extensions'
66

7+
apply plugin: 'kotlin-kapt'
8+
79
android {
810
compileSdkVersion 29
911
buildToolsVersion "29.0.2"
@@ -28,6 +30,9 @@ android {
2830
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
2931
}
3032
}
33+
packagingOptions {
34+
exclude 'META-INF/atomicfu.kotlin_module'
35+
}
3136
}
3237

3338
dependencies {
@@ -38,6 +43,25 @@ dependencies {
3843
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
3944
implementation 'androidx.preference:preference:1.1.0'
4045

46+
def roomVersion = '2.2.2'
47+
def archLifecycleVersion = '2.2.0-rc03'
48+
def coroutines = '1.3.3'
49+
50+
// Room components
51+
implementation "androidx.room:room-runtime:$roomVersion"
52+
implementation "androidx.room:room-ktx:$roomVersion"
53+
kapt "androidx.room:room-compiler:$roomVersion"
54+
55+
// Lifecycle components
56+
implementation "androidx.lifecycle:lifecycle-extensions:$archLifecycleVersion"
57+
implementation "androidx.lifecycle:lifecycle-common-java8:$archLifecycleVersion"
58+
59+
// ViewModel Kotlin support
60+
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$archLifecycleVersion"
61+
62+
// Coroutines
63+
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines"
64+
4165
implementation 'com.google.android.material:material:1.2.0-alpha02'
4266

4367
implementation 'com.github.topjohnwu.libsu:core:2.5.1'

app/src/main/assets/AndroidManifest.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
package="com.android.theme.color.custom"
66
platformBuildVersionCode="29"
77
platformBuildVersionName="10"
8-
android:versionName="1.0">
8+
android:versionName="1.0"
9+
android:versionCode="1">
910

1011
<overlay
1112
android:category="android.theme.customization.accent_color"

app/src/main/assets/src/values/colors.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
<resources>
33
<color name="accent_device_default_dark">#03DAC5</color>
44
<color name="accent_device_default_light">#183693</color>
5+
<color name="accent_device_default_700">#673AB7</color>
56
</resources>
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package app.akilesh.qacc
2+
3+
import android.content.Context
4+
import android.content.res.ColorStateList
5+
import android.graphics.Color
6+
import android.util.Log
7+
import android.view.LayoutInflater
8+
import android.view.View
9+
import android.view.ViewGroup
10+
import androidx.appcompat.widget.AppCompatImageView
11+
import androidx.core.content.res.ResourcesCompat
12+
import androidx.recyclerview.widget.RecyclerView
13+
import app.akilesh.qacc.model.Accent
14+
import com.google.android.material.button.MaterialButton
15+
import com.google.android.material.textview.MaterialTextView
16+
import com.topjohnwu.superuser.Shell
17+
18+
class AccentListAdapter internal constructor(
19+
private val context: Context
20+
): RecyclerView.Adapter<AccentListAdapter.AccentViewHolder>() {
21+
private val inflater: LayoutInflater = LayoutInflater.from(context)
22+
private var accents = mutableListOf<Accent>()
23+
24+
25+
inner class AccentViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
26+
val name: MaterialTextView = itemView.findViewById(R.id.name)
27+
val color: AppCompatImageView = itemView.findViewById(R.id.color)
28+
val button: MaterialButton = itemView.findViewById(R.id.enable_or_disable_accent)
29+
}
30+
31+
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AccentViewHolder {
32+
val itemView = inflater.inflate(R.layout.recyclerview_item, parent, false)
33+
return AccentViewHolder(itemView)
34+
}
35+
36+
override fun onBindViewHolder(holder: AccentViewHolder, position: Int) {
37+
val current = accents[position]
38+
val text = current.name + " - " + current.color
39+
val color = Color.parseColor(current.color)
40+
val colorStateList = ColorStateList.valueOf(color)
41+
holder.name.text = text
42+
holder.color.setColorFilter(color)
43+
44+
if (isOverlayInstalled(current.pkgName)) {
45+
46+
if(isOverlayEnabled(current.pkgName)) {
47+
holder.button.strokeColor = colorStateList
48+
holder.button.strokeWidth = 3
49+
holder.button.text = context.resources.getString(R.string.disable_accent)
50+
holder.button.icon = ResourcesCompat.getDrawable(context.resources, R.drawable.ic_check_circle_unchecked, context.theme)
51+
}
52+
else {
53+
holder.button.text = context.resources.getString(R.string.enable_accent)
54+
holder.button.icon = ResourcesCompat.getDrawable(context.resources, R.drawable.ic_check_circle_checked, context.theme)
55+
}
56+
57+
holder.button.iconTint = colorStateList
58+
holder.button.rippleColor = colorStateList
59+
holder.button.setOnClickListener {
60+
if (holder.button.text == "Enable")
61+
Shell.su("cmd overlay enable-exclusive --category ${current.pkgName}").exec()
62+
else
63+
Shell.su("cmd overlay disable ${current.pkgName}").exec()
64+
}
65+
}
66+
else {
67+
holder.button.strokeWidth = 0
68+
holder.button.text = context.resources.getString(R.string.overlay_not_installed)
69+
holder.button.isClickable = false
70+
holder.button.icon = null
71+
}
72+
}
73+
74+
internal fun setAccents(accents: MutableList<Accent>) {
75+
this.accents = accents
76+
notifyDataSetChanged()
77+
}
78+
79+
internal fun getAccentAndRemoveAt(position: Int): Accent {
80+
val current = accents[position]
81+
accents.removeAt(position)
82+
notifyItemRemoved(position)
83+
return current
84+
}
85+
override fun getItemCount() = accents.size
86+
87+
private fun isOverlayInstalled(pkgName: String): Boolean {
88+
return try {
89+
context.packageManager.getPackageInfo(pkgName, 0)
90+
true
91+
} catch (e: Exception) {
92+
false
93+
}
94+
}
95+
96+
private fun isOverlayEnabled(pkgName: String): Boolean {
97+
return Shell.su("cmd overlay dump isenabled $pkgName").exec().out.component1() == "true"
98+
}
99+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package app.akilesh.qacc
2+
3+
import androidx.lifecycle.LiveData
4+
import app.akilesh.qacc.db.dao.AccentDao
5+
import app.akilesh.qacc.model.Accent
6+
7+
class AccentRepository(private val accentDao: AccentDao) {
8+
9+
val allAccents: LiveData<MutableList<Accent>> = accentDao.getAll()
10+
11+
suspend fun insert(accent: Accent) {
12+
accentDao.insert(accent)
13+
}
14+
15+
suspend fun delete(accent: Accent) {
16+
accentDao.delete(accent)
17+
}
18+
19+
}

0 commit comments

Comments
 (0)