RecyclerView not render cells with 0dp height - android

I made an app with onboarding flow.
I have a recyclerview in my MainActivity class and I want to update it when onResume hits(Right after the onboarding flow).
So this how the recycler xml looks:
<android.support.v7.widget.RecyclerView
android:id="#+id/notifyRecycler"
android:layout_width="0dp"
android:layout_height="230dp"
android:clipToPadding="false"
android:orientation="horizontal"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
and this it the cell layout:
<android.support.constraint.ConstraintLayout 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:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="#+id/cardDetails"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
</...>
I swap the data within the adapter with clear and add and everything works great when I change the cell layout view height from 0dp to match parent.
It also works great for the first run from oncreate, but when I try to update from onResume it just not notify the data set changed.
Here's the code of the adapter called from onResume function:
public void setNewData(ArrayList<Model> models) {
this.notifications.clear();
this.notifications.addAll(models);
notifyDataSetChanged();
}
in onCreate:
adapter = new NotificationsAdapter(new ArrayList<>(), this);
notifyRecycler.setAdapter(adapter);
in onResume,I made boolan var to make it update only when resuming the app:
ArrayList<NotificationModel> notificationsList = new ArrayList<>();
notificationsList.add(...);
notificationsList.add(...);
adapter.setNewData(notificationsList);

Wierd solution, Solved by changing the parent ViewGroup from ConstraintsLayout to RelativeLayout.

Related

How to place a view and a recyclerView in the same screen

I am trying to put recyclerView with a screen (Fragment) that has textView.
The .xml file of the fragment i'm trying to add to:
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".ui.ways.WaysFragment">
<TextView
android:id="#+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/ways_quote"
android:layout_marginTop="#dimen/card_margin"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:textSize="18sp"
android:layout_marginBottom="10dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerview"
android:layout_width="0dp"
android:layout_height="0dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView"
tools:listitem="#layout/custom_ways_item" />
</androidx.constraintlayout.widget.ConstraintLayout>
I will try to describe the appearance (result) of what I tried to do with code and words, rather than pictures, I think it will be easily understood that way.
At first I added textView and just put the recyclerView under it.
And the result(appearance on my test device) I got look like:
Layout:
....
TextView:
....
ScrollView:
....
and the contents of my recyclerView
By this I mean, the textView doesn't scroll but the recyclerView does.
Next I put the textView and recyclerView inside the a single scrollView. But the textView scrolls seperately from the recyclerView, as if textView and recyclerView were in different scrollView.
the result(appearance on my test device) I got look like:
Layout:
....
ScrollView:
....
TextView:
....
ScrollView:
....
and the contents of my recyclerView
And my desired Appearances, is:
Layout:
....
ScrollView:
....
TextView:
....
Contents of my recyclerView:
....
I have discovered I named this question wrong it should have been "how to put header in a recyclerview using kotlin".
To do I created a new layout for the header, and an adapter.
Then I used ConcatAdapter To add the adapter of the header and recyclerview together.
I followed this tutorial on medium.

Android: Adding RecyclerView below Fragment

I'm trying to add a RecyclerView underneath a Fragment that I add programmatically, but it doesn't show up. I would like the RecyclerView to dynamically use the remaining space of the screen (since the Fragment above it can vary in size) so I put constraints at the edges and set the height to 0dp. The RecyclerView populates just fine, but it displays somewhere below the screen (I have to put the height of the RecyclerView to ~1300 dp to make it show up).
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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"
android:background="#color/colorPrimary">
<ImageView
android:id="#+id/Toolbar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#color/colorPrimary"
android:contentDescription="#null"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<RelativeLayout
android:id="#+id/FragmentContainer"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/Toolbar" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/RecyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/FragmentContainer"/>
</androidx.constraintlayout.widget.ConstraintLayout>
I then use this code to programmatically add the Fragment to my FragmentContainer:
MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Remove current fragment(s)
for (fragment in supportFragmentManager.fragments) {
supportFragmentManager.beginTransaction().remove(fragment!!).commit()
}
val transaction: FragmentTransaction = supportFragmentManager.beginTransaction()
var fragment: Fragment
if (someBoolean)
fragment = FirstFragment()
else
fragment = SecondFragment()
// Add correct fragment to container
transaction.add(R.id.FragmentContainer, fragment)
transaction.commit()
}
I have tried putting the RecyclerView into various layouts, but the results weren't any better. Any ideas are appreciated!

Why does one of the two fragments in an activity take up the whole screen during run time?

