我遇到了一个问题,这是技术上的和概念上的,我正在尝试使用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/

10-13 03:26