Skip to content

Commit 1e4d093

Browse files
committed
Added BlurHash support. Updated third-party libs. Bugfix for transparent background
1 parent 9a880f7 commit 1e4d093

File tree

18 files changed

+573
-252
lines changed

18 files changed

+573
-252
lines changed

.idea/gradle.xml

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/build.gradle

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
apply plugin: 'com.android.application'
22
apply plugin: 'kotlin-android'
3-
apply plugin: 'kotlin-android-extensions'
43

54
android {
6-
compileSdkVersion 31
5+
compileSdkVersion 33
76
buildToolsVersion "30.0.3"
87

98
defaultConfig {
109
applicationId "com.goodayapps.avatarview"
11-
minSdkVersion 19
12-
targetSdkVersion 31
10+
minSdkVersion 21
11+
targetSdkVersion 33
1312
versionCode 1
1413
versionName "1.0"
1514

@@ -31,17 +30,20 @@ android {
3130
kotlinOptions {
3231
jvmTarget = JavaVersion.VERSION_1_8.toString()
3332
}
33+
buildFeatures {
34+
viewBinding true
35+
}
3436
}
3537

3638
dependencies {
3739
implementation fileTree(dir: "libs", include: ["*.jar"])
38-
implementation 'androidx.core:core-ktx:1.7.0'
39-
implementation 'androidx.appcompat:appcompat:1.4.0'
40-
implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
40+
implementation 'androidx.core:core-ktx:1.10.0'
41+
implementation 'androidx.appcompat:appcompat:1.6.1'
42+
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
4143
//Coil
42-
api("io.coil-kt:coil:1.4.0")
43-
api("io.coil-kt:coil-gif:1.4.0")
44-
api("io.coil-kt:coil-svg:1.4.0")
44+
api("io.coil-kt:coil:2.3.0")
45+
api("io.coil-kt:coil-gif:2.3.0")
46+
api("io.coil-kt:coil-svg:2.3.0")
4547

4648
implementation(project(':avatar-view'))
4749
}

app/src/main/AndroidManifest.xml

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,26 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3-
package="com.goodayapps.avatarview">
4-
<uses-permission android:name="android.permission.INTERNET" />
3+
package="com.goodayapps.avatarview">
54

6-
<application
7-
android:allowBackup="true"
8-
android:icon="@mipmap/ic_launcher"
9-
android:label="@string/app_name"
10-
android:roundIcon="@mipmap/ic_launcher_round"
11-
android:supportsRtl="true"
12-
android:theme="@style/AppTheme">
13-
<activity android:name=".MainActivity"
14-
android:exported="true">
15-
<intent-filter>
16-
<action android:name="android.intent.action.MAIN" />
5+
<uses-permission android:name="android.permission.INTERNET" />
176

18-
<category android:name="android.intent.category.LAUNCHER" />
19-
</intent-filter>
20-
</activity>
21-
</application>
7+
<application
8+
android:name=".App"
9+
android:allowBackup="true"
10+
android:icon="@mipmap/ic_launcher"
11+
android:label="@string/app_name"
12+
android:roundIcon="@mipmap/ic_launcher_round"
13+
android:supportsRtl="true"
14+
android:theme="@style/AppTheme">
15+
<activity
16+
android:name=".MainActivity"
17+
android:exported="true">
18+
<intent-filter>
19+
<action android:name="android.intent.action.MAIN" />
20+
21+
<category android:name="android.intent.category.LAUNCHER" />
22+
</intent-filter>
23+
</activity>
24+
</application>
2225

2326
</manifest>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.goodayapps.avatarview
2+
3+
import android.app.Application
4+
import android.os.Build
5+
import coil.Coil
6+
import coil.ImageLoader
7+
import coil.decode.GifDecoder
8+
import coil.decode.ImageDecoderDecoder
9+
import coil.util.DebugLogger
10+
11+
class App : Application() {
12+
override fun onCreate() {
13+
super.onCreate()
14+
iniCoil()
15+
}
16+
17+
private fun iniCoil() {
18+
val imageLoader = ImageLoader.Builder(this)
19+
.components {
20+
if (Build.VERSION.SDK_INT >= 28) {
21+
add(ImageDecoderDecoder.Factory())
22+
} else {
23+
add(GifDecoder.Factory())
24+
}
25+
}
26+
.logger(DebugLogger())
27+
.build()
28+
29+
Coil.setImageLoader(imageLoader)
30+
}
31+
}

app/src/main/java/com/goodayapps/avatarview/MainActivity.kt

Lines changed: 19 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -8,37 +8,33 @@ import android.widget.SeekBar
88
import androidx.appcompat.app.AppCompatActivity
99
import androidx.core.view.children
1010
import coil.Coil
11+
import coil.ComponentRegistry
1112
import coil.ImageLoader
1213
import coil.decode.GifDecoder
1314
import coil.decode.ImageDecoderDecoder
1415
import coil.decode.SvgDecoder
1516
import coil.load
1617
import coil.request.CachePolicy
1718
import coil.util.DebugLogger
19+
import com.goodayapps.avatarview.databinding.ActivityMainBinding
1820
import com.goodayapps.widget.AvatarDrawable
1921
import com.goodayapps.widget.AvatarView
20-
import kotlinx.android.synthetic.main.activity_main.*
2122

2223
class MainActivity : AppCompatActivity() {
24+
private lateinit var binding: ActivityMainBinding
2325
override fun onCreate(savedInstanceState: Bundle?) {
2426
super.onCreate(savedInstanceState)
25-
setContentView(R.layout.activity_main)
26-
initCoil(this)
27+
binding = ActivityMainBinding.inflate(layoutInflater)
28+
setContentView(binding.root)
2729

2830
initViews()
2931

30-
// avatar111.load("https://media4.giphy.com/media/f8hd7QP9LT31Rk2NG1/giphy.gif")
31-
// avatar111.load("https://data.whicdn.com/images/337953887/original.gif"){
32-
// placeholder(R.drawable.ic_circle)
33-
//// crossfade(false)
34-
// error(R.drawable.ic_circle)
35-
// }
36-
37-
avatar111.blurHash = "UBIEhD?d01D%0MbcIVWA0gIpV[f69zSO-o%2"
32+
binding.avatar111.load("https://media4.giphy.com/media/f8hd7QP9LT31Rk2NG1/giphy.gif")
3833
}
3934

4035
private fun initViews() {
41-
iconDrawableScaleSeek.setOnSeekBarChangeListener(object : OnSeekBarChangeListener() {
36+
binding.iconDrawableScaleSeek.setOnSeekBarChangeListener(object :
37+
OnSeekBarChangeListener() {
4238
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
4339
val processFl = progress / 100f
4440

@@ -47,7 +43,7 @@ class MainActivity : AppCompatActivity() {
4743
}
4844
}
4945
})
50-
sizeSeek.setOnSeekBarChangeListener(object : OnSeekBarChangeListener() {
46+
binding.sizeSeek.setOnSeekBarChangeListener(object : OnSeekBarChangeListener() {
5147
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
5248
val processFl = progress / 100f
5349
val newSize = (convertDpToPixel(100) * processFl).toInt()
@@ -60,14 +56,14 @@ class MainActivity : AppCompatActivity() {
6056
}
6157
}
6258
})
63-
avBorderWidth.setOnSeekBarChangeListener(object : OnSeekBarChangeListener() {
59+
binding.avBorderWidth.setOnSeekBarChangeListener(object : OnSeekBarChangeListener() {
6460
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
6561
applyToAvatars {
6662
it.borderWidth = convertDpToPixel(progress)
6763
}
6864
}
6965
})
70-
avTextSizePercentage.setOnSeekBarChangeListener(object : OnSeekBarChangeListener() {
66+
binding.avTextSizePercentage.setOnSeekBarChangeListener(object : OnSeekBarChangeListener() {
7167
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
7268
val processFl = progress / 100f
7369

@@ -76,15 +72,15 @@ class MainActivity : AppCompatActivity() {
7672
}
7773
}
7874
})
79-
avAvatarMargin.setOnSeekBarChangeListener(object : OnSeekBarChangeListener() {
75+
binding.avAvatarMargin.setOnSeekBarChangeListener(object : OnSeekBarChangeListener() {
8076
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
8177
applyToAvatars {
8278
it.avatarMargin = convertDpToPixel(progress)
8379
}
8480
}
8581
})
8682

87-
avVolumetric.setOnCheckedChangeListener { _, checkedId ->
83+
binding.avVolumetric.setOnCheckedChangeListener { _, checkedId ->
8884
applyToAvatars {
8985
it.volumetricType = when (checkedId) {
9086
R.id.avVolumetricAll -> AvatarDrawable.Volumetric.ALL
@@ -94,30 +90,31 @@ class MainActivity : AppCompatActivity() {
9490
}
9591
}
9692
}
97-
avBorderGradientAngle.setOnSeekBarChangeListener(object : OnSeekBarChangeListener() {
93+
binding.avBorderGradientAngle.setOnSeekBarChangeListener(object :
94+
OnSeekBarChangeListener() {
9895
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
9996
applyToAvatars {
10097
it.borderGradientAngle = progress
10198
}
10299
}
103100
})
104101

105-
archesDegreeArea.setOnSeekBarChangeListener(object : OnSeekBarChangeListener() {
102+
binding.archesDegreeArea.setOnSeekBarChangeListener(object : OnSeekBarChangeListener() {
106103
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
107104
applyToAvatars {
108105
it.archesDegreeArea = progress
109106
}
110107
}
111108
})
112109

113-
archesCount.setOnSeekBarChangeListener(object : OnSeekBarChangeListener() {
110+
binding.archesCount.setOnSeekBarChangeListener(object : OnSeekBarChangeListener() {
114111
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
115112
applyToAvatars {
116113
it.archesCount = progress
117114
}
118115
}
119116
})
120-
archesAngle.setOnSeekBarChangeListener(object : OnSeekBarChangeListener() {
117+
binding.archesAngle.setOnSeekBarChangeListener(object : OnSeekBarChangeListener() {
121118
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
122119
applyToAvatars {
123120
it.archesAngle = progress
@@ -127,36 +124,11 @@ class MainActivity : AppCompatActivity() {
127124
}
128125

129126
private inline fun applyToAvatars(action: (AvatarView) -> Unit) {
130-
avatars_list.children.mapNotNull { it as? AvatarView }.forEach { action.invoke(it) }
127+
binding.avatarsList.children.mapNotNull { it as? AvatarView }.forEach { action.invoke(it) }
131128
}
132129

133130
private fun convertDpToPixel(dp: Int): Int {
134131
val metrics = resources.displayMetrics
135132
return dp * (metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT)
136133
}
137-
138-
private fun initCoil(context: Context): ImageLoader {
139-
val builder = ImageLoader.Builder(context)
140-
.memoryCachePolicy(CachePolicy.DISABLED)
141-
.crossfade(true)
142-
.componentRegistry {
143-
if (Build.VERSION.SDK_INT >= 28) {
144-
add(ImageDecoderDecoder(context))
145-
} else {
146-
add(GifDecoder())
147-
}
148-
add(SvgDecoder(context))
149-
}
150-
151-
if (BuildConfig.DEBUG) {
152-
builder.logger(DebugLogger())
153-
}
154-
155-
val imageLoader = builder.build()
156-
157-
Coil.setImageLoader(imageLoader)
158-
159-
return imageLoader
160-
}
161-
162134
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.goodayapps.avatarview.blur_hash;
2+
3+
final class Base83 {
4+
5+
static final char[] ALPHABET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~"
6+
.toCharArray();
7+
8+
private static int indexOf(char[] a, char key) {
9+
for (int i = 0; i < a.length; i++) {
10+
if (a[i] == key) {
11+
return i;
12+
}
13+
}
14+
return -1;
15+
}
16+
17+
static String encode(long value, int length) {
18+
char[] buffer = new char[length];
19+
encode(value, length, buffer, 0);
20+
return new String(buffer);
21+
}
22+
23+
static void encode(long value, int length, char[] buffer, int offset) {
24+
int exp = 1;
25+
for (int i = 1; i <= length; i++, exp *= 83) {
26+
int digit = (int)(value / exp % 83);
27+
buffer[offset + length - i] = ALPHABET[digit];
28+
}
29+
}
30+
31+
static int decode(String value) {
32+
int result = 0;
33+
char[] chars = value.toCharArray();
34+
for (int i = 0; i < chars.length; i++) {
35+
result = result * 83 + indexOf(ALPHABET, chars[i]);
36+
}
37+
return result;
38+
}
39+
40+
private Base83() {
41+
}
42+
}

0 commit comments

Comments
 (0)