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);
}
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;
}
}