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 :)
Related
I'm implementing a listview on android that contains an imageview and I'm experiencing a problem:
When a row does not have an image it is repeating an image of the previous item.
Here's my adapter:
public class NewsAdapter extends BaseAdapter {
private final LayoutInflater inflater;
private final Context context;
private List<News> newsList;
public NewsAdapter(List<News> newsList, Context context) {
this.newsList = newsList;
this.context = context;
inflater = LayoutInflater.from(context);
}
...
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder;
if (convertView == null) {
LayoutInflater row = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = row.inflate(R.layout.image_new_row, null);
viewHolder = new ViewHolder();
viewHolder.mTitle = convertView.findViewById(R.id.txtNewsTitle);
viewHolder.mImage = convertView.findViewById(R.id.imageNews);
viewHolder.mDescription = convertView.findViewById(R.id.txtDescription);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
News news = newsList.get(position);
viewHolder.mTitle.setText(news.getTitle());
viewHolder.mDescription.setText(news.getDescription());
if (news.getImageUrl() != null){
ImageLoader.getInstance().displayImage(news.getImageUrl(), viewHolder.mImage);
}
else{
viewHolder.mImage.setImageResource(R.drawable.loading);
}
return convertView;
}
my viewHolder:
static class ViewHolder {
private TextView mTitle;
private TextView mDescription;
private ImageView mImage;
}
my activity:
public class NewsActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
private static final String ITEM = "item";
private static final String TITLE = "title";
private static final String LINK = "link";
private static final String DESCRIPTION = "description";
private static final String MEDIA = "media:content";
private static final String IMAGE_URL = "url";
private Feed feed;
private ListView newsListView;
private ArrayList<News> newsList;
private NewsAdapter mAdapter;
private ImageLoaderConfiguration imageLoaderConfiguration;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_news);
newsListView = (ListView) findViewById(R.id.newsList);
this.feed = (Feed) getIntent().getSerializableExtra(Constants.EXTRA_CLICKED_FEED);
configListView();
}
private void configListView() {
File cacheDir = StorageUtils.getCacheDirectory(this);
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.showImageForEmptyUri(R.drawable.loading)
.showImageOnLoading(R.drawable.loading)
.showImageOnFail(R.drawable.loading).cacheInMemory(true).cacheOnDisk(true).build();
imageLoaderConfiguration = new ImageLoaderConfiguration.Builder(this)
.defaultDisplayImageOptions(defaultOptions).build();
ImageLoader.getInstance().init(imageLoaderConfiguration);
newsList = new ArrayList<News>();
mAdapter = new NewsAdapter(newsList, this);
newsListView.setAdapter(mAdapter);
newsListView.setOnItemClickListener(this);
new RssAsyncTask().execute(
feed.getUrl());
}
private List<News> readXML(InputStream is) {
List<News> newsList =
new ArrayList<News>();
try {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder =
factory.newDocumentBuilder();
Document xmlDocument = builder.parse(is);
NodeList posts =
xmlDocument.getElementsByTagName(ITEM);
String title = null, description = null,
link = null, image = null;
for (int i = 0; i < posts.getLength(); i++) {
Node post = posts.item(i);
// Cada nó ITEM tem os filhos:
// TITLE, DESCRIPTION e LINK
NodeList postInfo = post.getChildNodes();
for (int j = 0; j < postInfo.getLength(); j++) {
Node info = postInfo.item(j);
if (TITLE.equals(info.getNodeName())) {
title = info.getTextContent();
} else if (LINK.equals(
info.getNodeName())) {
link = info.getTextContent();
} else if (DESCRIPTION.equals(
info.getNodeName())) {
description = extractText(info.getTextContent()).trim();
} else if (MEDIA.equals(
info.getNodeName())) {
image = ((Element) info).getAttribute(IMAGE_URL);
}
}
newsList.add(
new News(title, description, link, image));
}
} catch (Throwable e) {
e.printStackTrace();
}
return newsList;
}
class RssAsyncTask extends
AsyncTask<String, Void, List<News>> {
ProgressDialog dialog;
...
#Override
protected void onPostExecute(List<News> result) {
super.onPostExecute(result);
dialog.dismiss();
newsList.addAll(result);
mAdapter.notifyDataSetChanged();
}
}
}
obs: I'm using universal image load api:
https://github.com/nostra13/Android-Universal-Image-Loader
put your variable initialization into for loop as shown below so that it re initializes variables to null every time..
for (int i = 0; i < posts.getLength(); i++) {
String title = null, description = null,
link = null, image = null;
Node post = posts.item(i);
// Cada nó ITEM tem os filhos:
// TITLE, DESCRIPTION e LINK
NodeList postInfo = post.getChildNodes();
for (int j = 0; j < postInfo.getLength(); j++) {
Node info = postInfo.item(j);
if (TITLE.equals(info.getNodeName())) {
title = info.getTextContent();
} else if (LINK.equals(
info.getNodeName())) {
link = info.getTextContent();
} else if (DESCRIPTION.equals(
info.getNodeName())) {
description = extractText(info.getTextContent()).trim();
} else if (MEDIA.equals(
info.getNodeName())) {
image = ((Element) info).getAttribute(IMAGE_URL);
}
}
newsList.add(
new News(title, description, link, image));
}
Of course it does... You are reusing the previous item's layouts. that's what the below statement means.
viewHolder = (ViewHolder) convertView.getTag();
If you're not initializing it in the getView method it'll show the same contents as the previous item.
From your code - it may happens when image failed to download.
You can use:
viewHolder.mImage.setImageResource(R.drawable.loading);
if (news.getImageUrl() != null){
ImageLoader.getInstance().displayImage(news.getImageUrl(), viewHolder.mImage);
}
Or
You may use below code:
ImageLoader.getInstance().displayImage(imageUri, imageView, options, 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) {
...
}
#Override
public void onLoadingCancelled(String imageUri, View view) {
...
}
}
});
I'm newbie Android Programming. I have Fragment which shows on Listview and now, i want Listview load more item when list ends. But data is not appending. I need help !
My code :
public class InfoTeacherFragment extends Fragment {
private String URL = "http://scv.udn.vn/dhdn/trdhsp/page/";
ProgressDialog pDialog;
Context mContext;
Vector<ArrayList<String>> data;
ArrayList<String> Name;
ArrayList<String> School;
ArrayList<String> Link;
ArrayList<String> Icon;
ListView lvItem;
DisplayImageOptions options;
ImageLoader imageloader;
View mFooterView;
InfoTeacher adapter;
ProgressBar loading;
int CurrentPage = 1;
int visibleThreshold = 3;
int startPage = 1;
boolean loadingMore = false;
public InfoTeacherFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_mission)
.showImageForEmptyUri(R.drawable.ic_empty)
.showImageOnFail(R.drawable.ic_error).cacheInMemory(true)
.cacheOnDisk(true).considerExifParams(true)
.bitmapConfig(Bitmap.Config.RGB_565).build();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.teacherinfo_layout,
container, false);
mContext = container.getContext();
lvItem = (ListView) rootView.findViewById(R.id.lvTeacher);
lvItem.setOnScrollListener(new EndlessScrollListener() {
#Override
public void onLoadMore(int page, int totalItemsCount) {
CurrentPage++;
customLoadMoreDataFromApi(CurrentPage);
Toast.makeText(mContext, "EndlessScrollListener",
Toast.LENGTH_SHORT).show();
}
});
imageloader = ImageLoader.getInstance();
imageloader.init(ImageLoaderConfiguration.createDefault(mContext));
if (Utils.isOnline(mContext) == true
&& Utils.KEY_CHECK_SUCCESS.equals("SUCCESS")) {
new LoadData().execute(URL + startPage);
lvItem.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View view,
int position, long id) {
Intent intent = new Intent(mContext, NewsItemView.class);
if (Link != null) {
intent.putExtra("URL", Link.get(position));
startActivity(intent);
}
}
});
} else if (Utils.isOnline(mContext) == true
&& Utils.KEY_CHECK_SUCCESS.equals("FAIL")) {
Utils.MyToast(Utils.KEYWORK_ERROR[0], R.drawable.warning_icon,
mContext, false);
}
return rootView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public void onDestroy() {
super.onDestroy();
AnimateFirstDisplayListener.displayedImages.clear();
}
class LoadData extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
pDialog = ProgressDialog.show(mContext, "", Utils.KEYWORK_ERROR[2]);
data = new Vector<ArrayList<String>>();
Name = new ArrayList<String>();
School = new ArrayList<String>();
Link = new ArrayList<String>();
Icon = new ArrayList<String>();
super.onPreExecute();
}
#Override
protected String doInBackground(String... URL) {
data = Utils.getInformationTeacher(URL[0]);
if (!(data.isEmpty())) {
return Utils.KEY_CHECK_SUCCESS;
} else {
return Utils.KEY_CHECK_FAIL;
}
}
#Override
protected void onPostExecute(String result) {
if (result.equals(Utils.KEY_CHECK_SUCCESS)) {
pDialog.dismiss();
Name = data.get(0);
School = data.get(1);
Icon = data.get(2);
Link = data.get(3);
adapter = new InfoTeacher(mContext, Name, School, Icon);
lvItem.setAdapter(adapter);
} else if (result.equals(Utils.KEY_CHECK_FAIL)) {
pDialog.dismiss();
Utils.MyToast(Utils.KEYWORK_ERROR[0], R.drawable.warning_icon,
mContext, false);
}
super.onPostExecute(result);
}
}
class InfoTeacher extends BaseAdapter {
private ArrayList<String> Icon = new ArrayList<String>();
private ArrayList<String> Name = new ArrayList<String>();
private ArrayList<String> School = new ArrayList<String>();
private LayoutInflater inflater;
ImageLoadingListener animateFirstListener = new AnimateFirstDisplayListener();
public InfoTeacher(Context context, ArrayList<String> Name,
ArrayList<String> School, ArrayList<String> Icon) {
this.Name = Name;
this.Icon = Icon;
this.School = School;
Collections.reverse(Name);
Collections.reverse(School);
Collections.reverse(Icon);
inflater = LayoutInflater.from(getActivity());
}
#Override
public int getCount() {
return Name.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View view, ViewGroup arg2) {
View rowView = view;
ViewHolder holder;
if (rowView == null) {
holder = new ViewHolder();
rowView = inflater
.inflate(R.layout.teacher_layout, arg2, false);
holder.Name = (TextView) rowView
.findViewById(R.id.tv_NameTeacher);
holder.School = (TextView) rowView.findViewById(R.id.tv_School);
holder.ic_naviga = (ImageView) rowView
.findViewById(R.id.ivNaviga);
holder.icon = (ImageView) rowView
.findViewById(R.id.iv_IconTeacher);
rowView.setTag(holder);
} else
holder = (ViewHolder) view.getTag();
final String mIcon = Icon.get(position);
holder.Name.setText(Name.get(position).toString());
holder.School.setText(School.get(position).toString());
ImageLoader.getInstance().displayImage(mIcon, holder.icon, options,
animateFirstListener);
return rowView;
}
}
static class ViewHolder {
ImageView icon;
TextView Name;
TextView School;
ImageView ic_naviga;
}
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);
}
}
}
}
public void customLoadMoreDataFromApi(int page) {
new LoadData().execute(URL + page);
adapter.notifyDataSetChanged();
// This method probably sends out a network request and appends new data
// items to your adapter.
// Use the offset value and add it as a parameter to your API request to
// retrieve paginated data.
// Deserialize API response and then construct new objects to append to
// the adapter
}
class LoadMoreItemsList extends
AsyncTask<Void, Void, Vector<ArrayList<String>>> {
private LoadMoreItemsList() {
loadingMore = true;
mFooterView = LayoutInflater.from(mContext).inflate(
R.layout.loading_view, null);
}
#Override
protected void onPreExecute() {
lvItem.addFooterView(mFooterView);
lvItem.setAdapter(adapter);
super.onPreExecute();
}
#Override
protected Vector<ArrayList<String>> doInBackground(Void... params) {
return null;
}
#Override
protected void onPostExecute(Vector<ArrayList<String>> result) {
super.onPostExecute(result);
}
}
}
Function Utils.Utils.getInformationTeacher(URL[0]) :
public static Vector<ArrayList<String>> getInformationTeacher(String url) {
Vector<ArrayList<String>> data = new Vector<ArrayList<String>>();
ArrayList<String> Name = new ArrayList<String>();
ArrayList<String> School = new ArrayList<String>();
ArrayList<String> Link = new ArrayList<String>();
ArrayList<String> Icon = new ArrayList<String>();
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
try {
Document doc = Jsoup.connect(url).timeout(10 * 300).get();
Charset.forName("UTF-8");
doc.outputSettings().escapeMode(EscapeMode.xhtml);
Elements eles = doc.select("div#Thu tbody a.linkheader");
Elements elesIcon = doc.select("div#Thu img[src]");
int i = 0;
for (Element element : eles) {
i++;
String fillinfo = element.ownText();
String link = element.attr("href");
if (i % 2 == 0) {
School.add(fillinfo);
} else {
Name.add(fillinfo);
Link.add(link);
}
}
for (Element icon : elesIcon) {
String hrefIcon = icon.attr("src");
Icon.add(hrefIcon);
}
data.add(Name);
data.add(School);
data.add(Icon);
data.add(Link);
} catch (IOException e) {
return data;
}
}
return data;
}
And Finally : abstract EndlessScrollListener
package android.readnews.support;
import android.util.Log;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
public abstract class EndlessScrollListener implements OnScrollListener {
// The minimum amount of items to have below your current scroll position
// before loading more.
private int visibleThreshold = 5;
// The current offset index of data you have loaded
private int currentPage = 0;
// The total number of items in the dataset after the last load
private int previousTotalItemCount = 0;
// True if we are still waiting for the last set of data to load.
private boolean loading = true;
// Sets the starting page index
private int startingPageIndex = 0;
public EndlessScrollListener() {
}
public EndlessScrollListener(int visibleThreshold) {
this.visibleThreshold = visibleThreshold;
}
public EndlessScrollListener(int visibleThreshold, int startPage) {
this.visibleThreshold = visibleThreshold;
this.startingPageIndex = startPage;
this.currentPage = startPage;
}
// This happens many times a second during a scroll, so be wary of the code
// you place here.
// We are given a few useful parameters to help us work out if we need to
// load some more data,
// but first we check if we are waiting for the previous load to finish.
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// If the total item count is zero and the previous isn't, assume the
// list is invalidated and should be reset back to initial state
if (totalItemCount < previousTotalItemCount) {
Log.i("abc", "ABC + totalItemCount < previousTotalItemCount");
this.currentPage = this.startingPageIndex;
this.previousTotalItemCount = totalItemCount;
if (totalItemCount == 0) {
this.loading = true;
}
}
// If it’s still loading, we check to see if the dataset count has
// changed, if so we conclude it has finished loading and update the
// current page
// number and total item count.
if (loading && (totalItemCount > previousTotalItemCount)) {
Log.i("abc", "ABC + totalItemCount > previousTotalItemCount");
loading = false;
previousTotalItemCount = totalItemCount;
currentPage++;
}
// If it isn’t currently loading, we check to see if we have breached
// the visibleThreshold and need to reload more data.
// If we do need to reload some more data, we execute onLoadMore to
// fetch the data.
if (!loading
&& (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) {
Log.i("abc", "ABC + !loading");
onLoadMore(currentPage + 1, totalItemCount);
loading = true;
}
}
// Defines the process for actually loading more data based on page
public abstract void onLoadMore(int page, int totalItemsCount);
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// Don't take any action on changed
}
}
I want load more 7 pages
In your LoadData AsyncTask, in onPostExecute, you always re-create the adapter with new data received, so it does not append the existing data.
What you need to do is add a method to InfoTeacher adapter to append new items to your existing data, and then call that method from onPostExecute if the adapter already exists (adapter != null).
I am getting a memory leak from the following code. It is an activity that contains a mainViewPager. That viewPager return 4 different fragments, which each have their own ViewPagers that hold images which are being retrieved from the same asyncTask. Here is my code. When I run it I can scroll throught the Pages with some lag. But when I exit the go back into the activity I get an Out Of Memory Error. So it must be a memory leak. I've stared at my code forever and I can't figure out why. Please help me... PS. I am using the Picasso library to fetch the images from a server.
Activity
package info.nightowl.nightowl;
import info.nightowl.nightowl.LocationsGridFragment.onLocationSelectedListener;
public class NightWatch extends FragmentActivity implements onLocationSelectedListener {
public static ArrayList<String> imageUrl = new ArrayList<String>();
public static ArrayList<String> dateList = new ArrayList<String>();
public static ArrayList<String> trendList = new ArrayList<String>();
public static ArrayList<String> nameList = new ArrayList<String>();
public static ArrayList<String> imageLocationsList = new ArrayList<String>();
public static ArrayList<String> imageClubsList = new ArrayList<String>();
public static ArrayList<String> locationsList = new ArrayList<String>();
public static ArrayList<String> clubsList = new ArrayList<String>();
public static ArrayList<String> locationImagesUrl = new ArrayList<String>();
public static ArrayList<String> addressList = new ArrayList<String>();
public static ArrayList<String> hotImageUrl = new ArrayList<String>();
public static ArrayList<String> hotDateList = new ArrayList<String>();
public static ArrayList<String> hotTrendList = new ArrayList<String>();
public static ArrayList<String> hotNameList = new ArrayList<String>();
public static ArrayList<String> hotImageLocationsList = new ArrayList<String>();
public static ArrayList<String> hotImageClubsList = new ArrayList<String>();
FetchClubs fetchClubs = null;
public int width, height;
public JSONArray list;
public final String IMAGE_URL = "http://www.night-owl.info/webservice/";
SharedPreferences prefs;
static FeedFragment feedFragment;
static LocationsFragment locationsFragment;
static HotFragment hotFragment;
static ClubsFragment clubsFragment;
CustomViewPager customPager;
CustomViewPageAdapter theAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_night_watch);
//Method to set up the tabs
getSizes();
setupFragments();
updateList();
prefs = getSharedPreferences("prefs", 0);
}
//Called from the fragment which fetches image
public void loadBitmap(String image, ImageView imageView, boolean grid, TextView loadText) {
int size;
if (grid) size = (width-width/9)/3;
else size = width - width/9;
Log.d("Pager About to load", "Pager Loading bitmap picasso");
getBitmap load = new getBitmap(image, imageView, size, loadText);
load.execute(image);
}
public class getBitmap extends AsyncTask<String, Void, Bitmap> {
String loadImageUrl;
Bitmap bmp;
int sizes;
TextView loadingTextView;
private final WeakReference<ImageView> imageViewReference;
public getBitmap(String image, ImageView imageView, int size, TextView loadText){
imageViewReference = new WeakReference<ImageView>(imageView);
sizes = size;
loadingTextView = loadText;
}
#Override
protected void onPreExecute() {
Log.d("async", "async starting");
super.onPreExecute();
}
#Override
protected Bitmap doInBackground(String... arg0) {
// TODO Auto-generated method stub
try {
bmp = Picasso.with(NightWatch.this).load(IMAGE_URL+arg0[0]).resize(sizes,
sizes).get();
} catch (IOException e) {
Log.d("ioexc", "Pager IOEXCEPTION IDIOT!!!");
e.printStackTrace();
}
return bmp;
}
#Override
protected void onPostExecute(Bitmap bitmap) {
/*RoundedCornersDrawable drawable = new RoundedCornersDrawable(getResources(), bmp);
loadImage.setImageDrawable(drawable);
loadingTextView.setVisibility(View.GONE);
loadImage.setVisibility(View.VISIBLE);*/
if(imageViewReference != null && bitmap!= null) {
final ImageView imageView = imageViewReference.get();
if(imageView != null) {
imageView.setImageBitmap(bitmap);
loadingTextView.setVisibility(View.GONE);
imageView.setVisibility(View.VISIBLE);
}
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.feed, menu);
return true;
}
//SET UP THE TWO TABS 'FEED' AND 'LOCATIONS'
//Update ArrayList of the image names
public void updateList() {
imageUrl.clear();
trendList.clear();
dateList.clear();
nameList.clear();
imageLocationsList.clear();
imageClubsList.clear();
locationsList.clear();
clubsList.clear();
locationImagesUrl.clear();
addressList.clear();
hotImageUrl.clear();
hotTrendList.clear();
hotDateList.clear();
hotNameList.clear();
hotImageLocationsList.clear();
hotImageClubsList.clear();
new getImageUrl().execute();
new getLocationsUrl().execute();
}
class getImageUrl extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... arg0) {
JSONParser parser = new JSONParser();
JSONObject json = parser.getJSONFromUrl(IMAGE_URL + "updateimages.php");
try {
list = json.getJSONArray("posts");
for(int i = 0; i < list.length(); i++) {
JSONObject c = list.getJSONObject(i);
String imgSrc = c.getString("source");
String trend = c.getString("trend");
String date = c.getString("date");
String name = c.getString("name");
String location = c.getString("location");
String club = c.getString("club");
imageUrl.add(imgSrc);
dateList.add(date);
trendList.add(trend);
nameList.add(name);
imageLocationsList.add(location);
imageClubsList.add(club);
Log.d("async trend", trendList.get(0));
}
Log.d("Got list", imageUrl.get(0) + " " + trendList.get(0));
} catch(JSONException je) {
je.printStackTrace();
}
try {
list = json.getJSONArray("hot");
for(int i = 0; i < list.length(); i++) {
JSONObject c = list.getJSONObject(i);
String imgSrc = c.getString("source");
String trend = c.getString("trend");
String date = c.getString("date");
String name = c.getString("name");
String location = c.getString("location");
String club = c.getString("club");
hotImageUrl.add(imgSrc);
hotDateList.add(date);
hotTrendList.add(trend);
hotNameList.add(name);
hotImageLocationsList.add(location);
hotImageClubsList.add(club);
Log.d("async trend", trendList.get(0));
}
Log.d("Got list","hot list" + hotImageUrl.get(0) + " " + hotTrendList.get(0));
} catch(JSONException je) {
je.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
hotFragment.updateAdapter();
feedFragment.updateAdapter();
}
}
public void scrollMainPager(int pos) {
customPager.setCurrentItem(pos, true);
}
public void scrollPager(int pos) {
feedFragment.scrollPager(pos);
}
public void setupFragments() {
feedFragment = new FeedFragment();
locationsFragment = new LocationsFragment();
hotFragment = new HotFragment();
clubsFragment = new ClubsFragment();
customPager = (CustomViewPager) findViewById(R.id.customviewpager);
customPager.setOffscreenPageLimit(3);
theAdapter = new CustomViewPageAdapter(getSupportFragmentManager());
customPager.setAdapter(theAdapter);
customPager.setCurrentItem(1);
}
//GET SIZES OF SCREEN
public void getSizes(){
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
width = size.x;
height = size.y;
}
public static class CustomViewPageAdapter extends FragmentStatePagerAdapter {
public CustomViewPageAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int arg0) {
if(arg0 == 0) return hotFragment;
else if(arg0 == 1) return feedFragment;
else if(arg0 == 2) return locationsFragment;
else if(arg0 == 3) return clubsFragment;
return null;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return 4;
}
}
#Override
public void onLocationSelected(int position) {
}
}
FeedFragment
public class FeedFragment extends Fragment implements OnClickListener {
ToggleButton buttonGrid;
static Spinner spinnerUploadStatus;
CustomEditText et;
CustomScrollTextView tv;
int width, height;
View view;
static boolean isGrid;
ViewPager mPager;
SharedPreferences prefs;
public ImagePagerAdapter mPageAdapter;
Button buttonSwitchFragment;
Integer[] b = { R.drawable.statusunpressed, R.drawable.red,
R.drawable.green, R.drawable.blue };
List<Integer> spinnerList = new ArrayList<Integer>(Arrays.asList(b));
CustomSpinnerAdapter myAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
prefs = getActivity().getSharedPreferences("prefs", 0);
getSizes();
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.activity_feed, container, false);
setup();
return view;
}
#SuppressLint("NewApi")
public void setup() {
isGrid = false;
mPager = (ViewPager) view.findViewById(R.id.myviewpager1);
mPager.setOffscreenPageLimit(0);
buttonGrid = (ToggleButton) view.findViewById(R.id.button_grid);
buttonGrid.setOnClickListener(this);
spinnerUploadStatus = (Spinner) view
.findViewById(R.id.buttonUploadStatus);
myAdapter = new CustomSpinnerAdapter(getActivity(),
R.layout.item_simple_list_item, spinnerList);
myAdapter
.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerUploadStatus.setAdapter(myAdapter);
spinnerUploadStatus.setDropDownWidth((int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 50, getResources()
.getDisplayMetrics()));
spinnerUploadStatus.setOnItemSelectedListener(myOnItemSelectedListener);
spinnerUploadStatus.getBackground().setAlpha(0);
buttonSwitchFragment = (Button) view
.findViewById(R.id.buttonSwitchFragment);
buttonSwitchFragment.setOnClickListener(this);
Typeface font = Typeface.createFromAsset(getActivity().getAssets(),
"NotCourierSans.ttf");
et = (CustomEditText) view.findViewById(R.id.customEditText1);
et.updateTypeFace(font);
tv = (CustomScrollTextView) view
.findViewById(R.id.customscrolltextview);
tv.setText("WELCOME TO NIGHTOWL");
tv.setTypeface(font);
tv.start(width / 2500.0);
Log.d("width", "width is " + width);
}
public void getSizes() {
Display display = getActivity().getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
width = size.x;
height = size.y;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_grid:
isGrid = !isGrid;
updateAdapter();
break;
case R.id.buttonSwitchFragment:
((NightWatch) getActivity()).scrollMainPager(2);
break;
}
}
public OnItemSelectedListener myOnItemSelectedListener = new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
int colour = arg2;
spinnerUploadStatus.setSelection(0, true);
et.sendText(prefs.getString("username", "username invalid"), colour);
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
};
public void scrollPager(int position) {
isGrid = false;
buttonGrid.setChecked(false);
updateAdapter();
mPager.setCurrentItem(position, true);
Log.d("Pager", "PAGER UPDATED");
}
public static void disableButton(Boolean enabled) {
spinnerUploadStatus.setEnabled(enabled);
}
public void updateAdapter() {
int theSize;
if (!isGrid)
theSize = NightWatch.imageUrl.size();
else if (NightWatch.imageUrl.size() % 9 > 0)
theSize = NightWatch.imageUrl.size() / 9 + 1;
else
theSize = NightWatch.imageUrl.size() / 9;
mPageAdapter = new ImagePagerAdapter(getChildFragmentManager(), theSize);
mPager.setAdapter(mPageAdapter);
Log.d("size of viewPager Adapter", "" + theSize);
}
public static class ImagePagerAdapter extends FragmentStatePagerAdapter {
int mSize;
public ImagePagerAdapter(FragmentManager fm, int size) {
super(fm);
mSize = size;
}
#Override
public Fragment getItem(int arg0) {
// TODO Auto-generated method stub
Log.d("Starting imageDetailFragment", "");
Log.d("Pager", "Pager starting fragment");
Log.d("GRID", "fuck grid");
if (!isGrid)
return ImageDetailFragment.newInstance(
arg0, NightWatch.imageUrl, NightWatch.nameList,
NightWatch.trendList, NightWatch.dateList);
else
return GridFragment.newInstance(arg0, NightWatch.imageUrl);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return mSize;
}
}
public class CustomSpinnerAdapter extends ArrayAdapter<Integer> {
List<Integer> resourceId;
Context c;
public CustomSpinnerAdapter(Context context, int textViewResourceId,
List<Integer> objects) {
super(context, textViewResourceId, objects);
resourceId = objects;
c = context;
}
#Override
public View getDropDownView(int position, View convertView,
ViewGroup parent) {
return getCustomDropdownView(position, convertView, parent);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
return getCustomView(position, convertView, parent);
}
public View getCustomView(int position, View convertView,
ViewGroup parent) {
ImageView imageView = new ImageView(c);
imageView.setImageResource(resourceId.get(position));
imageView.setLayoutParams(new ListView.LayoutParams(
(int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 50, getResources()
.getDisplayMetrics()), (int) TypedValue
.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 34,
getResources().getDisplayMetrics())));
return imageView;
}
public View getCustomDropdownView(int position, View convertView,
ViewGroup parent) {
ImageView imageView = new ImageView(c);
imageView.setImageResource(resourceId.get(position));
imageView.setLayoutParams(new ListView.LayoutParams(
(int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 50, getResources()
.getDisplayMetrics()), (int) TypedValue
.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 34,
getResources().getDisplayMetrics())));
if (position == 0) {
imageView.setVisibility(View.GONE);
}
return imageView;
}
}
}
ImageDetailFragment
package info.nightowl.nightowl;
import java.io.IOException;
import java.util.ArrayList;
import com.example.nightowl.R;
import com.squareup.picasso.Picasso;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Typeface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class ImageDetailFragment extends Fragment implements OnClickListener {
int mImageNum;
ImageView imageView;
TextView trendTextView;
TextView nameTextView;
TextView dateTextView;
TextView loadingTextView;
Button upVoteButton, downVoteButton;
final String list = "voteList";
static SharedPreferences prefs;
SharedPreferences.Editor editor;
public ArrayList<String> imageUrl;
public ArrayList<String> trendList;
public ArrayList<String> nameList;
public ArrayList<String> dateList;
RelativeLayout.LayoutParams rParams;
int width, height;
static ImageDetailFragment newInstance(int imageNum,
ArrayList<String> imageList, ArrayList<String> tempNameList,
ArrayList<String> tempTrendList, ArrayList<String> tempDateList) {
final ImageDetailFragment f = new ImageDetailFragment();
Bundle args = new Bundle();
args.putInt("imageNum", imageNum);
args.putStringArrayList("imageList", imageList);
args.putStringArrayList("nameList", tempNameList);
args.putStringArrayList("trendList", tempTrendList);
args.putStringArrayList("dateList", tempDateList);
f.setArguments(args);
return f;
}
public ImageDetailFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mImageNum = getArguments().getInt("imageNum");
imageUrl = getArguments().getStringArrayList("imageList");
nameList = getArguments().getStringArrayList("nameList");
trendList = getArguments().getStringArrayList("trendList");
dateList = getArguments().getStringArrayList("dateList");
} else
mImageNum = -1;
prefs = getActivity().getSharedPreferences("prefs", 0);
editor = getActivity().getSharedPreferences("prefs", 0).edit();
getSizes();
rParams = new RelativeLayout.LayoutParams((width - width/9), width - width/9);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.image_detail_fragment,
container, false);
imageView = (ImageView) v.findViewById(R.id.imageView1);
imageView.setVisibility(View.INVISIBLE);
loadingTextView = (TextView) v.findViewById(R.id.loadingTextView);
loadingTextView.setVisibility(View.VISIBLE);
trendTextView = (TextView) v.findViewById(R.id.trendTextView);
nameTextView = (TextView) v.findViewById(R.id.nameTextView);
dateTextView = (TextView) v.findViewById(R.id.dateTextView);
upVoteButton = (Button) v.findViewById(R.id.buttonUpVote);
downVoteButton = (Button) v.findViewById(R.id.buttonDownVote);
rParams.addRule(RelativeLayout.BELOW, nameTextView.getId());
rParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
imageView.setLayoutParams(rParams);
upVoteButton.setOnClickListener(this);
downVoteButton.setOnClickListener(this);
if (NightWatch.class.isInstance(getActivity())) {
Typeface font = Typeface.createFromAsset(getActivity().getAssets(),
"NotCourierSans.ttf");
final String image = imageUrl.get(mImageNum);
((NightWatch) getActivity()).loadBitmap(image, imageView, false, loadingTextView);
trendTextView.setText(trendList.get(mImageNum));
nameTextView.setText(nameList.get(mImageNum));
dateTextView.setText(dateList.get(mImageNum));
updateButtonBackgrounds();
loadingTextView.setTypeface(font);
trendTextView.setTypeface(font);
nameTextView.setTypeface(font);
dateTextView.setTypeface(font);
Log.d("fragment trend", NightWatch.trendList.get(0));
}
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.buttonUpVote:
if (prefs.getInt(imageUrl.get(mImageNum), 0) == -1) {
downVoteButton
.setBackgroundResource(R.drawable.downvoteunpressed);
upVoteButton.setBackgroundResource(R.drawable.upvotepressed);
((NightWatch) getActivity()).sendVote(1,
imageUrl.get(mImageNum));
} else if (prefs.getInt(imageUrl.get(mImageNum), 0) == 0) {
upVoteButton.setBackgroundResource(R.drawable.upvotepressed);
((NightWatch) getActivity()).sendVote(1,
imageUrl.get(mImageNum));
}
break;
case R.id.buttonDownVote:
if (prefs.getInt(imageUrl.get(mImageNum), 0) == 1) {
downVoteButton
.setBackgroundResource(R.drawable.downvotepressed);
upVoteButton.setBackgroundResource(R.drawable.upvoteunpressed);
((NightWatch) getActivity()).sendVote(-1,
imageUrl.get(mImageNum));
} else if (prefs.getInt(imageUrl.get(mImageNum), 0) == 0) {
downVoteButton
.setBackgroundResource(R.drawable.downvotepressed);
((NightWatch) getActivity()).sendVote(-1,
imageUrl.get(mImageNum));
}
break;
}
};
public void updateButtonBackgrounds() {
if (prefs.getInt(imageUrl.get(mImageNum), 0) == -1) {
downVoteButton.setBackgroundResource(R.drawable.downvotepressed);
} else if (prefs.getInt(imageUrl.get(mImageNum), 0) == 1) {
upVoteButton.setBackgroundResource(R.drawable.upvotepressed);
}
}
public static void sendVote(int vote, String imageName) {
prefs.edit().putInt(imageName, vote).commit();
}
public void getSizes() {
Display display = getActivity().getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
width = size.x;
height = size.y;
}
}
HotFragment
package info.nightowl.nightowl;
public class HotFragment extends Fragment implements OnClickListener {
ToggleButton buttonGrid;
static Spinner spinnerUploadStatus;
CustomEditText et;
CustomScrollTextView tv;
int width, height;
View view;
static boolean isGrid;
ViewPager mPager;
SharedPreferences prefs;
public ImagePagerAdapter mPageAdapter;
Button buttonSwitchFragment;
Integer[] b = { R.drawable.statusunpressed, R.drawable.red,
R.drawable.green, R.drawable.blue };
List<Integer> spinnerList = new ArrayList<Integer>(Arrays.asList(b));
CustomSpinnerAdapter myAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
prefs = getActivity().getSharedPreferences("prefs", 0);
getSizes();
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.activity_feed, container, false);
setup();
return view;
}
#SuppressLint("NewApi")
public void setup() {
isGrid = false;
mPager = (ViewPager) view.findViewById(R.id.myviewpager1);
mPager.setOffscreenPageLimit(0);
buttonGrid = (ToggleButton) view.findViewById(R.id.button_grid);
buttonGrid.setOnClickListener(this);
spinnerUploadStatus = (Spinner) view
.findViewById(R.id.buttonUploadStatus);
myAdapter = new CustomSpinnerAdapter(getActivity(),
R.layout.item_simple_list_item, spinnerList);
myAdapter
.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerUploadStatus.setAdapter(myAdapter);
spinnerUploadStatus.setDropDownWidth((int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 50, getResources()
.getDisplayMetrics()));
spinnerUploadStatus.setOnItemSelectedListener(myOnItemSelectedListener);
spinnerUploadStatus.getBackground().setAlpha(0);
buttonSwitchFragment = (Button) view
.findViewById(R.id.buttonSwitchFragment);
buttonSwitchFragment.setOnClickListener(this);
Typeface font = Typeface.createFromAsset(getActivity().getAssets(),
"NotCourierSans.ttf");
et = (CustomEditText) view.findViewById(R.id.customEditText1);
et.updateTypeFace(font);
tv = (CustomScrollTextView) view
.findViewById(R.id.customscrolltextview);
tv.setText("WELCOME TO NIGHTOWL");
tv.setTypeface(font);
tv.start(width / 2500.0);
Log.d("width", "width is " + width);
}
public void getSizes() {
Display display = getActivity().getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
width = size.x;
height = size.y;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_grid:
isGrid = !isGrid;
updateAdapter();
break;
case R.id.buttonSwitchFragment:
((NightWatch) getActivity()).scrollMainPager(1);
break;
}
}
public OnItemSelectedListener myOnItemSelectedListener = new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
spinnerUploadStatus.setSelection(0, true);
et.sendText(prefs.getString("username", "username invalid"), arg2);
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
};
public void scrollPager(int position) {
isGrid = false;
buttonGrid.setChecked(false);
updateAdapter();
mPager.setCurrentItem(position, true);
Log.d("Pager", "PAGER UPDATED");
}
public static void disableButton(Boolean enabled) {
spinnerUploadStatus.setEnabled(enabled);
}
public void updateAdapter() {
int theSize;
if (!isGrid)
theSize = NightWatch.imageUrl.size();
else if (NightWatch.imageUrl.size() % 9 > 0)
theSize = NightWatch.imageUrl.size() / 9 + 1;
else
theSize = NightWatch.imageUrl.size() / 9;
mPageAdapter = new ImagePagerAdapter(getChildFragmentManager(), theSize);
mPager.setAdapter(mPageAdapter);
Log.d("size of viewPager Adapter", "" + theSize);
}
public static class ImagePagerAdapter extends FragmentStatePagerAdapter {
int mSize;
public ImagePagerAdapter(FragmentManager fm, int size) {
super(fm);
mSize = size;
}
#Override
public Fragment getItem(int arg0) {
// TODO Auto-generated method stub
Log.d("Starting imageDetailFragment", "");
Log.d("Pager", "Pager starting fragment");
Log.d("GRID", "fuck grid");
if (!isGrid)
return ImageDetailFragment.newInstance(arg0,
NightWatch.hotImageUrl, NightWatch.hotNameList,
NightWatch.hotTrendList, NightWatch.hotDateList);
else
return GridFragment.newInstance(arg0, NightWatch.imageUrl);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return mSize;
}
}
public class CustomSpinnerAdapter extends ArrayAdapter<Integer> {
List<Integer> resourceId;
Context c;
public CustomSpinnerAdapter(Context context, int textViewResourceId,
List<Integer> objects) {
super(context, textViewResourceId, objects);
resourceId = objects;
c = context;
}
#Override
public View getDropDownView(int position, View convertView,
ViewGroup parent) {
return getCustomDropdownView(position, convertView, parent);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
return getCustomView(position, convertView, parent);
}
public View getCustomView(int position, View convertView,
ViewGroup parent) {
ImageView imageView = new ImageView(c);
imageView.setImageResource(resourceId.get(position));
imageView.setLayoutParams(new ListView.LayoutParams(
(int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 50, getResources()
.getDisplayMetrics()), (int) TypedValue
.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 34,
getResources().getDisplayMetrics())));
return imageView;
}
public View getCustomDropdownView(int position, View convertView,
ViewGroup parent) {
ImageView imageView = new ImageView(c);
imageView.setImageResource(resourceId.get(position));
imageView.setLayoutParams(new ListView.LayoutParams(
(int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 50, getResources()
.getDisplayMetrics()), (int) TypedValue
.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 34,
getResources().getDisplayMetrics())));
if (position == 0) {
imageView.setVisibility(View.GONE);
}
return imageView;
}
}
}
I dont see a point in posting the rest of the fragments. The memory leak is somewhere here I'm sure
I would really appreciate it if someone helped me with this.
Loading a Bitmap from a URL in such manner will cause IOException. With Picasso, you don't even need asynctask. Simply call this in UI Thread:
Picasso.with(getActivity())
.load(url)
.into(imageView); //you can add .resize() before .into()
OR if you really want to have the Bitmap, you use this code:
new AsyncTask<Void, Void, Void>() {
Bitmap bitmap;
#Override
protected void onPreExecute() {
//some code
}
#Override
protected Void doInBackground(Void... arg0) {
bitmap = getBitmapFromURL(url);
return null;
}
#Override
protected void onPostExecute(Void result) {
imageView.setImageBitmap(bitmap);
}
}.execute();
And getBitmapFromURL():
public Bitmap getBitmapFromURL(String src) {
try {
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
return BitmapFactory.decodeStream(input);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
Ok so I would recommend you stick with using Picasso as this will make your life a lot easier in terms of memory management and the likes. One thing to remember is that the image contained in an imageview can ultimately retrieved as a Bitmap regardless of the image type (eg jpeg, png etc), so if you use Picasso to load the image via a URL you can still retrieve the image as a Bitmap after it is loaded and apply your transformation on it. Picasso also have a function called .transform() which you can use to transform your images by supplying a custom transformation. Here is an example for a rounded transformation, first the code that implements the transformation:
//calcualte the raduis for the rounded images
final float scale = mContext.getResources().getDisplayMetrics().density; //get screen density for scale
int pixels = (int) ((imageView.getWidth()-5) * scale); //get screen pixels based on density. Imageview is 60dp x 60dp in size, subtract some padding = 55
mRadiusCenter = pixels / 2; //get the raduis
//now load your image
Picasso.with(mContext)
.load(imageUrl)
.fit().centerCrop()
.transform(new RoundedTransformation(mRadiusCenter))
.into(imageView);
The you need to create a class for the RoundedTransformation that implements Picasso Transformation:
// enables hardware accelerated rounded corners
// original idea here : http://www.curious-creature.org/2012/12/11/android-recipe-1-image-with-rounded-corners/
public class RoundedTransformation implements com.squareup.picasso.Transformation {
private final int radius;
// radius is corner radii in dp
public RoundedTransformation(final int radius) {
this.radius = radius;
}
#Override
public Bitmap transform(final Bitmap source) {
final Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
Bitmap output = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
canvas.drawCircle(radius, radius, radius, paint);
if (source != output) {
source.recycle();
}
return output;
}
#Override
public String key() {
return "rounded";
}
}
Here are some more links that might prove useful:
https://gist.github.com/julianshen/5829333
Load large images with Picasso and custom Transform object
Hope that helps!
What I'm trying to achieve is to obtain the URL received from Instagram and pass its array position to an onlick listener for each corresponding photo in a grid view.
Here is my code:
MainActivity.java
public class MainActivity extends Activity {
private InstagramSession mInstagramSession;
private Instagram mInstagram;
private ProgressBar mLoadingPb;
private GridView mGridView;
private static final String CLIENT_ID = "83549f9eb76f4a5b90daf6e4e14da107";
private static final String CLIENT_SECRET = "6df26b0c8f664323a07126bfe8511651";
private static final String REDIRECT_URI = "http://www.yahoo.com";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mInstagram = new Instagram(this, CLIENT_ID, CLIENT_SECRET, REDIRECT_URI);
mInstagramSession = mInstagram.getSession();
if (mInstagramSession.isActive()) {
setContentView(R.layout.activity_user);
InstagramUser instagramUser = mInstagramSession.getUser();
mLoadingPb = (ProgressBar) findViewById(R.id.pb_loading);
mGridView = (GridView) findViewById(R.id.gridView);
((TextView) findViewById(R.id.tv_name)).setText(instagramUser.fullName);
((TextView) findViewById(R.id.tv_username)).setText(instagramUser.username);
((Button) findViewById(R.id.btn_logout)).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
mInstagramSession.reset();
startActivity(new Intent(MainActivity.this, MainActivity.class));
finish();
}
});
ImageView userIv = (ImageView) findViewById(R.id.iv_user);
DisplayImageOptions displayOptions = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_user)
.showImageForEmptyUri(R.drawable.ic_user)
.showImageOnFail(R.drawable.ic_user)
.cacheInMemory(true)
.cacheOnDisc(false)
.considerExifParams(true)
.build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this)
.writeDebugLogs()
.defaultDisplayImageOptions(displayOptions)
.build();
ImageLoader imageLoader = ImageLoader.getInstance();
imageLoader.init(config);
AnimateFirstDisplayListener animate = new AnimateFirstDisplayListener();
imageLoader.displayImage(instagramUser.profilPicture, userIv, animate);
new DownloadTask().execute();
} else {
setContentView(R.layout.activity_main);
((Button) findViewById(R.id.btn_connect)).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
mInstagram.authorize(mAuthListener);
}
});
}
}
private void showToast(String text) {
Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG).show();
}
private Instagram.InstagramAuthListener mAuthListener = new Instagram.InstagramAuthListener() {
#Override
public void onSuccess(InstagramUser user) {
finish();
startActivity(new Intent(MainActivity.this, MainActivity.class));
}
#Override
public void onError(String error) {
showToast(error);
}
#Override
public void onCancel() {
showToast("OK. Maybe later?");
}
};
public 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);
}
}
}
}
ArrayList<String> photoList;
public class DownloadTask extends AsyncTask<URL, Integer, Long> {
protected void onCancelled() {
}
protected void onPreExecute() {
}
protected Long doInBackground(URL... urls) {
long result = 0;
try {
List<NameValuePair> params = new ArrayList<NameValuePair>(1);
params.add(new BasicNameValuePair("count", "20"));
InstagramRequest request = new InstagramRequest(mInstagramSession.getAccessToken());
String response = request.createRequest("GET", "/users/21846697/media/recent", params);
if (!response.equals("")) {
JSONObject jsonObj = (JSONObject) new JSONTokener(response).nextValue();
JSONArray jsonData = jsonObj.getJSONArray("data");
int length = jsonData.length();
if (length > 0) {
photoList = new ArrayList<String>();
for (int i = 0; i < length; i++) {
JSONObject jsonPhoto = jsonData.getJSONObject(i).getJSONObject("images").getJSONObject("standard_resolution");
photoList.add(jsonPhoto.getString("url"));
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
protected void onProgressUpdate(Integer... progress) {
}
protected void onPostExecute(Long result) {
mLoadingPb.setVisibility(View.GONE);
if (photoList == null) {
Toast.makeText(getApplicationContext(), "No Photos Available", Toast.LENGTH_LONG).show();
} else {
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width = (int) Math.ceil((double) dm.widthPixels / 2);
width=width-50;
int height = width;
PhotoListAdapter adapter = new PhotoListAdapter(MainActivity.this);
adapter.setData(photoList);
adapter.setLayoutParam(width, height);
mGridView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// Maybe you'll have to cast it to a string, I'm currently writing directly in SO
String url = (String) parent.getAdapter().getItem(position);
Intent myintent=new Intent(MainActivity.this, FullscreenImageView.class).putExtra("SelectedImageURL", position);
startActivity(myintent);
}
});
mGridView.setAdapter(adapter);
}
}
}
}
PhotoListAdapter.java
public class PhotoListAdapter extends BaseAdapter {
private Context mContext;
private ImageLoader mImageLoader;
private AnimateFirstDisplayListener mAnimator;
private ArrayList<String> mPhotoList;
private int mWidth;
private int mHeight;
public PhotoListAdapter(Context context) {
mContext = context;
DisplayImageOptions displayOptions = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.instagram_logo)
.showImageForEmptyUri(R.drawable.instagram_logo)
.showImageOnFail(R.drawable.instagram_logo)
.cacheInMemory(true)
.cacheOnDisc(false)
.considerExifParams(true)
.build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
.writeDebugLogs()
.defaultDisplayImageOptions(displayOptions)
.build();
mImageLoader = ImageLoader.getInstance();
mImageLoader.init(config);
mAnimator = new AnimateFirstDisplayListener();
}
public void setData(ArrayList<String> data) {
mPhotoList = data;
}
public void setLayoutParam(int width, int height) {
mWidth = width;
mHeight = height;
}
#Override
public int getCount() {
return (mPhotoList == null) ? 0 : mPhotoList.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageIv;
if (convertView == null) {
imageIv = new ImageView(mContext);
imageIv.setLayoutParams(new GridView.LayoutParams(mWidth, mHeight));
imageIv.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
imageIv.setPadding(0, 0, 0, 0);
} else {
imageIv = (ImageView) convertView;
}
mImageLoader.displayImage(mPhotoList.get(position), imageIv, mAnimator);
return imageIv;
}
}
FullScreenImageView.java
import android.app.Activity;
public class FullscreenImageView extends Activity {
String imageURL = getIntent().getStringExtra("SelectedImageURL");
}
The workflow of the gridView as you understood is to have an adapter to populate this view.
What I would do is that the getItem(int position) returns the URL which, if I good understood, is contained in your mPhotoList. Something like:
#Override
public Object getItem(int position) {
return mPhotoList.get(position);
}
And use it where you need it like this:
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// Maybe you'll have to cast it to a string, I'm currently writing directly in SO
String url = parent.getAdapter().getItem(position)
Intent myintent=new Intent(MainActivity.this, FullscreenImageView.class).putExtra("SelectedImageURL", url);
startActivity(myintent);
}
});
Hope it helps.
Hello stackoverflow I'm trying to develop an application like Gallery for a particular directory of SD Card. For example I have took WhatsApp Images directory, here is my code
public class WhatsAppInboxImagesActivity extends Activity {
private ImageAdapter imageAdapter;
private ProgressDialog pd;
ArrayList<String> f = null;
File[] listFile;
Button btnDelete;
HashSet<String> selectedFile = null;
GridView imagegrid;
AlertDialog alertDialog = null;
static
{
File noFile = new File(Environment.getExternalStorageDirectory().getPath(), "/WhatsApp/Media/WhatsApp Images/Sent/.nomedia");
if(noFile.exists())
{
noFile.delete();
}
}//End of static block
private void initialize()
{
imagegrid = (GridView) findViewById(R.id.PhoneImageGrid);
btnDelete = (Button) findViewById(R.id.btnDeleteImg);
selectedFile = new HashSet<String>();// list of file paths boolean checked
f = new ArrayList<String>();// list of file paths
}//End of initialize method
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_whats_app_images_inbox);
this.initialize();
getFromSdcard();
imageAdapter = new ImageAdapter();
/*
* Performing time consuming actions
*/
new AsyncTask<Void, Void, Void>()
{
#Override
protected void onPreExecute()
{
pd = ProgressDialog.show(WhatsAppInboxImagesActivity.this,
"Loading..", "Please Wait", true, false);
}// End of onPreExecute method
#Override
protected Void doInBackground(Void... params)
{
return null;
}// End of doInBackground method
#Override
protected void onPostExecute(Void result)
{
imagegrid.setAdapter(imageAdapter);
imageAdapter.notifyDataSetChanged();
pd.dismiss();
}
}.execute((Void[]) null);
btnDelete.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
new AsyncTask<Void, Void, Void>()
{
#Override
protected void onPreExecute()
{
pd = ProgressDialog.show(WhatsAppInboxImagesActivity.this,
"Loading..", "Please Wait", true, false);
}// End of onPreExecute method
#Override
protected Void doInBackground(Void... params)
{
#SuppressWarnings("rawtypes")
Iterator iterator = selectedFile.iterator();
while (iterator.hasNext())
{
new File(iterator.next().toString()).delete();
}//End of while loop
return null;
}// End of doInBackground method
#Override
protected void onPostExecute(Void result)
{
pd.dismiss();
}//End of onPostExecute method
}.execute((Void[]) null);
finish();
startActivity(getIntent());
}//End of onClick method
});//End of btnDelete anonymous class
}//End of onCreate method
public void getFromSdcard()
{
File file = new File( Environment.getExternalStorageDirectory().getPath(), "/WhatsApp/Media/WhatsApp Images");
if (file.isDirectory())
{
listFile = file.listFiles();
for (int i = 0; i < listFile.length; i++)
{
if(listFile[i].isDirectory())
{
continue;
}
f.add(listFile[i].getAbsolutePath());
}//End of for loop
}//End of if condition
}//End of getFromSdcard method
public class ImageAdapter extends BaseAdapter
{
private LayoutInflater mInflater;
public ImageAdapter()
{
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}//End of ImageAdapter constructor
public int getCount()
{
return f.size();
}//End of getCount method
public Object getItem(int position)
{
return position;
}//End of getItem method
public long getItemId(int position)
{
return position;
}//End of getItemId method
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder holder;
if (convertView == null)
{
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.galleryitem, null);
holder.imageview = (ImageView) convertView.findViewById(R.id.thumbImage);
holder.checkbox = (CheckBox) convertView.findViewById(R.id.itemCheckBox);
convertView.setTag(holder);
}//End of if condition
else
{
holder = (ViewHolder) convertView.getTag();
}//End of else
BitmapFactory.Options options = new BitmapFactory.Options();
// will results in a much smaller image than the original
options.inSampleSize = 4;
// don't ever use a path to /sdcard like this, but I'm sure you have a sane way to do that
// in this case nebulae.jpg is a 19MB 8000x3874px image
final Bitmap b = BitmapFactory.decodeFile(f.get(position), options);
holder.imageview.setImageBitmap(b);
return convertView;
}//End of getView method
}//End of ImageAdapter instance inner class
class ViewHolder
{
ImageView imageview;
CheckBox checkbox;
int id;
}//End of ViewHolder instance inner class
}//End of WhatsAppImagesActivity
So far every thing is good, but the problem is images gets loaded all at one shot, so scrolling is very slow and some times OutOfMemoryException occurs though decoded file with BitMapFactory, can any one help me to solve this puzzle please.
Edit:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView == null) {
LayoutInflater inflator = context.getLayoutInflater();
view = inflator.inflate(R.layout.list_layout, null);
final ViewHolder viewHolder = new ViewHolder();
viewHolder.text = (TextView) view.findViewById(R.id.label);
viewHolder.text.setTextColor(Color.BLACK);
viewHolder.image = (ImageView) view.findViewById(R.id.image);
viewHolder.image.setVisibility(View.GONE);
viewHolder.cb = (CheckBox) view.findViewById(R.id.item_check_box);
viewHolder.pb = (ProgressBar) view.findViewById(R.id.progressBar);
view.setTag(viewHolder);
} else {
view = convertView;
}
final int pos = position;
ViewHolder holder = (ViewHolder) view.getTag();
holder.text.setText(list.get(position).getName());
holder.image.setTag(list.get(position).getURL());
holder.image.setId(position);
PbAndImage pb_and_image = new PbAndImage();
pb_and_image.setImg(holder.image);
pb_and_image.setPb(holder.pb);
new DownloadImageTask().execute(pb_and_image);
return view;
}
Thanks.
You should use Lazy loading
visit this tutorial for lazy loading here Its very easy.
Let me know if you have any issue on it.
Edit
public class MainActivity extends ListActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String path = Environment.getExternalStorageDirectory()+"/WhatsApp/Media/WhatsApp Images";
final List<Model> list = new ArrayList<Model>();
final File file = new File(path);
final ProgressDialog dialog = ProgressDialog.show(MainActivity.this, "",
"Please Wait...", true);
new Thread(new Runnable() {
public void run() {
dismissDialog(dialog);
for(File fileChild : file.listFiles()){
list.add(get(fileChild.getName(), fileChild.getAbsolutePath()));
}
}
}).start();
ArrayAdapter<Model> adapter = new MyCustomArrayAdapter(this, list);
setListAdapter(adapter);
}
public void dismissDialog(final ProgressDialog dialog) {
runOnUiThread(new Runnable() {
public void run() {
dialog.dismiss();
}
});
}
private Model get(String s, String url) {
return new Model(s, url);
}
}
This could help: UniversalImageLoader
And that's what I did:
/**
* UniversalImageLoader載入遠端圖片,僅使用RAM做圖片快取 (Load pic & use RAM as cache)
* #param android.content.Context
* #author https://github.com/nostra13/Android-Universal-Image-Loader
* #param android.widget.ImageView - 顯示圖片的元件 (your image container)
* #param int - 載入失敗的預設圖片Resource ID (default pic if load fail, I put default pic in resources folder)
* #param java.lang.String - 檔案URL (pic URL or path)
*/
public static void imageLoaderMemoryCache(Context context, final ImageView img, final int failImgID, String url)
{
ImageLoader imageLoader=ImageLoader.getInstance();
ImageLoaderConfiguration config=new ImageLoaderConfiguration.Builder(context)
.memoryCacheExtraOptions(100, 100) // max width, max height
.threadPoolSize(5)
.threadPriority(Thread.NORM_PRIORITY+1)
.denyCacheImageMultipleSizesInMemory()
.tasksProcessingOrder(QueueProcessingType.FIFO)
.defaultDisplayImageOptions(DisplayImageOptions.createSimple())
.enableLogging()
.build();
imageLoader.init(config);
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageForEmptyUri(R.drawable.cover_sample)
.cacheInMemory(true)
.imageScaleType(ImageScaleType.IN_SAMPLE_INT)
.bitmapConfig(Bitmap.Config.RGB_565)
.delayBeforeLoading(1)
.displayer(new FadeInBitmapDisplayer(500))
.build();
imageLoader.displayImage(url, img, options, new ImageLoadingListener()
{
#Override
public void onLoadingStarted(String url, View view)
{img.setImageResource(failImgID);} //一開始先顯示預設圖 (display default pic at first)
#Override
public void onLoadingFailed(String url, View view, FailReason failReason)
{img.setImageResource(failImgID);}
#Override
public void onLoadingComplete(String url, View view, Bitmap loadedImage)
{}
#Override
public void onLoadingCancelled(String url, View view)
{}
});
}
Usage (ListView)
public View getView(...)
{
vh.imgCover=(ImageView)convertView.findViewById(R.id.imgCover);
//...
// some stuff
//...
Util.imageLoaderDiskCache(getActivity(), vh.imgCover, R.drawable.cover_sample, "(pic file path)");
}
Hope it helps~