我正在开发一个Android应用程序,根据从 firebase 数据库中检索到的标记显示学生的等级。一切都运行正常但是,当我更新数据库中的标记时,它会保留旧数据并在recyclerView中添加新数据。我可以重新启动应用程序来刷新数据。但是当它仍在运行时,它也会显示旧数据。
以下是我的火力显示数据:
Student1: {
c: 70,
cPlus: 90,
java: 70,
name: "Samson",
regno: "16sksb7034",
unix: 60
}
Student2: {
c: 20,
cPlus: 85,
java: 68,
name: "Samson",
regno: "16sksb7034",
unix: 86
}
Student3: {
c: 70,
cPlus: 70,
java: 80,
name: "Samson",
regno: "16sksb7034",
unix: 90
}
这是我的dataModel类:
public class Marks {
private String name;
private String regno;
private int c;
private int cPlus;
private int java;
private int unix;
private int percentage;
public Marks() {}
public Marks(int c, int cPlus, int java, int unix) {
this.c = c;
this.cPlus = cPlus;
this.java = java;
this.unix = unix;
}
public int getPercentage() {
return percentage;
}
public void setPercentage(int percentage) {
this.percentage = percentage;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRegno() {
return regno;
}
public void setRegno(String regno) {
this.regno = regno;
}
public int getC() {
return c;
}
public void setC(int c) {
this.c = c;
}
public int getcPlus() {
return cPlus;
}
public void setcPlus(int cPlus) {
this.cPlus = cPlus;
}
public int getJava() {
return java;
}
public void setJava(int java) {
this.java = java;
}
public int getUnix() {
return unix;
}
public void setUnix(int unix) {
this.unix = unix;
}
}
class MarksComparator implements Comparator<Marks> {
@Override
public int compare(Marks marks1, Marks marks2) {
int Marks1Total = marks1.getPercentage();
int Marks2Total = marks2.getPercentage();
if (Marks2Total < Marks1Total) {
return -1;
} else if (Marks2Total > Marks1Total) {
return 1;
} else {
return 0;
}
}
}
这是我的活动课程:
public class MarksFragment extends Fragment{
private List<Marks> mMarksList = new ArrayList<>();
private RecyclerView mRecyclerView;
private MyAdapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private FirebaseDatabase mDatabase;
private DatabaseReference mReference;
private int total=0;
public MarksFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_marks, container, false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
// use a linear layout manager
mLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
// specify an adapter (see also next example)
/*mAdapter = new MyAdapter(getContext(),mMarksList);
mAdapter.notifyDataSetChanged();
mRecyclerView.setAdapter(mAdapter);*/
//get Firebase Reference
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
mDatabase = FirebaseDatabase.getInstance();
mReference = mDatabase.getReference();
mReference.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return view;
}
public void findPercentage(Marks value) {
total =value.getC() + value.getcPlus() + value.getJava() + value.getUnix();
value.setPercentage(total);
}
private void fetchData(DataSnapshot dataSnapshot) {
Marks value = dataSnapshot.getValue(Marks.class);
Log.v("Marks Fragment", "" +value);
findPercentage(value);
mMarksList.add(value);
Collections.sort(mMarksList, new MarksComparator());
// specify an adapter (see also next example)
mAdapter = new MyAdapter(getContext(),mMarksList);
mAdapter.notifyDataSetChanged();
mRecyclerView.setAdapter(mAdapter);
这是我的适配器类:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>{
private Context mContext;
private List<Marks> marksList;
public MyAdapter(Context mContext, List<Marks> marksList) {
this.mContext = mContext;
this.marksList = marksList;
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView mItemName, mItemRegNo, mItemNo, mTotal;
CircleImageView mImageView;
public MyViewHolder(View view) {
super(view);
mItemName = (TextView) view.findViewById(R.id.card_name);
mItemRegNo = (TextView) view.findViewById(R.id.card_regno);
mItemNo = (TextView) view.findViewById(R.id.item_id);
mImageView = (CircleImageView) view.findViewById(R.id.item_photo);
mTotal = view.findViewById(R.id.card_total);
}
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.card_item, parent, false);
return new MyViewHolder(itemView);
}
@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
Marks marks = marksList.get(position);
int count = position + 1;
holder.mItemName.setText("" + marks.getName());
holder.mItemRegNo.setText("" + marks.getRegno());
holder.mItemNo.setText("" + count);
holder.mImageView.setImageResource(R.drawable.after_cookie);
holder.mTotal.setText(""+ marks.getPercentage());
}
@Override
public int getItemCount() {
return marksList.size();
}
}
因此,代码执行的目的是检索数据并计算总数并对学生进行排名。但是当我更新firebase控制台中的数据时,recyclerView中的视图会暂时重复。例如,如果我将Student1 unix值更新为10,那么将在recyclerView中显示两个视图:1表示先前值,2表示更新值,如果更新值,它将再次显示另一个表示新数据的视图而不删除旧观点。但是,如果我重新启动recyclerView会刷新并且一切正常但是在更新期间我运行应用程序时它也会显示临时的重复视图。
我是新来的,这是我的第一个问题所以我甚至无法上传图片,因为您需要10分才能上传照片。我真的希望有人帮助我解决这个问题。我提前谢谢你。
更新
以下是图片链接:
当我启动应用程序时,图像为: first Image
当我更新Student3的unix值时,recyclerView中的图像变为如下所示: After updating the data in firebase console
因此,您会看到它会添加新数据并保留旧数据,直到我重新启动。
答案 0 :(得分:2)
您的问题是,您永远不会检查学生是否已经存在于您的mMarksList
中,因此您只需通过再次添加新成绩来复制他。
我要做的是在firebase中为每个学生添加一个唯一的ID。
然后,您可以检查fetchData
具有该ID的学生是否已经在数组中,删除他并添加新的。
private void fetchData(DataSnapshot dataSnapshot) {
Marks value = dataSnapshot.getValue(Marks.class);
Log.v("Marks Fragment", "" +value);
findPercentage(value);
// Get an iterator.
Iterator<Marks> ite = mMarksList.iterator();
while(ite.hasNext()) {
Marks iteValue = ite.next();
if(iteValue.getId().equals(value.getId())) ite.remove();
}
mMarksList.add(value);
....
}
(可选)为了使其更清晰,您可以覆盖equals
数据模型中的hashcode
和Marks
方法,以便{{1}如果id相等,则对象被认为是相同的。 More
Marks
}
然后可以使用一个hashmap,它会自动覆盖旧学生或者一个arraylist,并在之前迭代它并检查学生是否等于你的新学生,如下所示:
//ASSUMING THAT ID IS int
@Override
public int hashCode() {
return id;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (this.getClass() != obj.getClass()) return false;
Marks other = (Marks) obj;
if (this.getId != other.getId) {
return false;
}
return true;