ListView - ImageLoader moves List / Items on Scroll up - android

I'm looking for an answer half a day, but I can't find anything although I thought it is a common problem. My Problem:
I have a ListView which has items of different sizes (heights). Every item contains an ImageView. The Image for this ImageView is loaded in background by an ImageLoader class:
imageLoader.DisplayImage(url, holder.image);
If i scroll down the ListView everything works fine. the images are loaded and display (of course at the bottom of the screen / list).
But If I scroll up and the image isn't stored in cache anymore, so the ImageLoader has to reload the image, the ListView jumps / the items are moved. I think it is because a new View is created on top of the list, with an ImageView with 0dp height. If the Image is loaded and set to the ImageView the height of the ImageView changes automatically from 0dp to the size of the Image. This would push the ListView down, I think.
I tried saving the height of the ImageViews if an Image is set and then set the height of the ImageView which is created on top to the saved height. But with no success..
I don't know if you can understand my problem :D I hope so :)
Thanks and have a nice day!
EDIT: Added ImageLoader Class
public class ImageLoader {
MemoryCache memoryCache=new MemoryCache();
FileCache fileCache;
int size;
Context context;
private Map<ImageView, String> imageViews=Collections.synchronizedMap(new WeakHashMap<ImageView, String>());
private HashMap<String, Integer> imagesSizes;
ExecutorService executorService;
Handler handler=new Handler();//handler to display images in UI thread
public ImageLoader(Context context, int size){
fileCache=new FileCache(context);
this.context = context;
executorService=Executors.newFixedThreadPool(5);
this.size = size;
imagesSizes = new HashMap<String, Integer>();
}
final int stub_id=R.color.transparent;
public void DisplayImage(String url, ImageView imageView)
{
imageViews.put(imageView, url);
Bitmap bitmap=memoryCache.get(url);
if(bitmap!=null){
imageView.setImageBitmap(bitmap);
saveImageSize(imageView, url);
}
else
{
queuePhoto(url, imageView);
imageView.setImageResource(stub_id);
setImageSize(imageView, url);
}
}
public void DisplayImage(File file, ImageView imageView)
{
imageViews.put(imageView, file.getAbsolutePath());
Bitmap bitmap=memoryCache.get(file.getAbsolutePath());
if(bitmap!=null){
imageView.setImageBitmap(bitmap);
saveImageSize(imageView, file.getAbsolutePath());
}
else
{
queuePhoto(file, imageView);
imageView.setImageResource(stub_id);
setImageSize(imageView, file.getAbsolutePath());
}
}
private void saveImageSize(ImageView imageView, String url){
int height = imageView.getHeight();
imagesSizes.put(url, height);
System.out.println("IMAGE SIZE: Save: " + url + " " + height );
}
private void setImageSize(ImageView imageView, String url){
if(imageView != null && imagesSizes!=null && imagesSizes.containsKey(url)){
imageView.getLayoutParams().height = imagesSizes.get(url);
imageView.requestLayout();
System.out.println("IMAGE SIZE: Set: " + url + " " + imagesSizes.get(url) );
}
}
private void queuePhoto(String url, ImageView imageView)
{
PhotoToLoad p=new PhotoToLoad(url, imageView);
executorService.submit(new PhotosLoader(p));
}
private void queuePhoto(File file, ImageView imageView)
{
PhotoToLoad p=new PhotoToLoad(file, imageView);
executorService.submit(new PhotosLoader(p));
}
public Bitmap getImage(String url){
return getBitmap(url);
}
private Bitmap getBitmap(String url)
{
File f=fileCache.getFile(url);
//from SD cache
Bitmap b = decodeFile(f);
if(b!=null)
return b;
//from web
try {
Bitmap bitmap=null;
URL imageUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);
conn.setInstanceFollowRedirects(true);
InputStream is=conn.getInputStream();
OutputStream os = new FileOutputStream(f);
Utils.CopyStream(is, os);
os.close();
conn.disconnect();
bitmap = decodeFile(f);
return bitmap;
} catch (Throwable ex){
ex.printStackTrace();
if(ex instanceof OutOfMemoryError)
memoryCache.clear();
return null;
}
}
//decodes image and scales it to reduce memory consumption
private Bitmap decodeFile(File f){
try {
//decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
FileInputStream stream1=new FileInputStream(f);
BitmapFactory.decodeStream(stream1,null,o);
stream1.close();
//Find the correct scale value. It should be the power of 2.
final int REQUIRED_SIZE=size;
int width_tmp=o.outWidth, height_tmp=o.outHeight;
int scale=1;
while(true){
if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
break;
width_tmp/=2;
height_tmp/=2;
scale*=2;
}
//decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale;
FileInputStream stream2=new FileInputStream(f);
Bitmap bitmap=BitmapFactory.decodeStream(stream2, null, o2);
stream2.close();
return bitmap;
} catch (FileNotFoundException e) {
}
catch (IOException e) {
e.printStackTrace();
}
return null;
}
//Task for the queue
private class PhotoToLoad
{
public File file;
public String url;
public ImageView imageView;
public PhotoToLoad(String u, ImageView i){
url=u;
imageView=i;
file = null;
}
public PhotoToLoad(File file, ImageView i){
url=file.getAbsolutePath();
imageView=i;
this.file = file;
}
}
class PhotosLoader implements Runnable {
PhotoToLoad photoToLoad;
PhotosLoader(PhotoToLoad photoToLoad){
this.photoToLoad=photoToLoad;
}
#Override
public void run() {
try{
if(imageViewReused(photoToLoad))
return;
Bitmap bmp;
if(photoToLoad.file== null){
bmp=getBitmap(photoToLoad.url);
} else {
bmp=decodeFile(photoToLoad.file);
}
memoryCache.put(photoToLoad.url, bmp);
if(imageViewReused(photoToLoad))
return;
BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad);
handler.post(bd);
}catch(Throwable th){
th.printStackTrace();
}
}
}
boolean imageViewReused(PhotoToLoad photoToLoad){
String tag=imageViews.get(photoToLoad.imageView);
if(tag==null || !tag.equals(photoToLoad.url))
return true;
return false;
}
//Used to display bitmap in the UI thread
class BitmapDisplayer implements Runnable
{
Bitmap bitmap;
PhotoToLoad photoToLoad;
public BitmapDisplayer(Bitmap b, PhotoToLoad p){bitmap=b;photoToLoad=p;}
public void run()
{
if(imageViewReused(photoToLoad))
return;
if(bitmap!=null)
photoToLoad.imageView.setImageBitmap(bitmap);
else
photoToLoad.imageView.setImageResource(stub_id);
if(photoToLoad.file== null){
setImageSize(photoToLoad.imageView, photoToLoad.url);
} else {
setImageSize(photoToLoad.imageView, photoToLoad.file.getAbsolutePath());
}
}
}
public void clearCache() {
memoryCache.clear();
fileCache.clear();
}
EDIT: Added Adapter:
public class LazyNewPostsAdapter extends BaseAdapter implements Constants{
private Activity activity;
private ArrayList<Image> data;
private static LayoutInflater inflater=null;
private ImageLoader imageLoader;
private AsyncHelper helper;
public static final int VIEW_TYPE_LOADING = 0;
public static final int VIEW_TYPE_ACTIVITY = 1;
private int imgposition;
Handler fmHandler = null;
Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
switch(msg.what){
case HANDLER_NEW_POST_VOTE_IMAGE:
int position = msg.arg1;
JSONObject json;
try {
json = new JSONObject((String) msg.obj);
int success = json.getInt("success");
if(success == 1){
int i_id = json.getInt("i_id");
int votesUp = json.getInt("votes_up");
int votesDown = json.getInt("votes_down");
data.get(position).setVotesUp(votesUp);
data.get(position).setVotesDown(votesDown);
notifyDataSetChanged();
}
} catch (JSONException e) {
e.printStackTrace();
}
break;
case HANDLER_USER_REPORTED_IMAGE:
JSONObject json2 = Utils.createJSON((String)msg.obj);
System.out.println("REPORT IMAGE " + json2);
if(json2 != null){
try {
int success = json2.getInt("success");
if(success==1){
Toast.makeText(activity, "Image reported!", Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
break;
case HANDLER_IMAGE_SIZE_AVAILABLE:
String url = (String) msg.obj;
int height = msg.arg1;
int width = msg.arg2;
int imgPosition = findImageOfCertainURL(url);
System.out.println("GETVIEW HANDLER 1: IMAGE POSITION" + imgPosition);
if(imgPosition != -1){
data.get(imgPosition).setHeight(height);
data.get(imgPosition).setWidth(width);
}
Message copyMsg = new Message();
copyMsg.what = HANDLER_IMAGE_SIZE_AVAILABLE;
copyMsg.arg1 = height;
copyMsg.arg2 = width;
copyMsg.obj = url;
fmHandler.sendMessage(copyMsg);
notifyDataSetChanged();
break;
}
};
};
private int findImageOfCertainURL(String url){
for(int i = 0; i <data.size();i++){
if((URL_FOLDER_IMAGES + data.get(i).getUrl()).equalsIgnoreCase(url)){
return i;
}
}
return -1;
}
public LazyNewPostsAdapter(Activity a, ArrayList<Image> d, Handler fragmentHandler) {
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
helper = new AsyncHelper(activity, handler);
imageLoader=new ImageLoader(activity.getApplicationContext(), 600,handler) ;
fmHandler = fragmentHandler;
}
public void updateData(ArrayList<Image> d){
data = d;
notifyDataSetChanged();
}
public int getCount() {
return data.size()+1;
}
#Override
public int getViewTypeCount() {
return 2;
}
#Override
public int getItemViewType(int position) {
// TODO Auto-generated method stub
return (position >= data.size()) ? VIEW_TYPE_LOADING
: VIEW_TYPE_ACTIVITY;
}
#Override
public boolean isEnabled(int position) {
return getItemViewType(position) == VIEW_TYPE_ACTIVITY;
}
public Object getItem(int position) {
return (getItemViewType(position) == VIEW_TYPE_ACTIVITY) ? data.get(position) : null;
}
public long getItemId(int position) {
return (getItemViewType(position) == VIEW_TYPE_ACTIVITY) ? position
: -1;
}
public View getFooterView(int position, View convertView,
ViewGroup parent) {
// the ListView has reached the last row
TextView tvLastRow = new TextView(activity);
if(AsyncHelper.isDownloadingImages){
tvLastRow.setHint("Requesting new Images..");
} else {
tvLastRow.setHint("Reached the last row.");
}
tvLastRow.setGravity(Gravity.CENTER);
return tvLastRow;
}
private OnClickListener myHotButtonClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
int position = (Integer) v.getTag();
if(ActivityMain.user.isLoggedIn()){
data.get(position).setThisUserVote(1);
helper.vote_image(position, data.get(position).getId(), HOT);
} else {
Toast.makeText(activity, "Login to vote" , Toast.LENGTH_SHORT).show();
}
}
};
private OnClickListener myColdButtonClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
int position = (Integer) v.getTag();
if(ActivityMain.user.isLoggedIn()){
data.get(position).setThisUserVote(2);
helper.vote_image(position, data.get(position).getId(), COLD);
}else {
Toast.makeText(activity, "Login to vote" , Toast.LENGTH_SHORT).show();
}
}
};
private OnClickListener myOptionsButtonClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
final int position = (Integer) v.getTag();
Runnable optionsRunnable = new Runnable() {
#Override
public void run() {
openOptionsDialog(position);
}
};
handler.postDelayed(optionsRunnable, 500);
}
};
private void openOptionsDialog(final int imgposition){
final CharSequence[] items = {"Share", "Save", "Report"};
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle("Options");
builder.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
if(item==0){
Utils.shareImage(activity, imageLoader.getImage(URL_FOLDER_IMAGES + data.get(imgposition).getUrl()) , data.get(imgposition).getTitle());
} else if(item==1) {
Utils.saveImage(imageLoader.getImage(URL_FOLDER_IMAGES + data.get(imgposition).getUrl()),activity);
} else if(item==2) {
openReportDialog(imgposition);
}
}
});
AlertDialog alert = builder.create();
alert.show();
}
private void openReportDialog(final int imgposition){
AlertDialog.Builder builder = new AlertDialog.Builder(activity, R.style.AppCompatAlertDialogStyle);
builder.setTitle("Report This Image?");
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
helper.reportImage(data.get(imgposition).getId());
}
});
builder.setNegativeButton("No", null);
AlertDialog alert = builder.create();
alert.show();
}
public View getView(final int position, View convertView, ViewGroup parent) {
if (getItemViewType(position) == VIEW_TYPE_LOADING) {
// display the last row
return getFooterView(position, convertView, parent);
}
View vi=convertView;
final ViewHolder holder;
final Image img = data.get(position);
boolean isViNull = false;
if(convertView==null){
vi = inflater.inflate(R.layout.item_new_posts, null);
holder = new ViewHolder();
isViNull = true;
holder.title=(BrushTextView)vi.findViewById(R.id.tv_newposts_title);
holder.image=(RatioImageView)vi.findViewById(R.id.iv_newposts_image);
holder.uploader = (BrushTextView) vi.findViewById(R.id.tv_newposts_uploader);
holder.upvotes = (BrushTextView) vi.findViewById(R.id.tv_newposts_upvotes);
holder.downvotes= (BrushTextView) vi.findViewById(R.id.tv_newposts_downvotes);
holder.options=(LinearLayout)vi.findViewById(R.id.ll_newposts_button_options);
holder.iv_hot=(ImageView)vi.findViewById(R.id.iv_newposts_button_upvote);
holder.iv_cold=(ImageView)vi.findViewById(R.id.iv_newposts_button_downvote);
holder.ll_hot=(LinearLayout)vi.findViewById(R.id.ll_newposts_button_upvote);
holder.ll_cold=(LinearLayout)vi.findViewById(R.id.ll_newposts_button_downvote);
vi.setTag(holder);
} else {
holder = (ViewHolder) vi.getTag();
}
if(img.getHeight() != 0 && img.getWidth() != 0){
holder.image.getLayoutParams().height = img.getHeight();
holder.image.getLayoutParams().width = img.getWidth();
holder.image.requestLayout();
}
holder.ll_hot.setTag(position);
holder.ll_hot.setOnClickListener(myHotButtonClickListener);
holder.ll_cold.setTag(position);
holder.ll_cold.setOnClickListener(myColdButtonClickListener);
holder.options.setTag(position);
holder.options.setOnClickListener(myOptionsButtonClickListener);
changeVoteButtonImages(img, holder.iv_hot, holder.iv_cold);
if(img.getTitle()!=null){
holder.title.setVisibility(View.VISIBLE);
holder.title.setText(img.getTitle());
} else {
holder.title.setVisibility(View.GONE);
}
holder.uploader.setText(img.getUploader());
holder.upvotes.setText(img.getVotesUp()+"");
holder.downvotes.setText(img.getVotesDown()+"");
String url = URL_FOLDER_IMAGES + img.getUrl();
System.out.println("GETVIEW NEW POST ADAPTER: height = " + img.getHeight() + " width = " + img.getWidth());
if(isViNull)
System.out.println("GETVIEW CONVERTVIEW: VI: " +vi.getHeight());
imageLoader.DisplayImage(url, holder.image);
return vi;
}
private void changeVoteButtonImages(Image image, ImageView upvote,ImageView downvote){
switch(image.getThisUserVote()){
case 0:
upvote.setImageDrawable(activity.getResources().getDrawable(R.drawable.ic_post_hot_0));
downvote.setImageDrawable(activity.getResources().getDrawable(R.drawable.ic_post_cold_0));
break;
case 1:
downvote.setImageDrawable(activity.getResources().getDrawable(R.drawable.ic_post_cold_0));
upvote.setImageDrawable(activity.getResources().getDrawable(R.drawable.ic_post_hot_1));
break;
case 2:
upvote.setImageDrawable(activity.getResources().getDrawable(R.drawable.ic_post_hot_0));
downvote.setImageDrawable(activity.getResources().getDrawable(R.drawable.ic_post_cold_1));
break;
}
}
static class ViewHolder {
public BrushTextView title, uploader, upvotes, downvotes;
public ImageView iv_hot,iv_cold;
public LinearLayout options, ll_hot,ll_cold;
public RatioImageView image;
}
}
And here is the Fragment, which contains the ListView
public class Fragment_New_Posts extends Fragment implements Constants, OnRefreshListener{
private static final String ARG_SECTION_NUMBER = "section_number";
private ListView list;
private LazyNewPostsAdapter adapter;
private Images images;
private ArrayList<Image> imagesList;
private SharedPreferences prefs;
private Editor editor;
private int visible_i_id;
private SwipeRefreshLayout swipeLayout;
private int option_image_filter;
private AsyncHelper helper;
private boolean onRefreshFired = false;
private Parcelable state;
public static Fragment_New_Posts newInstance(int sectionNumber) {
Fragment_New_Posts fragment = new Fragment_New_Posts();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public static Fragment_New_Posts newInstance(int sectionNumber, Images imgs) {
Fragment_New_Posts fragment = new Fragment_New_Posts(imgs);
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public void updateImages(Images images, boolean createNew, boolean loadOldImages){
int i_id_position = 0;
this.images = images;
if(!images.hasErrorOccured){
if(this.imagesList == null || createNew || onRefreshFired){
this.imagesList = images.getListOfImages();
} else {
this.imagesList.addAll(images.getListOfImages());
}
}
if(loadOldImages){
i_id_position = this.images.getIDPosition(visible_i_id);
}
if(onRefreshFired){
swipeLayout.setRefreshing(false);
onRefreshFired = false;
}
synchronized (adapter) {
adapter.updateData(this.imagesList);
if(list!=null && createNew){
if(loadOldImages){
list.setSelection(i_id_position);
} else {
list.setSelection(0);
}
}
}
}
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
switch(msg.what){
case HANDLER_MAIN_IMAGE_UPDATE:
String imagesString = (String) msg.obj;
Images imgs = new Images(imagesString);
updateImages(imgs, false, false);
if(imgs.hasErrorOccured){
Toast.makeText(getActivity(), "Can\'t get new Images", Toast.LENGTH_SHORT).show();
}
break;
case HANDLER_IMAGE_SIZE_AVAILABLE:
String url = (String) msg.obj;
int height = msg.arg1;
int width = msg.arg2;
int imgPosition = findImageOfCertainURL(url);
System.out.println("GETVIEW HANDLER 2: IMAGE POSITION" + imgPosition);
if(imgPosition != -1){
imagesList.get(imgPosition).setHeight(height);
imagesList.get(imgPosition).setWidth(width);
}
break;
}
};
};
private int findImageOfCertainURL(String url){
for(int i = 0; i <imagesList.size();i++){
if((URL_FOLDER_IMAGES + imagesList.get(i).getUrl()).equalsIgnoreCase(url)){
return i;
}
}
return -1;
}
public Fragment_New_Posts() {
}
public Fragment_New_Posts(Images imgs) {
this.images = imgs;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
System.out.println("NEW POST FRAGMENT ONCREATE");
View rootView = inflater.inflate(R.layout.fragment_new_posts, container, false);
prefs = getActivity().getSharedPreferences(PREF_WOODU, getActivity().MODE_PRIVATE);
editor = prefs.edit();
if(prefs!=null){
visible_i_id = prefs.getInt(PREF_NEW_POSTS_VISIBLE_I_ID, 0);
option_image_filter = prefs.getInt(PHP_TAG_IMAGE_FILTER, 0);
}
swipeLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipe_container);
swipeLayout.setColorSchemeColors(R.color.red_hot);
swipeLayout.setOnRefreshListener(this);
helper = new AsyncHelper(getActivity(), handler);
imagesList = new ArrayList<Image>();
if(images != null){
imagesList = images.getListOfImages();
System.out.println("SAVE IMAGES: load: imgsList " + imagesList);
}
list = (ListView) rootView.findViewById(R.id.lv_new_posts);
adapter = new LazyNewPostsAdapter(getActivity(), imagesList, handler);
list.setAdapter(adapter);
list.setOnScrollListener(new EndlessScrollListener() {
#Override
public void onLoadMore(int page, int totalItemsCount) {
if(imagesList!=null && imagesList.size()!=0){
helper.getImageUpdate(imagesList.get(imagesList.size()-1).getId(), option_image_filter);
}
}
});
if(images != null){
updateImages(images, true, true);
}
return rootView;
}
#Override
public void onPause() {
int lastVisposition = list.getLastVisiblePosition();
if(lastVisposition>=0 && lastVisposition < this.imagesList.size()){
visible_i_id = this.imagesList.get(list.getFirstVisiblePosition()).getId();
editor.putInt(PREF_NEW_POSTS_VISIBLE_I_ID, visible_i_id);
editor.commit();
}
super.onPause();
}
#Override
public void onResume() {
super.onResume();
}
#Override
public void onDestroy() {
if(images != null){
editor.putString(PREF_NEW_POSTS_CURRENT_IMAGES, Utils.createJSONStringFromImageArrayList(imagesList, editor));
editor.commit();
}
super.onDestroy();
}
#Override
public void onRefresh() {
onRefreshFired = true;
if(prefs!=null){
option_image_filter = prefs.getInt(PHP_TAG_IMAGE_FILTER, 0);
}
helper.getImageUpdate(0, option_image_filter);
}
}
Now here are many many information and code. I hope that does not scare anyone to help :D
Thanks!!

