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.
Related
Hi in the below code I am working with bottom navigation it contains different option in that one thing is account .If click on the account bottom tab want to display the cardview in recyclerviews
But data is not coming anything. It is displaying empty.
using this below xml to display the content in listview format
accounts.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
Fragment_account.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="20dp"
android:background="#color/White">
<android.support.v7.widget.CardView
android:id="#+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
app:cardBackgroundColor="#color/slivergray"
app:cardCornerRadius="8dp"
app:cardElevation="4dp"
app:cardUseCompatPadding="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#color/White">
<ImageView
android:id="#+id/appImage"
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_marginLeft="16dp"
android:background="#drawable/ic_account_circle_black_24dp"
android:backgroundTint="#color/gray"
android:scaleType="centerCrop"
tools:ignore="ContentDescription"/>
<TextView
android:id="#+id/headingText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/appImage"
android:paddingLeft="16sp"
android:paddingRight="16dp"
android:text="Apollo Hospital"
android:textColor="#color/black"
android:textSize="18sp"
tools:ignore="RtlHardcoded"/>
<TextView
android:id="#+id/subHeaderText"
style="#style/Base.TextAppearance.AppCompat.Subhead"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/headingText"
android:layout_toRightOf="#+id/appImage"
android:paddingLeft="16dp"
android:text="Hospital"
android:paddingRight="16dp"
android:textColor="#color/gray"
android:textSize="15sp"/>
<TextView
android:id="#+id/subHeadingText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/subHeaderText"
android:layout_toRightOf="#+id/appImage"
android:gravity="left"
android:lines="5"
android:maxLines="5"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingTop="16dp"
android:paddingRight="16dp"
android:text="stories_detailstories_detailstories_detailstories_detailstories_detailstories_detailstories_detailstories_detailstories_detailstories_detailstories_detailstories_detailstories_detailstories_detailstories_detailstories_detailstories_detailstories_detailstories_detailstories_detailstories_detailstories_detailstories_detailstories_detailstories_detailstories_detailstories_detailstories_detailstories_detailstories_detail"
android:textColor="#color/gray"
android:textSize="14sp"/>
<TextView
android:id="#+id/textViewOptions"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:text="⋮"
android:textColor="#color/gray"
android:layout_marginRight="10dp"
android:textAppearance="?android:textAppearanceLarge"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_below="#id/subHeadingText">
<LinearLayout
android:layout_width="209dp"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_marginLeft="30dp"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:backgroundTint="#color/gray"
android:src="#drawable/ic_account_circle_black_24dp"></ImageView>
<Button
android:id="#+id/action1"
style="#style/Base.Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Action 1"
android:textColor="#color/gray"
android:textSize="14sp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="right">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:src="#drawable/ic_account_circle_black_24dp"
android:layout_marginLeft="50dp"></ImageView>
<Button
android:id="#+id/action2"
style="#style/Base.Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Action 2"
android:textColor="#color/gray"
android:textSize="14sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
</RelativeLayout>
AccountFragment.java:
public class AccountFragement extends Fragment {
public AccountFragement(){
}
RecyclerView rv;
private List<List_Data> list_data;
private MyAdapter adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate (R.layout.account, container, false);
rv=(RecyclerView) rootView.findViewById(R.id.recyclerview);
//rv.setHasFixedSize(true);
rv.setLayoutManager(new LinearLayoutManager(getContext()));
list_data=new ArrayList<>();
adapter=new MyAdapter(list_data,getContext());
rv.setAdapter(adapter);
return rootView;
}
private void setupData(List<List_Data> list_data) {
adapter=new MyAdapter(list_data,getContext());
rv.setAdapter(adapter);
}
}
List_Data.java:
public class List_Data {
String title;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
MyAdapter.java:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private List<List_Data>list_data;
private Context context;
private String title1;
public MyAdapter(List<List_Data> list_data, Context context) {
this.list_data = list_data;
this.context = context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_account,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
List_Data listData=list_data.get(position);
// title1=list_data.get(0).getTitle();
holder.title.setText(listData.getTitle());
}
#Override
public int getItemCount() {
return list_data.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
ImageView img;
TextView title,subtile;
public ViewHolder(View itemView) {
super(itemView);
title=(TextView)itemView.findViewById(R.id.headingText);
subtile=(TextView)itemView.findViewById(R.id.subHeaderText);
title.setText(title1);
}
}
}
the code you have written is somehow incomplete, first you can not view any data because there are no data in the List list_data in the AccountFragment so the adapter is does not know where to fetch data from.
When you have data in the list then you can populate to the adapter.
I recommend you follow the best approach from the link below in case you have any problem please do let us know.
https://www.androidhive.info/2017/12/android-working-with-bottom-navigation/
And try your best to start using AndroidX in your project
I want to update the style of the selected item inside a ViewPager.
How can I do this?
This is the UI design. As you can see, the "November" tab is selected, so the corresponding bar is highlighted in yellow.
The way I've implemented this is a ViewPager with a custom item (white, not highlighted):
<?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="match_parent">
<androidx.cardview.widget.CardView
android:layout_width="142dp"
android:layout_height="275dp"
android:layout_margin="0dp"
app:cardElevation="0dp"
app:cardBackgroundColor="#android:color/transparent">
<TextView
android:id="#+id/monthly_spend_month"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/December"
android:textColor="#color/aluminum"
android:textSize="20sp"
android:textStyle="normal"
android:layout_marginStart="22dp"
android:layout_marginTop="34dp"/>
<RelativeLayout
android:id="#+id/monthly_spend_card"
android:layout_marginTop="120dp"
android:layout_marginStart="22dp"
android:layout_width="120dp"
android:layout_height="155dp"
android:background="#drawable/monthlyspend_card_bg_inactive">
<TextView
android:id="#+id/monthly_spend_text"
android:textColor="#color/almost"
android:layout_marginTop="50dp"
android:layout_marginStart="22dp"
android:text="Total
spent"
android:textSize="#dimen/balanceDescTextSize"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/monthly_spend_amount"
android:textColor="#color/almost"
android:layout_marginTop="10dp"
android:layout_marginStart="22dp"
android:layout_below="#id/monthly_spend_text"
android:text="$ 254.98"
android:textSize="#dimen/balanceDescTextSize"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
I plan on doing the highlighting programmatically.
Here's some adapter code:
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
layoutInflater = LayoutInflater.from(context);
View view = layoutInflater.inflate(R.layout.monthlyspend_item, container, false);
TextView monthlySpendMonth, monthlySpendAmount;
monthlySpendCard = view.findViewById(R.id.monthly_spend_card);
monthlySpendMonth = view.findViewById(R.id.monthly_spend_month);
monthlySpendAmount = view.findViewById(R.id.monthly_spend_amount);
monthlySpendMonth.setText(monthlySpendings.get(position).getMonth());
monthlySpendAmount.setText(monthlySpendings.get(position).getAmountSpent());
container.addView(view, 0);
return view;
}
Any help would be appreciated!
I thing you are missing click listener :
view.setOnClickListener(new OnClickListener(){
public void onClick(View v){
// do you stuff here
}
});
((ViewPager)container).addView(view, 0)
Also inside instantiateItem() make int position as final.
you should change your model (in your case "monthlyspendings") at the selected item position.
then notify the adapter
adapter.notifyDataSetChanged()
and finally, custom selected view according to the model. for exapmle :
if(monthlySpendings.get(position).isSelected) monthlySpendCard.setBackgroundColor(Color.parseColor("#fcd14b"));
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)
}
The Problem
I have a recycler view with card items. These card items contain only text and are expandable.It looks like this Collapsed Expanded
Now I expand and collapse one of them sometimes and scroll around and somehow there appears now more whitespace between the cards:
Whitespace between cards
Moreover, for cards with long text when I click to collapse them, this appears:
Big Cards
The Code
xml:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.ramotion.foldingcell.FoldingCell
android:id="#+id/folding_cell"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
app:backSideColor="#F5F5F5">
<FrameLayout
android:id="#+id/cell_content_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="300dp"
android:visibility="gone">
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:cardview="http://schemas.android.com/apk/res-auto"
xmlns:custom="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/movie_card2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:foreground="?attr/selectableItemBackground"
android:minHeight="300dp"
cardview:cardBackgroundColor="#color/card_background"
cardview:cardCornerRadius="1dp"
cardview:cardElevation="4dp"
cardview:cardUseCompatPadding="true">
<RelativeLayout
android:id="#+id/review_item2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:orientation="vertical">
<View
android:id="#+id/review_detail_header"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#color/material_red_400" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#id/review_detail_header"
android:layout_alignTop="#id/review_detail_header"
android:layout_centerHorizontal="true"
android:gravity="center"
android:text="Review Details"
android:textColor="#color/text_secondary" />
<ImageView
android:id="#+id/ic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/review_detail_header"
android:layout_marginTop="#dimen/material_layout_keylines_horizontal_margin"
android:adjustViewBounds="true"
android:paddingLeft="#dimen/material_layout_keylines_horizontal_margin"
android:paddingRight="#dimen/material_layout_keylines_horizontal_margin"
android:src="#drawable/ic_account_circle_white_24dp"
android:tint="#color/accent"
tools:ignore="ContentDescription" />
<com.mt.moviesiwanttowatch.ui.widget.TextViewRoboto
android:id="#+id/review_author2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/review_detail_header"
android:layout_gravity="center_vertical"
android:layout_marginTop="#dimen/material_layout_keylines_horizontal_margin"
android:layout_toRightOf="#id/ic"
android:textSize="14sp"
custom:robotoType="bold"
tools:text="User Name" />
<com.mt.moviesiwanttowatch.ui.widget.TextViewRoboto
android:id="#+id/review_body2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/review_author2"
android:layout_marginBottom="#dimen/material_layout_keylines_horizontal_margin"
android:layout_marginLeft="56dp"
android:layout_marginRight="24dp"
android:layout_marginTop="#dimen/material_layout_vertical_spacing_between_content_areas"
android:layout_weight="1"
android:ellipsize="none"
android:maxLines="100"
android:scrollHorizontally="false"
android:textSize="14sp"
custom:robotoType="regular"
tools:text="The movie's review goes here..." />
<com.mt.moviesiwanttowatch.ui.widget.TextViewRoboto
android:id="#+id/review_spoiler2"
style="#style/ReviewBodyStyle"
android:text="#string/reviews_alert"
android:textColor="#color/primary"
android:visibility="gone"
custom:robotoType="bold" />
<com.mt.moviesiwanttowatch.ui.widget.TextViewRoboto
android:id="#+id/review_time2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_below="#+id/review_body2"
android:layout_margin="#dimen/material_layout_keylines_horizontal_margin"
android:textSize="#dimen/material_layout_keylines_horizontal_margin"
android:visibility="gone"
custom:robotoType="regular"
tools:text="01 Jan 2016" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</FrameLayout>
<FrameLayout
android:id="#+id/cell_title_view"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:cardview="http://schemas.android.com/apk/res-auto"
xmlns:custom="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/movie_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:foreground="?attr/selectableItemBackground"
cardview:cardBackgroundColor="#color/card_background"
cardview:cardCornerRadius="1dp"
cardview:cardElevation="4dp"
cardview:cardUseCompatPadding="true">
<RelativeLayout
android:id="#+id/review_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:orientation="vertical"
android:padding="#dimen/material_layout_keylines_horizontal_margin">
<ImageView
android:id="#+id/ic2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:adjustViewBounds="true"
android:src="#drawable/ic_account_circle_white_24dp"
android:tint="#color/accent"
tools:ignore="ContentDescription" />
<com.mt.moviesiwanttowatch.ui.widget.TextViewRoboto
android:id="#+id/review_author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/material_layout_keylines_horizontal_margin"
android:layout_toRightOf="#+id/ic2"
custom:robotoType="bold"
android:textSize="14sp"
tools:text="User Name" />
<!-- Review open icon -->
<ImageView
android:id="#+id/review_open"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:adjustViewBounds="true"
android:src="#drawable/ic_open_in_new_white_24dp"
android:tint="#color/accent"
tools:ignore="contentDescription" />
<!-- Review Body -->
<com.mt.moviesiwanttowatch.ui.widget.TextViewRoboto
android:id="#+id/review_body"
style="#style/ReviewBodyStyle"
android:layout_marginLeft="40dp"
android:layout_marginRight="8dp"
android:layout_below="#+id/review_spoiler"
custom:robotoType="regular"
tools:text="The movie's review goes here..." />
<com.mt.moviesiwanttowatch.ui.widget.TextViewRoboto
android:id="#+id/review_spoiler"
style="#style/ReviewBodyStyle"
android:layout_below="#id/review_open"
android:text="#string/reviews_alert"
android:textColor="#color/primary"
android:layout_marginLeft="40dp"
android:layout_marginRight="8dp"
android:visibility="gone"
custom:robotoType="bold" />
<com.mt.moviesiwanttowatch.ui.widget.TextViewRoboto
android:id="#+id/review_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_below="#+id/review_body"
android:layout_margin="#dimen/material_layout_keylines_horizontal_margin"
android:textSize="#dimen/material_layout_keylines_horizontal_margin"
android:visibility="gone"
custom:robotoType="regular"
tools:text="01 Jan 2016" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</FrameLayout>
</com.ramotion.foldingcell.FoldingCell>
</layout>
The adapter:
public class ReviewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public ArrayList<Review> reviewList;
public int foldingCellPosition = -1;
public FoldingCell currentFoldingCell;
// Constructor
public ReviewAdapter(ArrayList<Review> reviewList) {
this.reviewList = reviewList;
}
// RecyclerView methods
#Override
public int getItemCount() {
return reviewList.size();
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ViewGroup v = (ViewGroup) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list_review, parent, false);
return new ReviewViewHolder(v);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
Review review = reviewList.get(position);
ReviewViewHolder holder = (ReviewViewHolder) viewHolder;
if (position == foldingCellPosition) {
holder.binding.foldingCell.unfold(true);
holder.binding.reviewBody2.setText(review.getComment());
holder.binding.reviewAuthor2.setText(review.getUsername());
return;
}
holder.binding.foldingCell.fold(true);
holder.binding.reviewAuthor.setText(review.getUsername());
if (review.isHasSpoiler()) {
holder.binding.reviewBody.setVisibility(View.GONE);
holder.binding.reviewSpoiler.setVisibility(View.VISIBLE);
} else {
holder.binding.reviewBody.setText(review.getComment());
holder.binding.reviewBody.setVisibility(View.VISIBLE);
holder.binding.reviewSpoiler.setVisibility(View.GONE);
}
holder.binding.reviewTime.setText(review.getCreatedAt());
}
// ViewHolder
public class ReviewViewHolder extends RecyclerView.ViewHolder {
ItemListReviewBinding binding;
public ReviewViewHolder(final ViewGroup itemView) {
super(itemView);
binding = DataBindingUtil.bind(itemView);
binding.reviewItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// onReviewClickListener.onReviewClicked(getAdapterPosition());
Log.e("TEST", "CLIKC");
if (foldingCellPosition != -1) {
currentFoldingCell.fold(false);
}
currentFoldingCell = binding.foldingCell;
binding.reviewBody2.setText(reviewList.get(getAdapterPosition()).getComment());
binding.reviewAuthor2.setText(reviewList.get(getAdapterPosition()).getUsername());
binding.foldingCell.toggle(false);
foldingCellPosition = getAdapterPosition();
}
});
binding.reviewItem2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
binding.reviewItem2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
foldingCellPosition = -1;
binding.foldingCell.fold(false);
}
});
}
});
}
}
}
How the recycler view is created:
layoutManager = new LinearLayoutManager(getContext());
mBinding.movieDetailReviewListRvReviews.setHasFixedSize(true);
mBinding.movieDetailReviewListRvReviews.setLayoutManager(layoutManager);
mBinding.movieDetailReviewListRvReviews.setAdapter(adapter);
What I tried so far
I really dont have any idea why this happens.
However I tried notifyDataSetChanged() after each collapse/expand as well as invalidate().
Edit
For the collapsing / expanding effect I use this library:https://github.com/Juriv/folding-cell-android
Actually there were a lot of problems with my code. First of all, as rom4ek mentioned, I had to change foldingCellPosition = getAdapterPosition() to foldingCellPosition = getLayoutPosition(). The next Problem, was this call:
if(foldingCellPosition != -1) {
currentFoldingCell.fold(false);
}
Not visible views should fold, which resulted in strange behaviour, so I added this code:
public void checkForHide(int first, int last){
if(foldingCellPosition != -1){
if(foldingCellPosition < first || foldingCellPosition > last){
foldingCellPosition = -1;
}
}
}
If the unfolded view is not visible the folding cellposition will set to -1 instead of folding it manually.
It is called from the Fragment here:
mBinding.movieDetailReviewListRvReviews.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
// Load more data if reached the end of the list
adapter.checkForHide(layoutManager.findFirstVisibleItemPosition(), layoutManager.findLastVisibleItemPosition());
if (layoutManager.findLastVisibleItemPosition() == adapter.reviewList.size() - 1 && !isLoadingLocked && !isLoading) {
if (pageToDownload < totalPages) {
mBinding.layoutContent.pbLoadingMore.setVisibility(View.VISIBLE);
downloadMovieReviews();
}
}
}
});
Try leaving cardview:cardUseCompatPadding false, which is the default.
From https://developer.android.com/reference/android/support/v7/widget/CardView.html#setUseCompatPadding(boolean)
setUseCompatPadding
added in version 24.2.0 void setUseCompatPadding (boolean
useCompatPadding) CardView adds additional padding to draw shadows on
platforms before Lollipop.
This may cause Cards to have different sizes between Lollipop and
before Lollipop. If you need to align CardView with other Views, you
may need api version specific dimension resources to account for the
changes. As an alternative, you can set this flag to true and CardView
will add the same padding values on platforms Lollipop and after.
Since setting this flag to true adds unnecessary gaps in the UI,
default value is false.
This implies that the CardView may be adding padding when you collapse/expand cards.
I have very popular question - why the data not showing in the RecycleView.
That is my Adapter:
public class CommentsAdapter extends RecyclerView.Adapter<CommentsAdapter.ViewHolder> {
private static final String TAG = "CommentsAdapter";
public ImageView mThumbView;
private List<PostComment> postCommentList;
public CommentsAdapter(List<PostComment> postCommentList) {
this.postCommentList = postCommentList;
}
#Override
public CommentsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.post_comment_item, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(CommentsAdapter.ViewHolder holder, int position) {
PostComment record = postCommentList.get(position);
holder.mAuthorTextView.setText(record.getUser().getFull_name());
holder.mDateTextView.setText(record.getCreated_at());
holder.mTextTextView.setText(record.getText());
}
#Override
public int getItemCount() {
Log.i(TAG + " comments size", Integer.toString(postCommentList.size()));
return postCommentList.size();
}
public void addItems(List<PostComment> postCommentList) {
this.postCommentList.addAll(postCommentList);
}
public class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView mAuthorTextView;
public TextView mDateTextView;
public TextView mTextTextView;
public ViewHolder(View v) {
super(v);
mAuthorTextView = (TextView) itemView.findViewById(R.id.comment_author);
mDateTextView = (TextView) itemView.findViewById(R.id.comment_date);
mTextTextView = (TextView) itemView.findViewById(R.id.comment_text);
}
}
}
That is my view:
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/container"
....>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp">
<ImageView
android:id="#+id/comment_image"
android:layout_width="50dp"
android:layout_height="50dp"
android:scaleType="centerInside"
android:src="#drawable/cat"/>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/middleLayout"
android:layout_toRightOf="#+id/comment_image"
android:layout_marginTop="8dp">
<TextView
android:id="#+id/comment_author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:singleLine="true"
android:text="Dark Plastic"
android:textColor="?attr/colorPrimary"
android:textSize="14dp" />
<TextView
android:id="#+id/comment_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="8dp"
android:layout_toRightOf="#+id/comment_author"
android:text="21 minutes"
android:textSize="14dp" />
</RelativeLayout>
<TextView
android:id="#+id/comment_text"
android:layout_width="wrap_content"
android:layout_toRightOf="#+id/comment_image"
android:layout_height="wrap_content"
android:maxLines="3"
android:layout_marginTop="8dp"
android:layout_below="#id/middleLayout"
android:text="sd"
android:textColor="#android:color/black"
android:textSize="16dp" />
</RelativeLayout>
<View
android:id="#+id/divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_gravity="bottom"
android:paddingLeft="16dp"
android:paddingRight="16dp"></View>
That is how I set up the adapter:
mLayoutManager = new LinearLayoutManager(this);
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
post_details_comments_list.setLayoutManager(mLayoutManager);
mCommentListAdapter = new CommentsAdapter(new ArrayList<PostComment>());
post_details_comments_list.setAdapter(mCommentListAdapter);
After I set up the adapter, I the getItemCount returns the quantity of the items - so that is not null.
RecycleView layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.gms.maps.MapView
android:id="#+id/post_details_mapview"
android:layout_width="wrap_content"
android:layout_height="200dp" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/post_details_comments_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/TextLabelStyle"/>
</RelativeLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/post_details_comments_list"
android:layout_width="match_parent"
android:scrollbars="vertical"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/edit_comment"
android:hint="#string/hint_type_comment"/>
</LinearLayout>
I make the request to the server and here is the callback, where I get the results and set up the adapter:
#Override
public void onAllPostCommentsCallback(AllComments allComments) {
Log.i(TAG + " I've the comments", allComments.getPostCommentList().toString());
mCommentListAdapter.addItems(allComments.getPostCommentList());
post_details_comments_list.setAdapter(mCommentListAdapter);
mCommentListAdapter.notifyDataSetChanged();
}
But the list is not displaying.
What can be the reason?
put null inplace of parent in View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.post_comment_item, parent, false);
I've already solved the issue. The problem was that I had RecycleView inside the NestedScrollView
Answer in this post helped me a lot:
How to use RecyclerView inside NestedScrollView?