Coder Social home page Coder Social logo

getstream / avatarview-android Goto Github PK

View Code? Open in Web Editor NEW
431.0 4.0 24.0 18.74 MB

✨ Supports loading profile images with fractional styles, shapes, borders, indicators, and initials for Android.

Home Page: https://getstream.github.io/avatarview-android/

License: Apache License 2.0

Kotlin 100.00%
android kotlin android-library image coil glide profile loading loading-images

avatarview-android's People

Contributors

skydoves avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

avatarview-android's Issues

Initials: Ability to change Font or apply Theme Font

I tested it as an replacement for an Initials Avatar View.
It's great and has more customizability than the other library I used. However it's lacking the ability to change the font or apply the Theme's Font set in styles.xml.

It would be great if that funcionality could be added.

App Gets Crashed when textInitials Contains Multiple spaces in between. For eg :- "Test Name"

Hi,
Thanks for this amazing library, I found one issue here :-
When we set textInitials which contains multiple spaces in between at that time app is crashed :-
Eg :- When I try to set textInitials = Test Name

So main issue is here :-
/** Returns parsed initials from a String. */ internal val String.parseInitials: String @JvmSynthetic inline get() { val textList = trim().split(" ") return when { textList.size > 1 -> "${textList[0][0]}${textList[1][0]}" textList[0].length > 1 -> "${textList[0][0]}${textList[0][1]}" textList[0].isNotEmpty() -> "${textList[0][0]}" else -> "" }.uppercase() }

Now now when `Test     Name` is split it gives [Test, , ,Name] here second and third space is empty

Using loadImage inside a ListAdapter onBindViewHolder

I'm trying to use AvatarView-Coil to load images inside of a ListAdapter with a ViewHolder and I'm seeing weird behavior.

Essentially in onBindViewHolder I use loadImage to load a profile picture with a String url in an AvatarView. The initial load runs fine and displays the images. Once I reload data in the adapter onBindViewHolder gets called again, but then the images are not loaded or displayed anymore.

        holder.intialsView.loadImage(favourite.contact.profilePhoto,
            onSuccess = { _, _ ->
                logi("###### onsuccess ${favourite.contact.profilePhoto}")
                holder.intialsView.avatarInitials = null
            },
            onStart = {
                logi("## loading contact profile picture for ${favourite.displayName}: ${favourite.contact.profilePhoto}")
            }, onComplete = {
                logi("## oncomplete ${favourite.contact.profilePhoto}")
            }, onError = { _, _ ->
                logi("## error getting profile picture ${favourite.contact.profilePhoto}")
                holder.intialsView.avatarInitials = favourite.displayName.extractInitials()
            })

The first time it runs it outputs this:

2022-02-24 22:22:41.920 8701-8701/com.myapp I/FavouritesAdapter: ############## onBindViewHolder for User1 
2022-02-24 22:22:41.925 8701-8701/com.myapp I/FavouritesAdapter: ## loading contact profile picture for User1: https://placekitten.com/200/200
2022-02-24 22:22:41.925 8701-8701/com.myapp I/FavouritesAdapter: ## oncomplete https://placekitten.com/200/200
2022-02-24 22:22:41.927 8701-8701/com.myapp I/FavouritesAdapter: ## loading contact profile picture for User1: https://placekitten.com/200/200
2022-02-24 22:22:41.937 8701-8701/com.myapp I/FavouritesAdapter: ############## onBindViewHolder for User2
2022-02-24 22:22:41.938 8701-8701/com.myapp I/FavouritesAdapter: ## loading contact profile picture for User2: https://placekitten.com/200/200
2022-02-24 22:22:41.939 8701-8701/com.com.myapp I/FavouritesAdapter: ## oncomplete https://placekitten.com/200/200
2022-02-24 22:22:41.940 8701-8701/com.myapp I/FavouritesAdapter: ## loading contact profile picture for User2: https://placekitten.com/200/200
2022-02-24 22:22:41.992 8701-8813/com.myapp I/Builder: ## Loading image from : https://placekitten.com/200/200
2022-02-24 22:22:41.993 8701-8868/com.myapp I/Builder: ## Loading image from : https://placekitten.com/200/200
2022-02-24 22:22:42.180 8701-8701/com.myapp I/FavouritesAdapter: ###### onsuccess https://placekitten.com/200/200
2022-02-24 22:22:42.181 8701-8701/com.myapp I/FavouritesAdapter: ###### onsuccess https://placekitten.com/200/200
2022-02-24 22:22:42.298 8701-8701/com.myapp I/FavouritesAdapter: ## oncomplete https://placekitten.com/200/200
2022-02-24 22:22:42.298 8701-8701/com.myapp I/FavouritesAdapter: ## oncomplete https://placekitten.com/200/200