Please, Please , Please don't "re-invent the Wheel" and use any lib out there for image loading, caching etc like Picasso, Fresco , Glide etc....

I probably solved the Problem.. Finally.. My idea of setting the height of the ImageView in getView wasn't so bad.. problem was:
My ImageView was wrapped inside a CardView in XML.. So I needed to change the Height of the CardView instead of the ImageView :)

WeakHashMap ... you are using weak references. Which does right that. Deletes objects when used no more. So, just change it to HashMap and you should be doing fine.

Related

Nothing getting displayed in singleitem view

I am having an app that retrieves information from parse and display into a list view ,but when the app is run and the list view item is clicked it opens a new activity and display some images and text from parse.com but it shows nothing like the image below
Here is my code
main activity.java
public class MainActivity extends Activity
{
ListView listview;
List<ParseObject> ob;
ProgressDialog mProgressDialog;
FinalAdapter adapter;
private List<CodeList> codelist = null;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.beg_layout);
new RemoteDataTask().execute();
}
private class RemoteDataTask extends AsyncTask<Void, Void, Void>
{
#Override
protected void onPreExecute() {
super.onPreExecute();
// Create a progressdialog
mProgressDialog = new ProgressDialog(MainActivity.this);
// Set progressdialog title
mProgressDialog.setTitle("Testing");
// Set progressdialog message
mProgressDialog.setMessage("Loading. Please wait this may take few moments ....");
mProgressDialog.setIndeterminate(true);
// Show progressdialog
mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params)
{
codelist = new ArrayList<CodeList>();
try{
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>(
"BeginnerActivity");
query.orderByAscending("_created_at");
ob = query.find();
for(ParseObject begactivity : ob){
ParseFile listimg = (ParseFile) begactivity.get("alphabetimg");
ParseFile levelimg = (ParseFile) begactivity.get("levelimg");
ParseFile apiimg = (ParseFile) begactivity.get("apiimg");
ParseFile descimgone = (ParseFile) begactivity.get("descimgone");
ParseFile descimgtwo = (ParseFile) begactivity.get("descimgtwo");
CodeList map = new CodeList();
map.setListHeading((String) begactivity.get("listheading"));
map.setSingleItemHeading((String) begactivity.get("heading"));
map.setDescription((String) begactivity.get("subheading"));
map.setApiText((String) begactivity.get("apitext"));
map.setFinalCodeText((String) begactivity.get("codetext"));
map.setAlphabetimg(listimg.getUrl());
map.setLevelImg(levelimg.getUrl());
map.setApiImg(apiimg.getUrl());
map.setPreviewImgOne(descimgone.getUrl());
map.setPreviewImgTwo(descimgtwo.getUrl());
codelist.add(map);
}
}catch(ParseException e){
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// Locate the listview in listview_main.xml
listview = (ListView) findViewById(R.id.beg_layoutListView);
// Pass the results into ListViewAdapter.java
adapter = new FinalAdapter(MainActivity.this,
codelist);
// Binds the Adapter to the ListView
listview.setAdapter(adapter);
// Close the progressdialog
mProgressDialog.dismiss();
}
}
}
codelist.java
public class CodeList
{
private String alphabetimg;
private String listHeading;
private String levelImg;
private String singleItemHeading;
private String description;
private String apiImg;
private String apiText;
private String previewImgOne;
private String previewImgTwo;
private String finalCodeText;
public void setAlphabetimg(String alphabetimg)
{
this.alphabetimg = alphabetimg;
}
public String getAlphabetimg()
{
return alphabetimg;
}
public void setListHeading(String listHeading)
{
this.listHeading = listHeading;
}
public String getListHeading()
{
return listHeading;
}
public void setLevelImg(String levelImg)
{
this.levelImg = levelImg;
}
public String getLevelImg()
{
return levelImg;
}
public void setSingleItemHeading(String singleItemHeading)
{
this.singleItemHeading = singleItemHeading;
}
public String getSingleItemHeading()
{
return singleItemHeading;
}
public void setDescription(String description)
{
this.description = description;
}
public String getDescription()
{
return description;
}
public void setApiImg(String apiImg)
{
this.apiImg = apiImg;
}
public String getApiImg()
{
return apiImg;
}
public void setApiText(String apiText)
{
this.apiText = apiText;
}
public String getApiText()
{
return apiText;
}
public void setPreviewImgOne(String previewImgOne)
{
this.previewImgOne = previewImgOne;
}
public String getPreviewImgOne()
{
return previewImgOne;
}
public void setPreviewImgTwo(String previewImgTwo)
{
this.previewImgTwo = previewImgTwo;
}
public String getPreviewImgTwo()
{
return previewImgTwo;
}
public void setFinalCodeText(String finalCodeText)
{
this.finalCodeText = finalCodeText;
}
public String getFinalCodeText()
{
return finalCodeText;
}
}
parse application.java
public class ParseApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
// Add your initialization code here
Parse.initialize(this, "4rOrqK23m0nVq187Of3rhDe0TK1R7FObdBWhfX10", "afKA4B9ohvk3M9pZNv9qK2ypbrdOpXi0FPnrXOu6");
ParseUser.enableAutomaticUser();
ParseACL defaultACL = new ParseACL();
// If you would like all objects to be private by default, remove this line.
defaultACL.setPublicReadAccess(true);
ParseACL.setDefaultACL(defaultACL, true);
}
}
final adapter.java
public class FinalAdapter extends BaseAdapter
{
Context context;
LayoutInflater inflater;
ImageLoader imageLoader;
private List<CodeList> codeList = null;
private ArrayList<CodeList> arraylist;
public FinalAdapter(Context context,
List<CodeList> codeList) {
this.context = context;
this.codeList = codeList;
inflater = LayoutInflater.from(context);
this.arraylist = new ArrayList<CodeList>();
this.arraylist.addAll(codeList);
imageLoader = new ImageLoader(context);
}
public class ViewHolder{
TextView listHeading;
ImageView alphabetList;
}
#Override
public int getCount()
{
return codeList.size();
}
#Override
public Object getItem(int position)
{
return codeList.get(position);
}
#Override
public long getItemId(int position)
{
return position;
}
#Override
public View getView(final int position, View view, ViewGroup parent)
{
final ViewHolder holder;
if(view == null){
holder = new ViewHolder();
view = inflater.inflate(R.layout.beg_list_item,null);
holder.listHeading = (TextView) view.findViewById(R.id.beg_list_itemTextView);
holder.alphabetList = (ImageView) view.findViewById(R.id.beg_list_itemImageView);
view.setTag(holder);
}else{
holder = (ViewHolder) view.getTag();
}
holder.listHeading.setText(codeList.get(position).getListHeading());
imageLoader.DisplayImage(codeList.get(position).getAlphabetimg(),
holder.alphabetList);
view.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0){
Intent intent = new Intent(context, SingleItemView.class);
intent.putExtra("listheading",
(codeList.get(position).getListHeading()));
intent.putExtra("alphabetimg",
(codeList.get(position).getAlphabetimg()));
// Start SingleItemView Class
context.startActivity(intent);
}
});
return view;
}
}
singleitemview.java
public class SingleItemView extends Activity.
{
String heading;
String subHeading;
String levelImg;
String apiImg;
String apiText;
String descImgOne;
String descImgTwo;
String codeText;
ImageLoader imgloader = new ImageLoader(this);
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.singleitemview);
Intent i = getIntent();
heading= i.getStringExtra("heading");
subHeading = i.getStringExtra("subheading");
levelImg = i.getStringExtra("levelimg");
apiImg = i.getStringExtra("apiimg");
apiText = i.getStringExtra("apitext");
descImgOne = i.getStringExtra("descimgone");
descImgTwo = i.getStringExtra("descimgtwo");
codeText = i.getStringExtra("codetext");
TextView headingtxt = (TextView)findViewById(R.id.singleitemheading);
TextView subheadingtxt = (TextView)findViewById(R.id.singleitemsubheading);
TextView apitxt = (TextView)findViewById(R.id.singleitemviewapitext);
TextView codetxt = (TextView) findViewById(R.id.singleitemviewcodetext);
ImageView level =(ImageView) findViewById(R.id.levelimg);
ImageView api =(ImageView) findViewById(R.id.singleitemviewapiimg);
ImageView descone =(ImageView) findViewById(R.id.descriptionimgone);
ImageView desctwo =(ImageView) findViewById(R.id.descriptionimgtwo);
headingtxt.setText(heading);
subheadingtxt.setText(subHeading);
apitxt.setText(apiText);
codetxt.setText(codeText);
imgloader.DisplayImage(levelImg, level);
imgloader.DisplayImage(apiImg, api);
imgloader.DisplayImage(descImgOne, descone);
imgloader.DisplayImage(descImgTwo, desctwo);
}
}
image loaded.java
public class ImageLoader {
MemoryCache memoryCache = new MemoryCache();
FileCache fileCache;
private Map<ImageView, String> imageViews = Collections
.synchronizedMap(new WeakHashMap<ImageView, String>());
ExecutorService executorService;
// Handler to display images in UI thread
Handler handler = new Handler();
public ImageLoader(Context context) {
fileCache = new FileCache(context);
executorService = Executors.newFixedThreadPool(5);
}
final int stub_id = R.drawable.temp_img;
public void DisplayImage(String url, ImageView imageView) {
imageViews.put(imageView, url);
Bitmap bitmap = memoryCache.get(url);
if (bitmap != null)
imageView.setImageBitmap(bitmap);
else {
queuePhoto(url, imageView);
imageView.setImageResource(stub_id);
}
}
private void queuePhoto(String url, ImageView imageView) {
PhotoToLoad p = new PhotoToLoad(url, imageView);
executorService.submit(new PhotosLoader(p));
}
private Bitmap getBitmap(String url) {
File f = fileCache.getFile(url);
Bitmap b = decodeFile(f);
if (b != null)
return b;
// Download Images from the Internet
try {
Bitmap bitmap = null;
URL imageUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) imageUrl
.openConnection();
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);
conn.setInstanceFollowRedirects(true);
InputStream is = conn.getInputStream();
OutputStream os = new FileOutputStream(f);
Utils.CopyStream(is, os);
os.close();
conn.disconnect();
bitmap = decodeFile(f);
return bitmap;
} catch (Throwable ex) {
ex.printStackTrace();
if (ex instanceof OutOfMemoryError)
memoryCache.clear();
return null;
}
}
// Decodes image and scales it to reduce memory consumption
private Bitmap decodeFile(File f) {
try {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
FileInputStream stream1 = new FileInputStream(f);
BitmapFactory.decodeStream(stream1, null, o);
stream1.close();
// Find the correct scale value. It should be the power of 2.
final int REQUIRED_SIZE = 70;
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp / 2 < REQUIRED_SIZE
|| height_tmp / 2 < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
FileInputStream stream2 = new FileInputStream(f);
Bitmap bitmap = BitmapFactory.decodeStream(stream2, null, o2);
stream2.close();
return bitmap;
} catch (FileNotFoundException e) {
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
// Task for the queue
private class PhotoToLoad {
public String url;
public ImageView imageView;
public PhotoToLoad(String u, ImageView i) {
url = u;
imageView = i;
}
}
class PhotosLoader implements Runnable {
PhotoToLoad photoToLoad;
PhotosLoader(PhotoToLoad photoToLoad) {
this.photoToLoad = photoToLoad;
}
#Override
public void run() {
try {
if (imageViewReused(photoToLoad))
return;
Bitmap bmp = getBitmap(photoToLoad.url);
memoryCache.put(photoToLoad.url, bmp);
if (imageViewReused(photoToLoad))
return;
BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad);
handler.post(bd);
} catch (Throwable th) {
th.printStackTrace();
}
}
}
boolean imageViewReused(PhotoToLoad photoToLoad) {
String tag = imageViews.get(photoToLoad.imageView);
if (tag == null || !tag.equals(photoToLoad.url))
return true;
return false;
}
// Used to display bitmap in the UI thread
class BitmapDisplayer implements Runnable {
Bitmap bitmap;
PhotoToLoad photoToLoad;
public BitmapDisplayer(Bitmap b, PhotoToLoad p) {
bitmap = b;
photoToLoad = p;
}
public void run() {
if (imageViewReused(photoToLoad))
return;
if (bitmap != null)
photoToLoad.imageView.setImageBitmap(bitmap);
else
photoToLoad.imageView.setImageResource(stub_id);
}
}
public void clearCache() {
memoryCache.clear();
fileCache.clear();
}
}
filecache.java
public class FileCache {
private File cacheDir;
public FileCache(Context context) {
// Find the dir to save cached images
if (android.os.Environment.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED))
cacheDir = new File(
android.os.Environment.getExternalStorageDirectory(),
"ImgTxt");
else
cacheDir = context.getCacheDir();
if (!cacheDir.exists())
cacheDir.mkdirs();
}
public File getFile(String url) {
String filename = String.valueOf(url.hashCode());
// String filename = URLEncoder.encode(url);
File f = new File(cacheDir, filename);
return f;
}
public void clear() {
File[] files = cacheDir.listFiles();
if (files == null)
return;
for (File f : files)
f.delete();
}
}
memorycache.java
public class MemoryCache {
private static final String TAG = "MemoryCache";
// Last argument true for LRU ordering
private Map<String, Bitmap> cache = Collections
.synchronizedMap(new LinkedHashMap<String, Bitmap>(10, 1.5f, true));
// Current allocated size
private long size = 0;
// Max memory in bytes
private long limit = 1000000;
public MemoryCache() {
// Use 25% of available heap size
setLimit(Runtime.getRuntime().maxMemory() / 4);
}
public void setLimit(long new_limit) {
limit = new_limit;
Log.i(TAG, "MemoryCache will use up to " + limit / 1024. / 1024. + "MB");
}
public Bitmap get(String id) {
try {
if (!cache.containsKey(id))
return null;
return cache.get(id);
} catch (NullPointerException ex) {
ex.printStackTrace();
return null;
}
}
public void put(String id, Bitmap bitmap) {
try {
if (cache.containsKey(id))
size -= getSizeInBytes(cache.get(id));
cache.put(id, bitmap);
size += getSizeInBytes(bitmap);
checkSize();
} catch (Throwable th) {
th.printStackTrace();
}
}
private void checkSize() {
Log.i(TAG, "cache size=" + size + " length=" + cache.size());
if (size > limit) {
// Least recently accessed item will be the first one iterated
Iterator<Entry<String, Bitmap>> iter = cache.entrySet().iterator();
while (iter.hasNext()) {
Entry<String, Bitmap> entry = iter.next();
size -= getSizeInBytes(entry.getValue());
iter.remove();
if (size <= limit)
break;
}
Log.i(TAG, "Clean cache. New size " + cache.size());
}
}
public void clear() {
try {
cache.clear();
size = 0;
} catch (NullPointerException ex) {
ex.printStackTrace();
}
}
long getSizeInBytes(Bitmap bitmap) {
if (bitmap == null)
return 0;
return bitmap.getRowBytes() * bitmap.getHeight();
}
}
android manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mycompany.myapp" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:name="ParseApplication"
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SingleItemView">
</activity>
</application>
</manifest>
In the onclicklistener() add this code
intent.putExtra("levelimg",
(codeList.get(position).getLevelImg()));
intent.putExtra("heading",
(codeList.get(position).getSingleItemHeading()));
intent.putExtra("subheading",
(codeList.get(position).getDescription()));
intent.putExtra("apitext",
(codeList.get(position).getApiText()));
intent.putExtra("apiimg",
(codeList.get(position).getApiImg()));
intent.putExtra("descimgone",
(codeList.get(position).getPreviewImgOne()));
intent.putExtra("descimgtwo",
(codeList.get(position).getPreviewImgTwo()));
intent.putExtra("codetext",
(codeList.get(position).getFinalCodeText()));

