我尝试从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();
}
}
如何解决?