2016-08-26 13 views
0

私は曲をダウンロードするアプリケーションを作成しています。私のアプリケーションでは、曲のリストを含むRecyclerViewがあり、すべての曲にはダウンロードの進行状況を示すSeekBarがあります。私がダウンロードボタンを押すとうまくいきますが、それは間違ってSeekBarを更新します。私は特定の位置で特定のSeekBarを更新したいと思います。ここでRecyclerViewのための私のアダプタは次のとおりです。これを実現する方法についてRecyclerView内の特定の位置でSeekBarを更新します。

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="horizontal" 
    android:padding="10dp"> 

    <LinearLayout 
     android:id="@+id/LinearLayout" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"> 

     <TextView 
      android:id="@+id/downloadLink" 
      android:layout_width="0dp" 
      android:layout_height="wrap_content" 
      android:layout_weight="1" 
      android:padding="10dp" /> 

     <TextView 
      android:id="@+id/downloadButton" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:background="@drawable/custom_button" 
      android:text="DOWNLOAD" 
      android:textSize="15sp" /> 

     <TextView 
      android:id="@+id/playButton" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_marginLeft="5dp" 
      android:background="@drawable/custom_button" 
      android:text="PLAY" 
      android:textSize="15sp" 
      android:visibility="gone" /> 
    </LinearLayout> 

    <SeekBar 
     android:id="@+id/downloadProgress" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_below="@+id/LinearLayout" 
     android:layout_marginTop="10dp" /> 
</RelativeLayout> 

任意の提案:

@Override 
    public SongListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 

     itemViewLayout = LayoutInflater.from(parent.getContext()).inflate(R.layout.song_list_single_list, null); 
     holder = new ViewHolder(itemViewLayout); 
     return holder; 
    } 

    @Override 
    public void onBindViewHolder(SongListAdapter.ViewHolder holder, final int position) { 
     mSongListModel = mSongListArray.get(position); 
     holder.downloadLink.setText(mSongListModel.getDownloadLink()); 
     holder.downloadButton.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       new DownloadFileAsync().execute(String.valueOf(position)); 
      } 
     }); 
    } 

    @Override 
    public int getItemCount() { 
     return mSongListArray.size(); 
    } 

    @Override 
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 
     if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
      System.out.println("Permission: " + permissions[0] + "was " + grantResults[0]); 
      //resume tasks needing this permission 
      //downloadStreamingAudio(); 
     } 
    } 

    public class ViewHolder extends RecyclerView.ViewHolder { 

     private TextView downloadLink; 
     private SeekBar downloadProgress; 
     private TextView downloadButton; 

     public ViewHolder(View itemView) { 
      super(itemView); 
      downloadLink = (TextView) itemView.findViewById(R.id.downloadLink); 
      downloadButton = (TextView) itemView.findViewById(R.id.downloadButton); 
      downloadProgress = (SeekBar) itemViewLayout.findViewById(R.id.downloadProgress); 
     } 
    } 

    class DownloadFileAsync extends AsyncTask<String, String, String> { 
     ProgressDialog pDialog; 
     Uri uri; 
     String timeStamp; 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      pDialog = new ProgressDialog(c); 
      pDialog.setMessage("Downlaoding Audio..."); 
      pDialog.setCancelable(true); 
      pDialog.show(); 
     } 

     @Override 
     protected String doInBackground(String... params) { 

      try { 
       if (isStoragePermissionGranted()) { 
        File root = Environment.getExternalStorageDirectory(); 

        File dir = new File(root.getAbsolutePath() + "/AppDownloads/"); 

        timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
        System.out.println("Time Stamp::----" + timeStamp); 

        try { 
         if (dir.exists() == false) { 
          dir.mkdirs(); 
         } 

         RootFile = new File(dir, timeStamp + ".mp3"); 

        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
       } 

       InputStream input = null; 
       OutputStream output = null; 
       HttpURLConnection connection = null; 
       int count; 

       System.out.println("DownloadUrl::::----"+mSongListArray.get(Integer.parseInt(params[0])).getDownloadLink()); 
       URL url = new URL(mSongListArray.get(Integer.parseInt(params[0])).getDownloadLink()); 
       connection = (HttpURLConnection) url.openConnection(); 
       connection.connect(); 
       // this will be useful so that you can show a tipical 0-100% progress bar 
       int lenghtOfFile = connection.getContentLength(); 

       // downlod the file 
       input = new BufferedInputStream(url.openStream()); 
       output = new FileOutputStream(RootFile); 

       byte data[] = new byte[1024]; 

       long total = 0; 

       while ((count = input.read(data)) != -1) { 
        total += count; 
        // publishing the progress.... 
        //publishProgress((int)(total*100/lenghtOfFile)); 
        updateDownloadProgress((int) (total * 100/lenghtOfFile)); 
        output.write(data, 0, count); 
       } 

       output.flush(); 
       output.close(); 
       input.close(); 

      } catch (Exception e) 

      { 

       Log.d("Error....", e.toString()); 
      } 

      return null; 
     } 

     @Override 
     protected void onPostExecute(String s) { 
      super.onPostExecute(s); 
      if (pDialog.isShowing()) 

       pDialog.dismiss(); 

      Toast.makeText(c, "Download Complete", Toast.LENGTH_LONG).show(); 
     } 
    } 

    public boolean isStoragePermissionGranted() { 
     if (Build.VERSION.SDK_INT >= 23) { 
      if (c.checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) 
        == PackageManager.PERMISSION_GRANTED) { 
       System.out.println("Permission is granted"); 
       return true; 
      } else { 

       System.out.println("Permission is revoked"); 
       ActivityCompat.requestPermissions((Activity) c, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); 
       return false; 
      } 
     } else { 
      System.out.println("Permission is granted"); 
      return true; 
     } 
    } 

    private void updateDownloadProgress(int progress) { 
     holder.downloadProgress.setProgress(progress); 

    } 

