Android Recyclerview仅添加一个项目时添加多个项目

Android Recyclerview仅添加一个项目时添加多个项目,android,firebase-realtime-database,android-recyclerview,Android,Firebase Realtime Database,Android Recyclerview,首先,我研究了与我类似的问题。基本上,这个答案是我面临的问题的秘密-->。我没有看到任何适合我的问题的解决方案 我在下面附上了我的HomeFragment和HomeListAdapter的代码。我做了一些研究,有人说我不应该在bindviewholder中调用firebase数据库,但firebase quick start数据库示例是我正在关注的,因此如果任何firebase android工程师可以给我一些指导,那将是非常好的 当我在编辑配方片段上单击“添加”时。上传完成后,它进入主片段。我

首先,我研究了与我类似的问题。基本上,这个答案是我面临的问题的秘密-->。我没有看到任何适合我的问题的解决方案

我在下面附上了我的HomeFragment和HomeListAdapter的代码。我做了一些研究,有人说我不应该在bindviewholder中调用firebase数据库,但firebase quick start数据库示例是我正在关注的,因此如果任何firebase android工程师可以给我一些指导,那将是非常好的

当我在编辑配方片段上单击“添加”时。上传完成后,它进入主片段。我感到困惑的是,我在应用程序中的其他适配器都有正确的行为。它只添加一个配方(一次只添加一个是预期的行为)

HomeFragment

package com.irondigitalmedia.keep;


import java.util.ArrayList;


public class HomeFragment extends BaseFragment {

    private static final String TAG = HomeFragment.class.getSimpleName();

    private ArrayList<Recipe> mRecipeList;
    private ArrayList<String> mRecipeIds;
    private RecyclerView HomeRecyclerView;
    private HomeListAdapter adapter;
    private LinearLayoutManager LLM;
    private Context mContext;
    private FirebaseDatabase database;
    private DatabaseReference myRef;
    private Recipe mRecipe;
    private User mUser;
    private int likeCounter = 0;
    private MainActivity mainActivity;
    private BaseActivity baseActivity;
    private Toolbar toolbar;
    private ProgressBar progressBar;

