Skip to content

Commit 0e2f882

Browse files
committed
progress bar + material you title bar
1 parent 5e9ac8a commit 0e2f882

7 files changed

Lines changed: 109 additions & 23 deletions

File tree

app/build.gradle.kts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ dependencies {
7777
testImplementation("androidx.test.ext:junit:1.1.5")
7878
testImplementation("androidx.test.espresso:espresso-core:3.5.1")
7979
implementation("com.google.code.gson:gson:2.10.1")
80-
8180
}
8281

8382
ktlint {

app/src/main/java/com/fredhappyface/ewesticker/MainActivity.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import androidx.appcompat.app.AppCompatActivity
1616
import androidx.lifecycle.lifecycleScope
1717
import androidx.preference.PreferenceManager
1818
import com.fredhappyface.ewesticker.utilities.Toaster
19+
import com.google.android.material.progressindicator.LinearProgressIndicator
1920
import kotlinx.coroutines.Dispatchers
2021
import kotlinx.coroutines.launch
2122
import kotlinx.coroutines.withContext
@@ -120,11 +121,13 @@ class MainActivity : AppCompatActivity() {
120121
toaster.toast(getString(R.string.imported_010))
121122
val button = findViewById<Button>(R.id.updateStickerPackInfoBtn)
122123
val button2 = findViewById<Button>(R.id.reloadStickerPackInfoBtn)
124+
val progressBar = findViewById<LinearProgressIndicator>(R.id.linearProgressIndicator)
123125
button.isEnabled = false
124126
button2.isEnabled = false
125127

126128
lifecycleScope.launch(Dispatchers.IO) {
127-
val totalStickers = StickerImporter(baseContext, toaster).importStickers(stickerDirPath)
129+
val totalStickers =
130+
StickerImporter(baseContext, toaster, progressBar).importStickers(stickerDirPath)
128131

129132
withContext(Dispatchers.Main) {
130133
toaster.toastOnState(

app/src/main/java/com/fredhappyface/ewesticker/StickerImporter.kt

Lines changed: 51 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@ package com.fredhappyface.ewesticker
22

33
import android.content.Context
44
import android.net.Uri
5+
import android.os.Handler
6+
import android.os.Looper
7+
import android.view.View
58
import androidx.documentfile.provider.DocumentFile
69
import com.fredhappyface.ewesticker.utilities.Toaster
710
import com.fredhappyface.ewesticker.utilities.Utils
11+
import com.google.android.material.progressindicator.LinearProgressIndicator
812
import kotlinx.coroutines.Dispatchers
913
import kotlinx.coroutines.async
1014
import kotlinx.coroutines.awaitAll
@@ -28,11 +32,19 @@ private const val BUFFER_SIZE = 64 * 1024 // 64 KB
2832
class StickerImporter(
2933
private val context: Context,
3034
private val toaster: Toaster,
35+
private val progressBar: LinearProgressIndicator,
3136
) {
3237
private val supportedMimes = Utils.getSupportedMimes()
3338
private val packSizes: MutableMap<String, Int> = mutableMapOf()
3439
private var totalStickers = 0
3540

41+
private val mainHandler = Handler(Looper.getMainLooper())
42+
43+
private fun updateProgressBar(currentProgress: Int, totalStickers: Int) {
44+
val progressPercentage = (currentProgress.toFloat() / totalStickers.toFloat()) * 100
45+
progressBar.progress = progressPercentage.toInt()
46+
}
47+
3648

3749
/**
3850
* Used by the ACTION_OPEN_DOCUMENT_TREE handler function to copy stickers from a
@@ -43,18 +55,37 @@ class StickerImporter(
4355
*/
4456
suspend fun importStickers(stickerDirPath: String): Int {
4557
File(context.filesDir, "stickers").deleteRecursively()
58+
withContext(Dispatchers.Main) {
59+
progressBar.visibility = View.VISIBLE
60+
progressBar.isIndeterminate = true
61+
}
62+
4663
val leafNodes = fileWalk(DocumentFile.fromTreeUri(context, Uri.parse(stickerDirPath)))
4764
if (leafNodes.size > MAX_FILES) {
4865
toaster.setState(1)
4966
}
5067

68+
withContext(Dispatchers.Main) {
69+
progressBar.isIndeterminate = false
70+
}
71+
72+
5173
// Perform concurrent file copy operations
5274
withContext(Dispatchers.IO) {
53-
leafNodes.take(MAX_FILES).map { file ->
54-
async { importSticker(file) }
75+
leafNodes.take(MAX_FILES).mapIndexed { index, file ->
76+
async {
77+
importSticker(file)
78+
mainHandler.post {
79+
updateProgressBar(index + 1, leafNodes.size)
80+
}
81+
}
5582
}.awaitAll()
5683
}
5784

85+
withContext(Dispatchers.Main) {
86+
progressBar.visibility = View.GONE
87+
}
88+
5889
return leafNodes.size
5990
}
6091

@@ -107,18 +138,24 @@ class StickerImporter(
107138
*/
108139
private fun fileWalk(rootNode: DocumentFile?): Set<DocumentFile> {
109140
val leafNodes = mutableSetOf<DocumentFile>()
110-
if (rootNode == null || totalStickers >= MAX_FILES) {
111-
return leafNodes
112-
}
113-
rootNode.listFiles().forEach { file ->
114-
if (file.isFile) {
115-
leafNodes.add(file)
116-
totalStickers++
117-
} else if (file.isDirectory) {
118-
leafNodes.addAll(fileWalk(file))
119-
}
120-
if (totalStickers >= MAX_FILES) {
121-
return@forEach
141+
val stack = ArrayDeque<DocumentFile?>()
142+
143+
rootNode?.let { stack.addLast(it) }
144+
145+
while (stack.isNotEmpty() && leafNodes.size < MAX_FILES) {
146+
val currentFile = stack.removeLast()
147+
148+
currentFile?.listFiles()?.forEach { file ->
149+
if (file.isFile) {
150+
leafNodes.add(file)
151+
totalStickers++
152+
153+
if (leafNodes.size >= MAX_FILES) {
154+
return leafNodes
155+
}
156+
} else if (file.isDirectory) {
157+
stack.addLast(file)
158+
}
122159
}
123160
}
124161
return leafNodes

app/src/main/res/layout/activity_main.xml

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,48 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<com.google.android.material.circularreveal.coordinatorlayout.CircularRevealCoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
2+
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
33
xmlns:app="http://schemas.android.com/apk/res-auto"
44
android:id="@+id/activityMainRoot"
55
android:layout_width="match_parent"
66
android:layout_height="match_parent"
77
android:background="@color/bg">
88

9-
<ScrollView
9+
<com.google.android.material.appbar.AppBarLayout
10+
android:id="@+id/appBarLayout"
11+
android:layout_width="match_parent"
12+
android:layout_height="wrap_content"
13+
android:background="@color/accent">
14+
15+
<com.google.android.material.appbar.CollapsingToolbarLayout
16+
android:id="@+id/collapsingToolbarLayout"
17+
android:layout_width="match_parent"
18+
android:layout_height="wrap_content"
19+
app:layout_scrollFlags="scroll|exitUntilCollapsed"
20+
android:background="@color/accent"
21+
app:collapsedTitleTextAppearance="@style/ToolbarTitleTextAppearance"
22+
app:expandedTitleTextAppearance="@style/ToolbarTitleTextAppearance"
23+
app:title=" EweSticker">
24+
25+
<View
26+
android:layout_width="match_parent"
27+
android:layout_height="@dimen/appbar_padding"
28+
android:background="@color/accent" />
29+
30+
<androidx.appcompat.widget.Toolbar
31+
android:id="@+id/toolbar"
32+
android:layout_width="match_parent"
33+
android:layout_height="?attr/actionBarSize"
34+
app:layout_collapseMode="none"
35+
app:layout_collapseParallaxMultiplier="0.7"
36+
android:background="@color/accent" />
37+
38+
39+
</com.google.android.material.appbar.CollapsingToolbarLayout>
40+
</com.google.android.material.appbar.AppBarLayout>
41+
42+
<androidx.core.widget.NestedScrollView
1043
android:layout_width="match_parent"
1144
android:layout_height="match_parent"
12-
android:orientation="vertical">
45+
app:layout_behavior="@string/appbar_scrolling_view_behavior">
1346

1447
<LinearLayout
1548
style="@style/widthMatchHeightWrap"
@@ -111,6 +144,13 @@
111144
android:onClick="reloadStickers"
112145
android:text="@string/reload_sticker_pack_button"
113146
app:shapeAppearance="?attr/shapeAppearanceSmallComponent" />
147+
148+
<com.google.android.material.progressindicator.LinearProgressIndicator
149+
android:id="@+id/linearProgressIndicator"
150+
android:layout_width="match_parent"
151+
android:layout_height="wrap_content"
152+
android:visibility="gone" />
153+
114154
</LinearLayout>
115155
</com.google.android.material.card.MaterialCardView>
116156
<!-- Options -->
@@ -292,5 +332,5 @@
292332
</LinearLayout>
293333
</com.google.android.material.card.MaterialCardView>
294334
</LinearLayout>
295-
</ScrollView>
296-
</com.google.android.material.circularreveal.coordinatorlayout.CircularRevealCoordinatorLayout>
335+
</androidx.core.widget.NestedScrollView>
336+
</androidx.coordinatorlayout.widget.CoordinatorLayout>

app/src/main/res/values-v27/styles.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<resources>
33

4-
<style name="AppTheme" parent="Theme.Material3.DayNight">
4+
<style name="AppTheme" parent="Theme.Material3.DayNight.NoActionBar">
55
<!-- Primary brand color. -->
66
<item name="colorPrimaryVariant">@color/accent</item>
77
<item name="colorOnPrimary">@color/onAccent</item>

app/src/main/res/values/dimen.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<resources>
33
<dimen name="r_btn">32sp</dimen>
4+
<dimen name="appbar_padding">160dp</dimen>
5+
<dimen name="text_size_title">36sp</dimen>
46
<dimen name="text_size_heading">24sp</dimen>
57
<dimen name="text_size_body">16sp</dimen>
68
<dimen name="content_margin">10dp</dimen>

app/src/main/res/values/styles.xml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<resources>
22
<!-- Base application theme. -->
3-
<style name="AppTheme" parent="Theme.Material3.DayNight">
3+
<style name="AppTheme" parent="Theme.Material3.DayNight.NoActionBar">
44
<!-- Primary brand color. -->
55
<item name="colorPrimaryVariant">@color/accent</item>
66
<item name="colorOnPrimary">@color/onAccent</item>
@@ -23,6 +23,11 @@
2323
<item name="shapeAppearanceSmallComponent">@style/ShapeAppearance.App.SmallComponent</item>
2424
</style>
2525

26+
<style name="ToolbarTitleTextAppearance" parent="@style/TextAppearance.Widget.AppCompat.Toolbar.Title">
27+
<item name="android:textSize">@dimen/text_size_title</item>
28+
</style>
29+
30+
2631
<style name="ShapeAppearance.App.MediumComponent" parent="ShapeAppearance.MaterialComponents.MediumComponent">
2732
<item name="cornerSize">@dimen/corner</item>
2833
</style>

0 commit comments

Comments
 (0)