Android 从服务器提取数据后如何更新recyclerview?
如果我必须发送请求以获取Android 从服务器提取数据后如何更新recyclerview?,android,android-recyclerview,Android,Android Recyclerview,如果我必须发送请求以获取onBindViewHolder()中的数据,那么在数据从服务器返回后如何更新视图 我现在拥有的是缓存数据和行位置,以便下次用户滚动到该行时,我可以立即显示信息 但还有两个问题我不知道如何解决 我滚动列表以查看位置10、11和12处的项目。我决定等数据回来。我是否在之后调用notifyDataSetChanged()?因为数据返回时,onBindViewHolder已经被调用,视图将保持为空,但我也不认为在每次请求后调用notifyDataSetChanged()是个好主
onBindViewHolder()
中的数据,那么在数据从服务器返回后如何更新视图
我现在拥有的是缓存数据和行位置,以便下次用户滚动到该行时,我可以立即显示信息
但还有两个问题我不知道如何解决
notifyDataSetChanged()
?因为数据返回时,onBindViewHolder
已经被调用,视图将保持为空,但我也不认为在每次请求后调用notifyDataSetChanged()
是个好主意recyclerview
滚动的方式从服务器加载数据是一种不好的做法吗?但这样做会节省我很多时间,我想对用户来说也是这样吧?因为在后台加载其他数据时,用户可以看到部分数据,而不是提前发送所有请求
谢谢
已编辑
public class TestAdapter extends RecyclerView.Adapter<TestAdapter.ViewHolder> {
private Context ctx;
private ArrayList<Photo> alPhotos = new ArrayList<>();
private HashMap<String, Drawable> hmImages = new HashMap<>();
public TestAdapter(Context ctx, ArrayList<Photo> alPhotos) {
this.ctx = ctx;
this.alPhotos = alPhotos;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_photo_brief, parent, false));
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Photo photo = alPhotos.get(position);
loadRemoteImage(photo.IMG, holder.ivThumb, true);
holder.tvEmail.setText(photo.EMAIL);
}
@Override
public int getItemCount() {
return alPhotos.size();
}
private void loadRemoteImage(final String imgUrl, final ImageView view, final boolean cache) {
if (hmImages.containsKey(imgUrl)) {
view.setImageDrawable(hmImages.get(imgUrl));
} else {
final WeakReference<ImageView> weakView = new WeakReference<>(view);
RequestManager.getManager().add(new Request<>(imgUrl, new DrawableParser(), new RequestCallback<Drawable>() {
@Override
public void onFinished(Request<Drawable> request, Response<Drawable> response) {
if (cache) hmImages.put(imgUrl, response.result);
ImageView view = weakView.get();
if (view != null) {
view.setImageDrawable(response.result);
}
}
@Override
public void onError(Request<Drawable> request, Response<Drawable> response) {
}
@Override
public void onTimeout(Request<Drawable> request, Response<Drawable> response) {
}
})
);
}
}
public class ViewHolder extends RecyclerView.ViewHolder {
private ImageView ivThumb;
private TextView tvEmail;
public ViewHolder(View itemView) {
super(itemView);
findViews();
}
private void findViews() {
ivThumb = (ImageView) itemView.findViewById(R.id.ivThumb);
tvEmail = (TextView) itemView.findViewById(R.id.tvEmail);
}
}
}
公共类TestAdapter扩展了RecyclerView.Adapter{
私有上下文ctx;
私有ArrayList alPhotos=新ArrayList();
私有HashMap hmImages=新HashMap();
公共测试适配器(上下文ctx、ArrayList alPhotos){
this.ctx=ctx;
this.alPhotos=alPhotos;
}
@凌驾
public ViewHolder onCreateViewHolder(视图组父级,int-viewType){
返回新的ViewHolder(LayoutInflater.from(parent.getContext())。充气(R.layout.item_photo_brief,parent,false));
}
@凌驾
公共无效onBindViewHolder(ViewHolder,int位置){
Photo Photo=alPhotos.get(位置);
loadRemoteImage(photo.IMG,holder.ivThumb,true);
holder.tvEmail.setText(photo.EMAIL);
}
@凌驾
public int getItemCount(){
返回alPhotos.size();
}
私有void loadRemoteImage(最终字符串imgUrl、最终图像视图、最终布尔缓存){
if(hmImages.CONTANSKEY(imgUrl)){
view.setImageDrawable(hmImages.get(imgUrl));
}否则{
最终WeakReference weakView=新的WeakReference(视图);
添加(新请求(imgUrl,new DrawableParser(),new RequestCallback()){
@凌驾
public void onFinished(请求、响应){
if(缓存)hmImages.put(imgUrl,response.result);
ImageView=weakView.get();
如果(视图!=null){
view.setImageDrawable(response.result);
}
}
@凌驾
公共无效onError(请求、响应){
}
@凌驾
公共void onTimeout(请求、响应){
}
})
);
}
}
公共类ViewHolder扩展了RecyclerView.ViewHolder{
私人影像视图;
私人文本查看电视电子邮件;
公共视图持有者(视图项视图){
超级(项目视图);
FindView();
}
私有void findViews(){
ivThumb=(ImageView)itemView.findViewById(R.id.ivThumb);
TveEmail=(TextView)itemView.findViewById(R.id.TveEmail);
}
}
}
滚动时加载数据是个好主意,很多流行的应用程序都会这样做。我个人在这种情况下使用WeakReference
。开始加载数据时,我在模型中存储了对视图持有者的弱引用。如果在我得到响应时引用仍然有效,那么更新视图是有意义的。如果内存中没有视图持有者,那么它已经被回收,我不必再更新任何内容
<> >当代码> OnVIEW回收< /COD>被调用时,您可以清除弱引用,并考虑取消网络请求(取决于您的需求)。
缓存在这个模型中工作得非常完美,您只需在发出网络请求之前插入这个逻辑。同样,这取决于您的需要,可能您根本不需要缓存,或者您的数据很少更新,那么在发生某些事件之前始终使用缓存是有意义的
在我的应用程序中,我也使用EventBus,它帮助我处理事件,但只使用Android SDK和支持库是绝对好的
如果需要根据用户是否立即滚动列表来区分项目行为,还可以添加一个
ScrollListener
。例如,在我的应用程序中,如果列表已加载且用户未滚动数据,我会设置数据动画(提高与用户的交互)。当用户滚动时,我按原样加载数据,因为如果我设置数据动画,屏幕上会有太多的运动。滚动时加载数据是个好主意,很多流行的应用程序都会这样做。我个人在这种情况下使用WeakReference
。开始加载数据时,我在模型中存储了对视图持有者的弱引用。如果在我得到响应时引用仍然有效,那么更新视图是有意义的。如果内存中没有视图持有者,那么它已经被回收,我不必再更新任何内容
调用onViewRecycled
时,可以清除弱引用和als