Universal Image Loader Set unrelated images - android

I am Using Universal Image Loader library in order to set images from the server in my recycler view.
In my recycler View when I start to scroll on it, It will setup unrelated images for a few seconds and after that, it will set true image.
I don't know where is the problem.
This is my Adapter That I'm using:
public class HistoryDetailAdapter extends RecyclerView.Adapter<HistoryDetailAdapter.ViewHolder> {
private List<PList> menuItems;
private Context mContext;
private ActivityHistoryDetails activityHistoryDetails;
private DisplayImageOptions defaultOptions;
private ImageLoaderConfiguration config;
public HistoryDetailAdapter(List<PList> menuItems, Context mContext) {
this.menuItems = menuItems;
this.mContext = mContext;
this.activityHistoryDetails = (ActivityHistoryDetails) mContext;
byte[] toEncrypt = (G.getPremiumState()[0] + ":" + G.getPremiumState()[1]).getBytes();
String encryptedCredentials = Base64.encodeToString(toEncrypt, Base64.DEFAULT);
Map<String, String> headers = new HashMap();
headers.put("Authorization", "Basic " + encryptedCredentials);
defaultOptions = new DisplayImageOptions.Builder()
.cacheInMemory(false)
.cacheOnDisk(false)
.resetViewBeforeLoading(true)
.delayBeforeLoading(5000)
.showImageOnLoading(R.drawable.loading_02)
.showImageOnFail(R.drawable.ic_empty_white_box)
.extraForDownloader(headers)
.build();
config = new ImageLoaderConfiguration.Builder(activityHistoryDetails)
.defaultDisplayImageOptions(defaultOptions)
.imageDownloader(new AuthDownloader(activityHistoryDetails))
.build();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
ImageView imgDefault;
LinearLayout parentLayout;
CoordinatorLayout coordinatorLayout;
public ViewHolder(View v) {
super(v);
imgDefault = (ImageView) v.findViewById(R.id.img_defaultImage);
parentLayout = (LinearLayout) v.findViewById(R.id.parentLayout);
coordinatorLayout = (CoordinatorLayout) v.findViewById(R.id.coordinatorLayout);
}
}
#Override
public HistoryDetailAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// Create a new View
final View v = LayoutInflater.from(activityHistoryDetails).inflate(R.layout.activity_history_detail_recycler, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
//Download and Load Default Image from server into imgDefault ImageView
String url = "http://192.168.14.77:8080/api/images/download/";
if (menuItems.get(position).getPDefaultImage().getIId() != null) {
url += menuItems.get(position).getPDefaultImage().getIId();
ImageLoader imageLoader = ImageLoader.getInstance(); // Get singleton instance
imageLoader.init(config);
imageLoader.handleSlowNetwork(true);
// Load image, decode it to Bitmap and return Bitmap to callback
ImageSize targetSize = new ImageSize(120, 120); // result Bitmap will be fit to this size
imageLoader.loadImage(url, targetSize, new SimpleImageLoadingListener() {
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
// Do whatever you want with Bitmap
holder.imgDefault.setImageBitmap(loadedImage);
}
});
} else {
holder.imgDefault.setImageResource(R.drawable.loading_01);
}
}
#Override
public int getItemCount() {
if (menuItems.size() > 0) {
return menuItems.size();
} else {
return 0;
}
}
public List<PList> getList() {
return menuItems;
}
}
Thank you for your answers.

You can use Glide or Fresco image library for it. They are working stable.

Related

Smooth scroll on listview with calllogs

