更改数据后如何刷新recyclerView?

时间:2018-09-29 22:48:33

标签: android android-recyclerview recycler-adapter

我对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();
    }
}

1 个答案:

答案 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()

虽然“活动”中的alarmspublic 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()