Pra*_*tye 10 android android-recyclerview
我有一个RecyclerView.其中,项目具有标准布局 - 一个TextView和一个ProgressBar.项目在运行时添加到recyclerview.每当添加一个Item时,都会启动一个更新ProgressBar的AsyncTask.AsynTask保存了RecyclerView Adapter对ProgressBar对象的引用.当回收器视图中的项目太多时,会发生此问题.
我知道RecyclerView会回收任何旧视图,因此想要了解至少进度条的方法.
实现这个的理想方法是什么?
以下是适配器的摘录
public class RecViewAdapter extends
RecyclerView.Adapter<RecViewAdapter.ViewHolder> {
Context mContext;
List<String> mRunns;
static ExecutorService mExec;
static HashSet<Integer> mProcessed = new HashSet<>();
public RecViewAdapter(Context context, List<String> runns) {
mContext = context;
mRunns = runns;
mExec = Executors.newFixedThreadPool(1);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.runnabel_item, viewGroup,
false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.runnName.setText(mRunns.get(position));
if (!mProcessed.contains(position)) {
new ProgressTask(holder.pBar, position).executeOnExecutor(mExec, null);
mProcessed.add(position);
}
}
@Override
public int getItemCount() {
return mRunns.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView runnName;
ProgressBar pBar;
public ViewHolder(View view) {
super(view);
runnName = (TextView) view.findViewById(R.id.textView);
pBar = (ProgressBar) view.findViewById(R.id.progressBar);
pBar.setIndeterminate(false);
pBar.setMax(100);
pBar.setProgress(0);
}
}
}
Run Code Online (Sandbox Code Playgroud)
另外,我使用notifydatasetchanged将项目添加到RecyclerView.
您可以简单地使用回收器视图的“findViewHolderForAdapterPosition”方法,您将从中获得一个 viewHolder 对象,然后将该 viewHolder 类型转换为您的适配器视图,这样您就可以直接访问您的视图持有者的视图,(在这种情况下,我们访问 progressBar)
以下是 kotlin 的示例代码
/**
* update progress bar in recycler view
* get viewHolder from position and progress bar from that viewHolder
* we are rapidly updating progressbar so we did't use notify method as it always update whole row instead of only progress bar
* @param position : position of list cell
* @param progress : new progress value
*/
private fun updateDownloadProgressBar(position :Int, progress:Int)
{
val viewHolder = recyclerViewDownload.findViewHolderForAdapterPosition(position)
(viewHolder as ViewHolderDownload).progressBarDownload.progress=progress
}
Run Code Online (Sandbox Code Playgroud)
有点晚了,但我找到了一种让它发挥作用的方法。
我的 recyclerview 包含大量视图持有者,并且只有一个视图持有者有进度条。我有一个 sqlite 数据库,在其中维护标识符,用于在服务和活动之间同步(以识别 recyclerview 中的哪些视图需要更新)。
根据您的实现,您必须找到一种方法来识别哪个广播事件对应于哪个适配器项。我在下面给出了我所做工作的简化版本。
进度条模型:
class ProgressModel{
String progressId;
int progress = 0;
}
public int getProgress(){
return progress;
}
Run Code Online (Sandbox Code Playgroud)
视图持有者:
public class ProgressViewHolder extends RecyclerView.ViewHolder {
private ProgressBar mProgressBar;
public ProgressViewHolder(View itemView) {
mProgressBar = (ProgressBar) itemView.findViewById(R.id.mProgressBar);
}
public ProgressBar getProgressBar() {
return mProgressBar;
}
}
Run Code Online (Sandbox Code Playgroud)
在recyclerview适配器中,
@Override
public void onBindViewHolder(ProgressViewHolder holder, int position) {
ProgressModel item = mData.get(position);
int progress = item.getProgress();
if (progress > 0) {
ProgressBar downloadProgress = holder.getProgressBar();
if (downloadProgress.isIndeterminate()) {
downloadProgress.setIndeterminate(false);
}
downloadProgress.setProgress(progress);
}
}
public void refresh(position, ProgressModel item){
mData.set(position, item);
notifyItemChanged(position);
}
Run Code Online (Sandbox Code Playgroud)
在实现填充视图的 Activity 中,创建其自身的静态实例并将其传递给 BroadcastReceiver。我花了很长时间才弄清楚静态实例是必需的,否则即使我调用notifyItemchanged(),视图也不会改变。
public class MainActivity extends Activity{
private static MainActivity instance;
private MyReceiver mReceiver;
private MyAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
instance = this;
mReceiver = new MyReceiver(instance);
//TODO: Initialize adapter with data and set to recyclerview
}
public void update(Intent intent){
ProgressModel model = new ProgressModel ();
//TODO: set progress detail from intent to model and get position from progressId
instance.mAdapter.refresh(position,model);
}
private static class MyReceiver extends BroadcastReceiver {
MainActivity activity;
public DownloadReceiver(MainActivity activity) {
this.activity = activity;
}
@Override
public void onReceive(Context context, Intent intent) {
//pass intent with progress details to activity
activity.update(intent);
}
}
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助。
| 归档时间: |
|
| 查看次数: |
11069 次 |
| 最近记录: |