Android: Modifica l'image di un particolare elemento in listview

immagine dello schermo

Nell'image sopra esiste una list che contiene l'elenco di elementi che l'utente può scaricare. pulsante di download Questa è l'image che dice all'utente che può scaricare il file. Al termine del download, l'image cambierà scarica il pulsante completato . Il mio problema è quando scarica un file, l'image di stato (che indica che il download è stato completato) viene modificata per un'altra row, invece dovrebbe cambiare per la row che avevo selezionato. Al momento, se scarica il primo file nell'elenco, l'image viene modificata per la quarta o la quinta voce dell'elenco. Inoltre, quando provo a scaricare qualsiasi altro file dall'elenco. apre l'ultimo file scaricato (questa è la funzionalità dell'applicazione che se il file è già scaricato, quindi apriamola in lettore pdf), cioè, se scarica il primo file nell'elenco e poi vai per il secondo elemento, quindi invece di scaricare il secondo file, apre l'ultimo file scaricato. Inoltre, se scorri la list, lo stato del download viene modificato anche per altri elementi dell'elenco. Di seguito, è il mio codice dell'adattatore:

  • L'animation ActionBarSherlock muove la posizione
  • Regole di proguard della biblioteca di supporto di progettazione di Android
  • Come avviare un'applicazione android con valgrind
  • Android Studio - Monitor Android Device - Vista vuota
  • ClassNotFoundException: Non trovato la class sul path: DexPathList
  • Recupero di JSON da URL su Android
  • 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 

    Ho letto questo post per riciclare la vista (grazie a Knickedi per spiegazione approfondita). Ma non riesco a capire where sia il problema reale.

  • ListView non mostra valori corretti dopo lo scorrimento
  • ListView - getView viene chiamato troppe volte
  • Android utilizza sempre "tinyALSA"?
  • Cosa c'è di diverso tra SambaFileInputStream e FileInputStream?
  • Come posso get i dati grezzi GPS (pseudo gamma dei satelliti)?
  • Utilizzo di BroadcastReceiver con funzionalità di PhoneStateListener
  • One Solution collect form web for “Android: Modifica l'image di un particolare elemento in listview”

    Problema con il metodo getview che continua a ricreare each volta che scorri la visualizzazione, per gestire la posizione esatta che devi giocare con setTag & getTag , controlla sotto alcune risposte stackvoerflow per comprendere setTag & getTag :

    Pulsante in ListView utilizzando ArrayAdapter

    Ottenere il valore del button di selezione dall'elenco personalizzato in android

    e anche memorizzare lo stato scaricato in un booleanarrays come sotto:

     int boxState[]; 

    all'interno del constructor di adattatore, impostare inizialmente zero:

     for (int i = 0; i < getData.size(); i++) { boxState[i] = 0; } 

    all'interno del metodo getview per l'adattatore:

     holder.imgDownload.setTag(position); 

    Ora si fa clic sul valore impostato per il button di download come 1 (button interno di button):

     pos = (Integer) v.getTag(); boxState[pos]=1; 

    Infine quando scorri la condizione di controllo della visualizzazione nel modo seguente (inserisci il codice sotto il metodo getview):

     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. } 
    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.