The Loading image from... statements are from the ImageLoader requestInterceptor

Then, a bit later when reloading the data it outputs this:

2022-02-24 22:22:47.306 8701-8701/com.myapp I/FavouritesAdapter: ############## onBindViewHolder for User1
2022-02-24 22:22:47.308 8701-8701/com.myapp I/FavouritesAdapter: ## loading contact profile picture for User1 https://placekitten.com/200/200
2022-02-24 22:22:47.309 8701-8701/com.myapp I/FavouritesAdapter: ## oncomplete https://placekitten.com/200/200
2022-02-24 22:22:47.311 8701-8701/com.myapp I/FavouritesAdapter: ## loading contact profile picture for User1: https://placekitten.com/200/200
2022-02-24 22:22:47.312 8701-8701/com.myapp I/FavouritesAdapter: ## oncomplete https://placekitten.com/200/200
2022-02-24 22:22:47.325 8701-8701/com.myapp I/FavouritesAdapter: ############## onBindViewHolder for User2
2022-02-24 22:22:47.327 8701-8701/com.myapp I/FavouritesAdapter: ## loading contact profile picture for User2: https://placekitten.com/200/200
2022-02-24 22:22:47.328 8701-8701/com.myapp I/FavouritesAdapter: ## oncomplete https://placekitten.com/200/200
2022-02-24 22:22:47.330 8701-8701/com.myapp I/FavouritesAdapter: ## loading contact profile picture for User2: https://placekitten.com/200/200
2022-02-24 22:22:47.330 8701-8701/com.myapp I/FavouritesAdapter: ## oncomplete https://placekitten.com/200/200

The weird behavior I'm seeing is this:

  • the onStart seems to be fired twice when I call loadImage
  • the onComplete fires twice as well, once immediately after the first onStart, and a second time after onSuccess.
  • on the second run after rebinding the data, onStart is fired twice again
  • onComplete fires twice again, both immediately after the onStart
  • no Loading image from on the second run, presumably because of caching in the ImageLoader
  • on this second run onSuccess is never called (also because of caching?)
  • on this second run no images are displayed.

Am I misunderstanding the api or could this be a bug? I expected each call to loadImage to result in only one call to onStart and one call to onComplete/onSuccess and the images to be displayed after onComplete.

I'm using io.getstream:avatarview-coil:1.0.3

Supporting multiple avatars

Hello and congratulations on the amazing library.

I have a question here regarding multiple avatars.
I saw you support up to 4 avatars in one view.
But my case is a little bit different :

image

I know it's possible to implement that using a RecyclerView
and some logic with the max number of avatars to be shown so you can show the +7.

Do you intent to support a view like this in the library or is it out scope?

Using avatarview in recycler adapter doesn't work

Using avatarview in recycler adapter doesn't work

