我对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();
}
}
答案 0 :(得分:0)
更改此:
if(currentUserId.equals(model.getUserId())){
holder.message.setBackgroundResource(R.drawable.message_sender_bubbles);
holder.message.setGravity(Gravity.LEFT);
}else
{
holder.message.setBackgroundResource(R.drawable.message_resiver_bubbles);
holder.message.setGravity(Gravity.RIGHT);
}
对此:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/image_message_profile"
android:layout_width="32dp"
android:layout_height="32dp"
android:src="@drawable/profile_image"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginLeft="8dp"
app:layout_constraintLeft_toLeftOf="parent" />
<TextView
android:id="@+id/text_message_name"
android:text="user_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp"
app:layout_constraintLeft_toRightOf="@+id/image_message_profile"
android:layout_marginLeft="8dp"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="4dp" />
问题在于,当您在“活动”中调用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;
}
});
列表中删除警报。因为数据集在您的代码中从未更改,所以更改未得到反映。重新创建活动时,会将新的数据库列表传递到适配器中,以便随后进行更新。
我还建议不要这样做:
removeAlarm()
虽然“活动”中的alarms
和public void getData(){
new Thread(new Runnable() {
@Override
public void run() {
for (Alarm alarm : alarmDao.getAll()){
alarmsList.add(alarm);
}
}
}).start();
}
是相同的实例,因此反映了相同的添加和删除,但不能保证在RecyclerView膨胀并连接适配器之前,此逻辑将完成。这意味着您最终可能会丢失数据,尤其是在速度较慢的设备上。
除非您有绝对数量的警报,否则无需在新线程中运行它。您可以将for循环移至初始化适配器的位置上方,然后使用alarmsList
方法:
alarms
如果确实需要异步,请稍后在线程内连接适配器:
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();
}
调用:
notifyDataSetChanged()