    public HomeFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_home,container,false);

        mContext = view.getContext();
        mRecipeList = new ArrayList<>();
        mRecipeIds = new ArrayList<>();

        HomeRecyclerView = view.findViewById(R.id.frag_search_rv);
        HomeRecyclerView.addItemDecoration(new SpacesItemDecoration(8));
        LLM = new LinearLayoutManager(getContext());
        HomeRecyclerView.setLayoutManager(LLM);
        adapter = new HomeListAdapter(mContext, mRecipeList, mUser);
        HomeRecyclerView.setAdapter(adapter);

        mainActivity = (MainActivity) view.getContext();
        mainActivity.mMainNav.setSelectedItemId(R.id.nav_home);
        toolbar = mainActivity.findViewById(R.id.main_toolbar);
        toolbar.setTitle("Home");
        mainActivity.setSupportActionBar(toolbar);

        if(savedInstanceState != null){
            Log.e(TAG, "onCreateView: savedInstanceState is null");
        }else{
            LoadRecipes();
        }

        return view;
    }

    private void LoadRecipes() {
        database = FirebaseDatabase.getInstance();
        myRef = database.getReference();

        myRef.child(Constants.DATABASE_ROOT_FOLLOWING).child(getUid()).addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
                String key = dataSnapshot.getKey();
                Log.i(TAG, "onChildAdded: key is = " + key);
                if(key!=null){
                    Log.i(TAG, "onChildAdded: key is not null ");
                    myRef.child(Constants.DATABASE_ROOT_USERS_RECIPES).child(key).limitToFirst(5).addChildEventListener(new ChildEventListener() {
                        @Override
                        public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
                            Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey());

                            // A new comment has been added, add it to the displayed list
                            mRecipe = dataSnapshot.getValue(Recipe.class);

                            // [START_EXCLUDE]
                            // Update RecyclerView
                            mRecipeIds.add(dataSnapshot.getKey());
                            mRecipeList.add(mRecipe);
                            adapter.notifyItemInserted(mRecipeList.size() - 1);
                            // [END_EXCLUDE]
                        }

                        @Override
                        public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
                            Log.d(TAG, "onChildChanged:" + dataSnapshot.getKey());

                            // A comment has changed, use the key to determine if we are displaying this
                            // comment and if so displayed the changed comment.
                            mRecipe = dataSnapshot.getValue(Recipe.class);
                            String recipeKey = dataSnapshot.getKey();

                            // [START_EXCLUDE]
                            int commentIndex = mRecipeIds.indexOf(recipeKey);
                            if (commentIndex > -1) {
                                // Replace with the new data
                                mRecipeList.set(commentIndex, mRecipe);

                                // Update the RecyclerView
                                adapter.notifyItemChanged(commentIndex);
                            } else {
                                Log.w(TAG, "onChildChanged:unknown_child:" + recipeKey);
                            }
                            // [END_EXCLUDE]
                        }

                        @Override
                        public void onChildRemoved(DataSnapshot dataSnapshot) {
                            Log.d(TAG, "onChildRemoved:" + dataSnapshot.getKey());

                            // A comment has changed, use the key to determine if we are displaying this
                            // comment and if so remove it.
                            String recipeKey = dataSnapshot.getKey();

                            // [START_EXCLUDE]
                            int commentIndex = mRecipeIds.indexOf(recipeKey);
                            if (commentIndex > -1) {
                                // Remove data from the list
                                mRecipeIds.remove(commentIndex);
                                mRecipeList.remove(commentIndex);

                                // Update the RecyclerView
                                adapter.notifyItemRemoved(commentIndex);
                            } else {
                                Log.w(TAG, "onChildRemoved:unknown_child:" + recipeKey);
                            }
                            // [END_EXCLUDE]
                        }

                        @Override
                        public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
                            Log.d(TAG, "onChildMoved:" + dataSnapshot.getKey());

                            // A comment has changed position, use the key to determine if we are
                            // displaying this comment and if so move it.
                            mRecipe = dataSnapshot.getValue(Recipe.class);
                            String recipeKey = dataSnapshot.getKey();

                            // ...
                        }

                        @Override
                        public void onCancelled(DatabaseError databaseError) {
                            Log.w(TAG, "recipes:onCancelled", databaseError.toException());
                            Toast.makeText(mContext, "Failed to load recipes.",
                                    Toast.LENGTH_SHORT).show();
                        }
                    });

                }else{
                    Log.e(TAG, "onChildAdded: Key is null");
                }


            }

            @Override
            public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

            }

            @Override
            public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {

            }

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

            }

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

            }
        });

    }

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelableArrayList(Constants.SAVED_STATE_HOME,mRecipeList);
    }

    @Override
    public void onStart() {
        super.onStart();
        getActivity().setTitle("Home");
    }

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



}
package com.irondigitalmedia.keep.Adapters;



public class EditIngredientAdapter extends RecyclerView.Adapter<EditIngredientAdapter.IngredientViewHolder> {

    private static final String TAG = EditIngredientAdapter.class.getSimpleName();

    private String dataSnapShotKey;
    private Context mContext;
    private DatabaseReference mDatabaseReference;
    private ChildEventListener mChildEventListener;

    public List<String> mIngredientIds = new ArrayList<>();
    public List<Ingredient> mIngredients = new ArrayList<>();

    public EditIngredientAdapter(final Context mContext, DatabaseReference ref) {
        this.mContext = mContext;
        this.mDatabaseReference = ref;


        // Create child event listener
        // [START child_event_listener_recycler]
        ChildEventListener childEventListener = new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
                Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey());
                dataSnapShotKey = dataSnapshot.getKey();
                // A new comment has been added, add it to the displayed list
                Ingredient ingredient = dataSnapshot.getValue(Ingredient.class);

