Improved user profile image picking
This commit is contained in:
parent
607d1722da
commit
2c4b00edb9
7 changed files with 412 additions and 360 deletions
|
@ -183,4 +183,5 @@ dependencies {
|
|||
implementation 'com.google.android.play:core:1.7.2'
|
||||
implementation 'me.jorgecastillo:androidcolorx:0.2.0'
|
||||
debugImplementation 'com.amitshekhar.android:debug-db:1.0.4'
|
||||
implementation 'com.github.dhaval2404:imagepicker:1.7.1'
|
||||
}
|
|
@ -1,38 +1,38 @@
|
|||
package code.name.monkey.retromusic.activities
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.content.Intent
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.provider.MediaStore.Images.Media
|
||||
import android.provider.MediaStore.Images.Media.getBitmap
|
||||
import android.text.TextUtils
|
||||
import android.view.MenuItem
|
||||
import android.widget.Toast
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
||||
import code.name.monkey.appthemehelper.util.MaterialUtil
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
import code.name.monkey.retromusic.App
|
||||
import code.name.monkey.retromusic.Constants.USER_BANNER
|
||||
import code.name.monkey.retromusic.Constants.USER_PROFILE
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.activities.base.AbsBaseActivity
|
||||
import code.name.monkey.retromusic.extensions.accentColor
|
||||
import code.name.monkey.retromusic.extensions.applyToolbar
|
||||
import code.name.monkey.retromusic.util.Compressor
|
||||
import code.name.monkey.retromusic.util.ImageUtil.getResizedBitmap
|
||||
import code.name.monkey.retromusic.glide.ProfileBannerGlideRequest
|
||||
import code.name.monkey.retromusic.glide.UserProfileGlideRequest
|
||||
import code.name.monkey.retromusic.util.ImageUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.afollestad.materialdialogs.list.listItems
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import com.bumptech.glide.request.RequestListener
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import com.github.dhaval2404.imagepicker.ImagePicker
|
||||
import kotlinx.android.synthetic.main.activity_user_info.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.BufferedOutputStream
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
|
@ -46,53 +46,19 @@ class UserInfoActivity : AbsBaseActivity() {
|
|||
setNavigationbarColorAuto()
|
||||
setTaskDescriptionColorAuto()
|
||||
setLightNavigationBar(true)
|
||||
|
||||
applyToolbar(toolbar)
|
||||
|
||||
MaterialUtil.setTint(nameContainer, false)
|
||||
name.setText(PreferenceUtil.getInstance(this).userName)
|
||||
|
||||
if (PreferenceUtil.getInstance(this).profileImage.isNotEmpty()) {
|
||||
loadImageFromStorage(PreferenceUtil.getInstance(this).profileImage)
|
||||
}
|
||||
if (PreferenceUtil.getInstance(this).bannerImage.isNotEmpty()) {
|
||||
loadBannerFromStorage(PreferenceUtil.getInstance(this).bannerImage)
|
||||
}
|
||||
userImage.setOnClickListener {
|
||||
MaterialDialog(this).show {
|
||||
cornerRadius(PreferenceUtil.getInstance(this@UserInfoActivity).dialogCorner)
|
||||
title(text = getString(R.string.set_photo))
|
||||
listItems(
|
||||
items = listOf(
|
||||
getString(R.string.new_profile_photo),
|
||||
getString(R.string.remove_profile_photo)
|
||||
)
|
||||
) { _, position, _ ->
|
||||
when (position) {
|
||||
0 -> pickNewPhoto()
|
||||
1 -> PreferenceUtil.getInstance(this@UserInfoActivity).saveProfileImage("")
|
||||
}
|
||||
}
|
||||
}
|
||||
pickNewPhoto()
|
||||
}
|
||||
|
||||
bannerSelect.setOnClickListener {
|
||||
MaterialDialog(this).show {
|
||||
cornerRadius(PreferenceUtil.getInstance(this@UserInfoActivity).dialogCorner)
|
||||
title(R.string.select_banner_photo)
|
||||
listItems(
|
||||
items = listOf(
|
||||
getString(R.string.new_banner_photo),
|
||||
getString(R.string.remove_banner_photo)
|
||||
)
|
||||
)
|
||||
{ _, position, _ ->
|
||||
when (position) {
|
||||
0 -> selectBannerImage()
|
||||
1 -> PreferenceUtil.getInstance(this@UserInfoActivity)
|
||||
.setBannerImagePath("")
|
||||
}
|
||||
}
|
||||
}
|
||||
selectBannerImage()
|
||||
}
|
||||
|
||||
next.setOnClickListener {
|
||||
val nameString = name.text.toString().trim { it <= ' ' }
|
||||
if (TextUtils.isEmpty(nameString)) {
|
||||
|
@ -103,17 +69,26 @@ class UserInfoActivity : AbsBaseActivity() {
|
|||
setResult(Activity.RESULT_OK)
|
||||
finish()
|
||||
}
|
||||
next.backgroundTintList = ColorStateList.valueOf(ThemeStore.accentColor(this))
|
||||
ColorStateList.valueOf(
|
||||
MaterialValueHelper.getPrimaryTextColor(
|
||||
this,
|
||||
ColorUtil.isColorLight(ThemeStore.accentColor(this))
|
||||
)
|
||||
)
|
||||
.apply {
|
||||
next.setTextColor(this)
|
||||
next.iconTint = this
|
||||
}
|
||||
|
||||
val textColor =
|
||||
MaterialValueHelper.getPrimaryTextColor(this, ColorUtil.isColorLight(accentColor()))
|
||||
next.backgroundTintList = ColorStateList.valueOf(accentColor())
|
||||
next.iconTint = ColorStateList.valueOf(textColor)
|
||||
next.setTextColor(textColor)
|
||||
loadProfile()
|
||||
}
|
||||
|
||||
private fun loadProfile() {
|
||||
bannerImage?.let {
|
||||
ProfileBannerGlideRequest.Builder.from(
|
||||
Glide.with(this),
|
||||
ProfileBannerGlideRequest.getBannerModel()
|
||||
).build().into(it)
|
||||
}
|
||||
UserProfileGlideRequest.Builder.from(
|
||||
Glide.with(this),
|
||||
UserProfileGlideRequest.getUserModel()
|
||||
).build().into(userImage)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
|
@ -124,141 +99,138 @@ class UserInfoActivity : AbsBaseActivity() {
|
|||
}
|
||||
|
||||
private fun selectBannerImage() {
|
||||
val pickImageIntent = Intent(Intent.ACTION_PICK, Media.EXTERNAL_CONTENT_URI)
|
||||
pickImageIntent.type = "image/*"
|
||||
//pickImageIntent.putExtra("crop", "true")
|
||||
pickImageIntent.putExtra("outputX", 1290)
|
||||
pickImageIntent.putExtra("outputY", 720)
|
||||
pickImageIntent.putExtra("aspectX", 16)
|
||||
pickImageIntent.putExtra("aspectY", 9)
|
||||
pickImageIntent.putExtra("scale", true)
|
||||
//intent.setAction(Intent.ACTION_GET_CONTENT);
|
||||
startActivityForResult(
|
||||
Intent.createChooser(pickImageIntent, "Select Picture"),
|
||||
PICK_BANNER_REQUEST
|
||||
)
|
||||
ImagePicker.with(this)
|
||||
.compress(1024)
|
||||
.crop(16f, 9f)
|
||||
.start(PICK_BANNER_REQUEST)
|
||||
}
|
||||
|
||||
private fun pickNewPhoto() {
|
||||
val pickImageIntent = Intent(Intent.ACTION_PICK, Media.EXTERNAL_CONTENT_URI)
|
||||
pickImageIntent.type = "image/*"
|
||||
pickImageIntent.putExtra("crop", "true")
|
||||
pickImageIntent.putExtra("outputX", 512)
|
||||
pickImageIntent.putExtra("outputY", 512)
|
||||
pickImageIntent.putExtra("aspectX", 1)
|
||||
pickImageIntent.putExtra("aspectY", 1)
|
||||
pickImageIntent.putExtra("scale", true)
|
||||
startActivityForResult(
|
||||
Intent.createChooser(pickImageIntent, "Select Picture"),
|
||||
PICK_IMAGE_REQUEST
|
||||
)
|
||||
ImagePicker.with(this)
|
||||
.galleryOnly()
|
||||
.cropSquare()
|
||||
.compress(1024)
|
||||
.start(PICK_IMAGE_REQUEST)
|
||||
}
|
||||
|
||||
|
||||
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (resultCode == Activity.RESULT_OK && data != null) {
|
||||
when (requestCode) {
|
||||
PICK_IMAGE_REQUEST -> {
|
||||
try {
|
||||
data.data?.let {
|
||||
val bitmap = getResizedBitmap(
|
||||
getBitmap(contentResolver, it),
|
||||
PROFILE_ICON_SIZE
|
||||
)
|
||||
val profileImagePath = saveToInternalStorage(bitmap, USER_PROFILE)
|
||||
PreferenceUtil.getInstance(this).saveProfileImage(profileImagePath)
|
||||
loadImageFromStorage(profileImagePath)
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
if (resultCode == Activity.RESULT_OK && requestCode == PICK_IMAGE_REQUEST) {
|
||||
val fileUri = data?.data
|
||||
fileUri?.let { setAndSaveUserImage(it) }
|
||||
} else if (resultCode == Activity.RESULT_OK && requestCode == PICK_BANNER_REQUEST) {
|
||||
val fileUri = data?.data
|
||||
fileUri?.let { setAndSaveBannerImage(it) }
|
||||
} else if (resultCode == ImagePicker.RESULT_ERROR) {
|
||||
Toast.makeText(this, ImagePicker.getError(data), Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
Toast.makeText(this, "Task Cancelled", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setAndSaveBannerImage(fileUri: Uri) {
|
||||
Glide.with(this)
|
||||
.load(fileUri)
|
||||
.asBitmap()
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.listener(object : RequestListener<Any, Bitmap> {
|
||||
override fun onException(
|
||||
e: java.lang.Exception?,
|
||||
model: Any?,
|
||||
target: Target<Bitmap>?,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
return false
|
||||
}
|
||||
PICK_BANNER_REQUEST -> {
|
||||
try {
|
||||
data.data?.let {
|
||||
val bitmap = getBitmap(contentResolver, it)
|
||||
val profileImagePath = saveToInternalStorage(bitmap, USER_BANNER)
|
||||
PreferenceUtil.getInstance(this).setBannerImagePath(profileImagePath)
|
||||
loadBannerFromStorage(profileImagePath)
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
override fun onResourceReady(
|
||||
resource: Bitmap?,
|
||||
model: Any?,
|
||||
target: Target<Bitmap>?,
|
||||
isFromMemoryCache: Boolean,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
resource?.let { saveBannerImage(it) }
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.into(bannerImage)
|
||||
}
|
||||
|
||||
private fun getImagePath(aUri: Uri, aSelection: String?): String? {
|
||||
var path: String? = null
|
||||
val cursor = App.getContext().contentResolver.query(aUri, null, aSelection, null, null)
|
||||
if (cursor != null) {
|
||||
if (cursor.moveToFirst()) {
|
||||
path = cursor.getString(cursor.getColumnIndex(Media.DATA))
|
||||
}
|
||||
cursor.close()
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
private fun loadBannerFromStorage(profileImagePath: String) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
val bitmap = Compressor(this@UserInfoActivity).setQuality(100)
|
||||
.setCompressFormat(Bitmap.CompressFormat.WEBP)
|
||||
.compressToBitmap(File(profileImagePath, USER_BANNER))
|
||||
withContext(Dispatchers.Main) { bannerImage.setImageBitmap(bitmap) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadImageFromStorage(path: String) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
val bitmap = Compressor(this@UserInfoActivity)
|
||||
.setMaxHeight(300)
|
||||
.setMaxWidth(300)
|
||||
.setQuality(75)
|
||||
.setCompressFormat(Bitmap.CompressFormat.WEBP)
|
||||
.compressToBitmap(File(path, USER_PROFILE))
|
||||
withContext(Dispatchers.Main) { userImage.setImageBitmap(bitmap) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveToInternalStorage(bitmapImage: Bitmap, userBanner: String): String {
|
||||
val cw = ContextWrapper(this)
|
||||
val directory = cw.getDir("imageDir", Context.MODE_PRIVATE)
|
||||
val myPath = File(directory, userBanner)
|
||||
var fos: FileOutputStream? = null
|
||||
try {
|
||||
fos = FileOutputStream(myPath)
|
||||
// Use the compress method on the BitMap object to write image to the OutputStream
|
||||
bitmapImage.compress(Bitmap.CompressFormat.WEBP, 100, fos)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
} finally {
|
||||
private fun saveBannerImage(bitmap: Bitmap) {
|
||||
CoroutineScope(Dispatchers.IO).launch() {
|
||||
val appDir = applicationContext.filesDir
|
||||
val file = File(appDir, USER_BANNER)
|
||||
var successful = false
|
||||
try {
|
||||
fos?.close()
|
||||
val os = BufferedOutputStream(FileOutputStream(file))
|
||||
successful = ImageUtil.resizeBitmap(bitmap, 2048)
|
||||
.compress(Bitmap.CompressFormat.WEBP, 100, os)
|
||||
os.close()
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
if (successful) {
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(this@UserInfoActivity, "Done", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setAndSaveUserImage(fileUri: Uri) {
|
||||
Glide.with(this)
|
||||
.load(fileUri)
|
||||
.asBitmap()
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.listener(object : RequestListener<Any, Bitmap> {
|
||||
override fun onException(
|
||||
e: java.lang.Exception?,
|
||||
model: Any?,
|
||||
target: Target<Bitmap>?,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onResourceReady(
|
||||
resource: Bitmap?,
|
||||
model: Any?,
|
||||
target: Target<Bitmap>?,
|
||||
isFromMemoryCache: Boolean,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
resource?.let { saveImage(it) }
|
||||
return false
|
||||
}
|
||||
})
|
||||
.into(userImage)
|
||||
}
|
||||
|
||||
private fun saveImage(bitmap: Bitmap) {
|
||||
CoroutineScope(Dispatchers.IO).launch() {
|
||||
val appDir = applicationContext.filesDir
|
||||
val file = File(appDir, USER_PROFILE)
|
||||
var successful = false
|
||||
try {
|
||||
val os = BufferedOutputStream(FileOutputStream(file))
|
||||
successful = ImageUtil.resizeBitmap(bitmap, 2048)
|
||||
.compress(Bitmap.CompressFormat.WEBP, 100, os)
|
||||
os.close()
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
if (successful) {
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(this@UserInfoActivity, "Done", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
return directory.absolutePath
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val PICK_IMAGE_REQUEST = 9002
|
||||
private const val PICK_BANNER_REQUEST = 9004
|
||||
private const val PROFILE_ICON_SIZE = 400
|
||||
}
|
||||
}
|
||||
|
||||
fun Activity.pickImage(requestCode: Int) {
|
||||
Intent(Intent.ACTION_GET_CONTENT).apply {
|
||||
addCategory(Intent.CATEGORY_OPENABLE)
|
||||
type = "image/*"
|
||||
startActivityForResult(this, requestCode)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,13 +22,11 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.TintHelper
|
||||
import code.name.monkey.retromusic.Constants
|
||||
import code.name.monkey.retromusic.Constants.USER_BANNER
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.adapter.HomeAdapter
|
||||
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
|
||||
import code.name.monkey.retromusic.glide.ProfileBannerGlideRequest
|
||||
import code.name.monkey.retromusic.glide.UserProfileGlideRequest
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks
|
||||
import code.name.monkey.retromusic.loaders.SongLoader
|
||||
|
@ -38,12 +36,9 @@ import code.name.monkey.retromusic.model.smartplaylist.MyTopTracksPlaylist
|
|||
import code.name.monkey.retromusic.util.NavigationUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import kotlinx.android.synthetic.main.abs_playlists.*
|
||||
import kotlinx.android.synthetic.main.fragment_banner_home.*
|
||||
import kotlinx.android.synthetic.main.home_content.*
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallbacks {
|
||||
|
||||
|
@ -63,31 +58,10 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
|
|||
}
|
||||
|
||||
private fun loadImageFromStorage() {
|
||||
Glide.with(requireContext())
|
||||
.load(
|
||||
File(
|
||||
PreferenceUtil.getInstance(requireContext()).profileImage,
|
||||
Constants.USER_PROFILE
|
||||
)
|
||||
)
|
||||
.asBitmap()
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.skipMemoryCache(true)
|
||||
.placeholder(
|
||||
TintHelper.createTintedDrawable(
|
||||
requireContext(),
|
||||
R.drawable.ic_account_white_24dp,
|
||||
ThemeStore.accentColor(requireContext())
|
||||
)
|
||||
)
|
||||
.error(
|
||||
TintHelper.createTintedDrawable(
|
||||
requireContext(),
|
||||
R.drawable.ic_account_white_24dp,
|
||||
ThemeStore.accentColor(requireContext())
|
||||
)
|
||||
)
|
||||
.into(userImage)
|
||||
UserProfileGlideRequest.Builder.from(
|
||||
Glide.with(requireActivity()),
|
||||
UserProfileGlideRequest.getUserModel()
|
||||
).build().into(userImage)
|
||||
}
|
||||
|
||||
private val displayMetrics: DisplayMetrics
|
||||
|
@ -151,58 +125,24 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
|
|||
homeModel.sections.observe(viewLifecycleOwner, androidx.lifecycle.Observer { sections ->
|
||||
homeAdapter.swapData(sections)
|
||||
})
|
||||
loadProfile()
|
||||
}
|
||||
|
||||
override fun handleBackPress(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
getTimeOfTheDay()
|
||||
}
|
||||
|
||||
private fun getTimeOfTheDay() {
|
||||
val calendar = Calendar.getInstance()
|
||||
val timeOfDay = calendar.get(Calendar.HOUR_OF_DAY)
|
||||
var images = arrayOf<String>()
|
||||
when (timeOfDay) {
|
||||
in 0..5 -> images = resources.getStringArray(R.array.night)
|
||||
in 6..11 -> images = resources.getStringArray(R.array.morning)
|
||||
in 12..15 -> images = resources.getStringArray(R.array.after_noon)
|
||||
in 16..19 -> images = resources.getStringArray(R.array.evening)
|
||||
in 20..23 -> images = resources.getStringArray(R.array.night)
|
||||
}
|
||||
val day = images[Random().nextInt(images.size)]
|
||||
loadTimeImage(day)
|
||||
}
|
||||
|
||||
private fun loadTimeImage(day: String) {
|
||||
private fun loadProfile() {
|
||||
bannerImage?.let {
|
||||
val request = Glide.with(requireContext())
|
||||
if (PreferenceUtil.getInstance(requireContext()).bannerImage.isEmpty()) {
|
||||
request.load(day)
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.skipMemoryCache(true)
|
||||
.placeholder(R.drawable.material_design_default)
|
||||
.error(R.drawable.material_design_default)
|
||||
.into(it)
|
||||
} else {
|
||||
request.load(
|
||||
File(
|
||||
PreferenceUtil.getInstance(requireContext()).bannerImage,
|
||||
USER_BANNER
|
||||
)
|
||||
)
|
||||
.asBitmap()
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.skipMemoryCache(true)
|
||||
.placeholder(R.drawable.material_design_default)
|
||||
.error(R.drawable.material_design_default)
|
||||
.into(it)
|
||||
}
|
||||
ProfileBannerGlideRequest.Builder.from(
|
||||
Glide.with(requireContext()),
|
||||
ProfileBannerGlideRequest.getBannerModel()
|
||||
).build().into(it)
|
||||
}
|
||||
loadImageFromStorage()
|
||||
UserProfileGlideRequest.Builder.from(
|
||||
Glide.with(requireActivity()),
|
||||
UserProfileGlideRequest.getUserModel()
|
||||
).build().into(userImage)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
package code.name.monkey.retromusic.glide;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.bumptech.glide.BitmapRequestBuilder;
|
||||
import com.bumptech.glide.BitmapTypeRequest;
|
||||
import com.bumptech.glide.RequestManager;
|
||||
import com.bumptech.glide.load.Key;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.signature.MediaStoreSignature;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import code.name.monkey.retromusic.App;
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
||||
import static code.name.monkey.retromusic.Constants.USER_BANNER;
|
||||
|
||||
public class ProfileBannerGlideRequest {
|
||||
private static final DiskCacheStrategy DEFAULT_DISK_CACHE_STRATEGY = DiskCacheStrategy.NONE;
|
||||
private static final int DEFAULT_ERROR_IMAGE = R.drawable.material_design_default;
|
||||
private static final int DEFAULT_ANIMATION = android.R.anim.fade_in;
|
||||
|
||||
public static File getBannerModel() {
|
||||
File dir = App.Companion.getContext().getFilesDir();
|
||||
return new File(dir, USER_BANNER);
|
||||
}
|
||||
|
||||
private static BitmapTypeRequest<File> createBaseRequest(RequestManager requestManager, File profile) {
|
||||
return requestManager.load(profile).asBitmap();
|
||||
}
|
||||
|
||||
private static Key createSignature(File file) {
|
||||
return new MediaStoreSignature("", file.lastModified(), 0);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private RequestManager requestManager;
|
||||
private File profile;
|
||||
|
||||
private Builder(RequestManager requestManager, File profile) {
|
||||
this.requestManager = requestManager;
|
||||
this.profile = profile;
|
||||
}
|
||||
|
||||
public static Builder from(@NonNull RequestManager requestManager, File profile) {
|
||||
return new Builder(requestManager, profile);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public BitmapRequestBuilder<File, Bitmap> build() {
|
||||
//noinspection unchecked
|
||||
return createBaseRequest(requestManager, profile)
|
||||
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
|
||||
.placeholder(DEFAULT_ERROR_IMAGE)
|
||||
.animate(DEFAULT_ANIMATION)
|
||||
.signature(createSignature(profile));
|
||||
}
|
||||
}
|
||||
|
||||
public static class BitmapBuilder {
|
||||
private final Builder builder;
|
||||
|
||||
BitmapBuilder(Builder builder) {
|
||||
this.builder = builder;
|
||||
}
|
||||
|
||||
public BitmapRequestBuilder<?, Bitmap> build() {
|
||||
//noinspection unchecked
|
||||
return createBaseRequest(builder.requestManager, builder.profile)
|
||||
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
|
||||
.error(DEFAULT_ERROR_IMAGE)
|
||||
.animate(DEFAULT_ANIMATION)
|
||||
.signature(createSignature(builder.profile));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package code.name.monkey.retromusic.glide;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.bumptech.glide.BitmapRequestBuilder;
|
||||
import com.bumptech.glide.BitmapTypeRequest;
|
||||
import com.bumptech.glide.RequestManager;
|
||||
import com.bumptech.glide.load.Key;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.signature.MediaStoreSignature;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import code.name.monkey.retromusic.App;
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
||||
import static code.name.monkey.retromusic.Constants.USER_PROFILE;
|
||||
|
||||
public class UserProfileGlideRequest {
|
||||
private static final DiskCacheStrategy DEFAULT_DISK_CACHE_STRATEGY = DiskCacheStrategy.NONE;
|
||||
private static final int DEFAULT_ERROR_IMAGE = R.drawable.ic_account_white_24dp;
|
||||
private static final int DEFAULT_ANIMATION = android.R.anim.fade_in;
|
||||
|
||||
public static File getUserModel() {
|
||||
File dir = App.Companion.getContext().getFilesDir();
|
||||
return new File(dir, USER_PROFILE);
|
||||
}
|
||||
|
||||
private static BitmapTypeRequest<File> createBaseRequest(RequestManager requestManager, File profile) {
|
||||
return requestManager.load(profile).asBitmap();
|
||||
}
|
||||
|
||||
private static Key createSignature(File file) {
|
||||
return new MediaStoreSignature("", file.lastModified(), 0);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private RequestManager requestManager;
|
||||
private File profile;
|
||||
|
||||
private Builder(RequestManager requestManager, File profile) {
|
||||
this.requestManager = requestManager;
|
||||
this.profile = profile;
|
||||
}
|
||||
|
||||
public static Builder from(@NonNull RequestManager requestManager, File profile) {
|
||||
return new Builder(requestManager, profile);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public BitmapRequestBuilder<File, Bitmap> build() {
|
||||
//noinspection unchecked
|
||||
return createBaseRequest(requestManager, profile)
|
||||
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
|
||||
.placeholder(DEFAULT_ERROR_IMAGE)
|
||||
.animate(DEFAULT_ANIMATION)
|
||||
.signature(createSignature(profile));
|
||||
}
|
||||
}
|
||||
|
||||
public static class BitmapBuilder {
|
||||
private final Builder builder;
|
||||
|
||||
BitmapBuilder(Builder builder) {
|
||||
this.builder = builder;
|
||||
}
|
||||
|
||||
public BitmapRequestBuilder<?, Bitmap> build() {
|
||||
//noinspection unchecked
|
||||
return createBaseRequest(builder.requestManager, builder.profile)
|
||||
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
|
||||
.error(DEFAULT_ERROR_IMAGE)
|
||||
.animate(DEFAULT_ANIMATION)
|
||||
.signature(createSignature(builder.profile));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -67,11 +67,8 @@ import static code.name.monkey.retromusic.helper.SortOrder.SongSortOrder;
|
|||
public final class PreferenceUtil {
|
||||
|
||||
public static final String LIBRARY_CATEGORIES = "library_categories";
|
||||
|
||||
public static final String EXTRA_SONG_INFO = "extra_song_info";
|
||||
|
||||
public static final String DESATURATED_COLOR = "desaturated_color";
|
||||
|
||||
public static final String BLACK_THEME = "black_theme";
|
||||
public static final String KEEP_SCREEN_ON = "keep_screen_on";
|
||||
public static final String TOGGLE_HOME_BANNER = "toggle_home_banner";
|
||||
|
@ -549,9 +546,6 @@ public final class PreferenceUtil {
|
|||
editor.apply();
|
||||
}
|
||||
|
||||
public String getProfileImage() {
|
||||
return mPreferences.getString(PROFILE_IMAGE_PATH, "");
|
||||
}
|
||||
|
||||
public final String getSAFSDCardUri() {
|
||||
return mPreferences.getString(SAF_SDCARD_URI, "");
|
||||
|
@ -700,11 +694,6 @@ public final class PreferenceUtil {
|
|||
}
|
||||
|
||||
|
||||
public void saveProfileImage(String profileImagePath) {
|
||||
mPreferences.edit().putString(PROFILE_IMAGE_PATH, profileImagePath).apply();
|
||||
}
|
||||
|
||||
|
||||
public void setAlbumGridSize(final int gridSize) {
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putInt(ALBUM_GRID_SIZE, gridSize);
|
||||
|
|
|
@ -23,122 +23,114 @@
|
|||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/imageContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/imageContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
app:cardCornerRadius="12dp"
|
||||
app:cardUseCompatPadding="true"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/bannerImage"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="156dp"
|
||||
android:scaleType="centerCrop"
|
||||
app:srcCompat="@drawable/material_design_default" />
|
||||
|
||||
<View
|
||||
android:id="@+id/bannerSelect"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="156dp"
|
||||
android:background="@color/twenty_percent_black_overlay" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:background="?roundSelector"
|
||||
android:padding="16dp"
|
||||
app:srcCompat="@drawable/ic_add_photo_white_24dp" />
|
||||
|
||||
|
||||
</FrameLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
android:layout_margin="16dp"
|
||||
app:cardCornerRadius="12dp"
|
||||
app:cardElevation="8dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/userImageContainer"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|center_horizontal"
|
||||
android:layout_marginStart="16dp"
|
||||
android:elevation="8dp"
|
||||
android:transitionName="@string/transition_user_image"
|
||||
app:layout_constraintBottom_toBottomOf="@id/imageContainer"
|
||||
app:layout_constraintStart_toStartOf="@+id/imageContainer"
|
||||
app:layout_constraintTop_toBottomOf="@id/imageContainer">
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<code.name.monkey.retromusic.views.RetroShapeableImageView
|
||||
android:id="@+id/userImage"
|
||||
android:layout_width="72dp"
|
||||
android:layout_height="72dp"
|
||||
android:layout_gravity="center"
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/bannerImage"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="156dp"
|
||||
android:scaleType="centerCrop"
|
||||
app:retroCornerSize="36dp"
|
||||
app:srcCompat="@drawable/ic_person_flat"
|
||||
app:strokeColor="?attr/colorSurface"
|
||||
app:strokeWidth="2dp" />
|
||||
app:srcCompat="@drawable/material_design_default" />
|
||||
|
||||
<View
|
||||
android:id="@+id/bannerSelect"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="156dp"
|
||||
android:background="@color/twenty_percent_black_overlay" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="16dp"
|
||||
android:gravity="center"
|
||||
android:padding="12dp"
|
||||
android:src="@drawable/ic_add_photo_white_24dp"
|
||||
app:tint="?attr/colorControlNormal" />
|
||||
</FrameLayout>
|
||||
android:layout_gravity="end"
|
||||
android:background="?roundSelector"
|
||||
android:padding="16dp"
|
||||
app:srcCompat="@drawable/ic_add_photo_white_24dp" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/nameContainer"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
</FrameLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/userImageContainer"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|center_horizontal"
|
||||
android:layout_marginStart="16dp"
|
||||
android:elevation="8dp"
|
||||
android:transitionName="@string/transition_user_image"
|
||||
app:layout_constraintBottom_toBottomOf="@id/imageContainer"
|
||||
app:layout_constraintEnd_toEndOf="@id/imageContainer"
|
||||
app:layout_constraintStart_toStartOf="@+id/imageContainer"
|
||||
app:layout_constraintTop_toBottomOf="@id/imageContainer">
|
||||
|
||||
<code.name.monkey.retromusic.views.RetroShapeableImageView
|
||||
android:id="@+id/userImage"
|
||||
android:layout_width="72dp"
|
||||
android:layout_height="72dp"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="centerCrop"
|
||||
app:retroCornerSize="36dp"
|
||||
app:srcCompat="@drawable/ic_person_flat"
|
||||
app:strokeColor="?attr/colorSurface"
|
||||
app:strokeWidth="2dp" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="16dp"
|
||||
android:gravity="center"
|
||||
android:padding="12dp"
|
||||
android:src="@drawable/ic_add_photo_white_24dp"
|
||||
app:tint="?attr/colorControlNormal" />
|
||||
</FrameLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/nameContainer"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
app:hintAnimationEnabled="true"
|
||||
app:hintEnabled="true"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/userImageContainer">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
app:hintAnimationEnabled="true"
|
||||
app:hintEnabled="true"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/userImageContainer">
|
||||
android:autofillHints="name"
|
||||
android:hint="@string/my_name"
|
||||
android:importantForAutofill="yes"
|
||||
android:inputType="textPersonName|textCapWords|text"
|
||||
android:textAppearance="@style/TextViewSubtitle1"
|
||||
tools:text="@tools:sample/full_names" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:autofillHints="name"
|
||||
android:hint="@string/my_name"
|
||||
android:importantForAutofill="yes"
|
||||
android:inputType="textPersonName|textCapWords|text"
|
||||
android:textAppearance="@style/TextViewSubtitle1"
|
||||
tools:text="@tools:sample/full_names" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
android:id="@+id/next"
|
||||
|
|
Loading…
Reference in a new issue