У меня есть RecyclerView, который отображает задачи и содержит флажки. Когда пользователь установит флажок, я хочу проверить, меньше ли время завершения задачи, чем текущее время, и если это правда, то флажок останется установленным, в противном случае его следует снять. Позвольте мне прояснить мою проблему с помощью кода.
В моем адаптере я создал интерфейс:
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();
}
}
}
}