У меня проблема, она техническая и концептуальная, я пытаюсь использовать архитектуру MVVM и не хочу от нее отказываться, поэтому у меня есть список элементов, у каждого элемента есть кнопка удаления, я показать список с помощью recylcerview, поэтому я использую адаптер, теперь, когда я вызываю событие в каждой строке, я делаю это:
Это мой адаптер, go для deleteBtn внутри ViewHolder.
public class ContractListAdapter extends RecyclerView.Adapter<ContractListAdapter.ContractViewHolder> {
List<ContractModel> contracts;
Context context;
public ContractListAdapter(Context context, List<ContractModel> contracts){
this.context = context;
this.contracts = contracts;
}
@NonNull
@Override
public ContractViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
ContratBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.contrat, parent, false); // ContratBinding >> as your list item layout named "contrat"
return new ContractViewHolder(binding);
}
@Override
public void onBindViewHolder(@NonNull ContractViewHolder holder, int position) {
holder.binding.setContract(contracts.get(position));
}
@Override
public int getItemCount() {
return this.contracts.size();
}
public class ContractViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
ContractsListViewModel listViewModel;
@BindView(R.id.courtier)
TextView courtier;
@BindView(R.id.delete)
Button deleteButton;
ContratBinding binding;
@BindView(R.id.contratImage)
ImageView contractImage;
public ContractViewHolder(@NonNull ContratBinding binding){
super(binding.getRoot());
this.binding = binding;
ButterKnife.bind(this, itemView);
itemView.setOnClickListener(this);
courtier.setOnClickListener(this);
deleteButton.setOnClickListener(this);
contractImage.setOnClickListener(this);
}
@Override
public void onClick(View v) {
int position = getAdapterPosition();
int idOfContract = contracts.get(position).getId();
if(deleteButton.getId() == v.getId()){
// action here
}
else {
Intent myIntent = new Intent(context, ContractActivity.class);
myIntent.putExtra("key", idOfContract + ""); //Optional parameters
context.startActivity(myIntent);
}
}
}
}
Это моя MainActivity:
public class MainActivity extends AppCompatActivity {
ContractsListViewModel contractsListViewModel;
@BindView(R.id.contractList)
RecyclerView contractList;
@BindView(R.id.newContractBtn)
Button newContractBtn;
@BindView(R.id.listLoading)
ProgressBar listLoading;
@BindView(R.id.listError)
TextView listError;
RecyclerView.Adapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding main = DataBindingUtil.setContentView(this, R.layout.activity_main);
ButterKnife.bind(this);
main.contractList.setLayoutManager(new LinearLayoutManager(this));
contractsListViewModel = ViewModelProviders.of(this).get(ContractsListViewModel.class);
contractsListViewModel.call();
contractsListViewModel.contractList.observe(this,contractModels -> {
if(contractModels != null){
contractList.setVisibility((View.VISIBLE));
adapter = new ContractListAdapter(MainActivity.this, contractModels);
main.contractList.setAdapter(adapter);
}
});
contractsListViewModel.isLoading.observe(this,isLoading -> {
if(isLoading != null){
listLoading.setVisibility(isLoading ? View.VISIBLE : View.GONE );
if(isLoading){
listError.setVisibility(View.GONE);
contractList.setVisibility((View.GONE));
}
}
});
contractsListViewModel.error.observe(this,Error -> {
if(Error != null){
listError.setVisibility(Error ? View.VISIBLE : View.GONE );
}
});
newContractBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent newContractIntent = new Intent(getApplicationContext(), NewContractActivity.class);
MainActivity.this.startActivity(newContractIntent);
}
});
}
@Override
public void onResume()
{
super.onResume();
contractsListViewModel = ViewModelProviders.of(this).get(ContractsListViewModel.class);
contractsListViewModel.call();
}
}
Поэтому, когда я вызываю действие и наблюдаю его, я обычно делаю это в своей MainActivity, потому что я выполнял создание экземпляра ListViewModel внутри MainActivity, и вызывал мои методы ViewModel, но теперь я чувствую, что мне нужно создать те же ViewModels в этом ViewHolder.
Сначала я не знаю как, потому что когда я вызываю «this» в моей MainActivity, это относится к MainActvity, но если я вызываю его в ViewHolder (не активность), он не будет работать, так как я буду вызывать мою ViewModel в ViewHolder.
contractsListViewModel = ViewModelProviders.of(this).get(ContractsListViewModel.class);
Во-вторых, и это более важно, уважаю ли я в архитектуре MVVM, если я это сделаю?
Потому что, как я это представляю:
@Override
public void onClick(View v) {
int position = getAdapterPosition();
int idOfContract = contracts.get(position).getId();
// Delete Button clicked
if(deleteButton.getId() == v.getId()){
// I call the ViewModel
// call the action I want ( delete request )
// observe it in my MainActivity
}
}
Любая помощь будет высоко ценится, ребята!
Спасибо.