【问题标题】:Firebase Database getChildrenCount() AndroidFirebase 数据库 getChildrenCount() Android
【发布时间】:2019-07-21 01:57:51
【问题描述】:

我已经尝试了所有方法并查看了这些问题(onetwothree(vid tut))以寻求答案并尝试了它们,但仍然无济于事,我无法设置我的 childrencount可以在使用 int 的日志中清楚地看到 textview。

public class HomeListAdapter extends RecyclerView.Adapter<HomeListAdapter.ViewHolder> {
    private static final String TAG = HomeListAdapter.class.getSimpleName();
    private DatabaseReference mDatabase;
    private Context context;
    private List<Recipe> mRecipesList;
    private MainActivity mainActivity;
    private ProgressBar progressBar;
    private int likeCounter = 0;

    public HomeListAdapter(Context context, List<Recipe> mRecipesList) {
        this.context = context;
        this.mRecipesList = mRecipesList;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.list_recipes_recipe_item, parent, false);

        mDatabase = FirebaseDatabase.getInstance().getReference();
        mainActivity = (MainActivity) view.getContext();
        progressBar = mainActivity.findViewById(R.id.main_progressBar);

        return new HomeListAdapter.ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        final Recipe recipe = mRecipesList.get(position);
        SetUserData(holder, position);
        holder.tv_recipe_title.setText(mRecipesList.get(position).getTitle());
        holder.tv_recipe_prepTime.setText(mRecipesList.get(position).getPrepTime());


        Glide.with(context).load(mRecipesList.get(position).getUrl())
                .placeholder(R.drawable.ic_loading).thumbnail(0.05f).fitCenter()
                .transition(DrawableTransitionOptions.withCrossFade()).centerCrop()
                .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
                .into(holder.recipe_thumbnail);

        Log.i(TAG, "onBindViewHolder: Database Reference = " + mDatabase.child(Constants.DATABASE_ROOT_RECIPES).child(recipe.getUid()).child(Constants.DATABASE_ROOT_LIKES));
        mDatabase.child(Constants.DATABASE_ROOT_RECIPES).child(recipe.getUid()).child(Constants.DATABASE_ROOT_LIKES).addValueEventListener(new ValueEventListener() {
            @SuppressLint("SetTextI18n")
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                likeCounter = (int) dataSnapshot.getChildrenCount();
                Log.i(TAG, "onDataChange: ChildrenCount = " + recipe.getTitle() + " " + likeCounter);
                holder.tv_like_counter.setText(Integer.toString(likeCounter));
            }


            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

        mDatabase.child(Constants.DATABASE_ROOT_RECIPES).child(recipe.getUid())
                .child(Constants.DATABASE_ROOT_LIKES).addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if(dataSnapshot.hasChild(getUid())){
                    holder.like.setLiked(true);
                    Log.i(TAG, "onDataChange: LIKED RECIPE...");
                }else{
                    Log.i(TAG, "onDataChange: RECIPE IS NOT LIKED...");
                    holder.like.setLiked(false);
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });
        mDatabase.child(Constants.DATABASE_ROOT_RECIPES).child(recipe.getUid())
                .addValueEventListener(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                        if(dataSnapshot.hasChild(Constants.DATABASE_RECIPE_LIKE_COUNT_VALUE)){
                            holder.tv_like_counter.setText(String.valueOf(dataSnapshot.child(Constants.DATABASE_RECIPE_LIKE_COUNT_VALUE).getValue()));
                        }else{
                            holder.tv_like_counter.setText("0");
                        }
                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError databaseError) {

                    }
                });
        holder.like.setOnLikeListener(new OnLikeListener() {
            @Override
            public void liked(LikeButton likeButton) {
                Log.i(TAG, "liked: LIKED");
                // Add like
                holder.like.setLiked(true);
                Log.i(TAG, "CheckLikeStatus: " + recipe.title + " " + recipe.hasLiked);
                mDatabase.child(Constants.DATABASE_ROOT_RECIPES).child(recipe.getUid()).child(Constants.DATABASE_ROOT_LIKES).child(getUid()).setValue("true");

            }

            @Override
            public void unLiked(LikeButton likeButton) {
                Log.i(TAG, "unLiked: UNLIKED");
                // remove Like
                holder.like.setLiked(false);
                Log.i(TAG, "CheckLikeStatus: " + recipe.title + " " + recipe.hasLiked);
                mDatabase.child(Constants.DATABASE_ROOT_RECIPES).child(recipe.getUid()).child(Constants.DATABASE_ROOT_LIKES).child(getUid()).removeValue();

                }

        });

    }

    private void SetUserData(ViewHolder holder, int position) {
        mDatabase.child(Constants.DATABASE_ROOT_USERS).child(mRecipesList.get(position).getCreatorId())
                .addValueEventListener(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                        User user = dataSnapshot.getValue(User.class);
                        holder.tv_user_username.setText(user.getUsername());
                        Glide.with(context).load(user.getUrl()).centerCrop().placeholder(R.drawable.ic_loading).into(holder.userPhoto);
                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError databaseError) {

                    }
                });
    }

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


    public class ViewHolder extends RecyclerView.ViewHolder {

        public TextView tv_recipe_title, tv_recipe_prepTime, tv_user_username, tv_like_counter;
        public ImageView recipe_thumbnail;
        public LikeButton like;
        public CircleImageView userPhoto;
        public LinearLayout user_ll;
        public FirebaseAuth mAuth;
        public FirebaseDatabase mDatabase;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            mainActivity = (MainActivity) itemView.getContext();
            mDatabase = FirebaseDatabase.getInstance();
            tv_recipe_title = itemView.findViewById(R.id.recipe_item_title);
            tv_recipe_prepTime = itemView.findViewById(R.id.recipe_item_time);
            recipe_thumbnail = itemView.findViewById(R.id.recipe_item_photo);
            like = itemView.findViewById(R.id.recipe_item_image_like);
            tv_like_counter = itemView.findViewById(R.id.recipe_item_like_counter);
            userPhoto = itemView.findViewById(R.id.recipe_item_user_photo);
            tv_user_username = itemView.findViewById(R.id.recipe_item_user_username);
            user_ll = itemView.findViewById(R.id.recipe_item_user_linearLayout);

            user_ll.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    ProfileFragment pf = new ProfileFragment();
                    if(pf.isAdded()){
                        return;
                    }else{
                        Bundle bundle = new Bundle();
                        bundle.putString(Constants.EXTRA_USER_UID,mRecipesList.get(getAdapterPosition()).getCreatorId());
                        Log.i(TAG, "onClick: Fragment Interaction recipe Creator Id = " + mRecipesList.get(getAdapterPosition()).getCreatorId());
                        FragmentTransaction ft = mainActivity.getSupportFragmentManager().beginTransaction();
                        pf.setArguments(bundle);
                        ft.replace(R.id.main_frame, pf, Constants.FRAGMENT_TAG_PROFILE);
                        ft.addToBackStack(Constants.FRAGMENT_TAG_PROFILE);
                        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
                        ft.commit();
                    }
                }
            });

            itemView.setOnClickListener(v -> {
                RecipeDetailsFragment rd = new RecipeDetailsFragment();
                if(rd.isAdded()){
                    return;
                }else{
                    Bundle bundle = new Bundle();
                    bundle.putString(Constants.EXTRA_RECIPE_KEY,mRecipesList.get(getAdapterPosition()).getUid());
                    bundle.putString(Constants.EXTRA_RECIPE_CREATOR_ID, mRecipesList.get(getAdapterPosition()).getCreatorId());
                    Log.i(TAG, "onClick: Fragment Interaction recipe Key is = " + mRecipesList.get(getAdapterPosition()).getUid());
                    FragmentTransaction ft = mainActivity.getSupportFragmentManager().beginTransaction();
                    rd.setArguments(bundle);
                    ft.replace(R.id.main_frame, rd, Constants.FRAGMENT_TAG_RECIPE_DETAILS);
                    ft.addToBackStack(null);
                    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
                    ft.commit();
                }
            });
        }

    }

    public String getUid() {
        return FirebaseAuth.getInstance().getCurrentUser().getUid();
    }
    }