my activity_main.xml has two framelayouts that acts as containers for two fragments .When i run each fragment individually ,they run good .when i try to initialize and display both fragments ,one of the fragments called recents fragment is taking the full screen view .
when i run this fragment individually ,it takes full screen view instead of running in its own container.
and when i try to initialize my second fragment after initializing recents fragment i get an errorNo view found for id 0x7f070044 (com.example.diary:id/allnotesfragment) for fragment BlankFragment{7eb6bf4 (bc0fee9d-4a46-4e2b-ab31-d060c0ec14ae) id=0x7f070044}
activity code where i initialize both the fragments are is given below
package com.example.diary;
public class MainActivity extends AppCompatActivity {
int j;
List<NotesEntry> entries;
RecyclerAdapter adapter;
NotesDatabase db;
int numofitems;
String notesdata = "new_notes";
String defaultnotes = "old_notes";
Context c = this;
GridLayoutManager gridLayoutManager;
RecentsFragment recentsFragment;
ActivityMainBinding binding;
String textfortest;
int id;
FragmentManager fragmentManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecentsFragment recentsFragment=new RecentsFragment();
BlankFragment blankFragment=new BlankFragment();
fragmentManager =getSupportFragmentManager();
fragmentManager.beginTransaction().add(R.id.recentsfragment,recentsFragment).commit();
fragmentManager.beginTransaction().add(R.id.allnotesfragment,blankFragment).commit();
}
}
its layout xml is
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/recentsfragment"
android:layout_width="395dp"
android:layout_height="325dp"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.618"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/view"></FrameLayout>
<view
android:id="#+id/view"
class="android.widget.Button"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginBottom="8dp"
android:background="#android:color/darker_gray"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="-51dp" />
<FrameLayout
android:id="#+id/allnotesfragment"
android:layout_width="395dp"
android:layout_height="327dp"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toTopOf="#+id/view"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"></FrameLayout>
i tried to implement it on other layouts too ,but the result is same.
thanks for your time
Your layout is most likely incorrect. Try something like this.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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:id="#+id/main_constraint_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<FrameLayout
android:id="#+id/fragment_container1"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#id/some_view"/>
<view
android:id="#+id/some_view"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="#id/fragment_container1"
app:layout_constraintBottom_toTopOf="#id/fragment_container2"/>
<FrameLayout
android:id="#+id/fragment_container2"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="#id/some_view"
app:layout_constraintBottom_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
After spending a lot of time on it, I found that the problem is not with the layout but with the fragment itself.
In the oncreateView method of a fragment, I used databinding to refer to view instead of findViewById() and I have implemented a wrong way of databinding.
so by implementing databinding in the following way, I solved my problem.
fragmentBlankBinding = FragmentBlankBinding.inflate(inflater,container,false);
fragmentBlankBinding.recyclerView.setAdapter(adapter);
fragmentBlankBinding.recyclerView.setLayoutManager(layoutManager);
view=fragmentBlankBinding.getRoot();
return view;
Note: you need not refer to any layouts using this method as the layout is automatically fetched from databinding layout file of your fragment.
Hope it helps someone

How to hide footer in RecyclerView Adapter?

I want to add footer with empty layout to the bottom of the recyclerView which will show up only if certain View is visible on screen(In my case FabButton). FabButton is overlapping my last RecyclerView item, so I want to add empty Footer to the bottom of the recyclerview if this FabButton is visible.
ViewHolder inside Adapter for Footer:
inner class FooterViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
Inside onBindViewHolder:
... ViewHolder above is for items.
else if(holder is FooterViewHolder){
if (parentFragment.isFabButtonVisible()){
holder.itemView.visibility = View.VISIBLE
} else {
holder.itemView.visibility = View.GONE
}
}
This part of the code is working(also else branch is executed correctly), but my footer view is permanently visible on screen. Even if i add only View.GONE it is still visible.
XML for Parent Activity:
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#color/splash_white"
android:layout_weight="1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
>
<com.app.TabLayoutEntity.CustomViewPager
android:id="#+id/fragmentViewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="0dp"
android:background="#color/splash_white"
tools:layout_editor_absoluteY="-2dp" />
<ImageButton
android:id="#+id/fabButton"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
android:background="#drawable/fab_gradient"
android:clickable="true"
android:scaleType="fitCenter"
android:adjustViewBounds="true"
android:padding="8dp"
android:elevation="8dp"
android:shape="oval"
android:src="#drawable/ico_fab" />
</android.support.design.widget.CoordinatorLayout>
Fragment XML(Inside ViewPager):
<?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:clipToPadding="true"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/itemRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/recyclerview_corners"
android:clipToPadding="false"
android:scrollbars="vertical"
android:paddingBottom="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
If You just wanna avoid overlapping of last item and Fab then you should do this below simple change in xml on recyclerview and parent layout
<android.support.v7.widget.RecyclerView
android:clipToPadding="false"
android:paddingBottom="paddingindp"/>// for example You can add 100dp and test
and on parent layout add this below line
android:clipToPadding="true"
this will make your recyclerview scroll over that Fab and its doesnt require to add Footer view
Hope this work for your requirement.
You can add your condition in getItemCount() method since you need to increase your list size if you add footer
Like,
override fun getItemCount(): Int {
if (parentFragment.isFabButtonVisible()){
return mModels.size + 1
} else {
return mModels.size
}
}

RecyclerView isn't scrolling

I'm making an app, which contains a recyclerView with some items in it. The app uses a BottomNavigationView, and three other fragments to show some content.
Now, one of those fragments contains just a RecyclerView and isn't scrolling.
I already tried some things, like changing the height of the RecyclerView from match_parent to wrap_content, wrapping it with a LinearLayout, using a NestedScrollView or regular ScrollView, adding app:layout_behavior and even android:scrollbars. Nothing worked though.
The XML file of the layout with the list which isn't scrolling in it:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="55dp">
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_users"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
I set the ConstrainedLayout below as the parent of the other Fragment, this also contains the BottomNavigationView (this is generated by Android Studio when I created the project btw):
<android.support.constraint.ConstraintLayout
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:id="#+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.BottomNavigationView
android:id="#+id/navigation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="0dp"
android:layout_marginStart="0dp"
android:background="#color/colorPrimary"
app:itemIconTint="#drawable/bottom_nav_selector"
app:itemTextColor="#drawable/bottom_nav_selector"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="#menu/navigation" />
</android.support.constraint.ConstraintLayout>
Finally, this is inside the Fragment's class, where I set the RecyclerView:
adapter = new UserListAdapter(list, getContext(), getLayoutInflater(), container);
RecyclerView recyclerView = v.findViewById(R.id.rv_users);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter);
I hope one of you guys can help me!
Have you enough data to list on recycler for scrolling?

Categories

Resources