LiveData始终在片段内观察到null

时间:2019-12-25 01:11:07

标签: android android-fragments mvvm android-viewmodel

我尝试从RestAPI获取数据,以显示带有MVVM的BottomNavigationView的片段。 我使用DataRepository(retrofit)和ViewModel从REstAPI获取数据作为逻辑层。

当我检入logcat时,数据已成功从RestAPI到达DataRepository,但是当我检入View(Fragment)时,它总是返回NULL。

RestAPI响应

{
    "responseCode": "00",
    "responseDescription": "OK",
    "responseData": {
        "editorsChoices": [
            {
                "image_url": "https://images.pexels.com/photos/218983/pexels-photo-218983.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"
            },
            {
                "image_url": "https://images.pexels.com/photos/747964/pexels-photo-747964.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260"
            }
        ],
        "trendingProjects": [],
        "trendingWaqfs": [],
        "trendingDonations": [],
    }
}

RetrofitRequest.java

public class RetrofitRequest {
    private static final String BASE_URL = BuildConfig.API_URL;
    private static Retrofit retrofit = null;

    private static OkHttpClient buildClient()
    {
        // start logging type
        HttpLoggingInterceptor logHeader = new HttpLoggingInterceptor();
        logHeader.setLevel(HttpLoggingInterceptor.Level.HEADERS);

        HttpLoggingInterceptor logBody = new HttpLoggingInterceptor();
        logBody.setLevel(HttpLoggingInterceptor.Level.BODY);

        HttpLoggingInterceptor logBasic = new HttpLoggingInterceptor();
        logBasic.setLevel(HttpLoggingInterceptor.Level.BASIC);
        // end logging type

        // create client
        return new OkHttpClient.Builder()
                //.addInterceptor(logBasic)
                //.addInterceptor(logHeader)
                .addInterceptor(logBody)
                .build();
    }

    public static Retrofit getClient()
    {
        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .client(buildClient())
                    .addConverterFactory(GsonConverterFactory.create())
                    .baseUrl(BASE_URL)
                    .build();
        }
        return retrofit;
    }

    public static String getError(int errorCode){
        switch (errorCode) {
            case 400:
                return "400: Bad Request";
            case 401:
                return "401: Unauthorized";
            case 402:
                return "402: Payment Required";
            case 403:
                return "403: Forbidden";
            case 404:
                return "404: Not Found";
            case 405:
                return "405: Method Not Allowed";
            case 500:
                return "500: Internal Server Error";

        }
        return "Undefined Error";
    }
}

ApiRequest.java

public interface ApiRequest {
    @POST("beranda")
    Call<JsonObject> beranda(@Body JsonObject param);
}

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_nav_view);

        NavController navController = Navigation.findNavController(this, R.id.bottom_nav_host_fragment);

        NavigationUI.setupWithNavController(bottomNavigationView, navController);
    }

}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_nav_view"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="0dp"
        android:layout_marginEnd="0dp"
        app:labelVisibilityMode="labeled"
        android:background="?android:attr/windowBackground"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:menu="@menu/bottom_nav_menu" />

    <fragment
        android:id="@+id/bottom_nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toTopOf="@id/bottom_nav_view"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/mobile_navigation" />

</androidx.constraintlayout.widget.ConstraintLayout>

BerandaRepository.java

public class BerandaRepository {
    private static final String TAG = BerandaRepository.class.getSimpleName();
    private ApiRequest apiRequest;

    public BerandaRepository() {
        apiRequest = RetrofitRequest.getClient().create(ApiRequest.class);
    }

    public LiveData<JsonObject> getDataBeranda(JsonObject params){
        final MutableLiveData<JsonObject> data = new MutableLiveData<>();
        apiRequest.beranda(params)
                .enqueue(new Callback<JsonObject>() {

                    @Override
                    public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
                        Log.d(TAG, "onResponse response:: " + response);
                        if (response.body() != null) {
                            ApiResponse apiResponse = new ApiResponse(response);
                            if (apiResponse.isSuccess()) {
                                data.setValue(apiResponse.getDataJsonObject());
                            } else {
                                data.setValue(null);
                            }
                        } else {
                            data.setValue(null);
                            Log.d(TAG, "else onResponse response:: null" );
                        }
                    }

                    @Override
                    public void onFailure(Call<JsonObject> call, Throwable t) {
                        data.setValue(null);
                    }
                });
        return data;
    }
}

BerandaViewModel.java

public class BerandaViewModel extends AndroidViewModel {
    private BerandaRepository berandaRepository;
    private LiveData<JsonObject> jsonObjectLiveData;


    public BerandaViewModel(@NonNull Application application) {
        super(application);
        this.berandaRepository = new BerandaRepository();
        this.jsonObjectLiveData = this.berandaRepository.getDataBeranda(new JsonObject());

    }

    public LiveData<JsonObject> getBerandaData(){
        return jsonObjectLiveData;
    }

}

BerandaFragment.java

public class BerandaFragment extends Fragment {

    private BerandaViewModel berandaViewModel;
    private FragmentBerandaBinding binding;

    private List<String> urls = new ArrayList<>();



    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_beranda, container, false);

        initialize();

        loadDataBeranda();

        return binding.getRoot();
    }

    private void initialize(){
        berandaViewModel =ViewModelProviders.of(getActivity()).get(BerandaViewModel.class);
    }

    private void loadDataBeranda(){

        berandaViewModel.getBerandaData().observe(BerandaFragment.this, new Observer<JsonObject>() {
            @Override
            public void onChanged(JsonObject jsonObject) {
                if (jsonObject != null) {
                    Log.d("CHECK", "response: " + jsonObject.toString());
                    JsonArray arrUrls = jsonObject.get("editorsChoices").getAsJsonArray();
                    for (JsonElement je: arrUrls) {
                        JsonObject jo = je.getAsJsonObject();
                        urls.add(jo.get("image_url").getAsString());
                    }
                    Glide.with(getContext()).load(urls.get(0)).into(binding.imageView);
                } else {
                    Log.d("CHECK", "Data is NULL");
                }
            }
        });
    }
}

ApiResponse.java

public class ApiResponse {
    JsonObject body;

    public ApiResponse(Response<JsonObject> response) {
        this.body = response.body();
        Log.d("CEK", "Body: " + body.toString());
    }

    public String getCode() {
        return body.get("responseCode").getAsString();
    }

    public String getDescription(){
        return body.get("responseDescription").getAsString();
    }

    public boolean isSuccess(){
        return getCode().equals("00");
    }

    public JsonArray getDataJsonArray(){
        return body.get("responseData").getAsJsonArray();
    }

    public JsonObject getDataJsonObject(){
        return body.get("responseData").getAsJsonObject();
    }
}

如何解决?

0 个答案:

没有答案