I have a custom adapter added to listview. Data is call logs from phone. I reduce list by show only records from 3 days. Problem is that when I try to scroll listview from top to bottom I have a huge lags. My Scroll isn't smooth. Is there any way to make listview scroll smoother?
Here is my custom adapter:
public class CallListAdapter extends ArrayAdapter<CallList> {
Activity activity;
public CallListAdapter(Context context, ArrayList<CallList> calls, Activity activity) {
super(context, 0, calls);
this.activity = activity;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final CallList callList = getItem(position);
int actualPosition = 0;
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.call_list, parent, false);
}
final TextView call1 = convertView.findViewById(R.id.callNumber);
final TextView call2 = convertView.findViewById(R.id.callDate);
final TextView call3 = convertView.findViewById(R.id.conversationTime);
final TextView call4 = convertView.findViewById(R.id.callType);
final Button callView = convertView.findViewById(R.id.getViewName);
final ImageView bio = convertView.findViewById(R.id.lookBio);
final ImageView edit = convertView.findViewById(R.id.edit_call);
final ImageView block = convertView.findViewById(R.id.blockCall);
final ImageView call = convertView.findViewById(R.id.callUser);
final TextView bioLabel = convertView.findViewById(R.id.BioLabelSug);
final TextView editLabel = convertView.findViewById(R.id.NoteLabel);
final TextView blockLabel = convertView.findViewById(R.id.BlockLabelSug);
final TextView callLabel = convertView.findViewById(R.id.CallLabelSug);
final ConstraintLayout callContainer = convertView.findViewById(R.id.contact_container);
final ConstraintLayout bioContainer = convertView.findViewById(R.id.bio_container);
final ConstraintLayout blockContainer = convertView.findViewById(R.id.ignore_container);
final ConstraintLayout noteContainer = convertView.findViewById(R.id.note_container);
final TextView btnMarg = convertView.findViewById(R.id.buttonMargin);
final TextView callListNr2 = convertView.findViewById(R.id.callNumber2);
final LayoutInflater factory = activity.getLayoutInflater();
final View fullView = factory.inflate(R.layout.fragment_calls, null);
final RelativeLayout loading = fullView.findViewById(R.id.loadingBar);
String[] jsonData = new manageCalls().intentCallValues(position);
StringBuilder builder = new StringBuilder();
for (String s : jsonData) {
builder.append(s + "\n");
}
String str = builder.toString();
final String num = jsonData[0];
final String dat = jsonData[1];
final String typeCall = jsonData[2];
final String dur = jsonData[3];
final String authToken = SaveSharedPreferences.getPrefTokenName(getContext());
final Animation slideUp = AnimationUtils.loadAnimation(getContext(), R.anim.slideup);
final Animation slideDown = AnimationUtils.loadAnimation(getContext(), R.anim.slidedown);
final Handler handler = new Handler();
callView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (bioContainer.getVisibility() == View.GONE) {
callListNr2.setVisibility(View.GONE);
bio.setVisibility(View.VISIBLE);
bioLabel.setVisibility(View.VISIBLE);
edit.setVisibility(View.VISIBLE);
editLabel.setVisibility(View.VISIBLE);
} else if (bioContainer.getVisibility() == View.VISIBLE) {
handler.postDelayed(new Runnable() {
#Override
public void run() {
bio.setVisibility(View.GONE);
callContainer.setVisibility(View.GONE);
bioContainer.setVisibility(View.GONE);
noteContainer.setVisibility(View.GONE);
blockContainer.setVisibility(View.GONE);
}
}, 300);
}
}
});
if (actualPosition != position) {
if (bioContainer.getVisibility() == View.VISIBLE) {
bioContainer.setVisibility(View.GONE);
callContainer.setVisibility(View.GONE);
noteContainer.setVisibility(View.GONE);
blockContainer.setVisibility(View.GONE);
}
actualPosition = position;
}
call.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
call.setEnabled(false);
loading.setVisibility(View.VISIBLE);
Intent intentCall = new Intent(view.getContext(), CallUserActivity.class);
intentCall.putExtra("number", num);
intentCall.putExtra("authToken", authToken);
intentCall.putExtra("Date", dat);
activity.startActivityForResult(intentCall, position);
handler.postDelayed(new Runnable() {
#Override
public void run() {
call.setEnabled(true);
loading.setVisibility(View.GONE);
}
}, 1000);
}
});
call2.setText(callList.callDate);
call3.setText(callList.conversationTime);
call4.setText(callList.callType);
return convertView;
}
}
Try use ViewHolder and use AsyncTask to load bitmap.
You can try this way.
private static class ViewHolder {
public TextView call1;
public TextView call2;
public TextView call3;
public TextView call4;
public Button callView;
public ImageView bio;
public ImageView edit;
public ImageView block;
public ImageView call;
public TextView bioLabel;
public TextView editLabel;
public TextView blockLabel;
public TextView callLabel;
public ConstraintLayout callContainer;
public ConstraintLayout bioContainer;
public ConstraintLayout blockContainer;
public ConstraintLayout noteContainer;
public TextView btnMarg;
public TextView callListNr2;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
// inflate the layout
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(layoutResourceId, parent, false);
holder = new ViewHolder();
holder.call1 = convertView.findViewById(R.id....);
holder.call2 = convertView.findViewById(R.id....);
//Same for all other views
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.call1.setText(....);
//Lazy load for bitmap
loadBitmap(yourFileName..., bio)
return convertView;
}
static class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
BitmapWorkerTask(ImageView imageView) {
// Use a WeakReference to ensure the ImageView can be garbage collected
imageViewReference = new WeakReference<ImageView>(imageView);
}
// Decode image in background.
#Override
protected Bitmap doInBackground(String... params) {
return decodeSampledBitmapFromResource(params[0], 300, 300);
}
// Once complete, see if ImageView is still around and set bitmap.
#Override
protected void onPostExecute(Bitmap bitmap) {
if (imageViewReference != null && bitmap != null) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
}
public void loadBitmap(String fileName, ImageView imageView) {
BitmapWorkerTask task = new BitmapWorkerTask(imageView);
task.execute(fileName);
}
public static Bitmap decodeSampledBitmapFromResource(String fileName,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(fileName, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(fileName, options);
}
Your getview is HUGE.
Your (if convertview==null) has basically almost no effect as you're setting up the view again anyways.
What you need to do is refactor the getview to not be so slow. one thing you can do is create a class that has all the findviews done already for you and put that then in the .tag of the converted view. change your onclicks to use that as well, in a manner where you don't have to recreate them(other ways to do that exist as well).
ideally your code for if you have a converted view already should be just the .settexts().
depending on the size of your list, you could just get away with creating a view for each callist and avoid recycling the converted views alltogether, in such case you could just create them in advance.
also depending on the size of your list you could just get away with creating a just a simple linearlayout instead inside a scrollview. if your list isn't huge and it's not for some old phones, it works just fine as well (Don't knock on this as bad advice until you try on your phone how huge it can be before a listview starts making more sense).

RecyclerView shows wrong image after fast scroll

In my application I'm using RecyclerView.Adapter with my custom Holder class. Each item consist of few TextView's and one ImageView(icon). Problem is that RecyclerView shows wrong Image after fast scrolling.
Example:
truth
NOT truth
So, my holder is:
public class CafeHolder extends RecyclerView.ViewHolder implements OnClickListener {
TextView itemName, itemType, itemMarksCount, itemCommentsCount, itemRating;
ImageView imgCafe;
ImageLoader imgLoader;
private Context context;
private int cafeId;
public CafeHolder(View view, Context context){
super(view);
this.context = context;
itemName = (TextView) view.findViewById(R.id.tvCafeName);
imgCafe = (ImageView) view.findViewById(R.id.imgCafe);
itemType = (TextView) view.findViewById(R.id.tvCafeType);
itemMarksCount = (TextView) view.findViewById(R.id.tvMarksCount);
itemCommentsCount = (TextView) view.findViewById(R.id.tvCommentsCount);
itemRating = (TextView) view.findViewById(R.id.tvRatingCount);
imgLoader = new ImageLoader(context);
view.setOnClickListener(this);
}
#Override
public void onClick(View v) {
Intent intent = new Intent(context, InfoActivity.class);
intent.putExtra(CafeDomain.ID, cafeId);
context.startActivity(intent);
}
public void setCafeId(int cafeId){
this.cafeId = cafeId;
}
And my RecyclerView.Adapter:
public class CafeAdapter extends RecyclerView.Adapter<CafeHolder> {
private Context context;
List<CafeDomain> listItems;
public CafeAdapter(List<CafeDomain> listItems, Context context) {
this.listItems = listItems;
this.context = context;
}
#Override
public CafeHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_cafe_item2, parent, false);
CafeHolder vh = new CafeHolder(v, context);
return vh;
}
#Override
public void onBindViewHolder(CafeHolder holder, int position) {
CafeDomain dItem = this.listItems.get(position);
holder.imgCafe.setImageDrawable(null);
holder.itemName.setText(dItem.getName());
ArrayList<TypeDomain> types = dItem.getTypes();
StringBuilder sbTypes = new StringBuilder();
for (int i = 0; i < types.size(); i++){
sbTypes.append(types.get(i).getName());
if (i!=types.size()-1)
sbTypes.append(", ");
}
holder.itemType.setText(sbTypes.toString());
if (!dItem.getIconUrl().isEmpty()){
holder.imgLoader.DisplayImage(dItem.getIconUrl(), holder.imgCafe); //load image from cache or web
}
else{
holder.imgCafe.setImageResource(R.drawable.icon200); //set default image
}
holder.itemMarksCount.setText(String.valueOf(dItem.getMarksCount()));
holder.itemCommentsCount.setText(String.valueOf(dItem.getCommentsCount()));
holder.itemRating.setText(String.valueOf(dItem.getRating()));
holder.setCafeId(listItems.get(position).getId());
}
#Override
public int getItemCount() {
return listItems.size();
}
}
I can see, that this code:
else{
holder.imgCafe.setImageResource(R.drawable.icon200); //set default image
}
is working, but two images are wrong anyway :(
UPDATE:
The problem is only when you fast scrolling list without image cache in disk. When we have cache, there is no problem here...
Hi i think your problem is here:
if (!dItem.getIconUrl().isEmpty()){
holder.imgLoader.DisplayImage(dItem.getIconUrl(), holder.imgCafe); //load image from cache or web
}
else{
holder.imgCafe.setImageResource(R.drawable.icon200); //set default image
}
I can offer you two solutions that may work. First check your imageUrl is null with TextUtils.isEmpty()
if (!TextUtils.isEmpty(dItem.getIconUrl())){
holder.imgLoader.DisplayImage(dItem.getIconUrl(), holder.imgCafe);
}
else{
holder.imgCafe.setImageResource(R.drawable.icon200); //set default image
}
İf this does not work, if you can set a image drawable for empty url or url loading fail just leave it to your image downloader and just use the code below:
holder.imgLoader.DisplayImage(dItem.getIconUrl(), holder.imgCafe);

Universal Image Loader - listView was cleared

A few hours ago, I asked about AUIL call too many getView(). (Universal Image Loader - call too many getView())
By answers, I solve the problem that getView() was called too many times.
However, I've still have a problem.
When the activity was started, I can see the list. However, soon after, the list view was removed (or cleared). No images appear or load on the list view.
This is my source code.
public class MainActivity extends Activity{
AsyncTask<Void, Void, Void> asyncTask, registerTask;
DisplayImageOptions options;
ArrayList<HashMap<String, Object>> feedList = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int cacheSize = ((ActivityManager)getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass() * 1024 * 1024 / 8;
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this)
.memoryCacheExtraOptions(metrics.widthPixels, metrics.heightPixels)
.diskCacheExtraOptions(metrics.widthPixels, metrics.heightPixels, null)
.memoryCache(new LruMemoryCache(cacheSize))
.memoryCacheSize(cacheSize)
.memoryCacheSizePercentage(13)
.diskCache(new UnlimitedDiscCache(StorageUtils.getCacheDirectory(this)))
.diskCacheSize(100 * 1024 * 1024)
.diskCacheFileCount(200)
.diskCacheFileNameGenerator(new HashCodeFileNameGenerator())
.imageDownloader(new BaseImageDownloader(this))
.imageDecoder(new BaseImageDecoder(false))
.defaultDisplayImageOptions(DisplayImageOptions.createSimple())
.build();
ImageLoader.getInstance().init(config);
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_stub)
.showImageForEmptyUri(R.drawable.ic_empty)
.showImageOnFail(R.drawable.ic_error)
.cacheInMemory(true)
.cacheOnDisk(true)
.considerExifParams(true)
.displayer(new RoundedBitmapDisplayer(20))
.build();
asyncTask = new AsyncTask<Void, Void, Void>() {
protected Void doInBackground(Void... params) {
StyleFeedServerUtils serverUtils = new StyleFeedServerUtils();
feedList = serverUtils.getStyleFeedList(MainActivity.this);
return null;
}
#Override
protected void onPostExecute(Void result) {
if(feedList != null && feedList.size() > 0){
final ListView listView = (ListView)findViewById(R.id.list);
listView.setAdapter(new ImageAdapter());
PauseOnScrollListener listener = new PauseOnScrollListener(ImageLoader.getInstance(), true, true);
listView.setOnScrollListener(listener);
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.e("fashion", "onItemClick, position : "+position);
}
});
}
asyncTask.cancel(!isCancelled());
asyncTask = null;
}
};
asyncTask.execute(null, null, null);
}
#Override
public void onDestroy() {
super.onDestroy();
if (registerTask != null) {
registerTask.cancel(true);
}
//GCMRegistrar.onDestroy(this);
AnimateFirstDisplayListener.displayedImages.clear();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
class ImageAdapter extends BaseAdapter {
private LayoutInflater inflater;
private ImageLoadingListener animateFirstListener = new AnimateFirstDisplayListener();
ImageAdapter() {
inflater = LayoutInflater.from(MainActivity.this);
}
#Override
public int getCount() {
return feedList.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
if(convertView == null){
view = inflater.inflate(R.layout.style_feed_list_view, parent, false);
view.setTag((ImageView)view.findViewById(R.id.style_feed_image));
}
ImageLoader.getInstance().displayImage(feedList.get(position).get("URL").toString(), (ImageView)view.getTag(), options, animateFirstListener);
return view;
}
}
private static class AnimateFirstDisplayListener extends SimpleImageLoadingListener {
static final List<String> displayedImages = Collections.synchronizedList(new LinkedList<String>());
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
if (loadedImage != null) {
ImageView imageView = (ImageView) view;
boolean firstDisplay = !displayedImages.contains(imageUri);
if (firstDisplay) {
FadeInBitmapDisplayer.animate(imageView, 500);
displayedImages.add(imageUri);
}
}
}
}
}
Please help.
some times it create problem due to RoundedBitmapDisplayer just comment .displayer(new RoundedBitmapDisplayer(20)) this line and try to run again.
If you want to use rounded image view then try library from below
https://github.com/vinc3m1/RoundedImageView

