Android: 通过滑动下载绘图
Android: Download drawable via glide
我正在尝试更换适配器中的 radiobutton.buttonDrawable
。从我的 drawable 文件夹中选择静态 drawables 是可行的。我现在想要的是从我的 cloud-firestore-storage 下载可绘制对象(.svg 文件),将它们转换为可绘制对象并将它们设置为单选按钮。
我当前的实现不起作用,因为它什么都不做(不改变任何东西)。我已经检查了网址 (getItem(position).icon),它们似乎是正确的。
当前方法
class ShopFilterItemAdapter @Inject constructor(
// @ApplicationContext private val context: Context
) : ListAdapter<ShopFilterCategory, ShopFilterItemAdapter.ShopFilterViewHolder>(Companion) {
private var checkedRadioButton: CompoundButton? = null
var defaultCheckedId: Int = 0
private lateinit var listener: OnItemSelectedListener
companion object: DiffUtil.ItemCallback<ShopFilterCategory>() {
override fun areItemsTheSame(oldItem: ShopFilterCategory, newItem: ShopFilterCategory): Boolean = oldItem === newItem
override fun areContentsTheSame(oldItem: ShopFilterCategory, newItem: ShopFilterCategory): Boolean = oldItem == newItem
}
inner class ShopFilterViewHolder(val binding: ShopFilterListItemBinding) : RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ShopFilterViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = ShopFilterListItemBinding.inflate(layoutInflater, parent, false)
return ShopFilterViewHolder(binding)
}
override fun onBindViewHolder(holder: ShopFilterViewHolder, position: Int) {
holder.binding.filterItem = getItem(position)
if (checkedRadioButton == null && defaultCheckedId == position) holder.binding.rbItem.isChecked = true
if (holder.binding.rbItem.isChecked) checkedRadioButton = holder.binding.rbItem
// Trying to load the images here
Glide.with(holder.binding.root)
.asDrawable()
.load(getItem(position).icon)
.into(object : CustomTarget<Drawable>() {
override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) {
holder.binding.rbItem.buttonDrawable = resource
}
override fun onLoadCleared(placeholder: Drawable?) {
TODO("Not yet implemented")
}
})
holder.binding.executePendingBindings()
}
编辑
我错了一部分,它抛出了一个错误:
java.io.IOException: java.lang.RuntimeException: setDataSourceCallback failed: status = 0x80000000
at com.bumptech.glide.load.resource.bitmap.VideoDecoder.decode(VideoDecoder.java:185)
at com.bumptech.glide.load.engine.DecodePath.decodeResourceWithList(DecodePath.java:92)
at com.bumptech.glide.load.engine.DecodePath.decodeResource(DecodePath.java:70)
at com.bumptech.glide.load.engine.DecodePath.decode(DecodePath.java:59)
at com.bumptech.glide.load.engine.LoadPath.loadWithExceptionList(LoadPath.java:76)
at com.bumptech.glide.load.engine.LoadPath.load(LoadPath.java:57)
at com.bumptech.glide.load.engine.DecodeJob.runLoadPath(DecodeJob.java:524)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromFetcher(DecodeJob.java:488)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromData(DecodeJob.java:474)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromRetrievedData(DecodeJob.java:426)
at com.bumptech.glide.load.engine.DecodeJob.onDataFetcherReady(DecodeJob.java:390)
at com.bumptech.glide.load.engine.SourceGenerator.onDataFetcherReady(SourceGenerator.java:176)
at com.bumptech.glide.load.engine.DataCacheGenerator.onDataReady(DataCacheGenerator.java:94)
at com.bumptech.glide.load.model.ByteBufferFileLoader$ByteBufferFetcher.loadData(ByteBufferFileLoader.java:70)
at com.bumptech.glide.load.engine.DataCacheGenerator.startNext(DataCacheGenerator.java:74)
at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:50)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:279)
at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory.run(GlideExecutor.java:393)
Caused by: java.lang.RuntimeException: setDataSourceCallback failed: status = 0x80000000
at android.media.MediaMetadataRetriever._setDataSource(Native Method)
at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:210)
at com.bumptech.glide.load.resource.bitmap.VideoDecoder$ByteBufferInitializer.initialize(VideoDecoder.java:316)
at com.bumptech.glide.load.resource.bitmap.VideoDecoder$ByteBufferInitializer.initialize(VideoDecoder.java:310)
at com.bumptech.glide.load.resource.bitmap.VideoDecoder.decode(VideoDecoder.java:173)
at com.bumptech.glide.load.engine.DecodePath.decodeResourceWithList(DecodePath.java:92)
at com.bumptech.glide.load.engine.DecodePath.decodeResource(DecodePath.java:70)
at com.bumptech.glide.load.engine.DecodePath.decode(DecodePath.java:59)
at com.bumptech.glide.load.engine.LoadPath.loadWithExceptionList(LoadPath.java:76)
at com.bumptech.glide.load.engine.LoadPath.load(LoadPath.java:57)
at com.bumptech.glide.load.engine.DecodeJob.runLoadPath(DecodeJob.java:524)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromFetcher(DecodeJob.java:488)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromData(DecodeJob.java:474)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromRetrievedData(DecodeJob.java:426)
at com.bumptech.glide.load.engine.DecodeJob.onDataFetcherReady(DecodeJob.java:390)
at com.bumptech.glide.load.engine.SourceGenerator.onDataFetcherReady(SourceGenerator.java:176)
at com.bumptech.glide.load.engine.DataCacheGenerator.onDataReady(DataCacheGenerator.java:94)
at com.bumptech.glide.load.model.ByteBufferFileLoader$ByteBufferFetcher.loadData(ByteBufferFileLoader.java:70)
at com.bumptech.glide.load.engine.DataCacheGenerator.startNext(DataCacheGenerator.java:74)
at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:50)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:279)
at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory.run(GlideExecutor.java:393)
我已经设法解决了这个问题,不幸的是,用滑行是不可能的,但是用线圈是不可能的。
1。添加必要的依赖项
implementation "io.coil-kt:coil-base:1.1.0" // or "io.coil-kt:coil-1.1.0" if you don't want to use dependency Injection
implementation "io.coil-kt:coil-svg:1.1.0"
2。构建 ImageLoader Singleton 并添加 SVGEndoder
@Provides
@Singleton
fun provideImageLoader(@ApplicationContext context: Context) = ImageLoader.Builder(context)
.componentRegistry { add(SvgDecoder(context)) }
.build()
3.Build 请求
fun buildRequest(context: Context, data: Any, target: RadioButton) = ImageRequest.Builder(context)
.data(data)
.target { drawable -> target.buttonDrawable = drawable }
.size(64, 60) // unfortunately I was not able to get the default radiobutton.drawable size here
.build()
4。适配器内部
override fun onBindViewHolder(holder: YourHolder, position: Int) {
val newRequest = shopFilterValidator.buildRequest(
context = holder.binding.rbItem.context,
data = getItem(position).icon, // here a url from firebase
target = holder.binding.rbItem
)
imageLoader.enqueue(newRequest)
}
这会将 svg 图像加载为可绘制对象并将它们作为 radiobutton.drawable
我正在尝试更换适配器中的 radiobutton.buttonDrawable
。从我的 drawable 文件夹中选择静态 drawables 是可行的。我现在想要的是从我的 cloud-firestore-storage 下载可绘制对象(.svg 文件),将它们转换为可绘制对象并将它们设置为单选按钮。
我当前的实现不起作用,因为它什么都不做(不改变任何东西)。我已经检查了网址 (getItem(position).icon),它们似乎是正确的。
当前方法
class ShopFilterItemAdapter @Inject constructor(
// @ApplicationContext private val context: Context
) : ListAdapter<ShopFilterCategory, ShopFilterItemAdapter.ShopFilterViewHolder>(Companion) {
private var checkedRadioButton: CompoundButton? = null
var defaultCheckedId: Int = 0
private lateinit var listener: OnItemSelectedListener
companion object: DiffUtil.ItemCallback<ShopFilterCategory>() {
override fun areItemsTheSame(oldItem: ShopFilterCategory, newItem: ShopFilterCategory): Boolean = oldItem === newItem
override fun areContentsTheSame(oldItem: ShopFilterCategory, newItem: ShopFilterCategory): Boolean = oldItem == newItem
}
inner class ShopFilterViewHolder(val binding: ShopFilterListItemBinding) : RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ShopFilterViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = ShopFilterListItemBinding.inflate(layoutInflater, parent, false)
return ShopFilterViewHolder(binding)
}
override fun onBindViewHolder(holder: ShopFilterViewHolder, position: Int) {
holder.binding.filterItem = getItem(position)
if (checkedRadioButton == null && defaultCheckedId == position) holder.binding.rbItem.isChecked = true
if (holder.binding.rbItem.isChecked) checkedRadioButton = holder.binding.rbItem
// Trying to load the images here
Glide.with(holder.binding.root)
.asDrawable()
.load(getItem(position).icon)
.into(object : CustomTarget<Drawable>() {
override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) {
holder.binding.rbItem.buttonDrawable = resource
}
override fun onLoadCleared(placeholder: Drawable?) {
TODO("Not yet implemented")
}
})
holder.binding.executePendingBindings()
}
编辑
我错了一部分,它抛出了一个错误:
java.io.IOException: java.lang.RuntimeException: setDataSourceCallback failed: status = 0x80000000
at com.bumptech.glide.load.resource.bitmap.VideoDecoder.decode(VideoDecoder.java:185)
at com.bumptech.glide.load.engine.DecodePath.decodeResourceWithList(DecodePath.java:92)
at com.bumptech.glide.load.engine.DecodePath.decodeResource(DecodePath.java:70)
at com.bumptech.glide.load.engine.DecodePath.decode(DecodePath.java:59)
at com.bumptech.glide.load.engine.LoadPath.loadWithExceptionList(LoadPath.java:76)
at com.bumptech.glide.load.engine.LoadPath.load(LoadPath.java:57)
at com.bumptech.glide.load.engine.DecodeJob.runLoadPath(DecodeJob.java:524)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromFetcher(DecodeJob.java:488)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromData(DecodeJob.java:474)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromRetrievedData(DecodeJob.java:426)
at com.bumptech.glide.load.engine.DecodeJob.onDataFetcherReady(DecodeJob.java:390)
at com.bumptech.glide.load.engine.SourceGenerator.onDataFetcherReady(SourceGenerator.java:176)
at com.bumptech.glide.load.engine.DataCacheGenerator.onDataReady(DataCacheGenerator.java:94)
at com.bumptech.glide.load.model.ByteBufferFileLoader$ByteBufferFetcher.loadData(ByteBufferFileLoader.java:70)
at com.bumptech.glide.load.engine.DataCacheGenerator.startNext(DataCacheGenerator.java:74)
at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:50)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:279)
at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory.run(GlideExecutor.java:393)
Caused by: java.lang.RuntimeException: setDataSourceCallback failed: status = 0x80000000
at android.media.MediaMetadataRetriever._setDataSource(Native Method)
at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:210)
at com.bumptech.glide.load.resource.bitmap.VideoDecoder$ByteBufferInitializer.initialize(VideoDecoder.java:316)
at com.bumptech.glide.load.resource.bitmap.VideoDecoder$ByteBufferInitializer.initialize(VideoDecoder.java:310)
at com.bumptech.glide.load.resource.bitmap.VideoDecoder.decode(VideoDecoder.java:173)
at com.bumptech.glide.load.engine.DecodePath.decodeResourceWithList(DecodePath.java:92)
at com.bumptech.glide.load.engine.DecodePath.decodeResource(DecodePath.java:70)
at com.bumptech.glide.load.engine.DecodePath.decode(DecodePath.java:59)
at com.bumptech.glide.load.engine.LoadPath.loadWithExceptionList(LoadPath.java:76)
at com.bumptech.glide.load.engine.LoadPath.load(LoadPath.java:57)
at com.bumptech.glide.load.engine.DecodeJob.runLoadPath(DecodeJob.java:524)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromFetcher(DecodeJob.java:488)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromData(DecodeJob.java:474)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromRetrievedData(DecodeJob.java:426)
at com.bumptech.glide.load.engine.DecodeJob.onDataFetcherReady(DecodeJob.java:390)
at com.bumptech.glide.load.engine.SourceGenerator.onDataFetcherReady(SourceGenerator.java:176)
at com.bumptech.glide.load.engine.DataCacheGenerator.onDataReady(DataCacheGenerator.java:94)
at com.bumptech.glide.load.model.ByteBufferFileLoader$ByteBufferFetcher.loadData(ByteBufferFileLoader.java:70)
at com.bumptech.glide.load.engine.DataCacheGenerator.startNext(DataCacheGenerator.java:74)
at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:50)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:279)
at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory.run(GlideExecutor.java:393)
我已经设法解决了这个问题,不幸的是,用滑行是不可能的,但是用线圈是不可能的。
1。添加必要的依赖项
implementation "io.coil-kt:coil-base:1.1.0" // or "io.coil-kt:coil-1.1.0" if you don't want to use dependency Injection
implementation "io.coil-kt:coil-svg:1.1.0"
2。构建 ImageLoader Singleton 并添加 SVGEndoder
@Provides
@Singleton
fun provideImageLoader(@ApplicationContext context: Context) = ImageLoader.Builder(context)
.componentRegistry { add(SvgDecoder(context)) }
.build()
3.Build 请求
fun buildRequest(context: Context, data: Any, target: RadioButton) = ImageRequest.Builder(context)
.data(data)
.target { drawable -> target.buttonDrawable = drawable }
.size(64, 60) // unfortunately I was not able to get the default radiobutton.drawable size here
.build()
4。适配器内部
override fun onBindViewHolder(holder: YourHolder, position: Int) {
val newRequest = shopFilterValidator.buildRequest(
context = holder.binding.rbItem.context,
data = getItem(position).icon, // here a url from firebase
target = holder.binding.rbItem
)
imageLoader.enqueue(newRequest)
}
这会将 svg 图像加载为可绘制对象并将它们作为 radiobutton.drawable