When I try to inflate layout this error comes
2022-07-23 14:49:59.117 15628-15628/com.codewithritom.anonchat E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.codewithritom.anonchat, PID: 15628
android.view.InflateException: Binary XML file line #8 in com.codewithritom.anonchat:layout/searched_user_item: Binary XML file line #8 in com.codewithritom.anonchat:layout/searched_user_item: Error inflating class io.getstream.avatarview.AvatarView
Caused by: android.view.InflateException: Binary XML file line #8 in com.codewithritom.anonchat:layout/searched_user_item: Error inflating class io.getstream.avatarview.AvatarView
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
at android.view.LayoutInflater.createView(LayoutInflater.java:863)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:1019)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:970)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1149)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1110)
at android.view.LayoutInflater.inflate(LayoutInflater.java:692)
at android.view.LayoutInflater.inflate(LayoutInflater.java:542)
at com.codewithritom.anonchat.models.SearchedUsersAdapter.onCreateViewHolder(SearchedUsersAdapter.kt:25)
at com.codewithritom.anonchat.models.SearchedUsersAdapter.onCreateViewHolder(SearchedUsersAdapter.kt:19)
at androidx.recyclerview.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:7295)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6416)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6300)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6296)
at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2330)
at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1631)
at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1591)
at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:668)
at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4309)
at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:4012)
at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4578)
at android.view.View.layout(View.java:23488)
at android.view.ViewGroup.layout(ViewGroup.java:6575)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1103)
at android.view.View.layout(View.java:23488)
at android.view.ViewGroup.layout(ViewGroup.java:6575)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
at android.view.View.layout(View.java:23488)
at android.view.ViewGroup.layout(ViewGroup.java:6575)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1103)
at android.view.View.layout(View.java:23488)
at android.view.ViewGroup.layout(ViewGroup.java:6575)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
at android.view.View.layout(View.java:23488)
at android.view.ViewGroup.layout(ViewGroup.java:6575)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1841)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1582)
at android.view.View.layout(View.java:23488)
at android.view.ViewGroup.layout(ViewGroup.java:6575)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
at android.view.View.layout(View.java:23488)
at android.view.ViewGroup.layout(ViewGroup.java:6575)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1841)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673)
2022-07-23 14:49:59.118 15628-15628/com.codewithritom.anonchat E/AndroidRuntime: at android.widget.LinearLayout.onLayout(LinearLayout.java:1582)
at android.view.View.layout(View.java:23488)
at android.view.ViewGroup.layout(ViewGroup.java:6575)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
at com.android.internal.policy.DecorView.onLayout(DecorView.java:867)
at android.view.View.layout(View.java:23488)
at android.view.ViewGroup.layout(ViewGroup.java:6575)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:4119)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3495)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2416)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9478)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1242)
at android.view.Choreographer.doCallbacks(Choreographer.java:996)
at android.view.ChoreographerExtImpl.checkScrollOptSceneEnable(ChoreographerExtImpl.java:383)
at android.view.Choreographer.doFrame(Choreographer.java:865)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1227)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:233)
at android.os.Looper.loop(Looper.java:344)
at android.app.ActivityThread.main(ActivityThread.java:8248)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:589)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1071)
Caused by: android.content.res.Resources$NotFoundException: Can't find ColorStateList from drawable resource ID #0x7f0700b2
at android.content.res.ResourcesImpl.loadColorStateList(ResourcesImpl.java:1161)
at android.content.res.Resources.loadColorStateList(Resources.java:1158)
at android.content.res.TypedArray.getColor(TypedArray.java:521)
at io.getstream.avatarview.AvatarView.initAttributes(AvatarView.kt:170)
at io.getstream.avatarview.AvatarView.(AvatarView.kt:160)
at io.getstream.avatarview.AvatarView.(AvatarView.kt:55)
at io.getstream.avatarview.AvatarView.(Unknown Source:11)
... 74 more
2022-07-23 14:49:59.298 16459-16459/? E/hritom.anoncha: Unknown bits set in runtime_flags: 0x40000000
2022-07-23 14:49:59.740 16459-16494/com.codewithritom.anonchat E/QT: [QT]file does not exist
2022-07-23 14:49:59.878 16459-16459/com.codewithritom.anonchat E/OplusCustomizeRestrictionManager: sInstance is null, start a new sInstance
2022-07-23 14:50:00.049 16459-16459/com.codewithritom.anonchat E/hritom.anoncha: ofbOpen failed with error=No such file or directory
2022-07-23 14:50:00.049 16459-16459/com.codewithritom.anonchat E/hritom.anoncha: sysOpen failed with error=No such file or directory
2022-07-23 14:50:00.301 16459-16492/com.codewithritom.anonchat E/OpenGLRenderer: Device claims wide gamut support, cannot find matching config, error = EGL_SUCCESS
2022-07-23 14:50:00.314 16459-16520/com.codewithritom.anonchat E/ion: ioctl c0044901 failed with code -1: Invalid argument
2022-07-23 14:50:00.360 16459-16492/com.codewithritom.anonchat E/OpenGLRenderer: fbcNotifyFrameComplete error: undefined symbol: fbcNotifyFrameComplete
2022-07-23 14:50:00.360 16459-16492/com.codewithritom.anonchat E/OpenGLRenderer: fbcNotifyNoRender error: undefined symbol: fbcNotifyNoRender
2022-07-23 14:50:00.387 16459-16459/com.codewithritom.anonchat E/Parcel: Reading a NULL string not supported here.

XML

