繁体   English   中英

从服务器通过API传输数据完成后,如何使用远程数据构建recyclerview

[英]How to build recyclerview with remote data after the data transfer from server thorugh API is complete

我在片段中构建了一个回收视图。 要在 recyclerview 中填充的数据存储在远程服务器中,并通过 JSON 进行解析。

我正在使用 Retrofit 将数据从服务器传输到应用程序。 注意:我是 Android 开发初学者,第一次通过看教程使用 Retrofit。

到目前为止,我已经理解了以下内容,如果我错了,请纠正我由于 Retrofit 库使用另一个线程而不是主线程来从服务器获取响应,数据完全传输需要几秒钟,但直到那时 recyclerview 已经构建带有空的 ArrayList。

所以,我的问题是,如何保持 recyclerView 从构建到数据传输完成? 或如何在数据传输完成后更新空的 ArrayList 并从该数据填充 recyclerview? 或者你可以告诉我什么是达到预期结果的最好和最有效的方法。

我已经尝试过adapter.notifyDataSetChanged() ,但是我没有在正确的地方使用它,或者我没有以正确的方式使用它,因为它不起作用。 你可以在代码中看到它。

库片段:-

package com.diginfoexpert.mybooks.Fragment;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.diginfoexpert.mybooks.Activity.CategoryActvity;
import com.diginfoexpert.mybooks.Adapter.LibraryCategoriesCardAdapter;
import com.diginfoexpert.mybooks.Model.Category;
import com.diginfoexpert.mybooks.Model.LibraryAPI;
import com.diginfoexpert.mybooks.Model.LibraryCategories;
import com.diginfoexpert.mybooks.R;

import java.util.ArrayList;

import Controllers.JSONApiHolder;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.Retrofit.Builder;
import retrofit2.converter.gson.GsonConverterFactory;

public class LibraryFragment extends Fragment implements LibraryCategoriesCardAdapter.CategoryClickListener {

    private JSONApiHolder jsonApiHolder;
    ArrayList<Category> categories = new ArrayList<>();
    LibraryCategoriesCardAdapter adapter;
    RecyclerView recyclerView;


    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_library, container, false);
        Log.d("RETROFIT", "onCreateView: Library Fragment Started");

        recyclerView = view.findViewById(R.id.library_category_recycler_view);

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://myurl.in/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        jsonApiHolder = retrofit.create(JSONApiHolder.class);

        getCategories();

        buildRecyclerView();

        return view;
    }

    private void buildRecyclerView() {
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
        adapter = new LibraryCategoriesCardAdapter(buildCategoryList(),this);
        recyclerView.setLayoutManager(linearLayoutManager);
        recyclerView.setAdapter(adapter);
    }

    private void getCategories() {
        Call<LibraryAPI> call = jsonApiHolder.getLibrary();

        call.enqueue(new Callback<LibraryAPI>() {
            @Override
            public void onResponse(Call<LibraryAPI> call, Response<LibraryAPI> response) {
                if(!response.isSuccessful()){
                    Log.d("RETROFIT", "onResponse: callback failed");
                    return;
                }

                else{
                    Log.d("RETROFIT", "onResponse: callback successful");
                    LibraryAPI libraryAPI = response.body();
                    categories = libraryAPI.getCategories();
                    adapter.notifyDataSetChanged();

                    for (Category category :categories){
                        Log.d("RETROFIT", "onResponse: "+category.getTitle());
                    }

                }
            }

            @Override
            public void onFailure(Call<LibraryAPI> call, Throwable t) {
                Log.d("RETROFIT", "onFailure: response failed : " +t.getMessage());
            }
        });
    }

    private ArrayList<Category> buildCategoryList() {
        ArrayList<Category> mList = new ArrayList<>();
//        mList.add(new Category("Art"));
//        mList.add(new Category("Action"));
//        mList.add(new Category("Thrill"));
//        mList.add(new Category("Fiction"));
//        mList.add(new Category("Romance"));
//        mList.add(new Category("Crime"));
//        mList.add(new Category("Classical"));
//        mList.add(new Category("Financial"));
//        mList.add(new Category("Business"));
        Log.d("RETROFIT", "Size of categories ArrayList "+categories.size());
        return categories;
    }

    @Override
    public void onCategoryClick() {
        Intent intent = new Intent(getActivity(), CategoryActvity.class);
        startActivity(intent);
    }
}