Retrieves nothing from parse.com into singleitemview

My app retrieves information from parse and display it into a list view ,but when the app is run and the list view item is clicked it opens a new activity and display some images and text from parse.com but it shows nothing like the image below
Here is my code
MainActivity
public class MainActivity extends Activity
{
ListView listview;
List<ParseObject> ob;
ProgressDialog mProgressDialog;
FinalAdapter adapter;
private List<CodeList> codelist = null;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.beg_layout);
new RemoteDataTask().execute();
}
private class RemoteDataTask extends AsyncTask<Void, Void, Void>
{
#Override
protected void onPreExecute() {
super.onPreExecute();
// Create a progressdialog
mProgressDialog = new ProgressDialog(MainActivity.this);
// Set progressdialog title
mProgressDialog.setTitle("Testing");
// Set progressdialog message
mProgressDialog.setMessage("Loading. Please wait this may take few moments ....");
mProgressDialog.setIndeterminate(true);
// Show progressdialog
mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params)
{
codelist = new ArrayList<CodeList>();
try{
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>(
"BeginnerActivity");
query.orderByAscending("_created_at");
ob = query.find();
for(ParseObject begactivity : ob){
ParseFile listimg = (ParseFile) begactivity.get("alphabetimg");
ParseFile levelimg = (ParseFile) begactivity.get("levelimg");
ParseFile apiimg = (ParseFile) begactivity.get("apiimg");
ParseFile descimgone = (ParseFile) begactivity.get("descimgone");
ParseFile descimgtwo = (ParseFile) begactivity.get("descimgtwo");
CodeList map = new CodeList();
map.setListHeading((String) begactivity.get("listheading"));
map.setSingleItemHeading((String) begactivity.get("heading"));
map.setDescription((String) begactivity.get("subheading"));
map.setApiText((String) begactivity.get("apitext"));
map.setFinalCodeText((String) begactivity.get("codetext"));
map.setAlphabetimg(listimg.getUrl());
map.setLevelImg(levelimg.getUrl());
map.setApiImg(apiimg.getUrl());
map.setPreviewImgOne(descimgone.getUrl());
map.setPreviewImgTwo(descimgtwo.getUrl());
codelist.add(map);
}
}catch(ParseException e){
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// Locate the listview in listview_main.xml
listview = (ListView) findViewById(R.id.beg_layoutListView);
// Pass the results into ListViewAdapter.java
adapter = new FinalAdapter(MainActivity.this,
codelist);
// Binds the Adapter to the ListView
listview.setAdapter(adapter);
// Close the progressdialog
mProgressDialog.dismiss();
}
}
}
CodeList
public class CodeList
{
private String alphabetimg;
private String listHeading;
private String levelImg;
private String singleItemHeading;
private String description;
private String apiImg;
private String apiText;
private String previewImgOne;
private String previewImgTwo;
private String finalCodeText;
public void setAlphabetimg(String alphabetimg)
{
this.alphabetimg = alphabetimg;
}
public String getAlphabetimg()
{
return alphabetimg;
}
public void setListHeading(String listHeading)
{
this.listHeading = listHeading;
}
public String getListHeading()
{
return listHeading;
}
public void setLevelImg(String levelImg)
{
this.levelImg = levelImg;
}
public String getLevelImg()
{
return levelImg;
}
public void setSingleItemHeading(String singleItemHeading)
{
this.singleItemHeading = singleItemHeading;
}
public String getSingleItemHeading()
{
return singleItemHeading;
}
public void setDescription(String description)
{
this.description = description;
}
public String getDescription()
{
return description;
}
public void setApiImg(String apiImg)
{
this.apiImg = apiImg;
}
public String getApiImg()
{
return apiImg;
}
public void setApiText(String apiText)
{
this.apiText = apiText;
}
public String getApiText()
{
return apiText;
}
public void setPreviewImgOne(String previewImgOne)
{
this.previewImgOne = previewImgOne;
}
public String getPreviewImgOne()
{
return previewImgOne;
}
public void setPreviewImgTwo(String previewImgTwo)
{
this.previewImgTwo = previewImgTwo;
}
public String getPreviewImgTwo()
{
return previewImgTwo;
}
public void setFinalCodeText(String finalCodeText)
{
this.finalCodeText = finalCodeText;
}
public String getFinalCodeText()
{
return finalCodeText;
}
}
ParseApplication
public class ParseApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
// Add your initialization code here
Parse.initialize(this, "4rOrqK23m0nVq187Of3rhDe0TK1R7FObdBWhfX10", "afKA4B9ohvk3M9pZNv9qK2ypbrdOpXi0FPnrXOu6");
ParseUser.enableAutomaticUser();
ParseACL defaultACL = new ParseACL();
// If you would like all objects to be private by default, remove this line.
defaultACL.setPublicReadAccess(true);
ParseACL.setDefaultACL(defaultACL, true);
}
}
FinalAdapter
public class FinalAdapter extends BaseAdapter
{
Context context;
LayoutInflater inflater;
ImageLoader imageLoader;
private List<CodeList> codeList = null;
private ArrayList<CodeList> arraylist;
public FinalAdapter(Context context,
List<CodeList> codeList) {
this.context = context;
this.codeList = codeList;
inflater = LayoutInflater.from(context);
this.arraylist = new ArrayList<CodeList>();
this.arraylist.addAll(codeList);
imageLoader = new ImageLoader(context);
}
public class ViewHolder{
TextView listHeading;
ImageView alphabetList;
}
#Override
public int getCount()
{
return codeList.size();
}
#Override
public Object getItem(int position)
{
return codeList.get(position);
}
#Override
public long getItemId(int position)
{
return position;
}
#Override
public View getView(final int position, View view, ViewGroup parent)
{
final ViewHolder holder;
if(view == null){
holder = new ViewHolder();
view = inflater.inflate(R.layout.beg_list_item,null);
holder.listHeading = (TextView) view.findViewById(R.id.beg_list_itemTextView);
holder.alphabetList = (ImageView) view.findViewById(R.id.beg_list_itemImageView);
view.setTag(holder);
}else{
holder = (ViewHolder) view.getTag();
}
holder.listHeading.setText(codeList.get(position).getListHeading());
imageLoader.DisplayImage(codeList.get(position).getAlphabetimg(),
holder.alphabetList);
view.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0){
Intent intent = new Intent(context, SingleItemView.class);
intent.putExtra("listheading",
(codeList.get(position).getListHeading()));
intent.putExtra("alphabetimg",
(codeList.get(position).getAlphabetimg()));
// Start SingleItemView Class
context.startActivity(intent);
}
});
return view;
}
}
SingleItemView
public class SingleItemView extends Activity.
{
String heading;
String subHeading;
String levelImg;
String apiImg;
String apiText;
String descImgOne;
String descImgTwo;
String codeText;
ImageLoader imgloader = new ImageLoader(this);
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.singleitemview);
Intent i = getIntent();
heading= i.getStringExtra("heading");
subHeading = i.getStringExtra("subheading");
levelImg = i.getStringExtra("levelimg");
apiImg = i.getStringExtra("apiimg");
apiText = i.getStringExtra("apitext");
descImgOne = i.getStringExtra("descimgone");
descImgTwo = i.getStringExtra("descimgtwo");
codeText = i.getStringExtra("codetext");
TextView headingtxt = (TextView)findViewById(R.id.singleitemheading);
TextView subheadingtxt = (TextView)findViewById(R.id.singleitemsubheading);
TextView apitxt = (TextView)findViewById(R.id.singleitemviewapitext);
TextView codetxt = (TextView) findViewById(R.id.singleitemviewcodetext);
ImageView level =(ImageView) findViewById(R.id.levelimg);
ImageView api =(ImageView) findViewById(R.id.singleitemviewapiimg);
ImageView descone =(ImageView) findViewById(R.id.descriptionimgone);
ImageView desctwo =(ImageView) findViewById(R.id.descriptionimgtwo);
headingtxt.setText(heading);
subheadingtxt.setText(subHeading);
apitxt.setText(apiText);
codetxt.setText(codeText);
imgloader.DisplayImage(levelImg, level);
imgloader.DisplayImage(apiImg, api);
imgloader.DisplayImage(descImgOne, descone);
imgloader.DisplayImage(descImgTwo, desctwo);
}
}
ImageLoader
public class ImageLoader {
MemoryCache memoryCache = new MemoryCache();
FileCache fileCache;
private Map<ImageView, String> imageViews = Collections
.synchronizedMap(new WeakHashMap<ImageView, String>());
ExecutorService executorService;
// Handler to display images in UI thread
Handler handler = new Handler();
public ImageLoader(Context context) {
fileCache = new FileCache(context);
executorService = Executors.newFixedThreadPool(5);
}
final int stub_id = R.drawable.temp_img;
public void DisplayImage(String url, ImageView imageView) {
imageViews.put(imageView, url);
Bitmap bitmap = memoryCache.get(url);
if (bitmap != null)
imageView.setImageBitmap(bitmap);
else {
queuePhoto(url, imageView);
imageView.setImageResource(stub_id);
}
}
private void queuePhoto(String url, ImageView imageView) {
PhotoToLoad p = new PhotoToLoad(url, imageView);
executorService.submit(new PhotosLoader(p));
}
private Bitmap getBitmap(String url) {
File f = fileCache.getFile(url);
Bitmap b = decodeFile(f);
if (b != null)
return b;
// Download Images from the Internet
try {
Bitmap bitmap = null;
URL imageUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) imageUrl
.openConnection();
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);
conn.setInstanceFollowRedirects(true);
InputStream is = conn.getInputStream();
OutputStream os = new FileOutputStream(f);
Utils.CopyStream(is, os);
os.close();
conn.disconnect();
bitmap = decodeFile(f);
return bitmap;
} catch (Throwable ex) {
ex.printStackTrace();
if (ex instanceof OutOfMemoryError)
memoryCache.clear();
return null;
}
}
// Decodes image and scales it to reduce memory consumption
private Bitmap decodeFile(File f) {
try {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
FileInputStream stream1 = new FileInputStream(f);
BitmapFactory.decodeStream(stream1, null, o);
stream1.close();
// Find the correct scale value. It should be the power of 2.
final int REQUIRED_SIZE = 70;
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp / 2 < REQUIRED_SIZE
|| height_tmp / 2 < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
FileInputStream stream2 = new FileInputStream(f);
Bitmap bitmap = BitmapFactory.decodeStream(stream2, null, o2);
stream2.close();
return bitmap;
} catch (FileNotFoundException e) {
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
// Task for the queue
private class PhotoToLoad {
public String url;
public ImageView imageView;
public PhotoToLoad(String u, ImageView i) {
url = u;
imageView = i;
}
}
class PhotosLoader implements Runnable {
PhotoToLoad photoToLoad;
PhotosLoader(PhotoToLoad photoToLoad) {
this.photoToLoad = photoToLoad;
}
#Override
public void run() {
try {
if (imageViewReused(photoToLoad))
return;
Bitmap bmp = getBitmap(photoToLoad.url);
memoryCache.put(photoToLoad.url, bmp);
if (imageViewReused(photoToLoad))
return;
BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad);
handler.post(bd);
} catch (Throwable th) {
th.printStackTrace();
}
}
}
boolean imageViewReused(PhotoToLoad photoToLoad) {
String tag = imageViews.get(photoToLoad.imageView);
if (tag == null || !tag.equals(photoToLoad.url))
return true;
return false;
}
// Used to display bitmap in the UI thread
class BitmapDisplayer implements Runnable {
Bitmap bitmap;
PhotoToLoad photoToLoad;
public BitmapDisplayer(Bitmap b, PhotoToLoad p) {
bitmap = b;
photoToLoad = p;
}
public void run() {
if (imageViewReused(photoToLoad))
return;
if (bitmap != null)
photoToLoad.imageView.setImageBitmap(bitmap);
else
photoToLoad.imageView.setImageResource(stub_id);
}
}
public void clearCache() {
memoryCache.clear();
fileCache.clear();
}
}
MemoryCache
public class MemoryCache {
private static final String TAG = "MemoryCache";
// Last argument true for LRU ordering
private Map<String, Bitmap> cache = Collections
.synchronizedMap(new LinkedHashMap<String, Bitmap>(10, 1.5f, true));
// Current allocated size
private long size = 0;
// Max memory in bytes
private long limit = 1000000;
public MemoryCache() {
// Use 25% of available heap size
setLimit(Runtime.getRuntime().maxMemory() / 4);
}
public void setLimit(long new_limit) {
limit = new_limit;
Log.i(TAG, "MemoryCache will use up to " + limit / 1024. / 1024. + "MB");
}
public Bitmap get(String id) {
try {
if (!cache.containsKey(id))
return null;
return cache.get(id);
} catch (NullPointerException ex) {
ex.printStackTrace();
return null;
}
}
public void put(String id, Bitmap bitmap) {
try {
if (cache.containsKey(id))
size -= getSizeInBytes(cache.get(id));
cache.put(id, bitmap);
size += getSizeInBytes(bitmap);
checkSize();
} catch (Throwable th) {
th.printStackTrace();
}
}
private void checkSize() {
Log.i(TAG, "cache size=" + size + " length=" + cache.size());
if (size > limit) {
// Least recently accessed item will be the first one iterated
Iterator<Entry<String, Bitmap>> iter = cache.entrySet().iterator();
while (iter.hasNext()) {
Entry<String, Bitmap> entry = iter.next();
size -= getSizeInBytes(entry.getValue());
iter.remove();
if (size <= limit)
break;
}
Log.i(TAG, "Clean cache. New size " + cache.size());
}
}
public void clear() {
try {
cache.clear();
size = 0;
} catch (NullPointerException ex) {
ex.printStackTrace();
}
}
long getSizeInBytes(Bitmap bitmap) {
if (bitmap == null)
return 0;
return bitmap.getRowBytes() * bitmap.getHeight();
}
}
FileCache
public class FileCache {
private File cacheDir;
public FileCache(Context context) {
// Find the dir to save cached images
if (android.os.Environment.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED))
cacheDir = new File(
android.os.Environment.getExternalStorageDirectory(),
"ImgTxt");
else
cacheDir = context.getCacheDir();
if (!cacheDir.exists())
cacheDir.mkdirs();
}
public File getFile(String url) {
String filename = String.valueOf(url.hashCode());
// String filename = URLEncoder.encode(url);
File f = new File(cacheDir, filename);
return f;
}
public void clear() {
File[] files = cacheDir.listFiles();
if (files == null)
return;
for (File f : files)
f.delete();
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mycompany.myapp" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:name="ParseApplication"
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SingleItemView">
</activity>
</application>
</manifest>

Lazy Loading of image in listview by its position

i am trying lazy loading with LruCache as shown here : Example using Androids lrucache.
public class TCImageLoader implements ComponentCallbacks2 {
private TCLruCache cache;
Context cv;
public TCImageLoader(Context context) {
ActivityManager am = (ActivityManager) context.getSystemService(
Context.ACTIVITY_SERVICE);
int maxKb = am.getMemoryClass() * 1024;
int limitKb = maxKb / 8; // 1/8th of total ram
cache = new TCLruCache(limitKb);
cv = context;
}
public void display(String url, ImageView imageview, int defaultresource) {
imageview.setImageResource(defaultresource);
Bitmap image = cache.get(url);
if (image != null) {
imageview.setImageBitmap(image);
}
else {
new SetImageTask(imageview).execute(url);
}
}
private class TCLruCache extends LruCache<String, Bitmap> {
public TCLruCache(int maxSize) {
super(maxSize);
}
#Override
protected int sizeOf(String key, Bitmap value) {
int kbOfBitmap = value.getByteCount() / 1024;
return kbOfBitmap;
}
}
private class SetImageTask extends AsyncTask<String, Void, Integer> {
private ImageView imageview;
private Bitmap bmp;
public SetImageTask(ImageView imageview) {
this.imageview = imageview;
}
#Override
protected Integer doInBackground(String... params) {
String url = params[0];
try {
//bmp = BitmapFactory.decodeResource(cv.getResources(), url);
bmp = getBitmapFromURL(url);
if (bmp != null) {
cache.put(url, bmp);
}
else {
return 0;
}
} catch (Exception e) {
e.printStackTrace();
return 0;
}
return 1;
}
#Override
protected void onPostExecute(Integer result) {
if (result == 1) {
imageview.setImageBitmap(bmp);
}
//super.onPostExecute(result);
}
private Bitmap getBitmapFromURL(String src) {
try {
URL url = new URL(src);
HttpURLConnection connection
= (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
}
#Override
public void onLowMemory() {
}
#Override
public void onTrimMemory(int level) {
/* if (level >= TRIM_MEMORY_MODERATE) {
cache.evictAll();
}
else if (level >= TRIM_MEMORY_BACKGROUND) {
cache.trimToSize(cache.size() / 2);
}*/
}
}
the TCimageloader is as shown in above code. my getview is as shown below :
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
// if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(200, 200));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
// imageView.setPadding(10,10,10,10);
} else {
imageView = (ImageView) convertView;
}
imagloader = new TCImageLoader(mContext);
imagloader.display(mThumbIds[position], imageView, R.drawable.ic_launcher);
//Picasso.with(mContext).load(mThumbIds[position]).placeholder(R.drawable.ic_launcher).into(imageView);
imageView.setImageResource(R.drawable.ic_launcher);
return imageView;
}
but the problem i am facing is that when I scroll fast the getView has already been called and display method is already called. so the image views keep changing until the last called is implemented.
i am trying to make a custom gallery and this will also help me in downloading images from urls. I will have to use same method . will just have to change the file address to url address

Android ListView wrong images

I'm developing an Android app but I'm a newbie and I got stuck...
My ListView single element has an ImageView and some TextViews, but sometimes (when I scroll the page and there are more than 7-8 elements) it doesn't display the right image in the right row.
I'm using a custom Image Loader to manage the downloaded images.
Here's my Adapter:
public class AddVideogameActivityAdapter extends BaseAdapter {
private ArrayList<Videogame> videogames;
private Typeface typefaceMedium;
private Typeface typefaceLight;
private ImageLoader loader;
private LayoutInflater mInflater;
public AddVideogameActivityAdapter(Context context, ArrayList<Videogame> results) {
videogames = results;
mInflater = LayoutInflater.from(context);
typefaceMedium = Typeface.createFromAsset(context.getAssets(), "Roboto-Medium.ttf");
typefaceLight = Typeface.createFromAsset(context.getAssets(), "Roboto-Light.ttf");
loader = new ImageLoader(context);
}
public int getCount() {
return videogames.size();
}
public Object getItem(int position) {
return videogames.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_element,null);
holder = new ViewHolder();
holder.imgView = (ImageView) convertView.findViewById(R.id.thumbView);
holder.txtName = (TextView) convertView.findViewById(R.id.elementView);
holder.txtPlatform = (TextView) convertView.findViewById(R.id.elementView2);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
try {
Videogame vgame = (Videogame) videogames.get(position);
holder.txtName.setText(vgame.getTitle());
holder.txtName.setTypeface(typefaceMedium);
holder.txtPlatform.setText(videogames.get(position).getPlatform());
holder.txtPlatform.setTypeface(typefaceLight);
holder.imgUrl = videogames.get(position).getImage();
loader.display(holder.imgUrl, holder.imgView, R.drawable.youtube_icon);
}
catch (Exception e) {
e.printStackTrace();
Log.e(com.example.ludos2_0.MainActivity.TAG,
"Exception: " + e.getLocalizedMessage());
}
return convertView;
}
static class ViewHolder {
TextView txtName;
TextView txtPlatform;
public String imgUrl;
ImageView imgView;
}
}
Sorry for my english and thank you for your help!
EDIT:
Here's also the Loader:
public class ImageLoader implements ComponentCallbacks2 {
private TCLruCache cache;
public ImageLoader(Context context) {
ActivityManager am = (ActivityManager) context.getSystemService(
Context.ACTIVITY_SERVICE);
int memoryClass = am.getMemoryClass() * 1024 * 1024;
cache = new TCLruCache(memoryClass);
}
public void display(String url, ImageView imageview, int defaultresource) {
imageview.setImageResource(defaultresource);
Bitmap image = cache.get(url);
if (image != null) {
imageview.setImageBitmap(image);
}
else {
new SetImageTask(imageview).execute(url);
}
}
private class TCLruCache extends LruCache<String, Bitmap> {
public TCLruCache(int maxSize) {
super(maxSize);
}
}
private class SetImageTask extends AsyncTask<String, Void, Integer> {
private ImageView imageview;
private Bitmap bmp;
public SetImageTask(ImageView imageview) {
this.imageview = imageview;
}
#Override
protected Integer doInBackground(String... params) {
String url = params[0];
try {
bmp = getBitmapFromURL(url);
if (bmp != null) {
cache.put(url, bmp);
}
else {
return 0;
}
} catch (Exception e) {
e.printStackTrace();
return 0;
}
return 1;
}
#Override
protected void onPostExecute(Integer result) {
if (result == 1) {
imageview.setImageBitmap(bmp);
}
super.onPostExecute(result);
}
private Bitmap getBitmapFromURL(String src) {
try {
URL url = new URL(src);
HttpURLConnection connection
= (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
}
RE-EDIT
Activity code:
public class AddVideogameActivity extends ListActivity {
private TextView searchField = null;
private final Handler handler = new Handler();
private ArrayList<Videogame> videogamesList = null;
private static AddVideogameActivity mContext = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_book);
mContext = this;
searchField = (TextView) findViewById(R.id.searchField);
searchField.setMaxLines(1);
searchField.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
searchField.setHint("");
}
});
// Setup the list view and its listener
getListView().setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Log.d(MainActivity.TAG,
"AddBookActivity ---> AddButton:onClick()");
// Sets typefaces for TextView
String videogameId = videogamesList.get(position).getId();
String videogameName = videogamesList.get(position).getTitle();
String thumbnail = videogamesList.get(position).getThumbnail();
String description = videogamesList.get(position)
.getDescription();
String image = videogamesList.get(position).getImage();
String platform = videogamesList.get(position).getPlatform();
if (videogameName != null && videogameName.length() > 0
&& thumbnail != null && thumbnail.length() > 0
&& description != null && description.length() > 0
&& image != null && image.length() > 0
&& platform != null && platform.length() > 0) {
if (ListsManager.getInstance().addVideogame(
new Videogame(videogameId, videogameName,
thumbnail, image, description, platform)) == 0) {
Log.d(MainActivity.TAG,
"AddBookActivity --> Videogame:[" + videogameId
+ "#" + videogameName + "]");
Toast toast = Toast.makeText(mContext, "["
+ videogameName + "] Saved !",
Toast.LENGTH_LONG);
toast.show();
} else {
Log.e(MainActivity.TAG,
"AddBookActivity --> Error ! Videogame already in the list ! ");
Toast toast = Toast.makeText(mContext,
"Error! Videogame already in the list!",
Toast.LENGTH_LONG);
toast.show();
}
} else {
Log.e(MainActivity.TAG,
"AddBookActivity --> Error ! Invalid Videogame Name or Thumbnail or Id or Deck");
Toast toast = Toast
.makeText(
mContext,
"Error ! Invalid Videogame Name or Thumbnail or Id or Deck",
Toast.LENGTH_LONG);
toast.show();
}
Intent newIntent = new Intent(getApplicationContext(),
MainActivity.class);
startActivity(newIntent);
}
});
// Setup the search button and its listener
Button searchButton = (Button) findViewById(R.id.searchButton);
searchButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.d(com.example.ludos2_0.MainActivity.TAG, "Search Game ...");
String searchInputString = searchField.getText().toString();
if (searchInputString != null && searchInputString.length() > 0) {
try {
String requestURL = ("http://www.giantbomb.com/api/search/?api_key=fcf60d6d67b98b0d17b3905d1a90b3fd31ed1e8e&format=json&query="
+ Uri.encode(searchInputString) + "&resources=game");
// String requestURL =
// String.format("https://gdata.youtube.com/feeds/api/videos?v=2&alt=jsonc&category=Music&orderby=relevance&q=%s",Uri.encode(searchInputString));
Log.d(com.example.ludos2_0.MainActivity.TAG, requestURL);
DownloadGiantBombJSONData giantbombAsyncTask = new DownloadGiantBombJSONData();
giantbombAsyncTask.execute(new String[] { requestURL });
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
if (videogamesList == null)
videogamesList = new ArrayList<Videogame>();
else
updateVideogamesListView(videogamesList);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.add_book, menu);
return true;
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onPause() {
super.onPause();
}
public void updateVideogamesListView(ArrayList<Videogame> values) {
AddVideogameActivityAdapter adapter = new AddVideogameActivityAdapter(this, values);
setListAdapter(adapter);
}
#Override
protected void onDestroy() {
super.onDestroy();
}
}
The other classes involved in building the ListView are the REST classes and the AsyncTask class that downloads and parses the JSon files.
What does your ListView look like, does it look like this:
<ListView android:id="#id/android:list"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dip" ></ListView>
Especially the id of the ListView. Check your layout file, probably the bug exists there.