<io.getstream.avatarview.AvatarView android:id = "@+id/profile_image" android:layout_width="110dp" android:layout_height="110dp" app:avatarViewBorderColor="@drawable/color_4" app:avatarViewBorderWidth="3dp" app:avatarViewIndicatorBorderColor="@color/white" app:avatarViewIndicatorBorderSizeCriteria="10" app:avatarViewIndicatorColor="@color/black" app:avatarViewIndicatorEnabled="true" app:avatarViewIndicatorPosition="bottomRight" app:avatarViewIndicatorSizeCriteria="9" app:avatarViewInitialsTextStyle="bold" app:avatarViewShape="circle" />

line 25 - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view: View = LayoutInflater.from(mcontext).inflate(R.layout.searched_user_item, parent, false) return ViewHolder(view) }

The photo goes out of the round line

1111

== Here My Code:
loadImage(
data = imageUrl,
requestBuilder = Glide.with(context)
.asDrawable()
.override(120, 120)
.circleCrop()
.dontAnimate()
.listener(object : RequestListener {
override fun onLoadFailed(
e: GlideException?,
model: Any?,
target: com.bumptech.glide.request.target.Target?,
isFirstResource: Boolean
): Boolean {
return false
}
override fun onResourceReady(
resource: Drawable?,
model: Any?,
target: com.bumptech.glide.request.target.Target?,
dataSource: DataSource?,
isFirstResource: Boolean
): Boolean {
// Image loaded successfully
return false
}
})

== Dependency
//Image Avatar View
implementation "io.getstream:avatarview-coil:1.0.7"
implementation "io.getstream:avatarview-glide:1.0.7"
implementation("com.github.Commit451.coil-transformations:transformations:2.0.2")
implementation("io.coil-kt:coil:2.2.2")

Please check this one issue and let me know if it is fix

Loading Images with Fractional Style with Glide.

Hi, there seems to be a bug when uploading multiple images with Glide.
For example, calling the avatarView1.loadImage(cats.take(4)) method will result in an error:

java.lang.IllegalStateException: You can't start or clear loads in RequestListener or Target callbacks. If you're trying to start a fallback request when a load fails, use RequestBuilder#error(RequestBuilder). Otherwise consider posting your into() or clear() calls to the main thread using a Handler instead.
        at com.bumptech.glide.request.SingleRequest.assertNotCallingCallbacks(SingleRequest.java:289)
        at com.bumptech.glide.request.SingleRequest.clear(SingleRequest.java:309)
        at com.bumptech.glide.manager.RequestTracker.clearAndRemove(RequestTracker.java:72)
        at com.bumptech.glide.RequestManager.untrack(RequestManager.java:660)
        at com.bumptech.glide.RequestManager.untrackOrDelegate(RequestManager.java:628)
        at com.bumptech.glide.RequestManager.clear(RequestManager.java:624)
        at io.getstream.avatarview.glide.AvatarBitmapLoader$loadBitmaps$1$2.invoke(AvatarBitmapLoader.kt:91)
        at io.getstream.avatarview.glide.AvatarBitmapLoader$loadBitmaps$1$2.invoke(AvatarBitmapLoader.kt:90)

The error refers to this code

awaitClose {
            requestManager.clear(avatarViewTarget)
        }

Since Glide loads images on the main thread, it seems that we can fix this problem by adding launch(Dispatchers.Main) to

   launch() {
        val avatarResults: ArrayList<AvatarResult> = arrayListOf()
        val avatarResultFlow = AvatarBitmapLoader.loadBitmaps(
            requestManager = Glide.with(this@collectAndCombineBitmaps),
            data = data,
            errorPlaceholder = errorPlaceholder
        )

But not sure if that would be the right decision.

support for Java

Is the library support for Java? If yes, can you include a sample for java using. Thank you so much for this awesome lib.

Data Loading Fail/Fallback to Initials

Hi @skydoves

Is there any way, by that I can set a fallback to Initials. Like i provided HTTP Url and initial both.
Expectation : Initially it should ajow initials when image is is downloaded then show image.

Current behaviour : If i gave both url and initials then it shows Initials always.

Correct me I missed something.

Getting initial image drawable

I was trying to get the drawable of the initial image in order to download it to local storage, however, it is not possible now. I was using this piece of code
avatarView.drawable.toBitmap()
it throws null pointer exception, stating that drawable is null all the time.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.