In the above image, there is a list view which contains list of items that the user can download. This is the image which tells user that he can download the file. On completion of download, the image will change to . My problem is when I download a file, the status image(which denotes that download has completed) gets changed for another row, instead, it should change for the row that I had selected. At present, if I download first file in the list, the image gets changed for 4th or 5th item in the list. Also, when I try to download any other file from the list. it opens up last downloaded file(This is functionality of the app that if file is already downloaded, then open it in pdf reader),i.e., if I download 1st file in the list and then go for second item,then instead of downloading 2nd file, it opens up last downloaded file. More over, if I scroll the listview, the status of download gets changed for other items in the list also. Below,is my adapter code:
public class DownloadListAdapter extends BaseAdapter {
Context ctx;
public ArrayList<DownloadListDao> mDownloadList;
String readMoreLink;
public static final String TAG = "DownloadListAdapter";
ProgressDialog mProgressDialog;
private boolean isSDCardPresent;
File tieDir;
int downloadState[];
public DownloadListAdapter(Context ctx,
ArrayList<DownloadListDao> mDownloadList) {
this.ctx = ctx;
this.mDownloadList = mDownloadList;
downloadState = new int [mDownloadList.size()];
for(int i = 0; i < mDownloadList.size(); i++) {
downloadState[i] = 0;
}
tieDir = new File(Environment.getExternalStorageDirectory().toString()
+ "/tie");
}// Constructor
public int getCount() {
return this.mDownloadList.size();
}// getCount
public Object getItem(int position) {
return this.mDownloadList.get(position);
}// getItem
public long getItemId(int position) {
return 0;
}// getItemId
static class ViewHolder {
TextView txtTitle, txtTheme, txtDate;
ImageView imgDownload;
}// ViewHolder
ViewHolder holder;
public View getView(final int position, View convertView, ViewGroup parent) {
final String url = mDownloadList.get(position).getUrl();
if (convertView == null) {
convertView = LayoutInflater.from(parent.getContext()).inflate(
R.layout.downlist_adapter, null);
holder = new ViewHolder();
holder.txtTitle = (TextView) convertView
.findViewById(R.id.txtTitle);
holder.txtTheme = (TextView) convertView
.findViewById(R.id.txtTheme);
holder.txtDate = (TextView) convertView.findViewById(R.id.txtDate);
holder.imgDownload = (ImageView) convertView
.findViewById(R.id.imgDload);
holder.imgDownload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
File mediaFile = null;
if (url != null && !url.equals("null") && !url.equals("")) {
String fileName = url.toString().substring(
url.toString().lastIndexOf("/") + 1,
url.toString().length());
mediaFile = new File(tieDir, fileName);
}
processFile(mediaFile, url, position);
int pos = (Integer)v.getTag();
downloadState[pos] = 1;
}
});
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if (mDownloadList != null && mDownloadList.size() > 0) {
if (mDownloadList.get(position).getTitle() != null
&& !mDownloadList.get(position).getTitle().equals("null")
&& !mDownloadList.get(position).getTitle().equals("")) {
holder.txtTitle.setText(mDownloadList.get(position).getTitle());
}
if (mDownloadList.get(position).getTheme() != null
&& !mDownloadList.get(position).getTheme().equals("null")
&& !mDownloadList.get(position).getTheme().equals("")) {
holder.txtTheme.setText(mDownloadList.get(position).getTheme());
}
if (mDownloadList.get(position).getDate() != null
&& !mDownloadList.get(position).getDate().equals("null")
&& !mDownloadList.get(position).getDate().equals("")) {
holder.txtDate.setText(mDownloadList.get(position).getDate());
}
if (downloadState[position] == 1) {
holder.imgDownload.setImageDrawable(ctx.getResources()
.getDrawable(R.drawable.ic_dloaded));
} else {
holder.imgDownload.setImageDrawable(ctx.getResources()
.getDrawable(R.drawable.ic_dload));
}
}
holder.imgDownload.setTag(position);
return convertView;
}// getView
protected void downloadFile(String url, int position, String fileName) {
Log.v(TAG, "Preparing to download");
mProgressDialog = new ProgressDialog(ctx);
mProgressDialog.setMessage("Dowloading...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
isSDCardPresent = Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED);
if (!isSDCardPresent) {
noSDCardAlert(ctx);
} else {
if ((tieDir.exists()) && (tieDir != null)) {
if (NetworkConnection.isOnline(ctx)) {
if (tieDir.isDirectory()) {
Log.v(TAG, "if tie dir URL:::" + url);
new DownloadAudioAsync(ctx, position, fileName).execute(url);
}
} else {
((DownloadListActivity) ctx)
.OpenNetErrDialog("Please check your internet connection...");
}
} else {
boolean isDirectoryCreated = tieDir.mkdirs();
if (isDirectoryCreated) {
Log.v(TAG, "if tie not dir URL:::" + url);
if (NetworkConnection.isOnline(ctx)) {
new DownloadAudioAsync(ctx, position, fileName).execute(url);
} else {
((DownloadListActivity) ctx)
.OpenWiFiDialog("Please check your internet connection...");
}
}
}
}
}
private void noSDCardAlert(Context ctx) {
AlertDialog.Builder ad = new AlertDialog.Builder(ctx);
ad.setMessage("No sd card present..");
ad.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
if (!((DownloadDetail) ctx).isFinishing()) {
ad.show();
}
}
public void OpenDialog(String messageID) {
final Dialog dialog = new Dialog(ctx,
android.R.style.Theme_Translucent_NoTitleBar);
dialog.setContentView(R.layout.dialog_base);
dialog.getWindow().getAttributes().windowAnimations = android.R.style.Animation_Dialog;
dialog.setCancelable(false);
TextView alertMessage = (TextView) dialog.findViewById(R.id.txtMessage);
Button btnOK = (Button) dialog.findViewById(R.id.btnOk);
btnOK.setText("Show");
alertMessage.setText(messageID);
dialog.show();
btnOK.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
}
protected void showPdf(File mediaFile) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(mediaFile), "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
ctx.startActivity(intent);
}
public class DownloadAudioAsync extends AsyncTask<String, String, String> {
Context ctx;
int pos;
private ProgressDialog pd;
String fileName;
public DownloadAudioAsync(Context ctx, int pos, String fileName) {
this.ctx = ctx;
this.pos = pos;
this.fileName = fileName;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
Log.v(TAG, "inside on pre execute");
pd = new ProgressDialog(ctx);
pd.setMessage("Downloading...\nPlease wait..");
pd.show();
}
#Override
protected String doInBackground(String... aurl) {
int count;
try {
Log.v(TAG,
"inside do in background with url::"
+ aurl[0].toString());
aurl[0] = aurl[0].replaceAll(" ", "%20");
URL url = new URL(aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
fileName = URLDecoder.decode(fileName, "UTF-8");
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(tieDir + "/"
+ fileName);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress("" + (int) ((total * 100) / lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {
}
return null;
}
#Override
protected void onPostExecute(String unused) {
if (!((DownloadListActivity) ctx).isFinishing()) {
pd.dismiss();
updateView(pos);
}
}
private void updateView(int pos) {
View v = ((DownloadListActivity) ctx).menuListView.getChildAt(pos
- ((DownloadListActivity) ctx).menuListView
.getFirstVisiblePosition());
ImageView imgDloadBtn = (ImageView) v.findViewById(R.id.imgDload);
imgDloadBtn.setImageDrawable(ctx.getResources().getDrawable(
R.drawable.ic_dloaded));
notifyDataSetChanged();
}
}
private void processFile(File mediaFile, String url, int pos) {
if (url != null && !url.equals("null") && !url.equals("")) {
if (mediaFile != null) {
Log.v(TAG, "in processFile FileName " + mediaFile.getName());
Log.v(TAG, "in processFile Position " + pos);
if(!mediaFile.exists()) {
Log.v(TAG, "in processFile Media file doesn't exists");
downloadFile(url, pos, mediaFile.getName());
} else {
Log.v(TAG, "in processFile Media file exists");
try {
showPdf(mediaFile);
} catch (ActivityNotFoundException anfe) {
OpenDialog("PDF Reader is not installed on your device.");
}
}
}
}
}
}// DownloadAdapter
I had read this post for recycling the view(Thanks to Knickedi for in depth explaination). But, I can't figure out where is actual problem.
Issue with getview Method which keep recreating whenever you scroll your view, to handle exact position you have to play with setTag & getTag,check below few stackvoerflow answers to understand setTag & getTag:
Button in ListView using ArrayAdapter
Getting radio button value from custom list in android
and even store downloaded state into one booleanarray like below:
int boxState[];
within adapter constructor, set zero initially:
for (int i = 0; i < getData.size(); i++) {
boxState[i] = 0;
}
within adapter getview method:
holder.imgDownload.setTag(position);
Now you click on download button set value as 1 (Inside onclick of button):
pos = (Integer) v.getTag();
boxState[pos]=1;
At last when you scroll your view check condition into following way(put below code inside getview method):
if (boxState[position] == 0) {
holder.imgDownload.setImageDrawable(ctx.getResources()
.getDrawable(R.drawable.ic_dloaded)); //which aren't downloaded
} else {
holder.imgDownload.setImageDrawable(ctx.getResources()
.getDrawable(R.drawable.ic_dload)); // which are downloaded.
}
Related
I have a ListView and a list view adapter. The adapter populates the ListView from a List. The list view has a onScrollListener. The problem I have is when on scroll new data are loaded to the view but the scroll bar jumps to the top of the view.
What I want is to keep the scroll position where it was!
Any help?
Thanks
List View class:
private class GetItems extends AsyncTask<Void, Void, Void>
{
#Override
protected void onPreExecute() {
super.onPreExecute();
// Create a progressdialog
mProgressDialog = new ProgressDialog(AppList.this);
// Set progressdialog title
mProgressDialog.setTitle("Loading more");
mProgressDialog.setMessage("loading);
mProgressDialog.setIndeterminate(false);
// Show progressdialog
mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params)
{
applicationList = new ArrayList();
try
{
GetDataAppList getDataAppList = new GetDataAppList();
JSONArray jsonData = getDataAppList.getJSONData(webfileName, limit, offset);
for (int i = 0; i <= jsonData.length() - 2; i++)
{
JSONObject c = jsonData.getJSONObject(i);
id = c.getString("id");
name = c.getString("name");
logo = c.getString("logo");
developer = c.getString("developer");
rate = c.getInt("rates");
category = c.getInt("category");
fileName = c.getString("filename");
path = c.getString("path");
appSize = c.getDouble("size");
if(category == 1001)
{
String gCat = c.getString("game_category");
applicationList.add(new ApplicationPojo(id,name,logo,developer,appSize,category,fileName,path,gCat));
}
else
{
applicationList.add(new ApplicationPojo(id,name,logo,developer,appSize,category,fileName,path));
}
}
JSONObject sizeObj = jsonData.getJSONObject(jsonData.length() - 1);
size = sizeObj.getInt("size");
}
catch (Exception ex)
{
Log.d("Thread:", ex.toString());
}
return null;
}
#Override
protected void onPostExecute(Void result)
{
// Locate the ListView in listview.xml
listview = (ListView) findViewById(R.id.listView);
// Pass the results into ListViewAdapter.java
adapter = new ListViewAdapter(AppList.this, applicationList,listview);
// Binds the Adapter to the ListView
listview.setAdapter(adapter);
// Close the progressdialog
mProgressDialog.dismiss();
// Create an OnScrollListener
listview.setOnScrollListener(new OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
int threshold = 1;
int count = listview.getCount();
if (scrollState == SCROLL_STATE_IDLE) {
if (listview.getLastVisiblePosition() >= count - threshold) {
if (size >= offset)
{
new LoadMoreDataTask().execute();
offset = offset + 15;
}
else
{
Toast.makeText(getApplicationContext(), "ختم لست!", Toast.LENGTH_LONG).show();
}
}
}
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
}
});
RatingBar bar = (RatingBar) findViewById(R.id.ratingBarShow);
}
}
private class LoadMoreDataTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog = new ProgressDialog(AppList.this);
mProgressDialog.setTitle("Loading more");
mProgressDialog.setMessage("loading);
mProgressDialog.setIndeterminate(false);
mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params)
{
try
{
GetDataAppList getDataAppList = new GetDataAppList();
JSONArray jsonData = getDataAppList.getJSONData(webfileName, limit, offset);
for (int i = 0; i <= jsonData.length(); i++) {
JSONObject c = jsonData.getJSONObject(i);
id = c.getString("id");
name = c.getString("name");
logo = c.getString("logo");
developer = c.getString("developer");
rate = c.getInt("rates");
category = c.getInt("category");
fileName = c.getString("filename");
path = c.getString("path");
appSize = c.getDouble("size");
if(category == 1001)
{
String gCat = c.getString("game_category");
applicationList.add(new ApplicationPojo(id,name,logo,developer,appSize,category,fileName,path,gCat));
}
else
{
applicationList.add(new ApplicationPojo(id,name,logo,developer,appSize,category,fileName,path));
}
}
}
catch (Exception ex)
{
}
return null;
}
#Override
protected void onPostExecute(Void result)
{
int position = listview.getLastVisiblePosition();
adapter = new ListViewAdapter(AppList.this, applicationList,listview);
listview.setAdapter(adapter);
listview.setSelectionFromTop(position, 0);
mProgressDialog.dismiss();
}
}
The Adpater class:
public ListViewAdapter(Activity activity, ArrayList<ApplicationPojo> applicationList, ListView listView)
{
this.activity = activity;
this.applicationList = applicationList;
this.inflater = LayoutInflater.from(activity);
downloader = new ApkFileDownloader(activity);
this.listView = listView;
}
#Override
public int getCount() {
return applicationList.size();
}
#Override
public ApplicationPojo getItem(int position) {
return applicationList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(final int position, View view, ViewGroup parent)
{
if (view == null)
{
holder = new ViewHolder();
view = inflater.inflate(R.layout.singleapp, null);
holder.openInstalledAppBtn = (ImageView) view.findViewById(R.id.openInstalledApp);
holder.downloadBtn = (ImageView) view.findViewById(R.id.updateApp);
holder.progressBar = (ProgressBar)view.findViewById(R.id.updateProgress);
holder.cancelBtn = (ImageView) view.findViewById(R.id.cancel);
holder.appName = (TextView) view.findViewById(R.id.appName);
holder.developer = (TextView) view.findViewById(R.id.developer);
holder.size = (TextView) view.findViewById(R.id.size);
holder.appCat = (TextView) view.findViewById((R.id.appCat));
holder.installBtn = (ImageView) view.findViewById(R.id.install);
holder.catlogo = (ImageView) view.findViewById(R.id.catlogo);
view.setTag(holder);
}
else
{
holder = (ViewHolder) view.getTag();
}
try
{
final View finalView = view;
holder.logo = (ImageView) finalView.findViewById(R.id.appLogo);
logoName = applicationList.get(position).getLogo();
Picasso.with(activity)
.load(IPClass.SERVERIP + logoName)
.into(holder.logo);
// holder.logo.setOnClickListener(new View.OnClickListener() {
// #Override
// public void onClick(View arg0) {
//
// }
// });
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String appid = applicationList.get(position).getId();
int category = applicationList.get(position).getCategory();
Intent rec1Intent = new Intent(activity, AppView.class);
activity.startActivity(rec1Intent);
AppView appView = new AppView();
appView.setParameters(appid, category);
AppList.adapter.notifyDataSetChanged();
}
});
final String id = applicationList.get(position).getId();
final String path = applicationList.get(position).getPath();
final String fileName = applicationList.get(position).getFileName();
final String name = applicationList.get(position).getName();
final String developer = applicationList.get(position).getDeveloper();
final double size = applicationList.get(position).getSize();
final String logo = applicationList.get(position).getLogo();
final int category = applicationList.get(position).getCategory();
final String appName = applicationList.get(position).getFileName();
String checkAppInstalled = appName.substring(0,appName.length() - 4);
//------------CHECK IF APPLICATION IS INSTALLED ----------------------------------------
if(appInstalled(checkAppInstalled))
{
holder.downloadBtn.setVisibility(View.GONE);
holder.cancelBtn.setVisibility(View.GONE);
holder.progressBar.setVisibility(View.GONE);
holder.installBtn.setVisibility(View.GONE);
holder.openInstalledAppBtn.setVisibility(View.VISIBLE);
holder.openInstalledAppBtn.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v) {
String fileName = (applicationList.get(position).getFileName());
String appToOpen = fileName.substring(0,fileName.length() - 4);
Context ctx = activity.getApplicationContext();
Intent mIntent = ctx.getPackageManager().getLaunchIntentForPackage(appToOpen);
String mainActivity = mIntent.getComponent().getClassName();
Intent intent = new Intent("android.intent.category.LAUNCHER");
intent.setClassName(appToOpen, mainActivity);
activity.startActivity(intent);
}
});
}
//------------- IF APPLICATION IS NOT ALREADY INSTALLED --------------------------------
else
{
//------------------------ CHECK IF APK EXISTS -------------------------------------
String filePath = Environment.getExternalStorageDirectory().toString();
File file = new File(filePath + "/appsaraai/" + fileName);
if(file.exists())
{
holder.downloadBtn.setVisibility(View.GONE);
holder.cancelBtn.setVisibility(View.GONE);
holder.openInstalledAppBtn.setVisibility(View.GONE);
holder.progressBar.setVisibility(View.GONE);
holder.installBtn.setVisibility(View.VISIBLE);
holder.installBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/appsaraai/" + fileName)), "application/vnd.android.package-archive");
activity.startActivity(intent);
for (int i = 0; i < DownloadLists.list.size(); i++) {
if (DownloadLists.list.get(i).getName().equals(name)) {
DownloadLists.list.remove(i);
}
}
}
});
AppList.adapter.notifyDataSetChanged();
}
//------------------ IF APK DOES NOT EXIST -----------------------------------------
else
{
//-----CHECK IF DOWNLOAD IS IN PROGRESS ----------------------------------------
if (ApkFileDownloader.applicationList.containsKey(name))
{
holder.downloadBtn.setVisibility(View.GONE);
holder.installBtn.setVisibility(View.GONE);
holder.openInstalledAppBtn.setVisibility(View.GONE);
new ApkFileDownloader(activity).getDownloadStatus(holder.progressBar, name, holder.installBtn, holder.cancelBtn);
holder.progressBar.setVisibility(View.VISIBLE);
holder.cancelBtn.setVisibility(View.VISIBLE);
holder.cancelBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
downloader.cancelDownload(name);
holder.cancelBtn.setVisibility(View.GONE);
holder.downloadBtn.setVisibility(View.VISIBLE);
DownloadLists dlist = new DownloadLists(activity);
dlist.deleteData(name);
try {
AppList.adapter.notifyDataSetChanged();
} catch (Exception ex) {
System.out.println(ex);
}
try
{
SearchResult.adapter.notifyDataSetChanged();
}
catch (Exception ex)
{
System.out.println(ex);
}
}
});
}
//-------------- IF DOWNLOAD IS NOT IN PROGRESS START NEW DOWNLOAD -------------
else
{
holder.progressBar.setVisibility(View.GONE);
holder.cancelBtn.setVisibility(View.GONE);
holder.installBtn.setVisibility(View.GONE);
holder.openInstalledAppBtn.setVisibility(View.GONE);
holder.downloadBtn.setVisibility(view.VISIBLE);
holder.downloadBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
holder.downloadBtn.setVisibility(View.GONE);
holder.cancelBtn.setVisibility(View.VISIBLE);
holder.cancelBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
downloader.cancelDownload(name);
holder.cancelBtn.setVisibility(View.GONE);
holder.downloadBtn.setVisibility(View.VISIBLE);
try {
AppList.adapter.notifyDataSetChanged();
} catch (Exception ex) {
System.out.println(ex);
}
try {
SearchResult.adapter.notifyDataSetChanged();
} catch (Exception ex) {
System.out.println(ex);
}
}
});
new Thread(new Runnable() {
#Override
public void run() {
try {
Bitmap logoImg = Picasso.with(activity).load(IPClass.SERVERIP + logo).get();
DownloadLists.list.add(new ApplicationPojo(id, name, developer, size, logoImg, holder.progressBar));
DownloadLists dlist = new DownloadLists(activity);
dlist.insertData(id, name, developer, size, fileName, logoImg);
UpdateServerDownload d = new UpdateServerDownload();
d.updateDownloadNo(id, category);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
new ApkFileDownloader(activity).setParameters(path, fileName, name);
try {
AppList.adapter.notifyDataSetChanged();
} catch (Exception ex) {
System.out.println(ex);
}
try {
SearchResult.adapter.notifyDataSetChanged();
} catch (Exception ex) {
System.out.println(ex);
}
}
});
}
}
}
holder.appName.setText(applicationList.get(position).getName());
holder.developer.setText(applicationList.get(position).getDeveloper());
String sizeText = " میگابایت ";
String appSize =String.valueOf(applicationList.get(position).getSize()) + sizeText;
holder.size.setText(appSize);
if(category == 1001)
{
String cat = applicationList.get(position).getgCat();
holder.appCat.setText(" " + returnGameCat(cat));
holder.catlogo.setImageResource(R.drawable.gamecatlogo);
}
}
catch (Exception ex)
{
Log.d("Adapter Exception", ex.toString());
}
return view;
}
//--------------- A METHOD TO CHECK IF APPLICATION IS ALREADY INSTALLED ------------------------
public boolean appInstalled(String checkApp)
{
pm = activity.getPackageManager();
try
{
pm.getPackageInfo(checkApp, PackageManager.GET_ACTIVITIES);
isAppInstalled = true;
}
catch (PackageManager.NameNotFoundException e)
{
isAppInstalled = false;
}
return isAppInstalled;
}
You are doing wrong in your GetItems and LoadMoreDataTask AsyncTask. you are setting new adapter each time when you scroll down so when new data are loaded to the view the scroll bar jumps to the top of the view.
You need to call
adapter = new ListViewAdapter(AppList.this, applicationList,listview);
listview.setAdapter(adapter);
only first time then you have to only call
adapter.notifyDataSetChanged()
to update your ListView no need to set adapter each time when making new request and also you have to set OnScrollListener to ListView only one time currently new OnScrollListener is set each time when making new request.
You need to setAdapter first time when adapter is null or you are fetching data first time after it just call notifyDataSetChanged()
Save state of listview before updating and then restore:
// save index and top position
int index = mListView.getFirstVisiblePosition();
View v = mListView.getChildAt(0);
int top = (v == null) ? 0 : v.getTop();
// notify dataset changed or re-assign adapter here
// restore the position of listview
mListView.setSelectionFromTop(index, top);
The most Optimal Solution will be
// Save the ListView state (= includes scroll position) as a Parceble
Parcelable state = listView.onSaveInstanceState();
// e.g. set new items
listView.setAdapter(adapter);
// Restore previous state (including selected item index and scroll position)
listView.onRestoreInstanceState(state);
Reference : Retain Scroll Position Android ListView
I have a listview with base adapter. each row in my list view contains image, title, download and view button and progress bar. initially progress bar and view button's visibility is GONE. when user press download button, progress bar should be visible. As soon as download is completed, download button should be gone and view button should visible.
My problem is: i am not able to change visibility of views from asynctask.
Here is my code.
public class PdfListAdapter extends BaseAdapter {
ArrayList<PdfDetails> arylstPdf = new ArrayList<PdfDetails>();
Context context;
String extStorageDirectory;
ViewHolder holder;
Activity activity;
public PdfListAdapter(Context context, ArrayList<PdfDetails> arylstPdf) {
super();
this.arylstPdf = arylstPdf;
this.context = context;
extStorageDirectory = Environment.getExternalStorageDirectory()
.toString();
holder = new ViewHolder();
}
#Override
public int getCount() {
return arylstPdf.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater mInflater = LayoutInflater.from(context);
activity = (Activity) context;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.layout_pdf_list, null);
holder.tvPdfTitle = (TextView) convertView
.findViewById(R.id.tvPdfTitle);
holder.imgPdfImage = (ImageView) convertView
.findViewById(R.id.imgPdfImage);
holder.btnDownload = (Button) convertView
.findViewById(R.id.btnDownload);
holder.btnView = (Button) convertView.findViewById(R.id.btnView);
holder.pbDownload = (ProgressBar) convertView
.findViewById(R.id.pbDownload);
holder.tvProgress = (TextView) convertView.findViewById(R.id.tvProgress);
holder.llProgress = (LinearLayout) convertView.findViewById(R.id.llProgress);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
File file = new File(extStorageDirectory + "/pdf", arylstPdf.get(
position).getPostTitle()
+ ".pdf");
if (file.exists()) {
holder.btnDownload.setVisibility(View.GONE);
holder.btnView.setVisibility(View.VISIBLE);
} else {
holder.btnDownload.setVisibility(View.VISIBLE);
holder.btnView.setVisibility(View.GONE);
}
holder.tvPdfTitle.setText(arylstPdf.get(position).getPostTitle());
ImageLoader objImageLoader = new ImageLoader(context);
objImageLoader.DisplayImage(arylstPdf.get(position).getAttachedImage(),
holder.imgPdfImage);
holder.btnDownload.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// NOT WORKING
holder.llProgress.setVisibility(View.VISIBLE);
Async async = new Async();
async.execute(Integer.toString(position));
}
});
holder.btnView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
readPDF(arylstPdf.get(position).getPostTitle());
}
});
return convertView;
}
class ViewHolder {
ImageView imgPdfImage;
TextView tvPdfTitle, tvProgress;
Button btnDownload;
Button btnView;
ProgressBar pbDownload;
LinearLayout llProgress;
}
class Async extends AsyncTask<String, String, String> {
File file, folder;
#Override
protected void onPreExecute() {
super.onPreExecute();
folder = new File(extStorageDirectory, "pdf");
folder.mkdir();
}
#Override
protected String doInBackground(String... params) {
String fileName = arylstPdf.get(Integer.parseInt(params[0]))
.getPostTitle();
file = new File(folder, fileName + ".pdf");
try {
file.createNewFile();
} catch (IOException e1) {
e1.printStackTrace();
}
int count;
try {
URL url = new URL(arylstPdf.get(Integer.parseInt(params[0]))
.getAttachedPdf());
URLConnection conection = url.openConnection();
conection.connect();
int lenghtOfFile = conection.getContentLength();
InputStream input = new BufferedInputStream(url.openStream(),
8192);
OutputStream output = new FileOutputStream(file);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress(Integer
.toString((int) ((total * 100) / lenghtOfFile)));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(String... progress) {
holder.tvProgress.setText(progress[0]);
holder.pbDownload.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// NOT WORKING
holder.btnDownload.setVisibility(View.GONE);
holder.btnDownload.setVisibility(View.VISIBLE);
Toast.makeText(context, "Downloaded", Toast.LENGTH_SHORT).show();
}
}
}
Add a boolean flag in PdfDetails class change download and view button visibility in getView method.
so just change that boolean flag of that particular row in arraylist position.
and user adapter.notifyDataStateChanged();
Add getter setter method in PdfDetails class.
and in getView() method
use
PdfDetails detailBin = list.get(position);
if(detailBin.isDownloaded)
// view button visible and download button hide
else
// download button visible and view button hide
and in postExecute()
list.get(position).setDownload(true);
adapter.notifyDataStateChanged();
Instead of creating holder in the Adapter class itself can you let it be inside getView itself and pass it to AsyncTask constructor.
public class PdfListAdapter extends BaseAdapter {
ArrayList<PdfDetails> arylstPdf = new ArrayList<PdfDetails>();
Context context;
String extStorageDirectory;
Activity activity;
public PdfListAdapter(Context context, ArrayList<PdfDetails> arylstPdf) {
super();
this.arylstPdf = arylstPdf;
this.context = context;
extStorageDirectory = Environment.getExternalStorageDirectory()
.toString();
}
#Override
public int getCount() {
return arylstPdf.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater mInflater = LayoutInflater.from(context);
activity = (Activity) context;
final ViewHolder holder= null;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.layout_pdf_list, null);
holder = new ViewHolder();
holder.tvPdfTitle = (TextView) convertView
.findViewById(R.id.tvPdfTitle);
holder.imgPdfImage = (ImageView) convertView
.findViewById(R.id.imgPdfImage);
holder.btnDownload = (Button) convertView
.findViewById(R.id.btnDownload);
holder.btnView = (Button) convertView.findViewById(R.id.btnView);
holder.pbDownload = (ProgressBar) convertView
.findViewById(R.id.pbDownload);
holder.tvProgress = (TextView) convertView.findViewById(R.id.tvProgress);
holder.llProgress = (LinearLayout) convertView.findViewById(R.id.llProgress);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
File file = new File(extStorageDirectory + "/pdf", arylstPdf.get(
position).getPostTitle()
+ ".pdf");
if (file.exists()) {
holder.btnDownload.setVisibility(View.GONE);
holder.btnView.setVisibility(View.VISIBLE);
} else {
holder.btnDownload.setVisibility(View.VISIBLE);
holder.btnView.setVisibility(View.GONE);
}
holder.tvPdfTitle.setText(arylstPdf.get(position).getPostTitle());
ImageLoader objImageLoader = new ImageLoader(context);
objImageLoader.DisplayImage(arylstPdf.get(position).getAttachedImage(),
holder.imgPdfImage);
holder.btnDownload.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// NOT WORKING
holder.llProgress.setVisibility(View.VISIBLE);
Async async = new Async(holder);
async.execute(Integer.toString(position));
}
});
holder.btnView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
readPDF(arylstPdf.get(position).getPostTitle());
}
});
return convertView;
}
class ViewHolder {
ImageView imgPdfImage;
TextView tvPdfTitle, tvProgress;
Button btnDownload;
Button btnView;
ProgressBar pbDownload;
LinearLayout llProgress;
}
class Async extends AsyncTask<String, String, String> {
File file, folder;
ViewHolder holder;
public Async(ViewHolder holder) {
this.holder=holder;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
folder = new File(extStorageDirectory, "pdf");
folder.mkdir();
}
#Override
protected String doInBackground(String... params) {
String fileName = arylstPdf.get(Integer.parseInt(params[0]))
.getPostTitle();
file = new File(folder, fileName + ".pdf");
try {
file.createNewFile();
} catch (IOException e1) {
e1.printStackTrace();
}
int count;
try {
URL url = new URL(arylstPdf.get(Integer.parseInt(params[0]))
.getAttachedPdf());
URLConnection conection = url.openConnection();
conection.connect();
int lenghtOfFile = conection.getContentLength();
InputStream input = new BufferedInputStream(url.openStream(),
8192);
OutputStream output = new FileOutputStream(file);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress(Integer
.toString((int) ((total * 100) / lenghtOfFile)));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(String... progress) {
holder.tvProgress.setText(progress[0]);
holder.pbDownload.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// NOT WORKING
holder.btnDownload.setVisibility(View.GONE);
holder.btnDownload.setVisibility(View.VISIBLE);
Toast.makeText(context, "Downloaded", Toast.LENGTH_SHORT).show();
}
}
}
You can not do any changes for UserInterface(UI) in other threads(Asynctasks) other than Main ui thread..
So you need to follow this
runOnUiThread(new Runnable() {
#Override
public void run() {
//Any UI changes can be done here
holder.btnDownload.setVisibility(View.GONE);
holder.btnView.setVisibility(View.VISIBLE);
}
});
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.
I am trying to parse the xml file and trying to load images and textviews and display it in a list view but whenever i try to load images in getView method in force closes the application even if try to scroll fast it also does the same. Iam tired of doing it in thread and asynctask for 5hours.please help if someone can solve it. Here are my two class files.
class NewsRowAdapter
public class NewsRowAdapter extends ArrayAdapter<Item>
{
LoadingImage loadingImage;
Bitmap bitmap = null;
private Activity activity;
private List<Item> items;
private Item objBean;
private int row;
public NewsRowAdapter(Activity act, int resource, List<Item> arrayList)
{
super(act, resource, arrayList);
this.activity = act;
this.row = resource;
this.items = arrayList;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent)
{
View view = convertView;
final 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.tvTitle = (TextView) view.findViewById(R.id.tvtitle);
holder.tvDesc = (TextView) view.findViewById(R.id.tvdesc);
holder.tvDate = (TextView) view.findViewById(R.id.tvdate);
holder.imgView = (ImageView) view.findViewById(R.id.image);
holder.pbar = (ProgressBar) view.findViewById(R.id.pbar);
if (holder.tvTitle != null && null != objBean.getTitle() && objBean.getTitle().trim().length() > 0)
{
holder.tvTitle.setText(Html.fromHtml(objBean.getTitle()));
}
if (holder.tvDesc != null && null != objBean.getDesc() && objBean.getDesc().trim().length() > 0)
{
holder.tvDesc.setText(Html.fromHtml(objBean.getDesc()));
}
if (holder.tvDate != null && null != objBean.getPubdate() && objBean.getPubdate().trim().length() > 0)
{
holder.tvDate.setText(Html.fromHtml(objBean.getPubdate()));
}
if (holder.imgView != null)
{
if (null != objBean.getLink() && objBean.getLink().trim().length() > 0)
{
final ProgressBar pbar = holder.pbar;
pbar.setVisibility(View.INVISIBLE);
//---------CHANGES MADE FOR LOADING IMAGE----------//
Log.d("IMAGE NULL----------", objBean.getLink());
//loadBitmap(objBean.getLink());
/*new Thread()
{
public void run()
{*/
try
{
URL linkurl = new URL(objBean.getLink());
bitmap = BitmapFactory.decodeStream(linkurl.openConnection().getInputStream());
holder.imgView.setImageBitmap(bitmap);
} catch (MalformedURLException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
/*}
}.start();*/
} else
{
holder.imgView.setImageResource(R.drawable.ic_launcher);
}
}
return view;
}
//------LOADING IMAGE FROM URL------//
public static Bitmap loadBitmap(String url)
{
Bitmap bitmap = null;
final AndroidHttpClient client = AndroidHttpClient.newInstance("Android");
final HttpGet getRequest = new HttpGet(url);
try
{
HttpResponse response = client.execute(getRequest);
final int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK)
{
Log.d("ImageDownloader", "Error " + statusCode + " while retrieving bitmap from " + url);
return null;
}
final HttpEntity entity = response.getEntity();
if (entity != null)
{
InputStream inputStream = null;
try
{
inputStream = entity.getContent();
bitmap = BitmapFactory.decodeStream(inputStream);
} finally
{
if (inputStream != null)
{
inputStream.close();
}
entity.consumeContent();
}
}
} catch (Exception e)
{
// Could provide a more explicit error message for IOException or IllegalStateException
getRequest.abort();
Log.d("Error while retrieving bitmap from " + url, e.toString());
} finally
{
if (client != null)
{
client.close();
}
}
return bitmap;
}
public class ViewHolder
{
public TextView tvTitle, tvDesc, tvDate;
private ImageView imgView;
private ProgressBar pbar;
}
}
and the main class is :
class MainActivity
public class MainActivity extends Activity implements OnItemClickListener
{
private static final String rssFeed = /*"https://www.dropbox.com/s/t4o5wo6gdcnhgj8/imagelistview.xml?dl=1"*/"http://78.46.34.27/kapapps/newparsedtransaction.xml";
List<Item> arrayOfList;
ListView listView;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.mainnewtransaction);
listView = (ListView) findViewById(R.id.listview);
listView.setOnItemClickListener(this);
if (Utils.isNetworkAvailable(NewTransactionActivity.this))
{
new MyTask().execute(rssFeed);
} else
{
showToast("No Network Connection!!!");
}
}
// My AsyncTask start...
class MyTask extends AsyncTask<String, Void, Void>
{
ProgressDialog pDialog;
#Override
protected void onPreExecute()
{
super.onPreExecute();
pDialog = new ProgressDialog(NewTransactionActivity.this);
pDialog.setTitle("Latest Transaction");
pDialog.setMessage("Loading... Please wait");
pDialog.show();
}
#Override
protected Void doInBackground(String... params)
{
arrayOfList = new NamesParser().getData(params[0]);
return null;
}
#Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
if (null == arrayOfList || arrayOfList.size() == 0)
{
showToast("No data found from web!!!");
NewTransactionActivity.this.finish();
} else
{
// check data...
/*
* for (int i = 0; i < arrayOfList.size(); i++)
* {
* Item item = arrayOfList.get(i); System.out.println(item.getId());
* System.out.println(item.getTitle());
* System.out.println(item.getDesc());
* System.out.println(item.getPubdate());
* System.out.println(item.getLink());
* }
*/
for(int i = 0 ; i < arrayOfList.size() ; i++)
{
Item item = arrayOfList.get(i);
Log.d("ID NEWTRANSACTION ACTIVITY ------>" , item.getId());
Log.d("TITLE NEWTRANSACTION ACTIVITY ------>" , item.getTitle());
Log.d("DESC NEWTRANSACTION ACTIVITY ------>", item.getDesc());
Log.d("LINK NEWTRANSACTION ACTIVITY ------>", item.getLink());
}
setAdapterToListview();
}
if (null != pDialog && pDialog.isShowing())
{
pDialog.dismiss();
}
}
}
#Override
public void onItemClick(AdapterView<?> parent , View view , int position , long id)
{
Item item = arrayOfList.get(position);
Intent intent = new Intent(NewTransactionActivity.this, DetailActivity.class);
intent.putExtra("url", item.getLink());
intent.putExtra("title", item.getTitle());
intent.putExtra("desc", item.getDesc());
Log.d("IMAGE_URL------>" , item.getLink());
startActivity(intent);
}
public void setAdapterToListview()
{
NewsRowAdapter objAdapter = new NewsRowAdapter(NewTransactionActivity.this , R.layout.row, arrayOfList);
listView.setAdapter(objAdapter);
}
public void showToast(String msg)
{
}
}
Do Image retrieving logic in another thread.It is taking too much time to load Images that's why you are getting ANR.
Use a single worker thread, and make it possible to stop in onPause() of activity.
Good way is to use a SingleThread Executor service to load images.
Here's an example https://stackoverflow.com/a/14579365/1366471
I recommend using the RemoteImageView from the Prime library. It reduces your work a lot.
In your layout, replace ImageView with com.handlerexploit.prime.widgets.RemoteImageView and in your code, change ImageView to RemoteImageView in your holder class.
In the getView method,
holder.imgView = (RemoteImageView) view.findViewById(R.id.image);
//...
holder.imgView.setImageURL(objBean.getLink());
I have grid containing images. On click of images, downloading of book starts. If the download is in progress and if i am clicking that image only the download getting started. Due to this the resultant file is corrupted. The downloading task has been put on the onClick event of image. I have tried to make first image clickable false then setEnable false. but both the way didn't work for me. The image click is working even download is in progress. Please guide.
For details,Here is my codes:
public class GridViewAdapter extends BaseAdapter {
ImageView imageView;
private Context context;
private int item;
private LayoutInflater layoutInflater;
GridViewAdapter(Context c, int griditem) {
this.context = c;
this.item = griditem;
this.layoutInflater = (LayoutInflater) c
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return bank.size();
}
#Override
public Object getItem(int position) {
return bank.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup arg2) {
View grid;
Display display = ((WindowManager) context
.getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
int orientation = display.getOrientation();
if (convertView == null) {
grid = new View(context);
grid = layoutInflater.inflate(item, null);
} else {
grid = (View) convertView;
}
final TextView title = (TextView) grid.findViewById(R.id.mgntitle);
title.setText(bank.get(position).getTitle());
imageView = (ImageView) grid.findViewById(R.id.thumbnail);
imageView.setImageResource(R.drawable.icon);
final ProgressBar progress = (ProgressBar) grid
.findViewById(R.id.progress);
final ImageView downloadmark = (ImageView) grid
.findViewById(R.id.downloadmark);
String pdfLink = bank.get(position).getPdfLink();
String filename = pdfLink.substring(pdfLink.lastIndexOf("/") + 1);
final File targetDir = new File(fileLocation + filename);
if(targetDir.exists()){
downloadmark.setVisibility(View.VISIBLE);
}
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!targetDir.exists()) {
if (isInternetConnected()) {
map.put(bank.get(position).getTitle(), progress);
new DownloadPdfFile(GridDisplayActivity.this, bank
.get(position).getPdfLink(), progress,
downloadmark, imageView).execute();
} else {
setAlertBox("You are not connected to Internet. Please switch your connection ON to be able to Downlaod Bespoken Magazines");
}
} else {
Toast.makeText(context, "File exists",
Toast.LENGTH_LONG).show();
// Book opening intent has to be fried here
}
}
});
imageView.setImageBitmap(BitmapFactory.decodeByteArray(
bank.get(position).getCoverPages(), 0, bank.get(position)
.getCoverPages().length));
if (!getPrefName(filename).equalsIgnoreCase("NA")) {
if (new File(fileLocation + filename).exists()) {
// tag.setImageResource(R.drawable.bookmark);
downloadmark.setVisibility(View.VISIBLE);
} else {
SharedPreferences pref = getApplicationContext()
.getSharedPreferences("BESPOKEN_PREF",
MODE_WORLD_WRITEABLE);
SharedPreferences.Editor editor = pref.edit();
editor.putString(filename, "NA");
editor.commit();
}
}
if (new File(fileLocation + filename).exists()) {
if (!getPrefName(filename).equalsIgnoreCase("NA")) {
// tag.setImageResource(R.drawable.bookmark);
// downloadmark.setVisibility(View.VISIBLE);
} else {
}
}
return grid;
}
}
private String getPrefName(String name) {
SharedPreferences pref = this.getSharedPreferences("BESPOKEN_PREF",
MODE_WORLD_WRITEABLE);
return pref.getString(name, "NA");
}
private void saveBookName(String title) {
SharedPreferences pref = this.getSharedPreferences("BESPOKEN_PREF",
MODE_WORLD_WRITEABLE);
SharedPreferences.Editor editor = pref.edit();
editor.putString(title, title);
editor.commit();
}
private boolean isInternetConnected() {
connManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
mMobile = connManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
return mWifi.isConnected() || mMobile.isConnected();
}
private class DownloadPdfFile extends AsyncTask<Void, Integer, Void> {
private int progressupdate;
String link;
ProgressBar progress;
ImageView cover;
String file;
ImageView dwnloadmark;
public DownloadPdfFile(GridDisplayActivity activity, String link,
ProgressBar progressbar, ImageView dwnmrk, ImageView imageView) {
imageView.setEnabled(false);
progress = progressbar;
this.link = link;
this.cover = imageView;
this.dwnloadmark = dwnmrk;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
cover.setEnabled(false);
progress.setVisibility(View.VISIBLE);
}
#Override
protected Void doInBackground(Void... params) {
file = link.substring(link.lastIndexOf("/") + 1);
InputStream is = null;
long startTime = 0;
int count;
// DownloadFromUrl(link, fileLocation + file,progress);
try {
URL url = new URL(link);
File dir = new File(fileLocation);
if (dir.exists()) {
} else {
Log.i("",
"---------targetDir not .exists()----------------4");
dir.mkdirs();
}
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
Log.d("ANDRO_ASYNC", "Lenght of file: " + lenghtOfFile);
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(fileLocation + file);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress((int) ((total * 100) / lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (IOException e) {
e.printStackTrace();
}
Log.d("ImageManager",
"download ready in"
+ ((System.currentTimeMillis() - startTime) / 1000)
+ " sec");
return null;
}
#Override
protected void onProgressUpdate(Integer... prog) {
progressupdate = prog[0];
progress.setProgress(progressupdate);
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
dwnloadmark.setVisibility(View.VISIBLE);
// tag.setImageResource(R.drawable.bookmark);
progress.setVisibility(View.INVISIBLE);
saveBookName(file);
cover.setEnabled(true);
}
}
class DoBackgroundTask extends CustomAsyncTask<Void, Integer, Void> {
private static final String TAG = "DoBackgroundTask";
private int progressupdate;
String link;
private ProgressBar progress;
ImageView dwnloadmark;
ImageView cover;
String file;
GridDisplayActivity activity;
public DoBackgroundTask(GridDisplayActivity activity, String link,
ProgressBar progressbar, ImageView dwnmrk, ImageView img) {
super(activity);
img.setEnabled(false);
this.activity = activity;
progress = progressbar;
this.link = link;
this.dwnloadmark = dwnmrk;
this.cover = img;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
cover.setEnabled(false);
progress.setVisibility(View.VISIBLE);
}
#Override
protected void onActivityDetached() {
if (progress != null) {
//progress.setActivated(false);
// progress = null;
}
}
#Override
protected void onActivityAttached() {
//progress.setActivated(true);
progress.setVisibility(View.VISIBLE);
progress.setProgress(progressupdate);
// showProgressDialog();
}
#Override
protected Void doInBackground(Void... params) {
file = link.substring(link.lastIndexOf("/") + 1);
InputStream is = null;
long startTime = 0;
int count;
// DownloadFromUrl(link, fileLocation + file,progress);
try {
URL url = new URL(link);
File dir = new File(fileLocation);
if (dir.exists()) {
} else {
dir.mkdirs();
}
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
Log.d("ANDRO_ASYNC", "Lenght of file: " + lenghtOfFile);
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(fileLocation + file);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress((int) ((total * 100) / lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (IOException e) {
e.printStackTrace();
}
Log.d("ImageManager",
"download ready in"
+ ((System.currentTimeMillis() - startTime) / 1000)
+ " sec");
return null;
}
#Override
protected void onProgressUpdate(Integer... prog) {
progressupdate = prog[0];
if (mActivity != null) {
progress.setProgress(progressupdate);
} else {
Log.d(TAG, "Progress updated while no Activity was attached.");
}
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
dwnloadmark.setVisibility(View.VISIBLE);
cover.setEnabled(true);
saveBookName(file);
if (mActivity != null) {
progress.setVisibility(View.INVISIBLE);
Toast.makeText(mActivity, "AsyncTask finished",
Toast.LENGTH_LONG).show();
} else {
}
}
}
public class GridViewAdapter extends BaseAdapter {
private boolean _buttonPressed = false;
.....
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(_buttonPressed){
return;
}
_buttonPressed = true;
.........
.....
private class DownloadPdfFile extends AsyncTask<....> {
.....
#Override
protected void onPostExecute(....) {
_buttonPressed = false;
}
.....
}
}