Universal ImageLoader java.io.EOFException

I'm trying to fetch JSON data and display it in my ListView using ArrayAdapter. Anyways, in my adapter, I'm using Universal Image Loader from https://github.com/nostra13/Android-Universal-Image-Loader and the other data were loaded correctly except for the images. Some images were displayed correctly, some should not be on a specific item, and some were not loaded completely.
This is my calling fragment:
public class SampleFragment extends Fragment implements
OnItemClickListener {
private ListView songsListView;
private ArrayList<String> list;
private ArrayAdapter<String> dataAdapter;
private View rootView;
private Button selectReferenceSong;
private Fragment memberFragment;
private String[] songsArray;
private ArrayAdapter<String> arrayAdapter;
private ArrayList<ReferenceTracks> arrayOfList;
private String bufferString;
private static final String rssFeed = "https://dl.dropboxusercontent.com/u/32769459/reference_tracks.json";
private static final String TAG_MUSIC = "music";
private static final String TAG_SONG = "song";
private static final String TAG_TITLE = "title";
private static final String TAG_ARTIST = "artist";
private static final String TAG_DURATION = "duration";
private static final String TAG_THUMBURL = "thumb_url";
public SampleFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.sample_layout, container, false);
songsListView = (ListView) rootView.findViewById(R.id.songsListView);
songsListView.setOnItemClickListener(this);
arrayOfList = new ArrayList<ReferenceTracks>();
if (Utility.isNetworkAvailable(getActivity())) {
new AsynchronousTask().execute(rssFeed);
} else {
Toast.makeText(getActivity().getApplicationContext(),
"No Network Connection!", Toast.LENGTH_SHORT).show();
}
return rootView;
}
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// TODO Auto-generated method stub
}
/**
*
* #Asynchronous class
*/
public class AsynchronousTask extends AsyncTask<String, Void, String> {
ProgressDialog pDialog;
private RowAdapter objRowAdapter;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Loading...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected String doInBackground(String... params) {
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
return Utility.getJSONString(params[0]);
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (null != pDialog && pDialog.isShowing()) {
pDialog.dismiss();
}
if (null == result || result.length() == 0) {
Toast.makeText(getActivity().getApplicationContext(),
"No data found from web.", Toast.LENGTH_SHORT).show();
} else {
try {
JSONObject topObject = new JSONObject(result);
JSONObject musicObject = topObject.getJSONObject(TAG_MUSIC);
JSONArray jsonArray = musicObject.getJSONArray(TAG_SONG);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject objJson = jsonArray.getJSONObject(i);
ReferenceTracks objItem = new ReferenceTracks();
objItem.setTitle(objJson.getString(TAG_TITLE));
objItem.setArtist(objJson.getString(TAG_ARTIST));
objItem.setDuration(objJson.getString(TAG_DURATION));
objItem.setThumbUrl(objJson.getString(TAG_THUMBURL));
arrayOfList.add(objItem);
}
} catch (JSONException e) {
e.printStackTrace();
}
setAdapterToListview();
}
}
public void setAdapterToListview() {
objRowAdapter = new RowAdapter(getActivity(), R.layout.reference_song_list_item, arrayOfList);
songsListView.setAdapter(objRowAdapter);
}
}}
This is my custom Adapter:
public class RowAdapter extends ArrayAdapter<ReferenceTracks> {
private Context activity;
private ArrayList<ReferenceTracks> items;
private ReferenceTracks objBean;
private int row;
private ImageLoader imageLoader;
private DisplayImageOptions options;
public RowAdapter(Context act, int resource, ArrayList<ReferenceTracks> arrayList) {
super(act, resource, arrayList);
this.activity = act;
this.row = resource;
this.items = arrayList;
imageLoader = ImageLoader.getInstance();
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
ViewHolder holder;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(row, null);
holder = new ViewHolder();
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
if ((items == null) || ((position + 1) > items.size()))
return view;
objBean = items.get(position);
holder.tvImage = (ImageView) view.findViewById(R.id.list_image);
holder.tvTitle = (TextView) view.findViewById(R.id.title);
holder.tvArtist = (TextView) view.findViewById(R.id.artist);
holder.tvDuration = (TextView) view.findViewById(R.id.duration);
holder.pbar = (ProgressBar) view.findViewById(R.id.progressbar);
if (holder.tvImage != null) {
if (null != objBean.getThumbUrl()
&& objBean.getThumbUrl().trim().length() > 0) {
final ProgressBar pbar = holder.pbar;
imageLoader.destroy();
imageLoader.init(ImageLoaderConfiguration.createDefault(activity));
imageLoader.displayImage(objBean.getThumbUrl(), holder.tvImage,
options, new ImageLoadingListener() {
#Override
public void onLoadingStarted(String imageUri,
View view) {
// TODO Auto-generated method stub
pbar.setVisibility(View.VISIBLE);
}
#Override
public void onLoadingFailed(String imageUri,
View view, FailReason failReason) {
// TODO Auto-generated method stub
pbar.setVisibility(View.INVISIBLE);
}
#Override
public void onLoadingComplete(String imageUri,
View view, Bitmap loadedImage) {
// TODO Auto-generated method stub
pbar.setVisibility(View.INVISIBLE);
}
#Override
public void onLoadingCancelled(String imageUri,
View view) {
// TODO Auto-generated method stub
}
});
} else {
holder.tvImage.setImageResource(R.drawable.ic_launcher);
}
}
if (holder.tvTitle != null && null != objBean.getTitle()
&& objBean.getTitle().trim().length() > 0) {
holder.tvTitle.setText(Html.fromHtml(objBean.getTitle()));
}
if (holder.tvArtist != null && null != objBean.getArtist()
&& objBean.getArtist().trim().length() > 0) {
holder.tvArtist.setText(Html.fromHtml(objBean.getArtist()));
}
if (holder.tvDuration != null && null != objBean.getDuration()
&& objBean.getDuration().trim().length() > 0) {
holder.tvDuration.setText(Html.fromHtml(objBean.getDuration()));
}
return view;
}
public class ViewHolder {
public ImageView tvImage;
public ProgressBar pbar;
public TextView tvTitle, tvArtist, tvDuration;
}}
While this is my application class:
public class SampleApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
DisplayImageOptions displayimageOptions = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.ic_stub)
.showImageOnFail(R.drawable.ic_error)
.showImageForEmptyUri(R.drawable.ic_empty)
.cacheInMemory()
.cacheOnDisc()
.bitmapConfig(Bitmap.Config.RGB_565)
.imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)
.build();
File cacheDir = StorageUtils.getCacheDirectory(getApplicationContext());
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
.threadPoolSize(4)
.threadPriority(Thread.NORM_PRIORITY)
.tasksProcessingOrder(QueueProcessingType.LIFO)
.defaultDisplayImageOptions(displayimageOptions)
.discCacheSize(50 * 1024 * 1024)
.discCacheFileCount(1000000)
.memoryCache(new WeakMemoryCache())
.build();
ImageLoader.getInstance().init(config);
}}
This is also the log:
06-24 11:18:12.935: E/ImageLoader(6428): null
06-24 11:18:12.935: E/ImageLoader(6428): java.io.EOFException
06-24 11:18:12.935: E/ImageLoader(6428): at libcore.io.Streams.readAsciiLine(Streams.java:203)
06-24 11:18:12.935: E/ImageLoader(6428): at libcore.net.http.HttpEngine.readResponseHeaders(HttpEngine.java:561)
06-24 11:18:12.935: E/ImageLoader(6428): at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:801)
06-24 11:18:12.935: E/ImageLoader(6428): at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:274)
06-24 11:18:12.935: E/ImageLoader(6428): at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:479)
06-24 11:18:12.935: E/ImageLoader(6428): at com.nostra13.universalimageloader.core.download.BaseImageDownloader.getStreamFromNetwork(BaseImageDownloader.java:113)
06-24 11:18:12.935: E/ImageLoader(6428): at com.nostra13.universalimageloader.core.download.BaseImageDownloader.getStream(BaseImageDownloader.java:84)
06-24 11:18:12.935: E/ImageLoader(6428): at com.nostra13.universalimageloader.core.decode.BaseImageDecoder.getImageStream(BaseImageDecoder.java:84)
06-24 11:18:12.935: E/ImageLoader(6428): at com.nostra13.universalimageloader.core.decode.BaseImageDecoder.decode(BaseImageDecoder.java:73)
06-24 11:18:12.935: E/ImageLoader(6428): at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.decodeImage(LoadAndDisplayImageTask.java:290)
06-24 11:18:12.935: E/ImageLoader(6428): at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.tryLoadBitmap(LoadAndDisplayImageTask.java:250)
06-24 11:18:12.935: E/ImageLoader(6428): at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.run(LoadAndDisplayImageTask.java:131)
06-24 11:18:12.935: E/ImageLoader(6428): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
06-24 11:18:12.935: E/ImageLoader(6428): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
06-24 11:18:12.935: E/ImageLoader(6428): at java.lang.Thread.run(Thread.java:856)
Were there any settings I made wrong or missed on my application class for the imageloader? I've been searching for the same exception but nothing seems getting close to the fix. Any help will do. Many thanks!
I'm working with Universal image loader for a long time. So, I prefer to have it's settings in a class then my application is able to access it simply.
This is setting class of Universal image loader. I have a utility package and this class is under this package. You are able to make corners of image curve by commenting out of lines in onLoadingComplete().
public class ImageDownloader {
private static final String TAG = "ImageDownloader";
public static final String DIRECTORY_NAME = "YOUR_DIRECTORY_NAME";
private static ImageDownloader instance = null;
private ImageLoader imageLoader;
protected ImageDownloader(Context context) {
// Exists only to defeat instantiation.
configImageDownloader(context);
}
public static ImageDownloader getInstance(Context context) {
if(instance == null) {
instance = new ImageDownloader(context);
}
return instance;
}
/**
* This constructor will configure loader object in order to display image.
* #param context
*/
private void configImageDownloader(Context context) {
File cacheDir = StorageUtils.getOwnCacheDirectory(context, DIRECTORY_NAME + "/Cache");
// Get singleton instance of ImageLoader
imageLoader = ImageLoader.getInstance();
// Create configuration for ImageLoader (all options are optional)
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context).denyCacheImageMultipleSizesInMemory()
.memoryCache(new UsingFreqLimitedMemoryCache(4 * 1024 * 1024))
.discCache(new UnlimitedDiscCache(cacheDir))
.discCacheFileNameGenerator(new HashCodeFileNameGenerator())
.defaultDisplayImageOptions(
new DisplayImageOptions.Builder()
.showStubImage(R.drawable.ic_default_logo)
.resetViewBeforeLoading()
.cacheInMemory()
.cacheOnDisc()
.imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)
.build())
.tasksProcessingOrder(QueueProcessingType.FIFO)
.build();
// Initialize ImageLoader with created configuration.
imageLoader.init(config);
}
public void displayImage(final ImageView imageView, String imageURI) {
if(imageView == null || imageURI == null) {
Log.e(TAG, "Either of image view or image uri is null");
return;
}
// Load and display image
imageLoader.displayImage(imageURI, imageView, new ImageLoadingListener() {
#Override
public void onLoadingStarted(String imageUri, View view) {}
#Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
// Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
// imageView.setImageBitmap(getRoundedCornerBitmap(bitmap, 30));
}
#Override
public void onLoadingCancelled(String imageUri, View view) {}
});
}
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
final float roundPx = pixels;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
}
In your adapter class, first you need move all definitions into if (view == null) {...}method. My sample adapter which is like this. You can ignore my listener which is because of a button that I have in my each row.
public class MyCrowdAdapter extends BaseAdapter {
public interface OnCrowdRemoveUserListener {
public void OnRemoveUserClicked(User user);
}
private final String TAG = "*** MyCrowdAdapter ***";
private Context context;
private OnCrowdRemoveUserListener listener;
private LayoutInflater myInflater;
private ImageDownloader imageDownloader;
private List<User> userList;
public MyCrowdAdapter(Context context) {
this.context = context;
myInflater = LayoutInflater.from(context);
imageDownloader = ImageDownloader.getInstance(context);
}
public void setData(List<User> userList) {
this.userList = userList;
Log.i(TAG, "List passed to the adapter.");
}
#Override
public int getCount() {
try {
return userList.size();
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = myInflater.inflate(R.layout.list_my_crowd_row, null);
holder = new ViewHolder();
Typeface font = Typeface.createFromAsset(context.getAssets(), "fonts/ITCAvantGardeStd-Demi.ttf");
holder.tvUserName = (TextView) convertView.findViewById(R.id.tvUserName);
holder.tvUserName.setTypeface(font);
holder.ivPicture = (ImageView) convertView.findViewById(R.id.ivPicture);
holder.btnRemove = (Button) convertView.findViewById(R.id.btnRemove);
holder.btnRemove.setFocusable(false);
holder.btnRemove.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Integer pos = (Integer)v.getTag();
Log.i(TAG, "Item: " + pos);
listener.OnRemoveUserClicked(userList.get(pos));
}
});
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.btnRemove.setTag(position);
holder.tvUserName.setText(userList.get(position).getFirstName());
imageDownloader.displayImage(holder.ivPicture, userList.get(position).getProfilePictureUrl());
return convertView;
}
public void setOnRemoveClickedListener(OnCrowdRemoveUserListener listener) {
this.listener = listener;
}
static class ViewHolder {
TextView tvUserName;
ImageView ivPicture;
Button btnRemove;
}
}
One suggestion, instead of validation like this:
if (holder.tvTitle != null && null != objBean.getTitle()
&& objBean.getTitle().trim().length() > 0) {...}
simply use TextUtils which is static method, like this:
if(!TextUtils.isEmpty(objBean.getTitle);
===========
Update
===========
About your question regard displaying progressbar on top of image:
It's simple and complex :) there are two ways,
1st way is based on your code:
1-define an interface inside ImageDownloader class like my interface inside adapter. should be something like this:
public interface OnImageDownloaderListener {
public void OnDownloadStarted();
public void OnDownloadFinished();
}
2- Declare it in decleration part
OnImageDownloaderListener listener;
3- Change thosr two listeners like this
#Override
public void onLoadingStarted(String imageUri, View view) {
listener.OnDownloadStarted();
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
// Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
// imageView.setImageBitmap(getRoundedCornerBitmap(bitmap, 30));
listener.OnDownloadFinished();
}
4- Add this method to ImageDownloader class
public void setOnImageDownloaderListener(OnImageDownloaderListener listener) {
this.listener = listener;
}
5- In your adapter and below this line:
imageDownloader = ImageDownloader.getInstance(context);
implement those two methodes like this:
imageDownloader.setOnImageDownloaderListener(new ImageDownloader.OnImageDownloaderListener{
#Override
public void OnDownloadStarted() {
pbar.start();
}
#Override
public void OnDownloadFinished(){
pbar.stop();
}
}
);
It should help you. However, if I were you I does second approach which is creating new component. The component includes two views an image view and progressbar on top (same to what you have currently). Then add all above method inside that component class. So, easily through your app you in whatever activity you want you can add your view and just pass URL then the component is responsible to display progressbar and stop it. Based on your code if you have 10 similr activities you need to copy/paste above code.
Hope it helps you :)