【问题讨论】:

  • 您是否在 onBindViewHolder 中运行此代码?
  • 请将您的数据库结构添加为 JSON 文件或至少作为屏幕截图。也请回复@AlexMamo
  • @AlexMamo,是的,我是。我将发布整个适配器代码,以便您查看。
  • @majuran 我更新了代码,向您展示了整个适配器。
  • 我要求的是数据库结构而不是适配器类。

标签: android firebase firebase-realtime-database


【解决方案1】:

所以,在检查了日志之后,很明显 Firebase 没有任何问题。但是,您使用适配器的视图绑定过程有问题。您现在正在遵循的教程不会有帮助,因为在 firebase 方面一切正常。

问题是,当你打电话时 holder.tv_like_counter.setText(Integer.toString(likeCounter)); , tv_like_counter 还没准备好。

如果您能展示如何在适配器中绑定视图,那就太好了。如果没有,您也可以参考此link 来解决您的问题。至少现在你知道你需要朝哪个方向搜索;)

【讨论】:

  • 抱歉,已经设置好了。我已经更新了我的问题以显示代码。
【解决方案2】:

检查视图绑定后,我做了更多不同的透视图。我发现有矛盾。见下文:

mDatabase.child(Constants.DATABASE_ROOT_RECIPES).child(recipe.getUid())
            .addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    if(dataSnapshot.hasChild(Constants.DATABASE_RECIPE_LIKE_COUNT_VALUE)){
                        holder.tv_like_counter.setText(String.valueOf(dataSnapshot.child(Constants.DATABASE_RECIPE_LIKE_COUNT_VALUE).getValue()));
                    }else{
                        // likes do not exist
                        holder.tv_like_counter.setText("0");
                    }
                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {

                }
            });

我删除了 holder.tv_like_counter.setText("0");。如果快照没有孩子,它应该只将其设置为 0。我只是忘记了我在进行故障排除时的逻辑。

【讨论】:

    【解决方案3】:

    不要在onBindViewHolder 中进行从数据库中获取数据的操作,这是一种非常糟糕的做法,并且每次视图显示时都会创建数据调用。

    它不会完成,这就是你没有得到输出的原因。因为在获得输出之前它可能会被破坏。

    在您的 Activity 中执行整个数据相关操作并传递 数据到适配器。

    this

    编码愉快!!!

    【讨论】:

    • 我最终解决了我的问题,这是一个我没有看到的错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-17
    • 1970-01-01
    • 2017-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多