【问题标题】:Data is getting added into list instead of getting updated in addChildEventListener's onChildChanged()数据被添加到列表中,而不是在 addChildEventListener 的 onChildChanged() 中更新
【发布时间】:2018-03-23 05:55:30
【问题描述】:

我在 firebase 中有一些数据会因某些特定操作而发生更改,我希望该更改显示在应用程序中。

我有一个 RecyclerView,其中填充了来自 firebase 的所有数据。

代码如下:

    databaseReference.child("uListings").child(AccessToken.getCurrentAccessToken().getUserId()).addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                // recyclerview gets populated here
            }

            @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String s) {
                if (dataSnapshot.getValue() != null) {
                    Map<String,String> map = (Map<String,String>)dataSnapshot.getValue();
                    Map<ArrayList<String>,ArrayList<String>> map2 = (Map<ArrayList<String>,ArrayList<String>>)dataSnapshot.getValue();
                    String pDescription = map.get("pDescription");
                    String pDuration = map.get("pDuration");
                    String pPrice = map.get("pPrice");
                    String postedAt = map.get("postedAt");
                    String views = map.get("views");
                    ArrayList<String> imageUrl = map2.get("imageUrl");

                            if (imageUrl != null) {
                                UHandler pHandler = new UHandler(imageUrl.get(0), pDescription, pDuration, pPrice, postedAt, views);
                                list.add(pHandler);
                                adapter.notifyDataSetChanged();
                                progressBar.setVisibility(View.INVISIBLE);
                            } else {
                                Toast.makeText(getBaseContext(), "imageUrlNone", Toast.LENGTH_SHORT).show();
                            }

                } else {
                    Log.d("PDPchange", "NULL");
                    progressBar.setVisibility(View.INVISIBLE);
                }
            }

            @Override
            public void onChildRemoved(DataSnapshot dataSnapshot) {

            }

            @Override
            public void onChildMoved(DataSnapshot dataSnapshot, String s) {

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });

这里是UHandlerAdapter.java

public class UHandlerAdapter extends RecyclerView.Adapter<UHandlerAdapter.MyViewHolder> {

    private Context mContext;
    private List<UHandler> listingList;

    public class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView pDescription, pDuration, pPrice, postedAt, listingViews, imageUrl;
        public ArrayList<String> imageUrls;
        public CircleImageView pImage;


        public MyViewHolder(View view) {
            super(view);
            pImage = (CircleImageView) view.findViewById(R.id.p_image_profile);
            pDescription = (TextView) view.findViewById(R.id.p_description_profile);
            pDuration = (TextView) view.findViewById(R.id.p_duration_profile);
            pPrice = (TextView) view.findViewById(R.id.p_price_profile);
            postedAt = (TextView) view.findViewById(R.id.p_posted_when_profile);
            listingViews = (TextView) view.findViewById(R.id.listing_views_profile);
            imageUrl = (TextView) view.findViewById(R.id.image_urls_profile);
        }
    }


    public UHandlerAdapter(Context mContext, List<UProfileHandler> listingList) {
        this.mContext = mContext;
        this.listingList = listingList;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.profile_all, parent, false);

        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(final MyViewHolder holder, int position) {
        UHandler handler = listingList.get(position);
        holder.pDescription.setText(handler.getPDescriptionProfile());
        holder.pDuration.setText(handler.getPDurationProfile());
        holder.pPrice.setText(handler.getPPriceProfile());
        holder.postedAt.setText(handler.getPostedAt());
        holder.listingViews.setText(handler.getListingViews());

        // loading album cover using Glide library
        Glide.with(mContext)
                .load(handler.getPImageProfile())
                .apply(new RequestOptions().placeholder(R.drawable.ic_placeholder).error(R.drawable.ic_error))
                .into(holder.pImage);

    }

    @Override
    public int getItemCount() {
        return listingList.size();
    }
}

问题在于,在 onChildChanged() 中,views 发生了更改,在列表中添加了一个完整的其他项目,反映了它的更改值,而不仅仅是在 onChildAdded() 中先前添加的项目中更新。

我如何才能在之前添加的项目本身中更新它?

【问题讨论】:

  • 首先你有一个ArrayList&lt;String&gt; imageUrl = map2.get("imageUrl"); 的错误map.get(Object key) 不是类型安全的,即。如果您提供错误类型的密钥,编译器不会抱怨。请参阅stackoverflow.com/questions/857420/… 了解更多信息。
  • @alan7678 好的。感谢您指出。也请回答提出的问题。
  • 假设 UHandler 是您的视图模型,如果您不想要新项目,则不应使用 new。所以简单地说不要使用new 不要使用list.add,使用list.get 来检索您的对象并更新它。
  • @alan7678 如何在此处使用 list.get 检索对象。无法知道此处的位置,因为列表中的任何项目的数据都可以更新。
  • 您的意思是有新数据添加到适配器或火力库中?如果是首选,您可能需要在此处提供您的适配器。

标签: android arraylist firebase-realtime-database android-recyclerview


【解决方案1】:

您可以存储keys 以更新它,例如:

 ArrayList<String> mKeys = new ArrayList<String>();  

databaseReference.child("uListings").child(AccessToken.getCurrentAccessToken().getUserId()).addChildEventListener(new ChildEventListener() {
                    @Override
                    public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                        // recyclerview gets populated here

                        String key = dataSnapshot.getKey();
                        mKeys.add(key);
                        adapter.notifyDataSetChanged();

                    }

                    @Override
                    public void onChildChanged(DataSnapshot dataSnapshot, String s) {
                        if (dataSnapshot.getValue() != null) {
                             .......
                             //now we get the index to update specific value
                              String key = dataSnapshot.getKey();
                              int index = mKeys.indexOf(key);
                              list.set(index, pHandler);

                              adapter.notifyDataSetChanged();
                              ....
                    }

【讨论】:

  • 这成功了!将在 14 小时后奖励赏金(由 StackOverflow 提示)。
  • @HammadNasir 我不知道那个库是如何工作的,抱歉。
  • hmm.. 我认为它只需要一个逻辑而不是库中的任何功能。你能好好看看这个问题吗?
  • 帮不上忙,兄弟?
  • 萨拉姆。请看看这个:stackoverflow.com/questions/46761756/…
猜你喜欢
  • 1970-01-01
  • 2017-10-25
  • 1970-01-01
  • 1970-01-01
  • 2022-01-13
  • 1970-01-01
  • 2023-02-04
  • 1970-01-01
  • 2011-05-08
相关资源
最近更新 更多