Eliran Goshen Eliran Goshen - 3 months ago 12
Android Question

Image loading failed in TokenAutoComplete library

Im using TokenAutoComplete to create recipients, so i created custom view with image, but when i'm trying to load image into it, it doesn't work.
I tried with Picasso and Glide with remote and local image url's.
It doesn't gives any error, just loads the placeholder and thats it.

This is the relevant code :

the xml :





<data>
<import type="android.text.TextUtils" />
<import type="android.view.View" />
<import type="android.graphics.Typeface" />

<variable name="drawCircle" type="boolean" />

<variable name="imageUrl" type="String" />
</data>

<LinearLayout
android:id="@id/layout_content_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_chip_token"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingRight="@dimen/view_padding"
android:paddingEnd="@dimen/view_padding">

<ImageView
style="@style/AppStyle.Widget.ListItem.Image"
android:id="@+id/image_user" />


<TextView
android:id="@+id/text_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_marginLeft="@dimen/view_margin"
android:layout_marginStart="@dimen/view_margin"
android:ellipsize="middle"
android:maxLines="1"
android:textColor="@android:color/white"
android:textAppearance="?android:attr/textAppearanceSmall" />

<ImageView
android:id="@+id/image_dismiss"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/view_margin"
android:layout_marginStart="@dimen/view_margin"
android:src="@drawable/ic_clear_white_24dp"
android:visibility="gone"/>

</LinearLayout>




styles :

<style name="AppStyle.Widget.ListItem.Image" parent="AppStyle.Widget.ImageView">
<item name="android:layout_width">@dimen/list_item_icon_size</item>
<item name="android:layout_height">@dimen/list_item_icon_size</item>
</style>


ContactsCompletionView:

public class ContactsCompletionView extends TokenCompleteTextView {

private ChipTokenBinding mBinding;


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

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

public ContactsCompletionView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);

}

@Override
protected View getViewForObject(final Recipient recipient) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
mBinding = DataBindingUtil.inflate(inflater, R.layout.chip_token, (ViewGroup) getParent(), false);
mBinding.textName.setText(recipient.getLabel());
ImageViewBindingAdapter.loadImage(mBinding.imageUser, recipient.getImageUrl(), true,
Drawables.getDrawable(getContext(), R.drawable.ic_account_circle_white_36dp));

return mBinding.getRoot();
}

@Override
protected Recipient defaultObject(String completionText) {
return null;
}


ImageViewBindingAdapter:

@BindingAdapter({"imageUrl", "circle", "error"})
public static void loadImage(ImageView view, String imageUrl, boolean circle, Drawable error) {
if (TextUtils.isEmpty(imageUrl) && error == null)
return;

Picasso.with(view.getContext())
.load(imageUrl)
.fit()
.transform(circle ? new CircleTransformation() : new NullTransformation())
.error(error)
.placeholder(error)
.into(view);
}

Answer

Solved !

problem was that this library doesn't resize the image so its get image in 0 size and doesn't show it. so there is need to use Picasso resize method :

solution :

 @Override
    protected View getViewForObject(final Recipient recipient) {
        final LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        final View rootView = inflater.inflate(R.layout.chip_token, (ViewGroup) getParent(), false);

        final TextView nameText = (TextView) rootView.findViewById(R.id.text_name);
        final ImageView userImage = (ImageView) rootView.findViewById(R.id.image_user);

        final int imageSize = getResources().getDimensionPixelSize(R.dimen.list_item_icon_size);

        nameText.setText(recipient.getLabel());

        Picasso.with(userImage.getContext())
                .load(recipient.getImageUrl())
                .resize(imageSize, imageSize)
                .transform(new CircleTransformation())
                .error(R.drawable.ic_account_circle_white_36dp)
                .placeholder(R.drawable.ic_account_circle_white_36dp)
                .into(new Target() {
                    @Override
                    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                        userImage.setImageDrawable(new BitmapDrawable(bitmap));
                        invalidate();
                    }

                    @Override
                    public void onBitmapFailed(Drawable errorDrawable) {
                        userImage.setImageDrawable(errorDrawable);
                        invalidate();
                    }

                    @Override
                    public void onPrepareLoad(Drawable placeHolderDrawable) {
                        userImage.setImageDrawable(placeHolderDrawable);
                        invalidate();
                    }
                });

        return rootView;
    }


/**
 * {@link Picasso} transformation which makes the images shaped as circle.
 */
public class CircleTransformation implements Transformation {

    private static final String TAG = "circle_transformation";

    @Override
    public Bitmap transform(Bitmap source) {
        int size = Math.min(source.getWidth(), source.getHeight());

        int x = (source.getWidth() - size) / 2;
        int y = (source.getHeight() - size) / 2;

        Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size);
        if (squaredBitmap != source) {
            source.recycle();
        }

        Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig());

        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        BitmapShader shader = new BitmapShader(squaredBitmap,
                BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
        paint.setShader(shader);
        paint.setAntiAlias(true);

        float r = size / 2f;
        canvas.drawCircle(r, r, r, paint);

        squaredBitmap.recycle();
        return bitmap;
    }

    @Override
    public String key() {
        return TAG;
    }
}