调试日志:-

2020-03-25 14:26:37.536 1703-1703/com.myurl.mybooks D/RETROFIT: onCreateView: Library Fragment Started
2020-03-25 14:26:37.630 1703-1703/com.myurl.mybooks D/RETROFIT: Size of categories ArrayList 0
2020-03-25 14:26:42.171 1703-1703/com.myurl.mybooks D/RETROFIT: onResponse: callback successful
2020-03-25 14:26:42.172 1703-1703/com.myurl.mybooks D/RETROFIT: onResponse: MPPSC Mains Syllabus
2020-03-25 14:26:42.172 1703-1703/com.myurl.mybooks D/RETROFIT: onResponse: MPPSC MAINS PAPER 1 PART "A" History
2020-03-25 14:26:42.172 1703-1703/com.myurl.mybooks D/RETROFIT: onResponse: MPPSC MAINS PAPER 1 PART "B" Geography
2020-03-25 14:26:42.172 1703-1703/com.myurl.mybooks D/RETROFIT: onResponse: MPPSC MAINS PAPER-2 (PART "A") Polity
2020-03-25 14:26:42.172 1703-1703/com.myurl.mybooks D/RETROFIT: onResponse: MPPSC MAINS PAPER 2 (PART "B") Economics & Social
2020-03-25 14:26:42.172 1703-1703/com.myurl.mybooks D/RETROFIT: onResponse: MPPSC MAINS PAPER 3 Science
2020-03-25 14:26:42.172 1703-1703/com.myurl.mybooks D/RETROFIT: onResponse: MPPSC MAINS PAPER 4 Ethics
2020-03-25 14:26:42.173 1703-1703/com.myurl.mybooks D/RETROFIT: onResponse: MPPSC HINDI

这是您修改后的代码部分

public void onResponse(Call<LibraryAPI> call, Response<LibraryAPI> response) {
                if(!response.isSuccessful()){
                    Log.d("RETROFIT", "onResponse: callback failed");
                    return;
                }

                else{
                    Log.d("RETROFIT", "onResponse: callback successful");
                    LibraryAPI libraryAPI = response.body();
                    categories = libraryAPI.getCategories();
                    adapter.notifyDataSetChanged();

                    for (Category category :categories){
                      categories.add(category) // Added by me  
                      Log.d("RETROFIT", "onResponse: "+category.getTitle());
                    }
                    adapter.notifyDataSetChanged() // Added by me
                }
            }

过了一段时间我找到了出路。 我在 main 方法中构建了回收器视图,这是主线程。 当我们在改造中对网络请求进行排队时,它在不同的线程上工作,因此直到数据传输完成,回收器视图已经构建在主线程中,没有可用的数据。

因此,我没有在主线程中构建回收器视图,而是创建了一个方法来构建它。 在应用程序得到服务器响应后,我调用了该方法。

private void buildRecyclerView() {
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
        adapter = new LibraryCategoriesCardAdapter(buildCategoryList(),this);
        recyclerView.setLayoutManager(linearLayoutManager);
        recyclerView.setAdapter(adapter);
    }



private void getCategories() {
    Call<LibraryAPI> call = jsonApiHolder.getLibrary();

    call.enqueue(new Callback<LibraryAPI>() {
        @Override
        public void onResponse(Call<LibraryAPI> call, Response<LibraryAPI> response) {
            if(!response.isSuccessful()){
                Log.d("RETROFIT", "onResponse: callback failed");
                return;
            }

            else{
                Log.d("RETROFIT", "onResponse: callback successful");
                LibraryAPI libraryAPI = response.body();
                categories = libraryAPI.getCategories();
                buildRecyclerView();

                for (Category category :categories){
                    Log.d("RETROFIT", "onResponse: "+category.getTitle());
                }

            }
        }

        @Override
        public void onFailure(Call<LibraryAPI> call, Throwable t) {
            Log.d("RETROFIT", "onFailure: response failed : " +t.getMessage());
        }
    });
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM