ListItemAdapter.java

  1package eu.siacs.conversations.ui.adapter;
  2
  3import android.content.Context;
  4import android.content.SharedPreferences;
  5import android.content.res.Resources;
  6import android.graphics.Bitmap;
  7import android.graphics.drawable.BitmapDrawable;
  8import android.graphics.drawable.Drawable;
  9import android.os.AsyncTask;
 10import android.preference.PreferenceManager;
 11import android.view.LayoutInflater;
 12import android.view.View;
 13import android.view.ViewGroup;
 14import android.widget.ArrayAdapter;
 15import android.widget.ImageView;
 16import android.widget.LinearLayout;
 17import android.widget.TextView;
 18
 19import com.wefika.flowlayout.FlowLayout;
 20
 21import java.lang.ref.WeakReference;
 22import java.util.List;
 23import java.util.concurrent.RejectedExecutionException;
 24
 25import eu.siacs.conversations.R;
 26import eu.siacs.conversations.entities.ListItem;
 27import eu.siacs.conversations.ui.XmppActivity;
 28import eu.siacs.conversations.utils.UIHelper;
 29import eu.siacs.conversations.xmpp.jid.Jid;
 30
 31public class ListItemAdapter extends ArrayAdapter<ListItem> {
 32
 33	protected XmppActivity activity;
 34	protected boolean showDynamicTags = false;
 35	private View.OnClickListener onTagTvClick = new View.OnClickListener() {
 36		@Override
 37		public void onClick(View view) {
 38			if (view instanceof  TextView && mOnTagClickedListener != null) {
 39				TextView tv = (TextView) view;
 40				final String tag = tv.getText().toString();
 41				mOnTagClickedListener.onTagClicked(tag);
 42			}
 43		}
 44	};
 45	private OnTagClickedListener mOnTagClickedListener = null;
 46
 47	public ListItemAdapter(XmppActivity activity, List<ListItem> objects) {
 48		super(activity, 0, objects);
 49		this.activity = activity;
 50		SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
 51		this.showDynamicTags = preferences.getBoolean("show_dynamic_tags",false);
 52	}
 53
 54	@Override
 55	public View getView(int position, View view, ViewGroup parent) {
 56		LayoutInflater inflater = (LayoutInflater) getContext()
 57				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 58		ListItem item = getItem(position);
 59		if (view == null) {
 60			view = inflater.inflate(R.layout.contact, parent, false);
 61		}
 62		TextView tvName = (TextView) view.findViewById(R.id.contact_display_name);
 63		TextView tvJid = (TextView) view.findViewById(R.id.contact_jid);
 64		ImageView picture = (ImageView) view.findViewById(R.id.contact_photo);
 65		FlowLayout tagLayout = (FlowLayout) view.findViewById(R.id.tags);
 66
 67		List<ListItem.Tag> tags = item.getTags(activity);
 68		if (tags.size() == 0 || !this.showDynamicTags) {
 69			tagLayout.setVisibility(View.GONE);
 70		} else {
 71			tagLayout.setVisibility(View.VISIBLE);
 72			tagLayout.removeAllViewsInLayout();
 73			for(ListItem.Tag tag : tags) {
 74				TextView tv = (TextView) inflater.inflate(R.layout.list_item_tag,tagLayout,false);
 75				tv.setText(tag.getName());
 76				tv.setBackgroundColor(tag.getColor());
 77				tv.setOnClickListener(this.onTagTvClick);
 78				tagLayout.addView(tv);
 79			}
 80		}
 81		final String jid = item.getDisplayJid();
 82		if (jid != null) {
 83			tvJid.setVisibility(View.VISIBLE);
 84			tvJid.setText(jid);
 85		} else {
 86			tvJid.setVisibility(View.GONE);
 87		}
 88		tvName.setText(item.getDisplayName());
 89		loadAvatar(item,picture);
 90		return view;
 91	}
 92
 93	public void setOnTagClickedListener(OnTagClickedListener listener) {
 94		this.mOnTagClickedListener = listener;
 95	}
 96
 97	public interface OnTagClickedListener {
 98		void onTagClicked(String tag);
 99	}
100
101	class BitmapWorkerTask extends AsyncTask<ListItem, Void, Bitmap> {
102		private final WeakReference<ImageView> imageViewReference;
103		private ListItem item = null;
104
105		public BitmapWorkerTask(ImageView imageView) {
106			imageViewReference = new WeakReference<>(imageView);
107		}
108
109		@Override
110		protected Bitmap doInBackground(ListItem... params) {
111			return activity.avatarService().get(params[0], activity.getPixel(48), isCancelled());
112		}
113
114		@Override
115		protected void onPostExecute(Bitmap bitmap) {
116			if (bitmap != null && !isCancelled()) {
117				final ImageView imageView = imageViewReference.get();
118				if (imageView != null) {
119					imageView.setImageBitmap(bitmap);
120					imageView.setBackgroundColor(0x00000000);
121				}
122			}
123		}
124	}
125
126	public void loadAvatar(ListItem item, ImageView imageView) {
127		if (cancelPotentialWork(item, imageView)) {
128			final Bitmap bm = activity.avatarService().get(item,activity.getPixel(48),true);
129			if (bm != null) {
130				cancelPotentialWork(item, imageView);
131				imageView.setImageBitmap(bm);
132				imageView.setBackgroundColor(0x00000000);
133			} else {
134				imageView.setBackgroundColor(UIHelper.getColorForName(item.getDisplayName()));
135				imageView.setImageDrawable(null);
136				final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
137				final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task);
138				imageView.setImageDrawable(asyncDrawable);
139				try {
140					task.execute(item);
141				} catch (final RejectedExecutionException ignored) {
142				}
143			}
144		}
145	}
146
147	public static boolean cancelPotentialWork(ListItem item, ImageView imageView) {
148		final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
149
150		if (bitmapWorkerTask != null) {
151			final ListItem oldItem = bitmapWorkerTask.item;
152			if (oldItem == null || item != oldItem) {
153				bitmapWorkerTask.cancel(true);
154			} else {
155				return false;
156			}
157		}
158		return true;
159	}
160
161	private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
162		if (imageView != null) {
163			final Drawable drawable = imageView.getDrawable();
164			if (drawable instanceof AsyncDrawable) {
165				final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
166				return asyncDrawable.getBitmapWorkerTask();
167			}
168		}
169		return null;
170	}
171
172	static class AsyncDrawable extends BitmapDrawable {
173		private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
174
175		public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) {
176			super(res, bitmap);
177			bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask);
178		}
179
180		public BitmapWorkerTask getBitmapWorkerTask() {
181			return bitmapWorkerTaskReference.get();
182		}
183	}
184
185}