Image issue with listview and Asynctask

I am using a listview and each items use an image called from a server with an asynctask class.
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
final ViewHolder viewHolder;
if (view == null) {
view = getActivity().getLayoutInflater().inflate(R.layout.item_liste, null);
viewHolder = new ViewHolder();
viewHolder.image = (ImageView) view.findViewById(R.id.imageView);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
if (/* Image not loaded */) {
/* Create and execute the request using an AsyncTask */
mRequestManager.getDrawable("0", listItemInformation.resumeBien.Identifiant, new SendBitmap() {
/* SendBack is called when the bitmap is received from the server */
#Override
public void sendBack(Bitmap bitmap) {
listItemInformation.drawable.add(bitmap);
listItemInformation.drawableCalled = false;
viewHolder.image.setImageBitmap(bitmap);
}
});
} else {
viewHolder.image.setImageBitmap(listItemInformation.drawable.get(0));
}
return view;
}
The problem is, when the image is received, the ImageView is not the good one.
And all the pictures are loaded in the first item of the listview..
I tried to use adapter.notifyDataSetChanged();
But the listview motion is cut when it is called during a scroll..
What are my possibilities to avoid those issues?
I want the same result as the googleplay's listview.
Thanks in advance :)
You can try Volley's NetworkImageView with just one or two lines to complete your job.
//Dummy:
public static class BitmapLruCache extends LruCache<String, Bitmap> implements ImageCache {
public BitmapLruCache(int maxSize) {
super(maxSize);
}
#Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight();
}
#Override
public Bitmap getBitmap(String url) {
return get(url);
}
#Override
public void putBitmap(String url, Bitmap bitmap) {
put(url, bitmap);
}
}
ImageLoader sImageLoader = new ImageLoader(sRequestQueue, new BitmapLruCache(100));
networkImageView.setImageUrl(url_to_image, sImageLoader);
what you need is called "Lazy adapter", to load images in list view you can try my code:
public class MainActivity extends Activity {
ListView list;
LazyAdapter adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
list=(ListView)findViewById(R.id.list);
adapter=new LazyAdapter(this, mStrings);
list.setAdapter(adapter);
adapter.imageLoader.clearCache();
adapter.notifyDataSetChanged();
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
//Toast.makeText(getApplicationContext(), id + "", 2000).show();
String wallcategory =(String) ((TextView) view.findViewById(R.id.text)).getText();
//Toast.makeText(getApplicationContext(),mStrings[position], 2000).show();
Intent myIntent = new Intent(MainActivity.this, Wallgrid.class);
myIntent.putExtra("cat", wallcategory); //Optional parameters
MainActivity.this.startActivity(myIntent);
}
});
}
#Override
public void onDestroy()
{
list.setAdapter(null);
super.onDestroy();
}
public String[] mStrings={
"http://www.bourax.com/android/paradise/categories/nature.jpg",
"http://www.bourax.com/android/paradise/categories/animals.jpg",
"http://www.bourax.com/android/paradise/categories/colorful.jpg",
"http://www.bourax.com/android/paradise/categories/cars.jpg",
"http://www.bourax.com/android/paradise/categories/city.jpg",
"http://www.bourax.com/android/paradise/categories/flowers.jpg",
"http://www.bourax.com/android/paradise/categories/girls.jpg",
"http://www.bourax.com/android/paradise/categories/sport.jpg",
"http://www.bourax.com/android/paradise/categories/cats.jpg",
"http://www.bourax.com/android/paradise/categories/fish.jpg",
"http://www.bourax.com/android/paradise/categories/sea.jpg",
"http://www.bourax.com/android/paradise/categories/love.jpg",
"http://www.bourax.com/android/paradise/categories/buildings.jpg",
"http://www.bourax.com/android/paradise/categories/paintings.jpg",
"http://www.bourax.com/android/paradise/categories/pink.jpg",
"http://www.bourax.com/android/paradise/categories/travel.jpg",
"http://www.bourax.com/android/paradise/categories/fantasy.jpg",
"http://www.bourax.com/android/paradise/categories/tree.jpg",
"http://www.bourax.com/android/paradise/categories/portrait.jpg",
"http://www.bourax.com/android/paradise/categories/top.jpg"
};
}
public class LazyAdapter extends BaseAdapter {
private Activity activity;
private String[] data;
private static LayoutInflater inflater=null;
public ImageLoader imageLoader;
public LazyAdapter(Activity a, String[] d) {
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader=new ImageLoader(activity.getApplicationContext());
}
public int getCount() {
return data.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public String[] Category={
"Nature",
"Animals",
"Colorful",
"Cars",
"City",
"Flowers",
"Girls",
"Sport",
"Cats & Dogs",
"Fish",
"Sea",
"Love",
"Buildings",
"Paintings",
"Pink",
"Travel",
"Fantasy",
"Tree",
"Portrait",
"Top Rated"
};
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.item, null);
TextView text=(TextView)vi.findViewById(R.id.text);
ImageView image=(ImageView)vi.findViewById(R.id.image);
text.setText(Category[position]);
imageLoader.DisplayImage(data[position], image);
return vi;
}
}
public class ImageLoader {
MemoryCache memoryCache=new MemoryCache();
FileCache fileCache;
private Map<ImageView, String> imageViews=Collections.synchronizedMap(new WeakHashMap<ImageView, String>());
ExecutorService executorService;
Handler handler=new Handler();//handler to display images in UI thread
public ImageLoader(Context context){
fileCache=new FileCache(context);
executorService=Executors.newFixedThreadPool(5);
}
final int stub_id=R.drawable.stub;
public void DisplayImage(String url, ImageView imageView)
{
imageViews.put(imageView, url);
Bitmap bitmap=memoryCache.get(url);
if(bitmap!=null)
imageView.setImageBitmap(bitmap);
else
{
queuePhoto(url, imageView);
//imageView.setImageResource(stub_id);
}
}
private void queuePhoto(String url, ImageView imageView)
{
PhotoToLoad p=new PhotoToLoad(url, imageView);
executorService.submit(new PhotosLoader(p));
}
private Bitmap getBitmap(String url)
{
File f=fileCache.getFile(url);
//from SD cache
Bitmap b = decodeFile(f);
if(b!=null)
return b;
//from web
try {
Bitmap bitmap=null;
URL imageUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);
conn.setInstanceFollowRedirects(true);
InputStream is=conn.getInputStream();
OutputStream os = new FileOutputStream(f);
Utils.CopyStream(is, os);
os.close();
conn.disconnect();
bitmap = decodeFile(f);
return bitmap;
} catch (Throwable ex){
ex.printStackTrace();
if(ex instanceof OutOfMemoryError)
memoryCache.clear();
return null;
}
}
//decodes image and scales it to reduce memory consumption
private Bitmap decodeFile(File f){
try {
//decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
FileInputStream stream1=new FileInputStream(f);
BitmapFactory.decodeStream(stream1,null,o);
stream1.close();
//Find the correct scale value. It should be the power of 2.
final int REQUIRED_SIZE=70;
int width_tmp=o.outWidth, height_tmp=o.outHeight;
int scale=1;
while(true){
if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
break;
width_tmp/=2;
height_tmp/=2;
}
//decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale;
FileInputStream stream2=new FileInputStream(f);
Bitmap bitmap=BitmapFactory.decodeStream(stream2, null, o2);
stream2.close();
return bitmap;
} catch (FileNotFoundException e) {
}
catch (IOException e) {
e.printStackTrace();
}
return null;
}
//Task for the queue
private class PhotoToLoad
{
public String url;
public ImageView imageView;
public PhotoToLoad(String u, ImageView i){
url=u;
imageView=i;
}
}
class PhotosLoader implements Runnable {
PhotoToLoad photoToLoad;
PhotosLoader(PhotoToLoad photoToLoad){
this.photoToLoad=photoToLoad;
}
#Override
public void run() {
try{
if(imageViewReused(photoToLoad))
return;
Bitmap bmp=getBitmap(photoToLoad.url);
memoryCache.put(photoToLoad.url, bmp);
if(imageViewReused(photoToLoad))
return;
BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad);
handler.post(bd);
}catch(Throwable th){
th.printStackTrace();
}
}
}
boolean imageViewReused(PhotoToLoad photoToLoad){
String tag=imageViews.get(photoToLoad.imageView);
if(tag==null || !tag.equals(photoToLoad.url))
return true;
return false;
}
//Used to display bitmap in the UI thread
class BitmapDisplayer implements Runnable
{
Bitmap bitmap;
PhotoToLoad photoToLoad;
public BitmapDisplayer(Bitmap b, PhotoToLoad p){bitmap=b;photoToLoad=p;}
public void run()
{
if(imageViewReused(photoToLoad))
return;
if(bitmap!=null)
photoToLoad.imageView.setImageBitmap(bitmap);
// else
// photoToLoad.imageView.setImageResource(stub_id);
}
}
public void clearCache() {
memoryCache.clear();
fileCache.clear();
}
}
public class FileCache {
private File cacheDir;
public FileCache(Context context){
//Find the dir to save cached images
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"LazyList");
else
cacheDir=context.getCacheDir();
if(!cacheDir.exists())
cacheDir.mkdirs();
}
public File getFile(String url){
//I identify images by hashcode. Not a perfect solution, good for the demo.
String filename=String.valueOf(url.hashCode());
//Another possible solution (thanks to grantland)
//String filename = URLEncoder.encode(url);
File f = new File(cacheDir, filename);
return f;
}
public void clear(){
File[] files=cacheDir.listFiles();
if(files==null)
return;
for(File f:files)
f.delete();
}
}

Categories

Resources