Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/195.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 从服务器提取数据后如何更新recyclerview?_Android_Android Recyclerview - Fatal编程技术网

Android 从服务器提取数据后如何更新recyclerview?

Android 从服务器提取数据后如何更新recyclerview?,android,android-recyclerview,Android,Android Recyclerview,如果我必须发送请求以获取onBindViewHolder()中的数据,那么在数据从服务器返回后如何更新视图 我现在拥有的是缓存数据和行位置,以便下次用户滚动到该行时,我可以立即显示信息 但还有两个问题我不知道如何解决 我滚动列表以查看位置10、11和12处的项目。我决定等数据回来。我是否在之后调用notifyDataSetChanged()?因为数据返回时,onBindViewHolder已经被调用,视图将保持为空,但我也不认为在每次请求后调用notifyDataSetChanged()是个好主

如果我必须发送请求以获取
onBindViewHolder()
中的数据,那么在数据从服务器返回后如何更新视图

我现在拥有的是缓存数据和行位置,以便下次用户滚动到该行时,我可以立即显示信息

但还有两个问题我不知道如何解决

  • 我滚动列表以查看位置10、11和12处的项目。我决定等数据回来。我是否在之后调用
    notifyDataSetChanged()
    ?因为数据返回时,
    onBindViewHolder
    已经被调用,视图将保持为空,但我也不认为在每次请求后调用
    notifyDataSetChanged()
    是个好主意
  • 我开始在位置0查看列表,并一直滚动到位置10。应用程序发出请求以提取位置0到10的数据。由于0处的请求是首先发出的,因此它很可能会首先返回,或者至少比位置10更早返回,但此时我已在位置10处查看该项目。如果所有请求恢复正常,我的视图将开始更改,因此它将显示位置0的数据,然后一直更新到10
    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