6

我需要使用材料设计库动态添加入口芯片以及将通过 API 调用检索的图标。如何使用 Glide 库设置芯片图标?

注意:我之前没有在可绘制文件夹中保存任何图像。正在通过 API 调用检索所有数据。

4

3 回答 3

8

例如,您可以使用此解决方法。定制芯片:

public class GlideChip extends Chip {

    public GlideChip(Context context) {
        super(context);
    }

    public GlideChip(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * Set an image from an URL for the {@link Chip} using {@link com.bumptech.glide.Glide}
     * @param url icon URL
     * @param errDrawable error icon if Glide return failed response
     */
    public GlideChip setIconUrl(String url, Drawable errDrawable) {
        Glide.with(this)
                .load(url)
                .listener(new RequestListener<Drawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                        setChipIcon(errDrawable);
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                        setChipIcon(resource);
                        return false;
                    }
                }).preload();
        return this;
    }

}

创建 GlideChip,添加到芯片组并启动项目:

public class ChipFragment extends Fragment {

    private ChipGroup chipGroup;

    public ChipFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_chip, container, false);
        chipGroup = view.findViewById(R.id.chipGroup);
        Chip chip = createChip("John Doe", "https://i1.sndcdn.com/avatars-000197335271-mztyvq-t500x500.jpg");
        chipGroup.addView(chip);
        return view;
    }

    private Chip createChip(String name, String avatarUrl) {
        GlideChip chip = new GlideChip(getContext());
        chip.setText(name);
        chip.setIconUrl(avatarUrl, getResources().getDrawable(R.drawable.err_avatar));
        chip.setClickable(true);
        chip.setFocusable(true);
        return chip;
    }

}

P/S...不要忘记将 Glide 添加到 build.gradle。看这里

于 2019-09-02T23:05:51.197 回答
1

对于 Coil 和 Kotlin 爱好者,我CoilChip根据@Javis回答做了一个。(向贾维斯致敬!)

class CoilChip(context: Context?) : Chip(context) {
    /**
     * @param url icon URL
     * @param errDrawable set error icon in onError callback
     */
    fun setIconUrl(url: String, placeholderDrawable: Drawable?, errDrawable: Drawable?) {
        chipDrawable?.let {
            val request = ImageRequest.Builder(context)
                .data(url)
                .target(
                    onStart = { placeholder ->
                        chipIcon = placeholderDrawable
                    },
                    onSuccess = { result ->
                        chipIcon = result
                    },
                    onError = { error ->
                        chipIcon = errDrawable
                    })
//              .memoryCachePolicy(CachePolicy.DISABLED) // caching strategy             
                .build()

            val imageLoader = ImageLoader.Builder(context)
                .build()
            imageLoader.enqueue(request)
        }
    }
}

如果您遇到异常Software rendering doesn't support hardware bitmaps,请将以下内容添加到您的图像请求中。

.bitmapConfig(Bitmap.Config.ARGB_8888)

干杯!

于 2021-09-14T07:48:25.923 回答
0

提供的答案有时会导致崩溃:

java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.isRecycled()' on a null object reference
at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1270)
at android.view.DisplayListCanvas.throwIfCannotDraw(DisplayListCanvas.java:257)
at android.graphics.Canvas.drawBitmap(Canvas.java:1415)
at com.bumptech.glide.load.resource.gif.GifDrawable.draw(SourceFile:291)
at com.google.android.material.chip.ChipDrawable.drawChipIcon(SourceFile:652)
at com.google.android.material.chip.ChipDrawable.draw(SourceFile:568)
at android.graphics.drawable.DrawableWrapper.draw(DrawableWrapper.java:228)
...

这是因为 drawable 没有正确清除。正确的实现是(示例在 Kotlin 中):

    Glide.with(this)
                .load(url)
                .into(object : CustomTarget<Drawable>(200, 200) { //size might be omitted

            override fun onLoadFailed(errorDrawable: Drawable?) {
                chipIcon = errDrawable
            }

            override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) {
                chipIcon = resource
            }

            override fun onLoadCleared(placeholder: Drawable?) {
                chipIcon = placeholder
            }

        })
于 2021-04-19T10:20:05.093 回答