2016-03-20 57 views
0

我正在使用AsyncTask製作一個列表視圖下載器。我想在下載過程中在我的列表視圖中顯示進度欄百分比,但是我的百分比並沒有增加。我知道鋤頭在進度對話框中顯示百分比,但我不知道如何在列表視圖中更新。這裏是我的代碼:在Android ListView中下載過程中增加進度百分比

FileDownloadTask.java

public class FileDownloadTask extends AsyncTask<String, Integer, String> { 
    private static final String TAG = FileDownloadTask.class.getSimpleName(); 
    final DownloadInfo mInfo; 
    public int progress; 

    public FileDownloadTask(DownloadInfo info) { 
     mInfo = info; 
    } 

    @Override 
    protected void onProgressUpdate(Integer... values) { 
     mInfo.setProgress(values[0]); 
     mInfo.setFilePercent(values[0]); 
     ProgressBar bar = mInfo.getProgressBar(); 

     if(bar != null) { 
      bar.setProgress(mInfo.getProgress()); 

     } 

    } 

    @Override 

    protected String doInBackground(String... f_url) { 
     int count; 
     try { 
      String root = Environment.getExternalStorageDirectory().toString(); 

      System.out.println("Downloading"); 
      URL url = new URL(mInfo.getFileUrl()); 

      URLConnection conection = url.openConnection(); 
      conection.connect(); 
      // getting file length 
      int lenghtOfFile = conection.getContentLength(); 

      // input stream to read file - with 8k buffer 

      // Output stream to write file 
      File rootdirectory= new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES),"Youtube Videos"); 
       if(!rootdirectory.exists()) 
       { 
        rootdirectory.mkdirs(); 
       } 
      String nameoffile= URLUtil.guessFileName(mInfo.getFileUrl(),null, MimeTypeMap.getFileExtensionFromUrl(mInfo.getFileUrl())); 
      File file= new File(rootdirectory,nameoffile); 
      file.createNewFile(); 



      mInfo.setDownloadState(DownloadState.DOWNLOADING); 
      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; 
       progress= (int)((total*1001)/lenghtOfFile); 
       publishProgress(progress); 

       mInfo.setFilePercent(progress); 

       // writing data to file 
       output.write(data, 0, count); 

      } 

      // flushing output 
      output.flush(); 

      // closing streams 
      output.close(); 
      input.close(); 

     } catch (Exception e) { 
      Log.e("Error: ", e.getMessage()); 
     } 
     mInfo.setDownloadState(DownloadState.COMPLETE); 
     return null; 
    } 






    protected void onPostExecute(String file_url) { 
     mInfo.setDownloadState(DownloadState.COMPLETE); 
     // String imagePath = Environment.getExternalStorageDirectory().toString() + "/downloadedfile.mp4"; 
    } 

    @Override 
    protected void onPreExecute() { 
     mInfo.setDownloadState(DownloadState.DOWNLOADING); 
    } 


} 

DownloadInfoArrayAdapter.Java

public class DownloadInfoArrayAdapter extends ArrayAdapter<DownloadInfo> { 
    // Simple class to make it so that we don't have to call findViewById frequently 

    public static Integer result; 
    private static class ViewHolder { 
     TextView textView; 
     ProgressBar progressBar; 
     Button button; 
     DownloadInfo info; 
     TextView size; 
     TextView prog; 
    } 


    private static final String TAG = DownloadInfoArrayAdapter.class.getSimpleName(); 

    public DownloadInfoArrayAdapter(Context context, int textViewResourceId, 
            List<DownloadInfo> objects) { 
     super(context, textViewResourceId, objects); 

    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     View row = convertView; 
     final DownloadInfo info = getItem(position); 
     // SignInAsyntask task1 = new SignInAsyntask(info); 
     //task1.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 
     //new SignInAsyntask().execute(); 
     // We need to set the convertView's progressBar to null. 

     ViewHolder holder = null; 

     if(null == row) { 
      LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      row = inflater.inflate(R.layout.file_download_row, parent, false); 

      holder = new ViewHolder(); 
      holder.textView = (TextView) row.findViewById(R.id.downloadFileName); 
      holder.progressBar = (ProgressBar) row.findViewById(R.id.downloadProgressBar); 
      holder.size=(TextView) row.findViewById(R.id.downloadFileSize); 
      holder.prog=(TextView) row.findViewById(R.id.downloadFileProgress); 
      holder.button = (Button)row.findViewById(R.id.downloadButton); 
      holder.info = info; 

      row.setTag(holder); 
     } else { 
      holder = (ViewHolder) row.getTag(); 

      holder.info.setProgressBar(null); 
      holder.info = info; 
      holder.info.setProgressBar(holder.progressBar); 
      holder.info.setProgress(null); 
      holder.info = info; 
      // holder.info.setProgress(holder.prog); 
     } 

     holder.textView.setText(info.getFilename()); 
     holder.progressBar.setProgress(info.getProgress()); 
     holder.progressBar.setMax(info.getFileSize()); 
     holder.prog.setText(info.getFilePercent() + "/100"); 
     holder.size.setText(info.getFileSize() + "MB"); 

     info.setProgressBar(holder.progressBar); 
     //info.setProgress(holder.prog); 

     holder.button.setEnabled(info.getDownloadState() == DownloadState.NOT_STARTED); 
     final Button button = holder.button; 
     holder.button.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       info.setDownloadState(DownloadState.QUEUED); 
       button.setEnabled(false); 
       button.invalidate(); 
       FileDownloadTask task = new FileDownloadTask(info); 
       task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 
      } 
     }); 


     //TODO: When reusing a view, invalidate the current progressBar. 

     return row; 
    } 
} 

請幫助!

回答

0

而是構造試圖通過doInbackground參數

FileDownloadTask task = new FileDownloadTask().execute(DownloadInfo info); 

@Override 
protected String doInBackground(DownloadInfo... params) { 
    info = params[0]; 
.. 

} 
0

的技巧來傳遞數據:不要試圖在視圖中直接設置任何東西。相反,更改數據,調用ArrayAdapter上的notifyDataSetChanged(),並允許它更改視圖。例如,

@Override 
protected void onProgressUpdate(Integer... values) { 
    mInfo.setProgress(values[0]); 
    mInfo.setFilePercent(values[0]); 

    adapter.notifyDataSetChanged(); 
} 

凡適配器要麼是你的適配器的情況下,或者回調到適配器的活動,這將隨後轉發更新消息適配器,這與當時打電話給你重寫getView(INT,查看,Viewgroup)方法並正確顯示更新的數據(我是後者的粉絲)。

(這也假設你明覆的實例是同一個實例通過適配器支持的,當然。)

編輯:只是一個後心想:你可能還需要確保只有單個實例的一個項目的下載器一次正在運行,因爲如果您繼續點擊,目前您將啓動多個不同的下載器,這可能會給您帶來一些問題。乾杯〜

+0

只要我在onProgressUpdate或doinBackground()中寫adapter.notifyDataSetChanged(),應用程序就會崩潰。 –

+0

有什麼樣的錯誤?如果是NullPointerException,那麼適配器的引用可能是null,或者適配器的重寫getView()方法有問題 – Guardanis