Имеется база из которой с помощью запросов достаются данные в формате json. Первый запрос возвращает массив объектов, в котором есть поле с внешним ключом к другой таблице, из которой нужно достать объект по данному ключу, а после этого заполнить адаптер. Проблема в том, что я хочу сделать это при помощи rxjava, но возникают ошибки на этапе присвоения значений в адаптере, так как ответ возвращается позже инициализации адаптера.
Класс API
public interface NetworkServiceApi {
@GET("odata/standard.odata/Document_уатПутевойЛист/")
Observable<WaybillResponse> getWaybills(@Query("$format") String format, @Query("$filter") String filter, @Query("$expand") String expand);
@GET("odata/standard.odata/InformationRegister_уатПервоначальныеСведенияТС/")
Observable<VehicleResponse> getVehicles(@Query("$format") String format, @Query("$filter") String filter, @Query("$expand") String expand);
}
Класс для работы с RXJava
public class RxUtil {
@SuppressLint("CheckResult")
public static <S> void networkConsumer(Observable<S> observable, Consumer<S> consumer, @Nullable Consumer<Throwable> errorConsumer) {
observable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(consumer, errorConsumer == null ? (Consumer<Throwable>) Throwable::printStackTrace : errorConsumer);
}
}
Вызов метода из активити и класс самой активити.
public class MainActivity extends AppCompatActivity implements InteractionListener<Waybill> {
@BindView(R.id.fab)
FloatingActionButton fab;
@BindView(R.id.state)
TextView state;
@BindView(R.id.waybill)
RecyclerView waybill;
@BindView(R.id.progressBar)
ProgressBar progressBar;
private WaybillAdapter waybillAdapter;
private User user;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
Bundle args = getIntent().getExtras();
user = (User) (args != null ? args.get("user") : null);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(MainActivity.this, WaybillActivity.class).putExtra("user", user));
}
});
initList();
}
@Override
protected void onResume() {
super.onResume();
getWaybills();
}
@Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
@Override
public void onItemClick(Waybill item) {
startActivity(new Intent(this, Main2Activity.class).putExtra("waybill", item));
}
private void initList() {
waybillAdapter = new WaybillAdapter(this, this);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(this, 1);
waybill.setLayoutManager(layoutManager);
waybill.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
waybill.setAdapter(waybillAdapter);
waybill.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy > 0 && fab.getVisibility() == View.VISIBLE) fab.hide();
else if (dy < 0 && fab.getVisibility() != View.VISIBLE) fab.show();
}
});
}
private void getWaybills() {
String credentials = getSharedPreferences("MyPref", Context.MODE_PRIVATE).getString("credentials", "");
state.setVisibility(View.GONE);
progressBar.setVisibility(View.VISIBLE);
final NetworkServiceApi networkServiceApi = NetworkService.getInstance().getNetworkServiceApi(credentials);
RxUtil.networkConsumer(networkServiceApi.getWaybills("json", "Ответственный_Key eq " + "guid'" + user.getRefKey() + "'", "*"),
waybillResponse -> {
if (!waybillResponse.isError()) {
if (waybillResponse.getWaybills().size() > 0 ) {
Log.e("Waybill", "Receive waybills " + waybillResponse.getWaybills().size());
for (int i = 0; i < waybillResponse.getWaybills().size(); i++) {
final int k = i;
RxUtil.networkConsumer(networkServiceApi
.getVehicles("json", "ОсновноеСредство_Key eq " + "guid'" + waybillResponse.getWaybills().get(k).getVehicleKey() + "'", "*"),
vehicleResponse -> {
if (!vehicleResponse.isError()) {
if (vehicleResponse.getVehicles().size() > 0 ) {
waybillResponse.getWaybills().get(k).setVehicle(vehicleResponse.getVehicles().get(0));
Log.e("Vehicle", "Init");
if (k == waybillResponse.getWaybills().size() - 1) {
Log.e("Activity", "Set");
waybillAdapter.setWaybills(waybillResponse.getWaybills());
state.setVisibility(View.GONE);
progressBar.setVisibility(View.GONE);
}
}
} else {
Toast.makeText(this, vehicleResponse.getError_messages().get(0), Toast.LENGTH_SHORT).show();
}
}, null);
}
} else {
state.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);
}
} else {
Toast.makeText(this, waybillResponse.getError_messages().get(0), Toast.LENGTH_SHORT).show();
}
}, null);
}
}
Классы WaybillResponce И VehicleResponce идентичны и возвращают массив объектов Waybill и Vehicle соответственно. Я создал поле Vehicle в классе Waybill для того чтобы работать с 1 объектом.
public class WaybillResponse extends BaseResponse {
@SerializedName("value")
private List<Waybill> waybills;
public List<Waybill> getWaybills() {
return waybills;
}
}
Адаптер начинает инициализицию раньше чем данные присвоятся.
Класс адаптера.
public class WaybillAdapter extends RecyclerView.Adapter<WaybillAdapter.ViewHolder> {
private Context context;
private List<Waybill> waybills;
private InteractionListener<Waybill> listener;
public WaybillAdapter(@NonNull Context context, InteractionListener<Waybill> listener) {
this.context = context;
this.listener = listener;
}
@NonNull
@Override
public WaybillAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
final View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.waybill_item, viewGroup, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull WaybillAdapter.ViewHolder viewHolder, int i) {
Log.e("Adapter", ""+i);
final Waybill waybill = getItem(i);
viewHolder.number.setText(waybill.getNumber());
viewHolder.date.setText(waybill.getDate());
viewHolder.vh_number.setText(waybill.getVehicle().getGarageNumber() != null ? waybill.getVehicle().getGarageNumber() : "");
viewHolder.vh_model.setText(waybill.getVehicle().getModel() != null ? waybill.getVehicle().getModel().getDescription() : "");
viewHolder.driver.setText(waybill.getFirstDriver().getCode());
viewHolder.dep_date.setText(waybill.getDepartureDate() != null ? waybill.getDepartureDate() : "");
viewHolder.speedo_dep.setText(String.valueOf(waybill.getDepartureSpeedo()));
viewHolder.ret_date.setText(waybill.getReturnDate() != null ? waybill.getReturnDate() : "");
viewHolder.speedo_ret.setText(String.valueOf(waybill.getReturnSpeedo()));
if (listener != null)
viewHolder.view.setOnClickListener(view -> listener.onItemClick(waybill));
}
@Override
public int getItemCount() {
return waybills == null ? 0 : waybills.size();
}
public void setWaybills(List<Waybill> waybills) {
this.waybills = waybills;
notifyDataSetChanged();
}
private Waybill getItem(int position) {
int index = position % waybills.size();
return waybills.get(position);
}
class ViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.number)
TextView number;
@BindView(R.id.date)
TextView date;
@BindView(R.id.vh_number)
TextView vh_number;
@BindView(R.id.vh_model)
TextView vh_model;
@BindView(R.id.driver)
TextView driver;
@BindView(R.id.dep_date)
TextView dep_date;
@BindView(R.id.speedo_dep)
TextView speedo_dep;
@BindView(R.id.ret_date)
TextView ret_date;
@BindView(R.id.speedo_ret)
TextView speedo_ret;
@BindView(R.id.status)
TextView status;
@BindView(R.id.status_route)
TextView status_route;
View view;
ViewHolder(@NonNull View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
this.view = itemView;
}
public Context getContext() {
return view.getContext();
}
}
}
Ошибка - в момент вызова метода getGarageNumber(): переменная является null и происходит ошибка приложения. viewHolder.vh_number.setText(waybill.getVehicle().getGarageNumber() != null ? waybill.getVehicle().getGarageNumber() : "");
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
axios (post, timeout: 1500) запрос из vue-приложения пытается получить данные с серверасервер не доступен (отключил специально)
Изучаю чистый JS, хочу добавить методы и свойства для моих DOM элементовВ интернетах сказали, что напрямую записывать методы и свойства в DOM-элементы...
Каким образом можно подключить внешний javascript файл к форме?