我遇到了一个问题,这是技术上的和概念上的,我正在尝试使用MVVM体系结构,并且我不想离开它,所以我有一个项目列表,每个项目都有一个删除按钮,我显示了该列表使用recylcerview,所以我正在使用适配器,现在当我在每一行上调用一个事件时,我会这样做:
这是我的适配器,转到ViewHolder内的deleteBtn。
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();
}
}
因此,当我调用一个 Action 并观察它时,我通常会在MainActivity中进行操作,因为我正在实例化MainActivity中的ListViewModel并调用了ViewModel方法,但是现在,我感觉必须在此ViewHolder中实例化相同的ViewModel。
首先,我不知道怎么做,因为当我在MainActivity中调用“this”时,它指的是MainActvity,但是如果我在ViewHolder(不是activity)中调用它,它将无法正常工作,因此我将如何在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
}
}
任何帮助将不胜感激的家伙!
谢谢你。
最佳答案
这是您更新的 Activity 。
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){
contracts.addAll(contractModels);
contractList.setVisibility((View.VISIBLE));
adapter = new ContractListAdapter(MainActivity.this, contractModels, new ContractListAdapter.OnButtonPressed() {
@Override
public void onClicked(int position) {
contractsListViewModel.callDelete(position);
}
});
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();
}
}
这是您更新的
ContractListAdapter
public class ContractListAdapter extends RecyclerView.Adapter<ContractListAdapter.ContractViewHolder> {
List<ContractModel> contracts;
Context context;
OnButtonPressed onButtonPressed;
public ContractListAdapter(Context context, List<ContractModel> contracts,OnButtonPressed onButtonPressed) {
this.context = context;
this.contracts = contracts;
this.onButtonPressed = onButtonPressed;
}
@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
onButtonPressed.onClicked(position);
} else {
Intent myIntent = new Intent(context, ContractActivity.class);
myIntent.putExtra("key", idOfContract + ""); //Optional parameters
context.startActivity(myIntent);
}
}
}
interface OnButtonPressed {
void onClicked(int position);
}
}
关于android - 在尊重MVVM体系结构的同时,如何在recyclerview中的项目内部的按钮上提交单击事件?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61184380/