在RecyclerView中的特定位置更新SeekBar [英] Update SeekBar at particular position within a RecyclerView
问题描述
我正在创建一个用于下载歌曲的应用程序.在我的应用程序中,有一个RecyclerView
带有歌曲列表,每首歌曲下方都有一个SeekBar
,它显示了下载进度.当我按下下载按钮时,它可以正常工作,但是会更新错误的SeekBar
.我想在特定位置更新特定的SeekBar
.这是我的RecyclerView
适配器:
I am creating an application for downloading songs. In my application, there is a RecyclerView
with a list of songs and with every song there is a SeekBar
below that shows the download progress. When I hit the download button, it works fine but it updates the wrong SeekBar
. I want to update a particular SeekBar
at a particular position. Here is my adapter for the RecyclerView
:
@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
的布局文件:
<?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>
关于如何实现这一目标的任何建议?
Any suggestions on how to achieve this?
推荐答案
您的程序是紧密耦合的.我建议您将程序分为3个阶段.
然后在onProgressUpdated
Your program is tightly-coupled. I recommend you to split program into 3 peaces.
And Call notifyItemChanged
at onProgressUpdated
下面的代码是示例.
RecyclerView.Adapter像这样:
RecyclerView.Adapter like this:
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:
DownloadFileAsync like this:
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);
}
}
...
}
这篇关于在RecyclerView中的特定位置更新SeekBar的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!