                // [START_EXCLUDE]
                // Update RecyclerView
                mIngredientIds.add(dataSnapshot.getKey());
                mIngredients.add(ingredient);
                notifyItemInserted(mIngredients.size() - 1);
                // [END_EXCLUDE]
            }

            @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
                Log.d(TAG, "onChildChanged:" + dataSnapshot.getKey());

                // A comment has changed, use the key to determine if we are displaying this
                // comment and if so displayed the changed comment.
                Ingredient newIngredient = dataSnapshot.getValue(Ingredient.class);
                String ingredientKey = dataSnapshot.getKey();

                // [START_EXCLUDE]
                int ingredientIndex = mIngredientIds.indexOf(ingredientKey);
                if (ingredientIndex > -1) {
                    // Replace with the new data
                    mIngredients.set(ingredientIndex, newIngredient);

                    // Update the RecyclerView
                    notifyItemChanged(ingredientIndex);
                } else {
                    Log.w(TAG, "onChildChanged:unknown_child:" + ingredientKey);
                }
                // [END_EXCLUDE]
            }

            @Override
            public void onChildRemoved(DataSnapshot dataSnapshot) {
                Log.d(TAG, "onChildRemoved:" + dataSnapshot.getKey());

                // A comment has changed, use the key to determine if we are displaying this
                // comment and if so remove it.
                String ingredientKey = dataSnapshot.getKey();

                // [START_EXCLUDE]
                int ingredientIndex = mIngredientIds.indexOf(ingredientKey);
                if (ingredientIndex > -1) {
                    // Remove data from the list
                    mIngredientIds.remove(ingredientIndex);
                    mIngredients.remove(ingredientIndex);

                    // Update the RecyclerView
                    notifyItemRemoved(ingredientIndex);
                } else {
                    Log.w(TAG, "onChildRemoved:unknown_child:" + ingredientKey);
                }
                // [END_EXCLUDE]
            }

            @Override
            public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
                Log.d(TAG, "onChildMoved:" + dataSnapshot.getKey());

                // A comment has changed position, use the key to determine if we are
                // displaying this comment and if so move it.
                Ingredient movedIngredient = dataSnapshot.getValue(Ingredient.class);
                String ingredientKey = dataSnapshot.getKey();

                // ...
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                Log.w(TAG, "postComments:onCancelled", databaseError.toException());
                Toast.makeText(mContext, "Failed to load comments.",
                        Toast.LENGTH_SHORT).show();
            }
        };


        ref.addChildEventListener(childEventListener);
        // [END child_event_listener_recycler]

        // Store reference to listener so it can be removed on app stop
        mChildEventListener = childEventListener;

    }

    @NonNull
    @Override
    public IngredientViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        View view = inflater.inflate(R.layout.list_item_recipe_ingredient, parent, false);
        return new IngredientViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull IngredientViewHolder holder, int position) {
        Ingredient ingredient = mIngredients.get(position);
        holder.ingred.setText(ingredient.ingredient);
    }

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

    public class IngredientViewHolder extends RecyclerView.ViewHolder {

        public TextView ingred;

        public IngredientViewHolder(View itemView) {
            super(itemView);

            ingred = itemView.findViewById(R.id.recipe_ingredients_tv);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(mContext, "Ingredient: " + mIngredients.get(getAdapterPosition()).ingredient, Toast.LENGTH_SHORT).show();
                }
            });

            itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    Toast.makeText(mContext, "Long Clicked " + getAdapterPosition(), Toast.LENGTH_SHORT).show();

                    return true;
                }
            });
        }
    }

    public void RemoveIngredient(DatabaseReference reference){
        reference.removeValue();
    }

    public void cleanupListener() {
        if (mChildEventListener != null) {
            mDatabaseReference.removeEventListener(mChildEventListener);
        }
    }


}
package com.irondigitalmedia.keep;
导入java.util.ArrayList;
公共类HomeFragment扩展了BaseFragment{
私有静态最终字符串标记=HomeFragment.class.getSimpleName();
私人阵列列表;
私人ArrayList mRecipeIds;
私人回收站查看家庭回收站查看;
私有HomeListAdapter;
私人直线酒店经理LLM;
私有上下文;
私有FirebaseDatabase数据库;
私有数据库参考myRef;
私家菜谱;
私人用户缪斯;
private int likeCounter=0;
私人活动;
私人基地活动;
专用工具栏;
私人ProgressBar ProgressBar;
公共HomeFragment(){
//必需的空公共构造函数
}
@凌驾
创建视图上的公共视图(布局、充气机、视图组容器、,
Bundle savedInstanceState){
视图=充气机。充气(右布局。碎片_home,容器,false);
mContext=view.getContext();
mRecipeList=newarraylist();
mRecipeIds=newarraylist();
HomeRecyclerView=view.findViewById(R.id.frag\u search\u rv);
HomeRecyclerView.addItemDecoration(新空间站点Decoration(8));
LLM=新的LinearLayoutManager(getContext());
HomeRecyclerView.setLayoutManager(LLM);
适配器=新的HomeListAdapter(McContext、mRecipeList、mUser);
HomeRecyclerView.setAdapter(适配器);
mainActivity=(mainActivity)view.getContext();
主活动。mMainNav.setSelectedItemId(R.id.nav_home);
toolbar=mainActivity.findViewById(R.id.main\u工具栏);
工具栏。设置标题(“主页”);
mainActivity.setSupportActionBar(工具栏);
如果(savedInstanceState!=null){
e(标记“onCreateView:savedInstanceState为null”);
}否则{
LoadRecipes();
}
返回视图;
}
私有void LoadRecipes(){
database=FirebaseDatabase.getInstance();
myRef=database.getReference();
myRef.child(Constants.DATABASE\u ROOT\u FOLLOWING).child(getUid()).addChildEventListener(new ChildEventListener()){
@凌驾
公共void onChildaded(@NonNull DataSnapshot DataSnapshot,@null字符串s){
String key=dataSnapshot.getKey();
Log.i(标记“onchildaded:key is=“+key”);
if(key!=null){
Log.i(标记“onchildaded:key不为null”);
myRef.child(常量.数据库\根用户\配方).child(键).limitToFirst(5).addChildEventListener(新的ChildEventListener()){
@凌驾
公共void onChildAdded(DataSnapshot DataSnapshot,字符串previousChildName){
d(标记“onchildaded:”+dataSnapshot.getKey());
//已添加新注释,请将其添加到显示的列表中
mRecipe=dataSnapshot.getValue(Recipe.class);
//[开始时不包括]
//更新回收视图
mRecipeIds.add(dataSnapshot.getKey());
mRecipeList.add(mRecipe);
adapter.notifyItemInserted(mRecipeList.size()-1);
//[完]
}
@凌驾
公共void onChildChanged(DataSnapshot DataSnapshot,字符串previousChildName){
d(标记“onChildChanged:”+dataSnapshot.getKey());
//注释已更改,请使用键确定是否显示此注释
//注释,如果是,则显示更改的注释。
mRecipe=dataSnapshot.getValue(Recipe.class);
字符串recipeKey=dataSnapshot.getKey();
//[开始时不包括]
int commentIndex=mRecipeIds.indexOf(recipeKey);
如果(注释索引>-1){
//替换为新数据
mRecipeList.set(commentIndex,mRecipe);
//更新RecyclerView
adapter.notifyItemChanged(commentIndex);
}否则{
Log.w(标记“onChildChanged:unknown_child:”+recipeKey);
}
//[完]
}
@凌驾
ChildRemoved上的公共void(DataSnapshot DataSnapshot){
d(标记“onChildRemoved:+dataSnapshot.getKey());
//注释已更改,请使用键确定是否显示此注释
//注释,如果是,则将其删除。
字符串recipeKey=dataSnapshot.getKey();
package com.irondigitalmedia.keep.Adapters;



public class EditIngredientAdapter extends RecyclerView.Adapter<EditIngredientAdapter.IngredientViewHolder> {

    private static final String TAG = EditIngredientAdapter.class.getSimpleName();

    private String dataSnapShotKey;
    private Context mContext;
    private DatabaseReference mDatabaseReference;
    private ChildEventListener mChildEventListener;

    public List<String> mIngredientIds = new ArrayList<>();
    public List<Ingredient> mIngredients = new ArrayList<>();

    public EditIngredientAdapter(final Context mContext, DatabaseReference ref) {
        this.mContext = mContext;
        this.mDatabaseReference = ref;


        // Create child event listener
        // [START child_event_listener_recycler]
        ChildEventListener childEventListener = new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
                Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey());
                dataSnapShotKey = dataSnapshot.getKey();
                // A new comment has been added, add it to the displayed list
                Ingredient ingredient = dataSnapshot.getValue(Ingredient.class);

                // [START_EXCLUDE]
                // Update RecyclerView
                mIngredientIds.add(dataSnapshot.getKey());
                mIngredients.add(ingredient);
                notifyItemInserted(mIngredients.size() - 1);
                // [END_EXCLUDE]
            }

            @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
                Log.d(TAG, "onChildChanged:" + dataSnapshot.getKey());

                // A comment has changed, use the key to determine if we are displaying this
                // comment and if so displayed the changed comment.
                Ingredient newIngredient = dataSnapshot.getValue(Ingredient.class);
                String ingredientKey = dataSnapshot.getKey();

                // [START_EXCLUDE]
                int ingredientIndex = mIngredientIds.indexOf(ingredientKey);
                if (ingredientIndex > -1) {
                    // Replace with the new data
                    mIngredients.set(ingredientIndex, newIngredient);

                    // Update the RecyclerView
                    notifyItemChanged(ingredientIndex);
                } else {
                    Log.w(TAG, "onChildChanged:unknown_child:" + ingredientKey);
                }
                // [END_EXCLUDE]
            }

            @Override
            public void onChildRemoved(DataSnapshot dataSnapshot) {
                Log.d(TAG, "onChildRemoved:" + dataSnapshot.getKey());

                // A comment has changed, use the key to determine if we are displaying this
                // comment and if so remove it.
                String ingredientKey = dataSnapshot.getKey();

                // [START_EXCLUDE]
                int ingredientIndex = mIngredientIds.indexOf(ingredientKey);
                if (ingredientIndex > -1) {
                    // Remove data from the list
                    mIngredientIds.remove(ingredientIndex);
                    mIngredients.remove(ingredientIndex);

                    // Update the RecyclerView
                    notifyItemRemoved(ingredientIndex);
                } else {
                    Log.w(TAG, "onChildRemoved:unknown_child:" + ingredientKey);
                }
                // [END_EXCLUDE]
            }

            @Override
            public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
                Log.d(TAG, "onChildMoved:" + dataSnapshot.getKey());

                // A comment has changed position, use the key to determine if we are
                // displaying this comment and if so move it.
                Ingredient movedIngredient = dataSnapshot.getValue(Ingredient.class);
                String ingredientKey = dataSnapshot.getKey();

                // ...
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                Log.w(TAG, "postComments:onCancelled", databaseError.toException());
                Toast.makeText(mContext, "Failed to load comments.",
                        Toast.LENGTH_SHORT).show();
            }
        };


        ref.addChildEventListener(childEventListener);
        // [END child_event_listener_recycler]

        // Store reference to listener so it can be removed on app stop
        mChildEventListener = childEventListener;

    }

    @NonNull
    @Override
    public IngredientViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        View view = inflater.inflate(R.layout.list_item_recipe_ingredient, parent, false);
        return new IngredientViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull IngredientViewHolder holder, int position) {
        Ingredient ingredient = mIngredients.get(position);
        holder.ingred.setText(ingredient.ingredient);
    }

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

    public class IngredientViewHolder extends RecyclerView.ViewHolder {

        public TextView ingred;

        public IngredientViewHolder(View itemView) {
            super(itemView);

            ingred = itemView.findViewById(R.id.recipe_ingredients_tv);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(mContext, "Ingredient: " + mIngredients.get(getAdapterPosition()).ingredient, Toast.LENGTH_SHORT).show();
                }
            });

            itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    Toast.makeText(mContext, "Long Clicked " + getAdapterPosition(), Toast.LENGTH_SHORT).show();

                    return true;
                }
            });
        }
    }

    public void RemoveIngredient(DatabaseReference reference){
        reference.removeValue();
    }

    public void cleanupListener() {
        if (mChildEventListener != null) {
            mDatabaseReference.removeEventListener(mChildEventListener);
        }
    }


}
mRecipeList = new ArrayList<>();
mRecipeIds = new ArrayList<>();
myRef = database.getReference();

mRecipeList.clear();
mRecipeIds.clear();

myRef.child(Constants.DATABASE_ROOT_FOLLOWING).child(getUid()).add...