Android, How to add title (a custom view) into each image item of Gallery (from gallery adapter)?

I can display my images inside gallery through gallery adapter. Now, I need to add Title to each image at the bottom of that. I have no idea how to add it. This is my adapter code:
public class LensaPhotoAdapter_KM extends BaseAdapter{
private int mGalleryItemBackground;
private Context context;
private ImageLoader imageLoader;
// private File cacheDir;
private ImageLoaderConfiguration config;
private DisplayImageOptions options;
private ArrayList<String> imageURLs = new ArrayList<String>();
private ArrayList<String> imageTitle = new ArrayList<String>();
public LensaPhotoAdapter_KM(Context context){
Log.i("LensaPhotoAdapter", "Try to build the screen...");
this.context = context;
TypedArray attr = context.obtainStyledAttributes(R.styleable.HelloGallery);
mGalleryItemBackground = attr.getResourceId(R.styleable.HelloGallery_android_galleryItemBackground, 0);
attr.recycle();
// Get singleton instance of ImageLoader
imageLoader = ImageLoader.getInstance();
}
public void setData(ImageFeedItemList imageFeedItemList){
int numberOfItems = imageFeedItemList.getHeaderImage().size();
imageTitle = imageFeedItemList.getTitle();
// for(String str: imageFeedItemList.getHeaderImage())
// Log.i("title is:", str);
for(int i=0; i<numberOfItems; i++){
String str = imageFeedItemList.getTitle().get(i);
str = str.substring(0, str.indexOf(" "));
if(str.equalsIgnoreCase("Konsert"))
imageURLs.add(imageFeedItemList.getHeaderImage().get(i));
// for(String str1: imageURLs)
// Log.i("title is:", str1);
}
// cacheDir = new File(Environment.getExternalStorageDirectory(), "UniversalImageLoader/Cache");
// Create configuration for ImageLoader
config = new ImageLoaderConfiguration.Builder(context)
.maxImageWidthForMemoryCache(800)
.maxImageHeightForMemoryCache(800)
.httpConnectTimeout(5000)
.httpReadTimeout(30000)
.threadPoolSize(5)
.threadPriority(Thread.MIN_PRIORITY + 2)
.denyCacheImageMultipleSizesInMemory()
.memoryCache(new UsingFreqLimitedMemoryCache(2000000)) // You can pass your own memory cache implementation
// .discCache(new UnlimitedDiscCache(cacheDir)) // You can pass your own disc cache implementation
.defaultDisplayImageOptions(DisplayImageOptions.createSimple())
.build();
// Creates display image options for custom display task
options = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.icon_loading)
.showImageForEmptyUrl(R.drawable.icon_remove)
.cacheInMemory()
.cacheOnDisc()
.decodingType(DecodingType.MEMORY_SAVING)
.build();
// Initialize ImageLoader with created configuration. Do it once.
imageLoader.init(config);
}
//---returns the number of images---
public int getCount() {
return imageURLs.size();
}
//---returns the ID of an item---
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return position;
}
//---returns an ImageView view---
public View getView(int position, View convertView, ViewGroup parent){
ImageView imageView = new ImageView(context);
imageView.setLayoutParams(new Gallery.LayoutParams(250, 250));
imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
imageView.setBackgroundResource(mGalleryItemBackground);
// Load and display image
String imageUrl = imageURLs.get(position);
imageLoader.displayImage(imageUrl, imageView, options);
return imageView;
}
}
Any suggestion would be appreciated. Thanks
In your getView(), instead of creating the ImageView on the fly, you can inflate a layout that has both an ImageView and a TextView, which you can then fill in appropriately:
View container = inflater.inflate(R.layout.the_layout, parent, false);
ImageView image = ll.findViewById(R.id.image);
String imageUrl = imageURLs.get(position);
imageLoader.displayImage(imageUrl, imageView, options);
TextView text = ll.findViewById(R.id.text);
text.setText("whatever");

Categories

Resources