This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 2 years ago.
I want to display a view holder for all users except the current user. The best solution I found was to simply query all the "Users" then hide the current user view holder. In order to so I check if the model user is the current user. However, my if statement is not working as it should. I print out both UID's and clearly they are equal. However, my if statement which should only run when they aren't equal still executes when the activity is initially opened. If I jump to another activity and then go back to this activity then it works as it should and it hides the view. Anyone know why my if statement isn't working when the activity is first created?
final FirebaseRecyclerAdapter<Users, UsersViewHolder> adapter = new FirebaseRecyclerAdapter<Users, UsersViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull UsersViewHolder holder, final int position, #NonNull final Users model) {
holder.setInfo(getApplicationContext(), model.getUsername(), model.getName(), model.getProfilePhoto());
final String currentUserID = FirebaseAuth.getInstance().getCurrentUser().getUid();
final String otherUserID = getRef(position).getKey();
System.out.println(currentUserID + " === " + otherUserID + "\n");
if (currentUserID != otherUserID) {
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DatabaseReference currentUserDB = FirebaseDatabase.getInstance().getReference().child("Users").child(userID);
Map newPost = new HashMap();
newPost.put("otherUserID", otherUserID);
currentUserDB.updateChildren(newPost);
startActivity(new Intent(SearchActivity.this, OthersProfileActivity.class));
}
});
}
else {
holder.mView.setVisibility(View.GONE);
}
}
#NonNull
#Override
public UsersViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.users_layout, parent, false);
return new UsersViewHolder(v);
}
};
adapter.startListening();
rvSearchUsers.setAdapter(adapter);
Do not use == for objects like String. Instead use .equals(). Read more.
Related
I try to open each video when I click on them but what I get instead is only the second video (sometimes first video). For example, when I click on "16 best video ideas for small business" I want it to open that particular video. But what I get instead is "this tiny camera can show the world from a bug's point of view. I think the problem occurs because of for loop inside query in UserHomeVideoAdapter.
UserHomeVideoAdapter.java:
public class UserHomeVideoAdapter extends FirestoreRecyclerAdapter<FollowList, UserHomeVideoAdapter.UserVideoHolder> {
Context context;
final FirebaseFirestore db = FirebaseFirestore.getInstance();
String thumbUrl, videoTitle, videoUrl, videoDesc, videoId, publisherId;
Video video;
public UserHomeVideoAdapter(#NonNull #NotNull FirestoreRecyclerOptions<FollowList> options, Context context) {
super(options);
this.context = context;
}
#Override
protected void onBindViewHolder(#NonNull #NotNull UserVideoHolder holder, int position, #NonNull #NotNull FollowList model) {
Query query = db.collection("Videos").whereEqualTo("publisherId", model.getUserId());
query.get().addOnCompleteListener(task -> {
if (task.isSuccessful()) {
if (task.getResult() != null) {
for (QueryDocumentSnapshot documentSnapshot : task.getResult()) {
video = documentSnapshot.toObject(Video.class);
Log.d("Data", documentSnapshot.getId() + " => " + documentSnapshot.getData());
thumbUrl = video.getThumbUrl();
videoTitle = video.getVideoTitle();
videoUrl = video.getVideoUrl();
videoDesc = video.getVideoDesc();
videoId = video.getVideoId();
publisherId = video.getPublisherId();
}
if (task.getResult().size() != 0) {
Glide.with(context).load(model.getUserImageUrl()).into(holder.userProfileImage);
Glide.with(context).load(thumbUrl).into(holder.videoImageView);
holder.videoTitle.setText(videoTitle);
holder.mainContainerVideo.setVisibility(View.VISIBLE);
} else if (task.getResult().size() == 0) {
holder.mainContainerVideo.getLayoutParams().height = 0;
holder.mainContainerVideo.getLayoutParams().width = 0;
}
}
} else {
Toast.makeText(context, String.valueOf(task.getException()), Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(e -> Toast.makeText(context, e.getLocalizedMessage(), Toast.LENGTH_SHORT).show());
holder.videoContainer.setOnClickListener(v -> {
Intent intent = new Intent(context, VideoActivity.class);
intent.putExtra("videoPublisherUserName", model.getUserName());
intent.putExtra("thumbUrl", thumbUrl);
intent.putExtra("videoPublisherEmail", model.getUserEmail());
intent.putExtra("videoUrl", videoUrl);
intent.putExtra("videoId", videoId);
intent.putExtra("videoPublisherFullName", model.getUserFullName());
intent.putExtra("videoPublisherId", publisherId);
context.startActivity(intent);
});
}
#NonNull
#NotNull
#Override
public UserVideoHolder onCreateViewHolder(#NonNull #NotNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.video_cell, parent, false);
return new UserVideoHolder(v);
}
public static class UserVideoHolder extends RecyclerView.ViewHolder {
RelativeLayout videoContainer, mainContainerVideo;
CircleImageView userProfileImage;
TextView videoTitle;
ImageView videoImageView;
public UserVideoHolder(#NonNull #NotNull View itemView) {
super(itemView);
mainContainerVideo = itemView.findViewById(R.id.mainContainerVideo);
videoContainer = itemView.findViewById(R.id.videoContainer);
userProfileImage = itemView.findViewById(R.id.userProfileImage);
videoTitle = itemView.findViewById(R.id.videoTitle);
videoImageView = itemView.findViewById(R.id.videoImageView);
}
}
}
I logged videoId inside that is assigned inside for loop. Sometimes it returns ids in this order "1"; "2" and sometimes it returns like this "2"; "1". When it returns in this order "1"; "2" click opens second video even if I click first video and when it returns like this "2"; "1" click opens first video even if I click second video.
If you need additional code to solve the problem please ask and I will provide it as soon as possible. Any help is appreciated. Thanks
The short answer is that onBindViewHolder() is trying to do too much. From the documentation:
Called by RecyclerView to display the data at the specified position. This method should update the contents of the ViewHolder#itemView to reflect the item at the given position.
In other words, onBindViewHolder() is only responsible for one single item in the RecyclerView. However, you are trying to fetch all of the data for every element in the list. Instead, you should fetch the data external to your adapter and pass it in as a parameter. Then onBindViewHolder() should update the UI elements of a view inside the RecyclerView to display whatever you want for one single item.
Google has a great example CustomerAdapter. First, the constructor takes the list of data that will be displayed:
public CustomAdapter(String[] dataSet) {
mDataSet = dataSet;
}
Then onbindViewHolder() is only responsible for setting what is displayed in the UI of a single item in the RecyclerView:
#Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
Log.d(TAG, "Element " + position + " set.");
// Get element from your dataset at this position and replace the contents of the view
// with that element
viewHolder.getTextView().setText(mDataSet[position]);
}
It does NOT try to get data or loop over a list or anything else. All of that is someone else's responsibility.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I want to provide history of users recently viewed items from database can anyone help me out how to do this?
I want to check if history child has key and show the key data from car child I hope you understand any help will be appreciated.
Below is the link of what database look like.
This is what is have tried :
private void recent(String data) {
Query query = Dataref.orderByChild("CarName").startAt(data).endAt(data + "\uf8ff");
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("Car");
String userId = databaseReference.push().getKey();
Query databaseReference2 = FirebaseDatabase.getInstance().getReference("users").child("history").equalTo(databaseReference.getKey());
DatabaseReference databaseReference1 = FirebaseDatabase.getInstance().getReference("Car");
if (databaseReference2 != null) {
options = new FirebaseRecyclerOptions.Builder<Car>().setQuery(query, Car.class).build();
adapter2 = new FirebaseRecyclerAdapter<Car, recentViewHolder>(options) {
#NonNull
#Override
public recentViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.history_view, parent, false);
return new recentViewHolder(v);
}
#Override
protected void onBindViewHolder(#NonNull recentViewHolder holder, final int position, #NonNull Car model) {
holder.textView.setText(model.getCarName());
Picasso.get().load(model.getImageUrl()).into(holder.imageView);
holder.v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(HomeActivity.this, ViewActivity.class);
intent.putExtra("CarKey", getRef(position).getKey());
startActivity(intent);
}
});
adapter.startListening();
recent.setAdapter(adapter);
}
};
}
}
i have found an answer an post similar to what i have asked we can get the key from other child by orderbykey.equalto()
I am facing a Firebase RecyclerView problem where I cannot remove unwanted CardViews from my RecyclerViews. In my code I check the city's name and the guide's chosen city to match them. It populates guide's details only if the guide's city matches the picked city, but it also shows empty cardview with default layout.
guideDataRef = FirebaseDatabase.getInstance().getReference().child("Guides");
public void recycler() {
super.onStart();
try {
//Guide RecyclerView
Query guideQuery = guideDataRef.orderByKey();
guideQuery.keepSynced(true);
FirebaseRecyclerOptions guideOptions =
new FirebaseRecyclerOptions.Builder<UserModelClass>().setQuery(guideQuery, UserModelClass.class).build();
guideAdapter = new FirebaseRecyclerAdapter<UserModelClass, guideViewHolder>(guideOptions) {
#Override
protected void onBindViewHolder(#NonNull guideViewHolder holder, final int position, #NonNull final UserModelClass model) {
String pickedcity = model.getPickedCity();
String postname = (String) cityName.getText();
if(pickedcity.equals(postname)) {
final String guide_key= getRef(position).getKey();
holder.setGuideName(model.getName());
holder.setGuideSurname(model.getSurName());
holder.setGuideImage(getApplicationContext(), model.getPhotoURL());
// holder.mView.setVisibility(View.VISIBLE);
//Guide Click listener
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent guideHireIntent = new Intent(getApplication(), GuideHireActivity.class);
guideHireIntent.putExtra("guide_id", guide_key);
finish();
startActivity(guideHireIntent);
}
});
}
}
#NonNull
#Override
public guideViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout_guides, parent, false);
return new guideViewHolder(view);
}
#Override
public void onError(DatabaseError e){
Toast.makeText(getApplicationContext(), "Error by stopping ", Toast.LENGTH_SHORT).show();
}
#Override
public int getItemCount() {
return super.getItemCount();
}
#Override
public void onDataChanged() {
super.onDataChanged();
notifyDataSetChanged();
}
};
guideAdapter.notifyDataSetChanged();
guideRecyclerView.setAdapter(guideAdapter);
guideAdapter.startListening();
} catch (DatabaseException e) {
Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
}
}
enter image description here
enter image description here
I can change the adapter visibility to gone if it does not match with the requirements but the problem is that after making it's visibility gone it is still there holding the place (but invisible - there's still an empty space). How can I avoid populating an item from the recycler view completely, instead of making it invisible if the requirements do not match?
You're not showing what guideDataRef is in your code, so I'm assuming that it's just aDatabaseReference object for everything beneath a \Guides node.
If you're doing that, you're going to get a call for onBindViewHolder for every child at that particular location. This means that you're going to be asked to make a view for every child. You cannot choose whether or not a view will appear for that item.
It looks like you're assuming that your if statement in onBindViewHolder method will skip over those items. But what's actually happening is that you're simply allowing an empty view to occupy that spot in the list.
Instead, you should come up with a query that generates only the items of interest to your list. This means you'll have to tell Firebase to filter for children that meet your criteria.
You can also read the entire contents of the location, manually filter out the items you don't want, and build a list of items you do want. You can then build an custom adapter with that list, and it can then become the input to a ListView or even better to a RecyclerView.
I am migrating my application from the Firebase Database to the Firebase Cloud Firestore.
Previously, I was using the FirebaseUI for the realtime database. After initializing all of my options and creating the adapter in the realtime database, I called .setOnClickListener() on a View of the RecyclerView to navigate to a new activity:
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent toClickedPoll = new Intent(getActivity(), PollHostActivity.class);
toClickedPoll.putExtra("POLL_ID", mFireAdapter.getRef(holder.getAdapterPosition()).getKey());
startActivity(toClickedPoll);
}
});
The extra I passed was the key of the location in my Firebase realtime database.
I am trying to access the same "key" via the FirebaseUI for the Cloud Firestore. Below is my code:
mFirestoreAdaper = new FirestoreRecyclerAdapter<Poll, PollHolder>(storeOptions) {
#Override
protected void onBindViewHolder(#NonNull final PollHolder holder, int position, #NonNull Poll model) {
holder.mPollQuestion.setText(model.getQuestion());
String voteCount = String.valueOf(model.getVote_count());
//TODO: Investigate formatting of vote count for thousands
holder.mVoteCount.setText(voteCount);
Picasso.with(getActivity().getApplicationContext())
.load(model.getImage_URL())
.fit()
.into(holder.mPollImage);
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent toClickedPoll = new Intent(getActivity(), PollHostActivity.class);
String position = String.valueOf(mFirestoreAdaper.getItemId(holder.getAdapterPosition()));
Log.v("Firestore ID", position);
toClickedPoll.putExtra("POLL_ID", position);
startActivity(toClickedPoll);
}
});
}
Right now, the position variable (I have logged) is returning -1. I essentially want it to return the Poll document below:
Try this:
String positions = getSnapshots().getSnapshot(position).getId();
Log.v("Firestore ID", positions);
toClickedPoll.putExtra("POLL_ID", positions);
instead of this:
String position = String.valueOf(mFirestoreAdaper.getItemId(holder.getAdapterPosition()));
Log.v("Firestore ID", position);
toClickedPoll.putExtra("POLL_ID", position);
This question already has an answer here:
How can I get Resources by name (string) and not by integer
(1 answer)
Closed 9 years ago.
Ok, here is what I have:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
title = (TextView) findViewById(R.id.title);
description = (TextView) findViewById(R.id.description);
Spinner dropdown = (Spinner) findViewById(R.id.mainMenu);
final String options[] = {"-Turf Diseases-", "Dollar Spot", "Red Thread"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item,options);
dropdown.setAdapter(adapter);
dropdown.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
newSelection(options[position]);
}
public void onNothingSelected(AdapterView<?> arg0) {}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public void newSelection(String selection) {
if(!selection.contains("-")) {
title.setText(selection);
selection=selection.replace(" ", "_");
selection=selection.toUpperCase();
description.setText("#string/DESC_"+selection);
}
}
The string array of options[] holds titles of strains of lawn diseases (the purpose of the app). It is in a spinner list in the main activity, and when a user clicks a title the action listener calls this last method, newSelection. This method is supposed to format the title to: WORD_WORD.
I have the descriptions saved as predefined strings in strings.xml, all starting with DESC_WORD_WORD. So by my logic, I could do this: description.setText("#string/DESC_"+selection); and it would easily locate the corresponding description in strings.xml.
This is, in fact, what has not ended up happening. The text just changes to the "#string/DESC_WORD_WORD" instead of the predefined string. I'm trying to think like an object-oriented programmer, but it isn't working out for me... I am fairly new to android, so go easy on me if this is a dumb question.
You need to get your resource by its string ID which is done thusly...
#SuppressWarnings("rawtypes")
public static int getResourceId(String name, Class resType){
try {
Class res = null;
if(resType == R.drawable.class)
res = R.drawable.class;
if(resType == R.id.class)
res = R.id.class;
if(resType == R.string.class)
res = R.string.class;
Field field = res.getField(name);
int retId = field.getInt(null);
return retId;
}
catch (Exception e) {
// Log.d(TAG, "Failure to get drawable id.", e);
}
return 0;
}
This is an example of a static method that will take a String that is your resource ID and the type of resource it is so you'd call it..
myText.setText( getResourceId("DESC_WORD_WORD", R.strings.class));