复选框接口和回收查看适配器出错



我有一个RecyclerView,它显示任务并包含复选框。当用户单击复选框时,我希望检查任务的结束时间是否小于当前时间,如果为true,则复选框将保持选中状态,否则应取消选中。让我借助代码来澄清我的问题。

在我的适配器中,我创建了一个接口:

private OnItemClickedListener listener;
public void setOnItemClickedListener(OnItemClickedListener listener){
this.listener = listener;
}
interface OnItemClickedListener {
void onItemClick(View v, int position, boolean isChecked, int time);
}

然后,在OnBindViewHolder中,我将onClickListener设置为复选框:

@Override
public void onBindViewHolder(@NonNull final SortedViewHolder holder, final int position) {
final Sorted data = list.get(position);
holder.title.setText(data.getSortedName());
holder.date.setText(data.getSortedDate());
holder.category.setText(String.valueOf(data.getSortedCategory()));
holder.attach.setText(String.valueOf(data.isSortedAttach()));
holder.to.setText(String.valueOf(toTime(data.getSortedDuration() + data.getSortedTimeBegin())));
holder.from.setText(String.valueOf(toTime(data.getSortedTimeBegin())));
holder.checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null){
boolean isChecked = holder.checkBox.isChecked();
listener.onItemClick(v, position, isChecked, data.getSortedDuration() + data.getSortedTimeBegin());
}
}
});
}

(注意:我将任务的时间存储为分钟,所以稍后我将把它们分别划分为分钟和小时(。

之后,在我的活动中,我得到了这个方法并检查时间:

//in OnCreate: 
final SortedAdapter adapter = new SortedAdapter();
adapter.setOnItemClickedListener(this);
@Override
public void onItemClick(View v, int position, boolean isChecked, int time) {
if (isChecked){
//String currentTime = new SimpleDateFormat("HH:mm:ss", Locale.getDefault()).format(new Date());
//get current day time
int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
int minute = Calendar.getInstance().get(Calendar.MINUTE);
//compare to the given
if (hour > time/60){
//save state
Toast.makeText(this, "check1", Toast.LENGTH_SHORT).show();
}
else if (hour == time/60){
if (minute > time % 60){
//save state
Toast.makeText(this, "check2", Toast.LENGTH_SHORT).show();
}
else{
//set the checkbox to false
Toast.makeText(this, "uncheck1", Toast.LENGTH_SHORT).show();
listener.onCheckBoxOff(v);
}
}
else{
Toast.makeText(this, "uncheck2", Toast.LENGTH_SHORT).show();
listener.onCheckBoxOff(v);
}
}
}

所有的吐司都很好用。现在我想以某种方式访问我的复选框变量并更改它的状态。这就是我的问题。我真的不知道该怎么做。我试图在我的活动中制作另一个界面:

//outside activity class
interface CheckBoxOff {
void onCheckBoxOff(View v);
}
//in activity class before onCreate
private CheckBoxOff listener;
void setCheckboxOffListener(CheckBoxOff listener){
this.listener = listener;
}

然后我在我的适配器中实现了它:

@Override
public void onCheckBoxOff(View v) {
SortedViewHolder holder = new SortedViewHolder(v);
holder.checkBox.setChecked(false);
}

在BindViewHolder中,我写道(也许是这里的错误?(:

ShowSortedActivity activity = new ShowSortedActivity();
activity.setCheckboxOffListener(this);

启动我的应用程序后,我得到错误:

java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.tryalgorithm.ui.CheckBoxOff.onCheckBoxOff(android.view.View)' on a null object reference
at com.example.tryalgorithm.ui.ShowSortedActivity.onItemClick(ShowSortedActivity.java:104)
at com.example.tryalgorithm.ui.SortedAdapter$1.onClick(SortedAdapter.java:66)
at android.view.View.performClick(View.java:6304)
at android.widget.CompoundButton.performClick(CompoundButton.java:134)
at android.view.View$PerformClick.run(View.java:24803)
at android.os.Handler.handleCallback(Handler.java:794)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:6635)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)

你能解释一下我在这里做错了什么吗?也许还有另一种方法可以将复选框设置为false,而不是在界面的帮助下,或者这种方法可以吗?谢谢你的帮助。

活动代码:

public class ShowSortedActivity extends AppCompatActivity {
SortedViewModel viewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_sorted);
final SortedAdapter adapter = new SortedAdapter();
RecyclerView showSorted = findViewById(R.id.show_sorted);
showSorted.setLayoutManager(new LinearLayoutManager(this));
showSorted.setHasFixedSize(true);
showSorted.setAdapter(adapter);
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_close);
setTitle(R.string.Sorted);
Intent intent = getIntent();
String currentDate = intent.getStringExtra("value");
viewModel = new ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(this.getApplication())).get(SortedViewModel.class);
try {
viewModel.getSortedWhereDateIs(currentDate).observe(this, new Observer<List<Sorted>>() {
@Override
public void onChanged(List<Sorted> sorteds) {
adapter.setSortedData(sorteds);
}
});
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void onItemClick(View v, int position, boolean isChecked, int time) {
if (isChecked){
//get current day time
int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
int minute = Calendar.getInstance().get(Calendar.MINUTE);
//compare to the given
if (hour > time/60){
//save state
Toast.makeText(this, "check1", Toast.LENGTH_SHORT).show();
}
else if (hour == time/60){
if (minute > time % 60){
//save state
Toast.makeText(this, "check2", Toast.LENGTH_SHORT).show();
}
else{
//set the checkbox to false
Toast.makeText(this, "uncheck1", Toast.LENGTH_SHORT).show();
}
}
else{
//set the checkbox to false
Toast.makeText(this, "uncheck2", Toast.LENGTH_SHORT).show();
}
}
}
}
@Override
public void onCheckBoxOff(View v) {
SortedViewHolder holder = new SortedViewHolder(v);
holder.checkBox.setChecked(false);
}

您的问题是您不能自己创建视图持有者,它应该由适配器通过onCreateViewHolder进行管理。将代码更改为

@Override
public void onCheckBoxOff(View v) {
((CheckBox)v).setChecked(false);
}

但这只是修复UI,您应该存储每个持有者的值,以便在滚动时保持复选框状态。遵循以下步骤:

  1. isChecked添加到Sorted型号

  2. onBindViewHolder应通过从data检查来更新checkBox

  3. 方法内部onItemClick应根据位置更新适配器列表数据中的isChecked模型

最新更新