ここRecyclerViewのための私のレイアウトファイルはありますか?

+0

と更新されシークバー? –

+0

ランダム....しかしほとんど最後のもの – AbhayBohra

+0

多分問題はupdateDownloadProgressにあります。ホルダーの進行状況バーを更新して特定のアイテムではなく、ホルダー内の特定のアイテムを更新しようとします。 –

答えて

1

あなたのプログラムは緊密に結合されています。プログラムを3つの区に分割することをお勧めします。 電話でnotifyItemChangedonProgressUpdated

以下のコードは例です。このような

RecyclerView.Adapter:このような

public class SongListAdapter extends RecyclerView.Adapter<SongListAdapter.ViewHolder> { 
    ... 

    private final Listener mListener; 
    private final Map<Integer, Integer> progressMap = new HashMap<>(); 

    ... 

    interface Listener { 
     void onClickDownload(int position, SongListModel songListModel); 
    } 

    public SongListAdapter(Listener listener) { 
     mListener = listener; 
    } 

    @Override 
    public void onBindViewHolder(SongListAdapter.ViewHolder holder, final int position) { 
     ... 
     int progress = progressMap.containsKey(position) ? progressMap.get(position) : 0; 
     holder.downloadProgress.setProgress(progress); 
     holder.downloadButton.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       SongListModel songListModel = mSongListArray.get(position); 
       mListener.onClickDownload(position, songListModel); 
      } 
     }); 
    } 
    ... 

    public void setProgress(int position, int progress) { 
     progressMap.put(position, progress); 
    } 
    ... 
} 

DownloadFileAsync:このような

public class DownloadFileAsync extends AsyncTask<String, String, String> { 

    ... 
    private final Callback mCallback; 
    private final int mPosition; 
    private final SongListModel mSongListModel; 

    interface Callback { 
     void onDownloadStarting(); 
     void onProgressUpdated(int progress, int position, SongListModel songListModel); 
     void onDownloadCompleted(); 
    } 

