I currently encounter an issue that everything returns to the same list. I know it is because I add everything into the same array. But how to add them to specific location like the one in my firebase.
public class GroupAdp extends RecyclerView.Adapter<GroupAdp.ViewHolder> {
//Initialize activities and array list
private Activity activity;
ArrayList<String> arrayListGroup;
MemberAdp adapterMember;
//Create constructor
GroupAdp(Activity activity,ArrayList<String> arrayListGroup){
this.activity = activity;
this.arrayListGroup = arrayListGroup;
// notifyDataSetChanged();
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_row_group,parent,false);
return new GroupAdp.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
//Set group name on TextView
holder.tvName.setText(arrayListGroup.get(position));
//Initialize member ArrayList
ArrayList<String> arrayListMember = new ArrayList<>();
//Using for loop to add multiple members
// for (int i=1; i<=6; i++){
// arrayListMember.add("Member " + i);
// }
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Course_ID_Section");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
String UID = user.getUid();
for (DataSnapshot courseSnapshot: snapshot.getChildren()) {
for (DataSnapshot userSnapshot: courseSnapshot.getChildren()) {
// arrayListMember.add(userSnapshot.getValue(String.class));
if(UID.equals(userSnapshot.getKey())) {
arrayListMember.add(userSnapshot.getValue(String.class));
}
}
}
adapterMember.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
//Initialize member adapter
adapterMember = new MemberAdp(arrayListMember);
//Initialize layout manager
LinearLayoutManager layoutManagerMember = new LinearLayoutManager(activity);
//Set layout manager
holder.rvMember.setLayoutManager(layoutManagerMember);
//Set adapter
holder.rvMember.setAdapter(adapterMember);
}
#Override
public int getItemCount() {
return arrayListGroup.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
//Initialize variable
TextView tvName;
RecyclerView rvMember;
public ViewHolder(#NonNull View itemView) {
super(itemView);
//Assign variable
tvName = itemView.findViewById(R.id.tv_name);
rvMember = itemView.findViewById(R.id.rv_member);
}
}
}
public class HealthAlertActivity2 extends Fragment {
//Initialize variable
RecyclerView rvGroup;
ArrayList<String> arrayListGroup;
LinearLayoutManager layoutManagerGroup;
GroupAdp adapterGroup;
//#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View healthAlertFragment = inflater.inflate(R.layout.healthalert_activity2, container, false);
//Assign variable
rvGroup = healthAlertFragment.findViewById(R.id.rv_group);
//Using for loop to add multiple group
//Used for dummy display for now
// for (int i= 1; i<=6; i++){
// arrayListGroup.add("Group " + i);
// }
ArrayList<String> arrayListGroup = new ArrayList<>();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Course_ID_Section");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
String UID = user.getUid();
Map<String, Object> map = (Map<String, Object>) snapshot.getValue();
Log.e("LOG_TAG", "Value:" + map);
assert map != null;
for (Map.Entry<String, Object> entry : map.entrySet()) {
Log.e("The Result", entry.getKey());
arrayListGroup.add(entry.getKey());
}
adapterGroup.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Log.e("LOG_TAG", "Failed to read value.", error.toException());
}
});
//Initialize group adapter
adapterGroup = new GroupAdp(getActivity(), arrayListGroup);
//Initialize layout manager
layoutManagerGroup = new LinearLayoutManager(getActivity());
//Set layout manager
rvGroup.setLayoutManager(layoutManagerGroup);
//Set adapter
rvGroup.setAdapter(adapterGroup);
return healthAlertFragment;
}
}
public class MemberAdp extends RecyclerView.Adapter<MemberAdp.ViewHolder> {
//Initialize ArrayList
ArrayList<String> arrayListMember;
//Create constructor
public MemberAdp(ArrayList<String> arrayListMember) {
this.arrayListMember = arrayListMember;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//Initialize view
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_row_member,parent,false);
return new MemberAdp.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
//Set member name on TextView
holder.tvName.setText(arrayListMember.get(position));
}
#Override
public int getItemCount() {
return arrayListMember.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
//Initialize variable
TextView tvName;
public ViewHolder(#NonNull View itemView) {
super(itemView);
//Assign variable
tvName = itemView.findViewById(R.id.tv_name);
}
}
}
Ideally, I want to return all students who have the same class as the user in the firebase and return them to different list based on how they are stored in firebase.
The thing is that you subscribe to the root of your data Course_ID_Section, so you get all the data in the same way without respect to its Courses ids. There are a few ways how to handle it, but in your case, I would recommend the following:
Store students not in the same array arrayListMember, but in Hashtable (or another associative array implementation), or in a new Course class. Then, fill in your new data structure when you are looping through courses in your line arrayListMember.add(userSnapshot.getValue(String.class)), because at this point you have a data about a student, and courseSnapshot to get the name of a course
Related
I want to retrieve my firebase data into a card list, but not showing anything.
public class GroupAdp extends RecyclerView.Adapter<GroupAdp.ViewHolder> {
//Initialize activities and array list
private Activity activity;
ArrayList<String> arrayListGroup;
//Create constructor
GroupAdp(Activity activity,ArrayList<String> arrayListGroup){
this.activity = activity;
this.arrayListGroup = arrayListGroup;
notifyDataSetChanged();
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_row_group,parent,false);
return new GroupAdp.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
//Set group name on TextView
holder.tvName.setText(arrayListGroup.get(position));
//Initialize member ArrayList
ArrayList<String> arrayListMember = new ArrayList<>();
//Using for loop to add multiple members
for (int i=1; i<=6; i++){
arrayListMember.add("Member " + i);
}
//Initialize member adapter
MemberAdp adapterMember = new MemberAdp(arrayListMember);
//Initialize layout manager
LinearLayoutManager layoutManagerMember = new LinearLayoutManager(activity);
//Set layout manager
holder.rvMember.setLayoutManager(layoutManagerMember);
//Set adapter
holder.rvMember.setAdapter(adapterMember);
}
#Override
public int getItemCount() {
return arrayListGroup.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
//Initialize variable
TextView tvName;
RecyclerView rvMember;
public ViewHolder(#NonNull View itemView) {
super(itemView);
//Assign variable
tvName = itemView.findViewById(R.id.tv_name);
rvMember = itemView.findViewById(R.id.rv_member);
}
}
}
public class MemberAdp extends RecyclerView.Adapter<MemberAdp.ViewHolder> {
//Initialize ArrayList
ArrayList<String> arrayListMember;
//Create constructor
public MemberAdp(ArrayList<String> arrayListMember) {
this.arrayListMember = arrayListMember;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//Initialize view
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_row_member,parent,false);
return new MemberAdp.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
//Set member name on TextView
holder.tvName.setText(arrayListMember.get(position));
}
#Override
public int getItemCount() {
return arrayListMember.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
//Initialize variable
TextView tvName;
public ViewHolder(#NonNull View itemView) {
super(itemView);
//Assign variable
tvName = itemView.findViewById(R.id.tv_name);
}
}
}
public class HealthAlertActivity2 extends Fragment {
//Initialize variable
RecyclerView rvGroup;
ArrayList<String> arrayListGroup;
LinearLayoutManager layoutManagerGroup;
GroupAdp adapterGroup;
//#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View healthAlertFragment = inflater.inflate(R.layout.healthalert_activity2, container, false);
//Assign variable
rvGroup = healthAlertFragment.findViewById(R.id.rv_group);
//Using for loop to add multiple group
//Used for dummy display for now
arrayListGroup = new ArrayList<>();
// for (int i= 1; i<=6; i++){
// arrayListGroup.add("Group " + i);
// }
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Course_ID_Section");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
Map<String, Object> map = (Map<String, Object>) snapshot.getValue();
Log.e("LOG_TAG", "Value is:" + map);
assert map != null;
for (Map.Entry<String, Object> entry : map.entrySet()) {
Log.e("The Result", entry.getKey() + "/" + entry.getValue());
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
String UID = user.getUid();
if (UID.equals(entry.getValue())) {
arrayListGroup.add("Class" + entry.getValue());
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Log.e("LOG_TAG", "Failed to read value.", error.toException());
}
});
//Initialize group adapter
adapterGroup = new GroupAdp(getActivity(),arrayListGroup);
//Initialize layout manager
layoutManagerGroup = new LinearLayoutManager(getActivity());
//Set layout manager
rvGroup.setLayoutManager(layoutManagerGroup);
//Set adapter
rvGroup.setAdapter(adapterGroup);
return healthAlertFragment;
}
}
I want the Group name to be the Course_ID_Section, for example, CSCI-110-MO1. Only if the value inside of this key(CSCI-110-MO1) is the same as the firebase UID. Otherwise, perform no action.
Currently, I am dealing with this kind output:
E/LOG_TAG: Value is:{CSCI-110-M01={BiazGfcXiBYKUUGk4NGwXjJ5C7k2=***********, nGrAfIS6NgbBlkmSPUA0zm4qwQb2=***********}, CSCI-415-M01={BiazGfcXiBYKUUGk4NGwXjJ5C7k2=***********, nGrAfIS6NgbBlkmSPUA0zm4qwQb2=***********}, CSCI-455-M03={BiazGfcXiBYKUUGk4NGwXjJ5C7k2=***********, nGrAfIS6NgbBlkmSPUA0zm4qwQb2=***********}, CSCI-300-M02={BiazGfcXiBYKUUGk4NGwXjJ5C7k2=***********, nGrAfIS6NgbBlkmSPUA0zm4qwQb2=***********}, CSCI-318-M01={BiazGfcXiBYKUUGk4NGwXjJ5C7k2=***********, nGrAfIS6NgbBlkmSPUA0zm4qwQb2=***********}}
E/The Result: CSCI-110-M01/{BiazGfcXiBYKUUGk4NGwXjJ5C7k2=***********, nGrAfIS6NgbBlkmSPUA0zm4qwQb2=***********}
E/The Result: CSCI-415-M01/{BiazGfcXiBYKUUGk4NGwXjJ5C7k2=***********, nGrAfIS6NgbBlkmSPUA0zm4qwQb2=***********}
CSCI-455-M03/{BiazGfcXiBYKUUGk4NGwXjJ5C7k2=***********, nGrAfIS6NgbBlkmSPUA0zm4qwQb2=***********}
CSCI-300-M02/{BiazGfcXiBYKUUGk4NGwXjJ5C7k2=***********, nGrAfIS6NgbBlkmSPUA0zm4qwQb2=***********}
CSCI-318-M01/{BiazGfcXiBYKUUGk4NGwXjJ5C7k2=***********, nGrAfIS6NgbBlkmSPUA0zm4qwQb2=***********}
Not sure if it is the "=" causing me the problem. Only want to compare firebase UID in this case.
You're loading data from:
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Course_ID_Section");
This means the snapshot you get has two nested, levels of dynamic nodes under it: the CSCI-110-M01 level, and then the level with the UIDs. So in your onDataChange you'll need two nested loops to iterate over both levels.
I'd also recommend iterating over the getChildren() of the snapshot, and only getting the values out of the snapshot at the lowest level.
Combined, that becomes:
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
String UID = user.getUid();
for (DataSnapshot courseSnapshot: snapshot.getChildren()) {
for (DataSnapshot userSnapshot: courseSnapshot.getChildren()) {
if (UID.equals(userSnapshot.getKey())) {
arrayListGroup.add("Class" + userSnapshot.getValue(String.class));
}
}
}
}
...
How to shuffle items from Firebase Database?
Let's say my DB contains 4 items [1,2,3,4]. In my RecyclerView, I want to display shuffled, something like [2,3,1,4]. How can I do that?
This is the code in my Fragment. So it works retrieving data but I need to shuffle it before displaying.
RecyclerView mRecyclerView;
FirebaseDatabase mFirebaseDatabase;
DatabaseReference mRef;
#Override
public View onCreateView(#NotNull LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstanceState) {
if (rootView == null) {
rootView = inflater.inflate(R.layout.fragment_store, viewGroup, false);
setHasOptionsMenu(false);
mRecyclerView = rootView.findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 3));
mFirebaseDatabase = FirebaseDatabase.getInstance();
mRef = mFirebaseDatabase.getReference("Store");
}
return rootView;
}
For retrieving data from Firebase Database I am using the following code:
#Override
public void onStart() {
super.onStart();
FirebaseRecyclerOptions<Store2> options =
new FirebaseRecyclerOptions.Builder<Store2>()
.setQuery(mRef, Store2.class)
.build();
FirebaseRecyclerAdapter<Store2, StoreHolder> firebaseRecyclerAdapter =
new FirebaseRecyclerAdapter<Store2, StoreHolder>(options) {
#NonNull
#Override
public StoreHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.store_gridview, parent, false);
return new StoreHolder(view);
}
#Override
protected void onBindViewHolder(#NonNull final StoreHolder holder, int position, #NonNull final Store2 model) {
holder.setDetails(getContext(), model.getImage(), model.getName(), model.getPrice());
}
};
firebaseRecyclerAdapter.startListening();
mRecyclerView.setAdapter(firebaseRecyclerAdapter);
}
There are no option available for shuffling data in firebase.
But you can do it locally .
Pass your list in this.
Collections.shuffle(arrayList);
When you are using the following reference:
mRef = mFirebaseDatabase.getReference("Store");
It means that you are trying to display all children that exist under Store node. If under this node you store children that are added using the push() method, the default ordering is chronological, since every pushed id contains a time component. If you want to change this behaviour, you need to get all the items and shuffle them manually.
As #DougStevenson mentioned in his comment, you have to use the same reference, get all items, add them to a list, shuffle them and then use a ListAdapter for that.
Please also note, that when you pass a DocumentReference or a Query object to the setQuery() method, where is no further mechanism that can help you shuffle your items. Unfortunately, you'll lose the benefits of the Firebase-UI library but you'll get your work done.
As #DougStevenson and #frankenstein mentioned, I added all items into a list, then I was able the shuffle it using Collections.shuffle(arrayList);
I couldn't do it using FirebaseRecyclerAdapter, and I needed a custom Adapter for my RecyclerView.ViewHolder.
What is the downside of not using FirebaseRecyclerAdapter? Or is it any? Maybe someone with experience can answer this question.
My fragment:
private View rootView;
private RecyclerView recyclerView;
private StoreAdapter storeAdapter;
private ArrayList<Store> arrayStore;
#Override
public View onCreateView(#NotNull LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstanceState) {
if (rootView == null) {
rootView = inflater.inflate(R.layout.fragment_store, viewGroup, false);
setHasOptionsMenu(false);
recyclerView = rootView.findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 3));
DatabaseReference reference = FirebaseDatabase.getInstance().getReference().child("Data");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
arrayStore = new ArrayList<>();
for(DataSnapshot snapshot: dataSnapshot.getChildren()) {
Store store = snapshot.getValue(Store.class);
arrayStore.add(store);
}
storeAdapter = new StoreAdapter(getActivity() ,arrayStore);
recyclerView.setAdapter(storeAdapter);
Collections.shuffle(arrayStore, new Random(3));
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
return rootView;
}
My adapter:
private final Context context;
private ArrayList<Store> arrayStore;
public StoreAdapter(Context context, ArrayList<Store> arrayStore) {
this.context = context;
this.arrayStore = arrayStore;
}
#NonNull
#Override
public StoreAdapter.GameViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
return new StoreAdapter.GameViewHolder(LayoutInflater.from(context).inflate(
R.layout.store_gridview, viewGroup, false));
}
#Override
public void onBindViewHolder(#NonNull final StoreAdapter.GameViewHolder viewHolder, final int position) {
setColor(viewHolder);
viewHolder.itemName.setText(arrayStore.get(position).getName());
Glide.with(viewHolder.view.getContext())
.load(arrayStore.get(position).getImage())
.thumbnail(0.75f)
.into(viewHolder.itemImage);
viewHolder.view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sendData(viewHolder, position);
}
});
}
#Override
public int getItemCount() {
return arrayStore.size();
}
class GameViewHolder extends RecyclerView.ViewHolder {
private final View view;
private final ImageView itemImage, itemRarity;
private final TextView itemName;
GameViewHolder(#NonNull View itemView) {
super(itemView);
this.view = itemView;
itemRarity = view.findViewById(R.id.itemRarity);
itemImage = view.findViewById(R.id.itemImage);
itemName = view.findViewById(R.id.itemName);
}
}
private void sendData(#NonNull final StoreAdapter.GameViewHolder viewHolder, int position) {
if (viewHolder.getAdapterPosition() != RecyclerView.NO_POSITION) {
Intent intent = new Intent(context, DetailsActivity.class);
intent.putExtra("name", arrayStore.get(position).getName());
intent.putExtra("rarity", arrayStore.get(position).getRarity());
intent.putExtra("item", arrayStore.get(position).getImage());
intent.putExtra("price", arrayStore.get(position).getPrice());
intent.putExtra("key", "Store");
context.startActivity(intent);
}
}
private void setColor(#NonNull final StoreAdapter.GameViewHolder viewHolder) {
String rarity = arrayStore.get(viewHolder.getAdapterPosition()).getRarity();
if (rarity.contains("legendary")) {
viewHolder.itemRarity.setImageResource(R.drawable.color_legendary_gradient);
} else if (rarity.contains("classic")) {
viewHolder.itemRarity.setImageResource(R.drawable.color_classic_gradient);
} else if (rarity.contains("epic")) {
viewHolder.itemRarity.setImageResource(R.drawable.color_epic_gradient);
} else if (rarity.contains("elite")) {
viewHolder.itemRarity.setImageResource(R.drawable.color_elite_gradient);
} else if (rarity.contains("rare")) {
viewHolder.itemRarity.setImageResource(R.drawable.color_rare_gradient);
} else if (rarity.contains("special")) {
viewHolder.itemRarity.setImageResource(R.drawable.color_special_gradient);
}
}
My bean class:
private String image, name, price, rarity;
public Store() {
}
public String getImage() {
return image;
}
public String getName() {
return name;
}
public String getPrice() {
return price;
}
public String getRarity() {
return rarity;
}
In my fragment I have an EditText which basically allows, when submitted, to query the values from Firebase Realtime Database and show them in a Recycler View.
Everything is fine when I search the first time but, when I search more than once, the previous results stay in the Recycler View.
I've tried to clear my lists but I got no success. I think I found the problem but I just can't solve it. I need to clear my bundle everytime I pass the retrieved values from the DB from one fragment to another. This is my fragment code (where I call the adaptor, not where I retrieve the DB values):
public class FilteredResultsFragment extends android.support.v4.app.Fragment {
ImageAdapter imageAdapter;
List<String> listOfImages = new ArrayList<>();
List<String> listOfNames = new ArrayList<>();
private RecyclerView recyclerView;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View viewFilteredResults = inflater.inflate(R.layout.fragment_filtered_results, container, false);
recyclerView = viewFilteredResults.findViewById(R.id.recyclerViewFiltered);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
imageAdapter = new ImageAdapter(listOfImages, listOfNames, getContext());
recyclerView.setAdapter(imageAdapter);
return viewFilteredResults;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (getArguments() != null) {
removeAll();
listOfImages.addAll(getArguments().getStringArrayList("listOfImages"));
listOfNames.addAll(getArguments().getStringArrayList("listOfNames"));
Log.d("IMAGENS", "img "+listOfImages);
Log.d("Nomes","nome "+listOfNames);
imageAdapter.notifyDataSetChanged();
}
}
public void removeAll(){
listOfImages.clear();
listOfNames.clear();
imageAdapter.notifyDataSetChanged();
}
}
As you can see, I've created a function that should allow me to clear the data... And this is my Adaptor:
public class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ImageViewHolder> {
List<String> listaPaisesFiltrados;
List<String> listaNomesFiltrados;
android.content.Context context;
ImageAdapter(List<String> listaPaisesFiltrados, List<String> listaNomesFiltrados, android.content.Context c) {
this.listaPaisesFiltrados = listaPaisesFiltrados;
this.listaNomesFiltrados = listaNomesFiltrados;
this.context = c;
}
#NonNull
#Override
public ImageViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_view, parent, false);
return new ImageViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull ImageViewHolder holder, int position) {
String imageUrl = listaPaisesFiltrados.get(holder.getAdapterPosition());
String nomePais = listaNomesFiltrados.get(holder.getAdapterPosition());
android.content.Context context1 = context.getApplicationContext();
Log.d("ADAPTER", "imageUrl : " + imageUrl + " position : " + holder.getAdapterPosition());
Typeface tpPaisNome = Typeface.createFromAsset(holder.itemView.getContext().getAssets(),"fonts/RobotoSlab-Bold.ttf"); // Define a Typeface
holder.textView.setTypeface(tpPaisNome);
holder.textView.setText(nomePais);
Glide.with(holder.imageView.getContext()).load(imageUrl).centerCrop().into(holder.imageView);
}
#Override
public int getItemCount() {
Log.d("ADAPTER", "SIZE : " + listaPaisesFiltrados.size());
return listaPaisesFiltrados.size();
}
public class ImageViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
TextView textView;
public ImageViewHolder(View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.imgPaisFiltrado);
textView = itemView.findViewById(R.id.txtNomePaisFiltrado);
}
}
}
EDIT
In my ExploreFragment (where I have the query and the EditText) I send two ArrayLists via Bundle to the fragment that opens the adaptor. I need to clear my Bundler but, when I use blunder.clear() than no value is passed to the other fragment and no image is displayed. This is my code
srcView.setOnEditorActionListener(new EditText.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
boolean handled = false;
if (actionId == EditorInfo.IME_ACTION_DONE) {
txtRecomendado.setVisibility(View.INVISIBLE);
scrollView.setVisibility(View.INVISIBLE);
final Bundle bundler = new Bundle();
bundler.clear();
FirebaseDatabase mDatabase = FirebaseDatabase.getInstance();
DatabaseReference paisNomeContinentes = mDatabase.getReference().child("paises");
Query queries = paisNomeContinentes.orderByChild("Nome").startAt(String.valueOf(srcView.getText())).endAt(String.valueOf(srcView.getText())+"\uf8ff");
Log.d("AQUIPUTO","teste "+String.valueOf(srcView.getText()));
queries.addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
List<String> imagemPaisList = new ArrayList<>();
List<String> nomePaisList = new ArrayList<>();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
String imagemPais = ds.child("Imagem").getValue(String.class);
String nomePais = ds.child("Nome").getValue(String.class);
imagemPaisList.add(imagemPais);
nomePaisList.add(nomePais);
}
int urlCount = imagemPaisList.size();
// int randomImage = new Random().nextInt(urlCount);
for (int i = 0; i < nomePaisList.size(); i++) {
//Integer randomVariavel = new Random().nextInt(urlCount);
randomImagemPaisList.add(imagemPaisList.get(i));
randomNomePaisList.add(nomePaisList.get(i));
}
getFragmentManager().popBackStack();
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.anim.slide_up_info,R.anim.slide_down_info);
FilteredResultsFragment fragment = new FilteredResultsFragment();
bundler.putStringArrayList("listOfImages", (ArrayList<String>) randomImagemPaisList);
bundler.putStringArrayList("listOfNames", (ArrayList<String>) randomNomePaisList);
fragment.setArguments(bundler);
transaction.replace(R.id.fragContainerExploreFilteredResults, fragment);
transaction.addToBackStack(null);
transaction.commit();
}
How can I clear my bundle? I've tried to clear it after I use:
bundler.putStringArrayList("listOfImages", (ArrayList<String>) randomImagemPaisList);
bundler.putStringArrayList("listOfNames", (ArrayList<String>) randomNomePaisList);
fragment.setArguments(bundler);
And if I do this no value is passed from one fragment to another. I've tried to clear it when the fragment.trasaction is complete but I still get the same 'error'...
might be possible that updated data is not notify with recyclerview, you can create doRefresh method in adapter class and then update the list and notify it, please see the below code
Fragment Code
public class FilteredResultsFragment extends android.support.v4.app.Fragment {
ImageAdapter imageAdapter;
List<String> listOfImages = new ArrayList<>();
List<String> listOfNames = new ArrayList<>();
private RecyclerView recyclerView;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View viewFilteredResults = inflater.inflate(R.layout.fragment_filtered_results, container, false);
setAdapter();
return viewFilteredResults;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (getArguments() != null) {
listOfImages.clear();
listOfNames.clear();
listOfImages.addAll(getArguments().getStringArrayList("listOfImages"));
listOfNames.addAll(getArguments().getStringArrayList("listOfNames"));
Log.d("IMAGENS", "img "+listOfImages);
Log.d("Nomes","nome "+listOfNames);
setAdapter();
}
}
private void setAdapter() {
if (listOfImages != null && listOfNames != null) {
if (imageAdapter == null) {
imageAdapter = new ImageAdapter(getContext());
}
imageAdapter.doRefresh(listOfImages, listOfNames);
if (recyclerView.getAdapter() == null) {
recyclerView = viewFilteredResults.findViewById(R.id.recyclerViewFiltered);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(imageAdapter);
}
}
}
}
and Adapter class as below
public class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ImageViewHolder> {
List<String> listaPaisesFiltrados;
List<String> listaNomesFiltrados;
android.content.Context context;
ImageAdapter(android.content.Context c) {
this.context = c;
}
public void doRefresh(List<String> listaPaisesFiltrados, List<String> listaNomesFiltrados) {
this.listaPaisesFiltrados = listaPaisesFiltrados;
this.listaNomesFiltrados = listaNomesFiltrados;
notifyDataSetChanged();
}
#NonNull
#Override
public ImageViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_view, parent, false);
return new ImageViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull ImageViewHolder holder, int position) {
String imageUrl = listaPaisesFiltrados.get(holder.getAdapterPosition());
String nomePais = listaNomesFiltrados.get(holder.getAdapterPosition());
android.content.Context context1 = context.getApplicationContext();
Log.d("ADAPTER", "imageUrl : " + imageUrl + " position : " + holder.getAdapterPosition());
Typeface tpPaisNome = Typeface.createFromAsset(holder.itemView.getContext().getAssets(),"fonts/RobotoSlab-Bold.ttf"); // Define a Typeface
holder.textView.setTypeface(tpPaisNome);
holder.textView.setText(nomePais);
Glide.with(holder.imageView.getContext()).load(imageUrl).centerCrop().into(holder.imageView);
}
#Override
public int getItemCount() {
Log.d("ADAPTER", "SIZE : " + listaPaisesFiltrados.size());
return listaPaisesFiltrados.size();
}
public class ImageViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
TextView textView;
public ImageViewHolder(View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.imgPaisFiltrado);
textView = itemView.findViewById(R.id.txtNomePaisFiltrado);
}
}
}
you can try to create new adapter and set to your recycler.
listOfImages.clear();
listOfNames.clear();
/*
Adding your new searching data here
*/
recyclerView.setAdapter(new ImageAdapter(listOfImages, listOfNames, getContext());
recyclerView.invalidate();
When you try to clear by calling removeAll, you only clear the list objects from the Fragment class. What you need is to clear the list objects in your RecyclerView.Adapter class.
Try this:
Move your removeAll to your adapter. That way, you clear the list objects in that adapter.
In your Fragment, just call your removeAll from your Adapter.
Sample Code:
Fragment.java
//No more removeAll() here
public void callAdapterToRemove() {
imageAdapter.removeAll();
}
ImageAdapter.java
//Now it's here
public void removeAll() {
listaPaisesFiltrados.clear();
listaNomesFiltrados.clear();
notifyDataSetChanged();
}
Please help me. I want to show the username only once from firebase. Although the user have multiple record in the firebase, I just want to view the name of user who make order. The user can make multiple order, but I just want to show their name once.
I tried many ways but can't succeed. Someone who know about this? Thank you very much.
public void onCreate(Bundle savedInstanceState) {
UID = this.getArguments().getString("UID");
mDatabase = FirebaseDatabase.getInstance().getReference();
mStorage = FirebaseStorage.getInstance();
mItems = new ArrayList<>();
wordDulicate = new ArrayList<>();
tempList = new ArrayList<>();
if(UID != null){
mItemsKey = new ArrayList<>();
mOrderedItemRef = mDatabase.child("OrderedItem");
Log.d(TAG, " mOrderedItemRef:" + mOrderedItemRef);
mOrderedItemVEL = mOrderedItemRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
mItems.clear();
mItemsKey.clear();
wordDulicate.clear();
Log.d(TAG, "onDataChange");
for (DataSnapshot d : dataSnapshot.getChildren()) {
OrderedItem orderedItem = d.getValue(OrderedItem.class);
Log.d(TAG, "orderedItem:" + orderedItem.getUserName());
mItems.add(orderedItem);
mItemsKey.add(d.getKey());
}
updateUI();
}
#Override
public void onCancelled (DatabaseError databaseError){
Log.d(TAG, "get item databaseError: "+databaseError);
}
});
}
else{
Log.d(TAG, "UID: "+UID);
}
super.onCreate(savedInstanceState);
}
#Override
public void onDestroy(){
super.onDestroy();
// if (mItemRef != null) mItemRef.removeEventListener(mItemVEL);
}
#Override
public void onDetach(){
super.onDetach();
// if (mItemRef != null) mItemRef.removeEventListener(mItemVEL);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_admin_list_user_order, container, false);
mItemRecyclerView = (RecyclerView) view.findViewById(R.id.admin_order_recycler_view);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mItemRecyclerView.getContext(), new LinearLayoutManager(getActivity()).getOrientation());
mItemRecyclerView.addItemDecoration(dividerItemDecoration);
mItemRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
return view;
}
private void updateUI(){
Log.d(TAG, "Enter updateUI(); mItems: " + mItems);
mAdapter = new ItemAdapter(mItems);
mItemRecyclerView.setAdapter(mAdapter);
}
private class ItemHolder extends RecyclerView.ViewHolder{
OrderedItem mItems;
TextView mNameTextView;
ItemHolder(final View itemView){
super(itemView);
mNameTextView = (TextView) itemView.findViewById(R.id.textview_username);
/* if (UID != null) {
itemView.setOnClickListener(new View.OnClickListener() {
#SuppressLint("LongLogTag")
#Override
public void onClick(View view) {
Log.d(TAG, "UID != null");
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder
.setMessage("Delete This Item?")
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
deleteItem(mItems);
}
}).setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
});
}*/
}
void bindData(OrderedItem s){
mItems = s;
mNameTextView.setText(s.getUserName());
}
}
private class ItemAdapter extends RecyclerView.Adapter<ItemHolder>{
private ArrayList<OrderedItem> mItems;
ItemAdapter(ArrayList<OrderedItem> Items){
mItems = Items;
}
#Override
public ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
View view = layoutInflater.inflate(R.layout.admin_listed_user_order,parent,false);
return new ItemHolder(view);
}
#Override
public void onBindViewHolder(ItemHolder holder, int position) {
OrderedItem s = mItems.get(position);
holder.bindData(s);
}
#Override
public int getItemCount() {
return mItems.size();
}
}
}
Since you rely on a key and a value, why not use a map instead? Maps have a key and a value, and you can check whether or not an item with a key is present by getting the key, instead of having to iterate through the list and find duplicates.
First you need to initialize it:
Map<String, ArrayList<OrderedItem>> items = new HashMap<>();
The value is an ArrayList to keep any existing data
then put the items:
for (DataSnapshot d : dataSnapshot.getChildren()) {
OrderedItem orderedItem = d.getValue(OrderedItem.class);
Log.d(TAG, "orderedItem:" + orderedItem.getUserName());
items.putIfAbsent(d.getKey(), new ArrayList<>());//create a list if it doesn't exist
items.get(d.geyKey()).add(orderedItem);//add the item
}
and clearing with a map is the same as with lists
I recently set up my RecyclerView and want to slide in all new items that are added. Specifically, I have a comment screen and every time a new comment is added, I want it to slide in from the left with an animation effect.
Note that I add all new items to my mCommentArrayList at index 0 so that they appear at the top of the view.
I have read about using third-party libraries, but from what I understand that is not necessary. Here is my code:
Where I first call to Firebase to find data to populate the RecyclerView:
mUpdateRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
setImage(dataSnapshot);
setQuestion(dataSnapshot);
createInitialCommentIDArray(dataSnapshot);
mNumberOfCommentsAtPoll = (int) dataSnapshot.child(COMMENTS_LABEL).getChildrenCount();
for (int i = 0; i < mNumberOfCommentsAtPoll; i++) {
String commentID = (String) dataSnapshot.child(COMMENTS_LABEL).child(mCommentIDArrayList.get(i)).child("COMMENT").getValue();
Log.v("COMMENT_ID", "The comment ID is " + commentID);
String userID = (String) dataSnapshot.child(COMMENTS_LABEL).child(mCommentIDArrayList.get(i)).child("USER_ID").getValue();
Log.v("USER_ID", "The user ID is " + userID);
mCommentArrayList.add(0, new Comments(mUserAvatar, userID, commentID));
mCommentAdapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
Subsequent Calls to Firebase on Data Change:
#Override
protected void onStart() {
super.onStart();
mUpdateComments = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
mNumberOfCommentsAtPoll = (int) dataSnapshot.getChildrenCount();
for (DataSnapshot x : dataSnapshot.child(COMMENTS_LABEL).getChildren()) {
Log.v("DATA_SNAPSHOT", x.toString());
if (mCommentIDArrayList.contains(x.getKey())) {
Log.v("Comment_Already_Added", x.getKey());
} else {
Log.v("Child_Added_Called", "Child Added Called");
mCommentIDArrayList.add(x.getKey());
String commentID = (String) dataSnapshot.child(COMMENTS_LABEL).child(x.getKey()).child("COMMENT").getValue();
Log.v("New_Comment", "The new comment is " + commentID);
String userID = (String) dataSnapshot.child(COMMENTS_LABEL).child(x.getKey()).child("USER_ID").getValue();
Log.v("New_User_ID", "The new userID is " + userID);
mCommentArrayList.add(0, new Comments(mUserAvatar, userID, commentID));
mCommentAdapter.notifyDataSetChanged();
}
}
}
My RecyclerView Adapter:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private ArrayList<Comments> mDataSet;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
protected ImageView userAvatar;
protected TextView userID;
protected TextView userComment;
public ViewHolder(View v) {
super(v);
userAvatar = (ImageView) v.findViewById(R.id.profile_image);
userID = (TextView) v.findViewById(R.id.user_ID);
userComment = (TextView) v.findViewById(R.id.user_comment_textview);
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(ArrayList<Comments> myDataset) {
mDataSet = myDataset;
}
// Create new views (invoked by the layout manager)
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.individual_comment, parent, false);
// set the view's size, margins, paddings and layout parameters
return new ViewHolder(v);
}
// Replace the contents of a view (invoked by the layout manager)
//The OutOfBoundsException is pointing here
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Comments comment = mDataSet.get(position);
holder.userComment.setText(comment.getUserComment());
holder.userID.setText("User " + position);
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return mDataSet.size();
}
}