簡體   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