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