I am using Recycleview Adapter to show my list of items from Firebase Real-time Database.
I have a button which shows text value from Firebase initially when clicked will change the same key value in Firebase Database and I want it to show the updated text in Button too.
But it doesn't unless exit activity and reopen activity. Then it displays the updated value in Button text instead of the initial one.
How to update and show the value without exiting the Adapter?
I used notifyItemChanged(position) but it doesn't do anything.
Here is my Code
public class SubjectBooksAdapter extends RecyclerView.Adapter<SubjectBooksAdapter.MyViewHolder> {
ArrayList<Books> bookslist;
CardView cv;
FirebaseAuth fauth;
FirebaseDatabase database;
DatabaseReference dbreference;
Books g;
SubjectBooksAdapter adapter;
public SubjectBooksAdapter(ArrayList<Books> bookslist){
this.bookslist = bookslist;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout,parent,false);
return new MyViewHolder(v);
}
public class MyViewHolder extends RecyclerView.ViewHolder {
Button mSolved;
MyViewHolder(final View itemView) {
super(itemView);
database = FirebaseDatabase.getInstance();
dbreference = database.getReference("books");
dbreference.keepSynced(true);
mSolved = (Button) itemView.findViewById(R.id.book_solved);
}
}
#Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
database = FirebaseDatabase.getInstance();
dbreference = database.getReference("books");
g = bookslist.get(position);
holder.mSolved.setText(g.getMarkid());
holder.bookName.setText(g.getBname());
holder.bookprice.setText("Rs. "+g.getPrice());
holder.sellername.setText(g.getSellername());
holder.mSolved.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference classicalMechanicsRef = rootRef.child("books").child(g.getCondition()).child(g.getBookid());
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
dataSnapshot.child("bmark").getRef().setValue("Solved");
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
};
classicalMechanicsRef.addListenerForSingleValueEvent(valueEventListener);
notifyItemChanged(position);
}
});
#Override
public int getItemCount() {
return bookslist.size();
}
}
xml code is
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/my_card_view"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="3dp"
android:layout_marginTop="4dp" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="2dp" >
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight=".9"
android:layout_marginBottom="5dp">
<ImageView
android:id="#+id/imageView"
android:layout_width="75dp"
android:layout_height="75dp"
android:scaleType="fitXY"
android:padding="2dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="8dp"
android:paddingRight="7dp"
android:gravity="left">
<TextView
android:id="#+id/book_name"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight=".4"
android:text="Book Name"
android:textStyle="bold"
android:fontFamily="sans-serif-condensed"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_margin="1dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/seller_name"
android:layout_width="match_parent"
android:fontFamily="sans-serif"
android:layout_height="35dp"
android:layout_weight=".3"
android:text="Seller"
android:layout_margin="2dp"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Button
android:fontFamily="sans-serif-condensed"
android:gravity="center"
android:textColor="#ffffff"
android:text="Remove"
android:textStyle="bold"
android:layout_marginEnd="15dp"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_marginRight="15dp"
android:layout_width="wrap_content"
android:id="#+id/book_solved"
android:textAllCaps="false"
android:layout_height="35dp"
android:background="#drawable/buttonshape1"
android:padding="8dp"
android:layout_toRightOf="#id/seller_name"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_marginTop="4dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/profile_details"
android:layout_width="match_parent"
android:layout_height="35dp"
android:fontFamily="sans-serif-condensed"
android:text="View Details"
android:background="#drawable/buttonshape1"
android:gravity="center"
android:textColor="#ffffff"
android:textStyle="bold"
android:layout_marginEnd="15dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_marginRight="15dp" />
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
Thanks in advance.
Whatever the value you want to change in your adapter you can do using notifyItemChanged(position). NotifyItemChange only works when there is a change in your Model Class.
Let say here you are setting the value your Book Name on a TextView by using this code.
Books g = bookslist.get(position);
holder.bookName.setText(g.getBname());
Now if you want to change the value of Book name on Button click you have to change the value in your ArrayList Model also then notify it.
Books g = bookslist.get(position);
g.setBname("your new value");
After this, your notifyItemChanged(position) will display the new value. This is how notify works in RecyclerView
Why you have to do so?
Whenever the notify is called in RecylerView it again set the value from the ArrayList. But in your case, the value is not updated locally in your list but is updated in the FireBase. That's why you get the updated value whenever you again open your app.
NOTE
To change the value of Button with text Remove, get the Markid in the Datachange of the FireBase. Then set that value in the respective model(of that position) from the ArrayList for String Markid.
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
dataSnapshot.child("bmark").getRef().setValue("Solved");
// Here you need to save the value in the arraylist.
bookslist.get(position).setMardid("Here what ever the value you will pass will get updated on the button after notify"); //Try adding the static string that you want after button click.
notifyItemChanged(position)
}
Related
I understand this might be a duplicate, but every other solution here didn't work in my case, such as changing the layout_height to wrap_content instead of match_parent.
My Firestore database has 2 values stored inside an array, and I want to display both of them (more in the future) in my RecyclerView, however, it only displays the first value, at position 0.
Here is my Activity where the Recycler and the Adapter are created:
ActivityOs
private FirestoreAdapter listAdapter;
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private CollectionReference osRef = db.collection("cliente");
private DocumentReference docRef = osRef.document("clienteTeste");
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_os);
RecyclerView recyclerView = findViewById(R.id.recyclerViewOs);
/*docRef.get().addOnCompleteListener(task -> {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
Log.e("RESULTADO","result:" + document.toString());
}
}
});*/
Query query = osRef.orderBy("serviceOrder",
Query.Direction.ASCENDING);
FirestoreRecyclerOptions<ServiceDocument> options =
new FirestoreRecyclerOptions.Builder<ServiceDocument>()
.setQuery(osRef, ServiceDocument.class)
.build();
listAdapter = new FirestoreAdapter(options);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(listAdapter);
listAdapter.notifyDataSetChanged();
}
#Override
protected void onStart() {
super.onStart();
listAdapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
listAdapter.stopListening();
}
The commented code shows me that the database does indeed return the 2 values stored in it.
Here is my Adapter class:
public class FirestoreAdapter extends FirestoreRecyclerAdapter<ServiceDocument, FirestoreAdapter.ViewHolder> {
public FirestoreAdapter(#NonNull FirestoreRecyclerOptions<ServiceDocument> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull ViewHolder holder, int position, #NonNull ServiceDocument model) {
holder.osIdItem.setText(String.valueOf(model.serviceOrderArray.get(position).getId()));
holder.osClientItem.setText(model.serviceOrderArray.get(position).getClient().getName());
holder.osDateItem.setText(model.serviceOrderArray.get(position).getDate());
holder.osValueItem.setText(String.valueOf(model.serviceOrderArray.get(position).getTotalValue()));
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.layout_os_item, parent, false);
return new FirestoreAdapter.ViewHolder(view);
}
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView osIdItem;
private TextView osClientItem;
private TextView osDateItem;
private TextView osValueItem;
public ViewHolder(View itemView) {
super(itemView);
osIdItem = itemView.findViewById(R.id.osIDItem);
osClientItem = itemView.findViewById(R.id.osClientNameItem);
osDateItem = itemView.findViewById(R.id.osDateItem);
osValueItem = itemView.findViewById(R.id.osValueItem);
}
}
}
And here are my layouts, activity_os.xml where my RecyclerView is created, and layout_os_item.xml where the layouts for each item of the recycler are made.
Activity_os.xml
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/activity_os"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="0dp"
android:background="#color/white"
tools:context="com.leonardomaito.autocommobile.activities.OsActivity">
<include
android:id="#+id/include"
layout="#layout/layout_header_search" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/glRecyclerLimit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_begin="124dp" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerViewOs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="650dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/glRecyclerLimit"
app:layout_constraintVertical_bias="0.0"
tools:listitem="#layout/layout_os_item" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/btNewOs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="Inserir OS"
android:onClick="createNewOs"
android:src="#drawable/custom_plus_icon"
app:backgroundTint="#color/autocom_blue"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.98"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/glRecyclerLimit"
app:layout_constraintVertical_bias="0.988"
app:rippleColor="#color/autocom_blue" />
</androidx.constraintlayout.widget.ConstraintLayout>
Layout_os_item.xml
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:showIn="#layout/activity_os"
android:background="#drawable/custom_card_view">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="10dp"
android:background="#drawable/custom_card_view">
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/custom_os_icon"
android:paddingLeft="5dp"/>
<TextView
android:id="#+id/osIDItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="N 00000"
android:textColor="#color/autocom_blue"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="#+id/osDateItem"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="#+id/imageView"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/osDateItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/autocom_blue"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.943"
app:layout_constraintStart_toEndOf="#+id/imageView"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.222" />
<TextView
android:id="#+id/osClientNameItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:textColor="#color/autocom_blue"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="#+id/imageView"
app:layout_constraintTop_toBottomOf="#+id/osIDItem"
app:layout_constraintVertical_bias="0.111" />
<TextView
android:id="#+id/osValueItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="1dp"
android:text="R$ 10,000"
android:textColor="#color/autocom_blue"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.791"
app:layout_constraintStart_toEndOf="#+id/osClientNameItem"
app:layout_constraintTop_toBottomOf="#+id/osDateItem"
app:layout_constraintVertical_bias="0.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
Any help is welcome!
Edit
Current Result:
Expected Result
Basically, Item 0 or the first item is correct, however, the second item in my database should also appear in Item 1.
I've set the visibility of RecyclerView to gone. How would I be able to remove the empty space it takes?
I tried putting layout_height as wrap_content, but it still doesn't show anything.
Recycler View:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycleView"
android:layout_gravity="top"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_editor_absoluteX="1dp"
tools:layout_editor_absoluteY="1dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
Card View:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="250dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_marginRight="10dp"
android:id="#+id/cardView"
android:backgroundTint="#5A10E7"
android:elevation="90dp"
android:orientation="vertical"
android:textColor="#FFFFFF"
app:cardCornerRadius="25dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.282">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/Requestfulfilled"
android:layout_width="139dp"
android:layout_height="41dp"
android:layout_weight="1"
android:backgroundTint="#4CAF50"
android:clickable="true"
android:defaultFocusHighlightEnabled="true"
android:hint="Request Fullfilled"
android:text="Fulfilled"
android:textColor="#FFFFFF"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/DeleteRequest"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="#+id/RlocationView"
app:layout_constraintTop_toBottomOf="#+id/RlocationView" />
<Button
android:id="#+id/DeleteRequest"
android:layout_width="139dp"
android:layout_height="41dp"
android:backgroundTint="#F44336"
android:clickable="true"
android:defaultFocusHighlightEnabled="true"
android:hint="Delete"
android:text="Delete"
android:textColor="#FFFFFF"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="#+id/RlocationView"
app:layout_constraintHorizontal_bias="0.894"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.904" />
<TextView
android:id="#+id/RemailView"
android:layout_width="340dp"
android:layout_height="35dp"
android:allowUndo="true"
android:focusable="auto"
android:focusableInTouchMode="true"
android:text="Email"
android:textAlignment="center"
android:textColor="#FFFFFF"
android:textSize="18sp"
app:layout_constraintBottom_toTopOf="#+id/RdateView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/RbloodView"
android:layout_width="116dp"
android:layout_height="35dp"
android:allowUndo="true"
android:focusable="auto"
android:focusableInTouchMode="true"
android:text="Blood Group"
android:textAlignment="center"
android:textColor="#FFFFFF"
android:textSize="18sp"
app:layout_constraintBottom_toTopOf="#+id/RlocationView"
app:layout_constraintEnd_toStartOf="#+id/RdateView"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/RemailView" />
<TextView
android:id="#+id/RdateView"
android:layout_width="164dp"
android:layout_height="42dp"
android:allowUndo="true"
android:focusable="auto"
android:focusableInTouchMode="true"
android:text="Date of Requirement"
android:textAlignment="center"
android:textColor="#FFFFFF"
android:textSize="18sp"
app:layout_constraintBottom_toTopOf="#+id/RlocationView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="#+id/RbloodView"
app:layout_constraintTop_toBottomOf="#+id/RemailView" />
<TextView
android:id="#+id/RlocationView"
android:layout_width="340dp"
android:layout_height="35dp"
android:allowUndo="true"
android:focusable="auto"
android:focusableInTouchMode="true"
android:text="Location"
android:textAlignment="center"
android:textColor="#FFFFFF"
android:textSize="18sp"
app:layout_constraintBottom_toTopOf="#+id/Requestfulfilled"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/RdateView" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
Code to set Card visibility as GONE:
public class yourRequestActivity extends AppCompatActivity {
private RecyclerView cardView;
private DatabaseReference dbRefForReq, dbRefForResp;
private FirebaseAuth mAuth;
private String AuthUserEmail, UserID;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.request_response_view);
mAuth = FirebaseAuth.getInstance();
AuthUserEmail = mAuth.getCurrentUser().getEmail();
UserID = mAuth.getCurrentUser().getUid();
dbRefForResp = FirebaseDatabase.getInstance().getReference().child("Responses").child(String.valueOf(UserID));
dbRefForReq = FirebaseDatabase.getInstance().getReference().child("Blood Requests");
dbRefForReq.keepSynced(true);
cardView = (RecyclerView) findViewById(R.id.recycleView);
cardView.setHasFixedSize(true);
cardView.setLayoutManager(new LinearLayoutManager(this));
}
#Override
protected void onStart() {
super.onStart();
FirebaseRecyclerOptions<getDbContents> options =
new FirebaseRecyclerOptions.Builder<getDbContents>()
.setQuery(dbRefForReq, getDbContents.class)
.build();
FirebaseRecyclerAdapter<getDbContents, contentHolder> adapter = new FirebaseRecyclerAdapter<getDbContents, contentHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull final contentHolder holder, final int position, #NonNull final getDbContents model) {
final int finalPosition = position + 1;
if (model.getUser().equals(AuthUserEmail)) {
dbRefForReq.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
DataSnapshot checkFulfillment = dataSnapshot.child(String.valueOf(("Request " + finalPosition))).child("Fulfillment");
if (checkFulfillment.exists()) {
if (checkFulfillment.child("Fulfilled").getValue().equals("yes")) {
/*------------- Set current user card as visible -----------------*/
holder.frameView.setVisibility(View.VISIBLE);
holder.fulfilled.setVisibility(View.GONE);
holder.requestFulfilled.setVisibility(View.VISIBLE);
holder.userEmail.setText(AuthUserEmail);
holder.bloodGroup.setText(model.getBloodGroup());
holder.dateOfRequirement.setText(model.getDate());
holder.Location.setText(model.getLocation());
////////////////////////////////////////////////////////////////////
}
} else {
holder.frameView.setVisibility(View.VISIBLE);
holder.fulfilled.setVisibility(View.VISIBLE);
holder.requestFulfilled.setVisibility(View.GONE);
/*------------- Set current user card as visible -----------------*/
holder.userEmail.setText(AuthUserEmail);
holder.bloodGroup.setText(model.getBloodGroup());
holder.dateOfRequirement.setText(model.getDate());
holder.Location.setText(model.getLocation());
////////////////////////////////////////////////////////////////////
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
} else if (model.getUser().equals(null)) {
holder.userEmail.setText("You have not posted any request");
} else {
holder.frameView.setVisibility(View.GONE);
}
/* Fulfilled and Delete button Functionality */
holder.fulfilled.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Map<String, Object> response = new HashMap<>();
response.put("Fulfilled", "yes");
/*-----------------Remove Responses------------------*/
dbRefForResp.removeValue();
///////////////////////////////////////////////////////
/*-----------------Update and insert child with fulfilled status as yes------------------*/
dbRefForReq.child(String.valueOf(("Request " + finalPosition))).child("Fulfillment").setValue(response).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(yourRequestActivity.this, "Request fulfillment status posted", Toast.LENGTH_SHORT).show();
}
});
////////////////////////////////////////////////////////////////////
holder.fulfilled.setVisibility(View.GONE);
holder.requestFulfilled.setVisibility(View.VISIBLE);
}
});
}
#NonNull
#Override
public contentHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.your_request_card, viewGroup, false);
contentHolder contentViewHolder = new contentHolder(view);
return contentViewHolder;
}
};
cardView.setAdapter(adapter);
adapter.startListening();
}
public class contentHolder extends RecyclerView.ViewHolder {
TextView userEmail, bloodGroup, dateOfRequirement, Location, requestFulfilled;
Button fulfilled;
FrameLayout frameView;
public contentHolder(#NonNull View itemView) {
super(itemView);
userEmail = itemView.findViewById(R.id.RemailView);
bloodGroup = itemView.findViewById(R.id.RbloodView);
dateOfRequirement = itemView.findViewById(R.id.RdateView);
Location = itemView.findViewById(R.id.RlocationView);
requestFulfilled = (TextView) itemView.findViewById(R.id.fulfilledTextMessage);
frameView = (FrameLayout) itemView.findViewById(R.id.cardFrame);
fulfilled = (Button) itemView.findViewById(R.id.Requestfulfilled);
}
}
}
I want to remove the blank space which occurs while visibility is set to GONE, as shown in the snapshot below.
Image of empty space on removing top card
Image before setting visibility GONE
Simply remove the object from the list if its user is not equal to AuthUserEmail and notify your adapter.
NO NEED TO MAKE VISBILITY GONE OF THE HOLDER VIEW
Your RecyclerView takes space even if visibility is set to gone. It still takes space because there are items that RecyclerView wants to display. Although you can fix this by removing the items RecyclerView wants to show. It would take a lot of memory if you want show that RecyclerView again because you still have to add the items back. What I would recommend is to wrap your RecyclerView with a layout eg. LinearLayout and set that layout's visibility to gone.
Try doing this:
<LinearLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Place your RecyclerView here -->
<!-- change visibility of container view -->
</LinearLayout>
*Edit: You didn't explain it well. I get what you want now. You simply have to remove the item from your RecyclerView list. The best way to do this is by using DiffUtil. This a great tutorial online showing how you can implement it in Java. https://codinginflow.com/tutorials/android/room-viewmodel-livedata-recyclerview-mvvm/part-1-introduction
Cover your RecyclerView with a FrameLayout and then set your visibility over there.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycleView"
android:layout_gravity="top"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_editor_absoluteX="1dp"
tools:layout_editor_absoluteY="1dp" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
If this doesnt works then:
Cover your Cardview which is the layout that you designed for your Recyclerview with a FrameLayout. Anyone of them will surely work out for you.
I have recyclerview in activity_main.xml and I have there the image which shows to user - empty or not empty recyclerview. activity_main.xml:
<RelativeLayout
android:id="#+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:visibility="gone"
android:id="#+id/main_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
<LinearLayout
android:visibility="visible"
android:id="#+id/block_no_alarms"
android:orientation="vertical"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:src="#drawable/ic_nothing"
android:layout_width="match_parent"
android:layout_height="70dp" />
<TextView
android:text="#string/no_alarms"
android:textColor="#color/colorWhite"
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</RelativeLayout>
And I have recyclerview one item xml file
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardCornerRadius="7dp"
app:cardBackgroundColor="#color/colorDark"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/tv_time_alarm_one_item"
android:textColor="#color/colorWhite"
android:layout_margin="15dp"
android:textSize="25sp"
android:layout_centerVertical="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/tv_description_alarm_one_item"
android:textColor="#color/colorWhite"
android:layout_toRightOf="#id/tv_time_alarm_one_item"
android:textSize="14sp"
android:maxLines="2"
android:layout_marginRight="60dp"
android:ellipsize="end"
android:layout_centerVertical="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toEndOf="#id/tv_time_alarm_one_item"
android:layout_marginEnd="60dp" />
<Switch
android:id="#+id/s_switch_alarm_one_item"
android:layout_alignParentRight="true"
android:checked="true"
android:layout_centerVertical="true"
android:layout_margin="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true" />
</RelativeLayout>
</android.support.v7.widget.CardView>
And I wanna during long press click to this cardview to delete one item from the recyclerview. Adapter:
public class AlarmsAdapterMain extends RecyclerView.Adapter<AlarmsAdapterMain.ViewHolder> {
private List<String> listTimes = new ArrayList<>();
private List<String> listDescriptions = new ArrayList<>();
private List<Boolean> listStarted = new ArrayList<>(); // checked a switch
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.alarm_item, viewGroup, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder viewHolder, int i) {
viewHolder.time.setText(listTimes.get(i));
viewHolder.description.setText(listDescriptions.get(i));
viewHolder.aSwitch.setChecked(listStarted.get(i));
}
#Override
public int getItemCount() {
return listTimes.size();
}
public void deleteAll() {
listDescriptions.clear();
listTimes.clear();
listStarted.clear();
}
public void add(String time, String description) {
listTimes.add(time);
listDescriptions.add(description);
listStarted.add(true); // by default
}
class ViewHolder extends RecyclerView.ViewHolder {
private TextView time, description;
private Switch aSwitch;
ViewHolder(#NonNull final View itemView) {
super(itemView);
time = itemView.findViewById(R.id.tv_time_alarm_one_item);
description = itemView.findViewById(R.id.tv_description_alarm_one_item);
aSwitch = itemView.findViewById(R.id.s_switch_alarm_one_item);
// I try to set long listener here
}
}
}
I've done it, but I need to show or hide image or recyclerview if it need. For example, I have one alarm, user deletes it alarm and he sees empty layout but he must see image(LinearLayout) and hide recyclerview. So, how can I do it inside my adapter?
control your arrayLists from outside of your adapter, for example in your activity you should have a list of your data and pass the arrayList to your adapter's constructor, and manipulate your adapter data from activity and just notifyDataChange after any changes on your arrayList. so when you delete data or add some data, you can check your arrayList size in last line of your ad or delete operations (in your activity), and if arrayList size equals to 0 you should do changes on your UI.
also there is another way, you can have an interface that implements in your activity and it should have two methods for zeroMode or nonZeroMode and you can pass this interface to your adapter and invoke these methods when your arrayList size become zero or non-zero in your adapter.
I am making a app in which a activity shows some blog post data in card view. Everything Works Fine until if i have only 9 blog posts to show but when tenth post added then card-view gets messed up like 10 post shows both in 1st cardview item and in last cardview item.
below is the code to fill the Recyclerview Cardview
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_transaction);
LinearLayoutManager lm = new LinearLayoutManager(this);
lm.setReverseLayout(true);
lm.setStackFromEnd(true);
recyclerView = findViewById(R.id.blog_list);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(lm);
mref = FirebaseDatabase.getInstance().getReference().child("IHIAUPDATES");
}
public static class bloglistviewholder extends RecyclerView.ViewHolder {
static View mview;
public bloglistviewholder(View itemView) {
super(itemView);
mview = itemView;
}
public static void setTitle(String title){
TextView post_title = mview.findViewById(R.id.blog_title);
post_title.setText(title);
}
public static void setPosteon(String postedon){
TextView post_title = mview.findViewById(R.id.blog_postedon);
post_title.setText(postedon);
}
public static void setPostby(String postedby){
TextView post_title = mview.findViewById(R.id.blog_postedby);
post_title.setText(postedby);
}
public static void setPost(String post){
TextView post_content = mview.findViewById(R.id.blog_post);
post_content.setText(post);
}
public static void setImageurl(Context ctx, String imageurl){
ImageView post_image = mview.findViewById(R.id.blog_pic);
Picasso.with(ctx).load(imageurl).into(post_image)
;
}
}
#Override
protected void onStart() {
super.onStart();
FirebaseRecyclerAdapter<blog_list,bloglistviewholder> rAdapter = new FirebaseRecyclerAdapter<blog_list, bloglistviewholder>(
blog_list.class,
R.layout.blog_row,
bloglistviewholder.class,
mref.orderByKey()
) {
#Override
protected void populateViewHolder(bloglistviewholder viewHolder, blog_list model, int position) {
bloglistviewholder.setTitle(model.getTitle());
bloglistviewholder.setPost(model.getPost());
bloglistviewholder.setPostby(model.getPostedby());
bloglistviewholder.setPosteon(model.getPostedon());
bloglistviewholder.setImageurl(getApplicationContext(),model.getImageurl());
}
};
recyclerView.setAdapter(rAdapter);
}
Xml blog_row
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<ImageView
android:id="#+id/blog_pic"
android:layout_width="120dp"
android:layout_height="90dp"
android:padding="4dp" />
<TextView
android:id="#+id/blog_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_toRightOf="#id/blog_pic"
android:text="Apple MacBook Air Core i5 5th Gen - (8 GB/128 GB SSD/Mac OS Sierra)"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Small"
android:textColor="#000000" />
<TextView
android:id="#+id/blog_postedon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/blog_title"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:layout_toRightOf="#id/blog_pic"
android:text="13.3 Inch, 256 GB"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Small" />
<TextView
android:id="#+id/blog_postedby"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/blog_postedon"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:layout_toRightOf="#id/blog_pic"
android:background="#color/colorPrimary"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:text="4.7"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Small.Inverse"
android:textStyle="bold" />
<TextView
android:id="#+id/blog_post"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/blog_postedby"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:layout_toRightOf="#id/blog_pic"
android:text="INR 56990"
android:textAppearance="#style/TextAppearance.AppCompat" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
what could be wrong?
am i doing something wrong?
what could be wrong?
You have a logic problem where you insert your data into the database, causing the same first item to show up as the 10th item. However, since you haven't shown the code, it's impossible to guess beyond that.
What have you done to debug your code?
am i doing something wrong?
Well, you have a bug ... so ... yes? :P
I have an adapter class which loads items dynamically and shows them in a RecyclerView. My problem is that when I swipe up and down the recycler view the images get mixed and are shown in wrong positions (i.e. in other item's view).
For example, I have an item X and another item Y. Now when I swipe up and down the image which was to be shown in item Y get shown in item X and the same happens with other attributes.
Here is my adapter class:
public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.NewsViewHolder> {
private DatabaseReference refDNewsTable= FirebaseDatabase.getInstance().getReference().child("news_feeds");
private StorageReference refStorage = FirebaseStorage.getInstance().getReferenceFromUrl("firebase_url_comes_here");
private Context mContext;
private List<NewsModel> newsList;
public class NewsViewHolder extends RecyclerView.ViewHolder {
public TextView nHeading, nDes,nDaTi;
public ImageView nImg;
public NewsViewHolder(View view) {
super(view);
nHeading = (TextView) view.findViewById(R.id.tv_newsHeadline);
nDes = (TextView) view.findViewById(R.id.tv_nDes);
nImg = (ImageView) view.findViewById(R.id.iv_nImg);
nDaTi=(TextView) view.findViewById(R.id.tv_nDaTi);
}
}
public NewsAdapter(Context mContext, List<NewsModel> newsList) {
this.mContext = mContext;
this.newsList = newsList;
}
#Override
public NewsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.news_model, parent, false);
return new NewsViewHolder(itemView);
}
#Override
public void onBindViewHolder(final NewsViewHolder holder, int position) {
NewsModel news = newsList.get(position);
holder.nHeading.setText(news.getnHeading());
if(news.hasDes()) {
holder.nDes.setText(news.getnDes());
}else{
holder.nDes.setVisibility(View.GONE);
}
if(news.hasImg()){
// Reference to an image file in Firebase Storage
StorageReference imgReference =refStorage.child(news.getnId());
// Load the image using Glide
Glide.with(mContext)
.using(new FirebaseImageLoader())
.load(imgReference)
.into(holder.nImg);
}else{
holder.nImg.setVisibility(View.GONE);
}
holder.nDaTi.setText(news.getnDaTi());
}
public void downloadFile(final NewsViewHolder holder){
try {
final File localFile = File.createTempFile("images", "jpg");
refStorage.getFile(localFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
Bitmap bitmap = BitmapFactory.decodeFile(localFile.getAbsolutePath());
holder.nImg.setImageBitmap(bitmap);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
}
});
} catch (IOException e ) {}
}
#Override
public int getItemCount() {
return newsList.size();
}
}
And this is my news_model.xml file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:padding="10dp"
android:layout_margin="4dp"
card_view:cardPreventCornerOverlap="true"
card_view:cardElevation="16dp"
android:layout_height="wrap_content"
android:id="#+id/card_view"
android:layout_gravity="center"
card_view:cardCornerRadius="0dp">
<LinearLayout
android:orientation="vertical"
android:background="#color/cBgNews"
android:padding="0dp"
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:padding="10dp"
card_view:cardElevation="6dp"
card_view:cardBackgroundColor="#color/cNewsHeadline"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="0dp"
android:id="#+id/card_des"
android:layout_gravity="center"
card_view:cardCornerRadius="0dp">
<TextView
android:text="TextView"
android:textSize="17sp"
android:textStyle="normal"
android:padding="10dp"
android:maxLines="3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/cWhite"
android:gravity="start"
android:layout_margin="0dp"
android:id="#+id/tv_newsHeadline" />
</android.support.v7.widget.CardView>
<LinearLayout
android:orientation="vertical"
android:gravity="center_horizontal"
android:background="#0000"
android:paddingEnd="6dp"
android:paddingStart="6dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_marginBottom="0dp"
android:layout_height="wrap_content"
android:maxHeight="300dp"
app:srcCompat="#mipmap/ic_launcher"
android:scaleType="fitCenter"
android:layout_gravity="center_horizontal"
android:id="#+id/iv_nImg" />
<TextView
android:text="Description..."
android:maxLines="8"
android:textSize="16sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:padding="10dp"
android:textColor="#color/cBlack"
android:id="#+id/tv_nDes" />
<TextView
android:text="Date and Time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="10sp"
android:textColor="#999999"
android:gravity="end"
android:id="#+id/tv_nDaTi" />
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
NOTE: I am using firebase to receive the content directly and haven't created any kind of database in my app yet. i.e. it loads data every time it needs it directly in adapter class.