我对RecyclerView有个问题。我需要在点击一个长点击后刷新它。我尝试使用notifyDataSetChanged()方法。但是什么都不起作用。这是我的代码。在当前情况下,项将立即从数据库中删除。但我必须移动到另一个活动,然后再回来查看任何UI更改。提前感谢您的帮助。
public class AlarmsActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private List<Alarm> alarmsList = new ArrayList<>();
private AlarmRecyclerAdapter mAdapter;
private AppDataBase db;
private AlarmsDao alarmDao;
private OnClickedRecyclerAdapter<Alarm> recyclerListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.alarms_activity);
db = App.getInstance().getDataBase();
alarmDao = db.AlarmDao();
recyclerView = findViewById(R.id.recycler);
recyclerListener = new OnClickedRecyclerAdapter<Alarm>() {
@Override
public void onLongClicked(final Alarm data) {
removeAlarm(data);
}
@Override
public void onClicked(Alarm data) {
}
};
mAdapter = new AlarmRecyclerAdapter(alarmsList, recyclerListener);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
getData();
}
public void getData(){
new Thread(new Runnable() {
@Override
public void run() {
for (Alarm alarm : alarmDao.getAll()){
alarmsList.add(alarm);
}
}
}).start();
}
public void removeAlarm(final Alarm alarm){
new Thread(new Runnable() {
@Override
public void run() {
Log.e("xxx", "Long clicked");
alarmDao.deleteAlarm(alarm);
}
}).start();
}
}
OnClickListener
public interface OnClickedRecyclerAdapter<Alarm> {
void onLongClicked(Alarm data);
void onClicked(Alarm data);
}
适配器。
public class AlarmRecyclerAdapter extends RecyclerView.Adapter<AlarmViewHolder> {
List<Alarm> alarms;
OnClickedRecyclerAdapter listener;
private AppDataBase db;
private AlarmsDao alarmsDao;
public AlarmRecyclerAdapter(List<Alarm> alarms, OnClickedRecyclerAdapter listener) {
this.alarms = alarms;
this.listener = listener;
db = App.getInstance().getDataBase();
alarmsDao = db.AlarmDao();
}
@NonNull
@Override
public AlarmViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycler, parent, false);
return new AlarmViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull AlarmViewHolder holder, final int position) {
final Alarm alarm = alarms.get(position);
holder.time.setText(alarm.getHour()+" : " + alarm.getMinute());
holder.days.setText(alarm.getDays());
holder.isOn.setChecked(alarm.isIs_on());
holder.isOn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
Log.e("xxx", b + " ");
}
});
holder.cardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listener.onClicked(alarm);
}
});
holder.cardView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
listener.onLongClicked(alarm);
return true;
}
});
}
@Override
public int getItemCount() {
return alarms.size();
}
}
发布于 2018-09-30 07:25:06
更改此设置:
holder.cardView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
listener.onLongClicked(alarm);
return true;
}
});
要这样做:
holder.cardView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
listener.onLongClicked(alarm);
alarms.remove(holder.getAdapterPosition()); //or alarms.remove(alarm);
notifyItemRemoved(holder.getAdapterPosition()); //or notifyDataSetChanged();
return true;
}
});
问题是,当您在Activity中调用removeAlarm()
时,您正在从数据库中删除警报,但您实际上并没有将其从适配器的alarms
列表中删除。更改不会反映在代码中,因为数据集永远不会更改。当您重新创建您的活动时,您将新的数据库列表传递到Adapter中,这样它就会更新。
我还建议不要这样做:
public void getData(){
new Thread(new Runnable() {
@Override
public void run() {
for (Alarm alarm : alarmDao.getAll()){
alarmsList.add(alarm);
}
}
}).start();
}
虽然Activity和alarms
中的alarmsList
是同一个实例,因此反映了相同的添加和删除,但不能保证此逻辑将在RecyclerView膨胀并附加适配器之前完成。这意味着你最终可能会丢失数据,特别是在速度较慢的设备上。
除非你有大量的警报,否则没有必要在新的线程中运行它。您只需将该for循环移到初始化适配器的位置上方,并使用addAll()
方法:
alarmsList.addAll(alarmDuo.getAll());
mAdapter = //your assignment from your code
如果您确实需要它是异步的,请稍后在您的线程中附加适配器:
public void getData(){
new Thread(new Runnable() {
@Override
public void run() {
alarmsList.addAll(alarmDuo.getAll());
runOnUiThread(new Runnable() {
mAdapter = new AlarmRecyclerAdapter(alarmsList, recyclerListener);
recyclerView.setAdapter(mAdapter);
}
}
}).start();
}
从onCreate()
方法中删除赋值、适配器设置和notifyDataSetChanged()
调用:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.alarms_activity);
db = App.getInstance().getDataBase();
alarmDao = db.AlarmDao();
recyclerView = findViewById(R.id.recycler);
recyclerListener = new OnClickedRecyclerAdapter<Alarm>() {
@Override
public void onLongClicked(final Alarm data) {
removeAlarm(data);
}
@Override
public void onClicked(Alarm data) {
}
};
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
getData();
}
https://stackoverflow.com/questions/52573170
复制相似问题