    public DownloadFileAsync(Callback callback, int position, SongListModel songListModel) { 
     mCallback = callback; 
     mPosition = position; 
     mSongListModel = songListModel; 
    } 

    @Override 
    protected void onPreExecute() { 
     mCallback.onDownloadStarting(); 
    } 

    @Override 
    protected String doInBackground(String... params) { 
     try { 
      ... 
      while ((count = input.read(data)) != -1) { 
       ... 
       mCallback.onProgressUpdated((int) (total * 100/lenghtOfFile), mPosition, mSongListModel); 
       ... 
       if (isCancelled()) { 
        break; 
       } 
      } 
      ... 
     } 
     return null; 
    } 

    ... 

    @Override 
    protected void onPostExecute(String s) { 
     mCallback.onDownloadCompleted(s); 
    } 
} 

活動:

public class MainActivity extends AppCompatActivity 
     implements SongListAdapter.Listener, DownloadFileAsync.Callback { 
    ... 

    private RecyclerView mRecyclerView; 
    private SongListAdapter mAdapter; 
    private DownloadFileAsync mDownloadFileAsync; 
    private ProgressDialog pDialog; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     ... 
     mRecyclerView = (RecyclerView)findViewById(...); 
     mAdapter = new SongListAdapter(this); 
     mRecyclerView.setAdapter(adapter); 
     ... 
    } 

    @Override 
    public void onClickDownload(int position, SongListModel songListModel) { 
     if (mDownloadFileAsync != null) { 
      //TODO currentry downloading. Insert error handing. 
      return; 
     } 

     mDownloadFileAsync = new DownloadFileAsync(this, position, songListModel); 
     mDownloadFileAsync.execute(); 
    } 


    @Override 
    public void onDownloadStarting() { 
     pDialog = new ProgressDialog(this); 
     pDialog.setMessage("Downlaoding Audio..."); 
     pDialog.setCancelable(true); 
     pDialog.show(); 
    } 

    @Override 
    public void onProgressUpdated(int progress, int position, SongListModel songListModel) { 
     mAdapter.setProgress(position, progress); 

     SongListAdapter.ViewHolder holder = mRecyclerView.findViewHolderForAdapterPosition(position); 
     if (holder != null) { 
      holder.downloadProgress.setProgress(progress); 
     } 
    } 

    @Override 
    public void onDownloadCompleted(String s) { 
     mDownloadFileAsync = null; 
     if (pDialog.isShowing()) { 
      pDialog.dismiss(); 
     } 
     Toast.makeText(this, "Download Complete", Toast.LENGTH_LONG).show(); 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 

     // If you want to stop downloading when activity is closing, call cancel method. 
     if (mDownloadFileAsync != null) { 
      mDownloadFileAsync.cancel(true); 
     } 
    } 

    ... 
} 
+0

それは動作しますが、スクロール時にUIシバリングを行います。 – AbhayBohra

+1

ああ、そうです。私は自分の答えを更新しました。 'MainActivity。onProgressUpdated'などが更新されました。 diffsを参照してくださいhttp://stackoverflow.com/posts/39165865/revisions @AbhayBohra – nshmura

+0

ありがとう...今それは正常に動作します – AbhayBohra

0

ホルダー=新しいViewHolder(itemViewLayout);

最後に作成したホルダーを、進行状況を更新するホルダーとして割り当てます。代わりにグローバル変数をホルダーとして使用しないでください。

ホルダーをonBindViewHolder()finalにします。

あなたのAsyncTaskは、この所有者への参照も取得する必要があります。 AsyncTask内にHolder変数を作成し、そのホルダをonBindViewHolder()にバインドされたものに設定することもできます。

実行コードは次のようになります。

DownloadFileAsync task = new DownloadFileAsync(String.valueOf(position)); 
task.setHolder(holder); 
task.execute(); 

幸運。

関連する問題