Search code examples
androidandroid-layoutandroid-recyclerviewandroid-nestedscrollview

Android: Why there are a blank space at the bottom of RecyclerView which is inside of NestedScrollView?


Using an RecyclerView inside NestedScrollView is creating a strange blank space (like bottom padding) in the activity, causing unnecessary scroll, because there aren't more elements to show.

This padding grows with the RecyclerView, I mean:

If in the RecyclerView there are 0 to 2 elements, this fit perfect on the screen, and there are no scroll. Here works well.

If in the RecyclerView there are 3 to 5 elements, these elements continue to fit on the screen BUT in this case there are more blank space that causing the unnecessary scroll.

With more elements, the blank space continue growing and creating more and more scroll.

Here is my XML:

<?xml version="1.0" encoding="utf-8"?>
<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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.ibosca.thub.ChannelProfileActivity">

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">


        <de.hdodenhof.circleimageview.CircleImageView xmlns:app="http://schemas.android.com/apk/res-auto"
            android:id="@+id/channelPicture"
            android:layout_width="90dp"
            android:layout_height="90dp"
            android:layout_marginBottom="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            app:civ_border_color="#FF000000"
            app:civ_border_width="2dp"
            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="parent"
            app:layout_constraintVertical_bias="0.0" />

        <TextView
            android:id="@+id/channelName"
            android:layout_width="256dp"
            android:layout_height="90dp"
            android:layout_marginBottom="8dp"
            android:layout_marginEnd="16dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:gravity="center_vertical"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:textAlignment="center"
            android:textColor="@android:color/black"
            android:textSize="20sp"
            android:textStyle="bold"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@+id/channelPicture"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.0" />

        <TextView
            android:id="@+id/description"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginEnd="24dp"
            android:layout_marginStart="24dp"
            android:layout_marginTop="8dp"
            android:textAlignment="center"
            android:textSize="15sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/channelPicture"
            app:layout_constraintVertical_bias="0.0" />

        <View
            android:id="@+id/line1"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_marginTop="8dp"
            android:background="@android:color/black"
            app:layout_constraintTop_toBottomOf="@+id/description" />

        <TextView
            android:id="@+id/contentsText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginEnd="24dp"
            android:layout_marginStart="24dp"
            android:layout_marginTop="8dp"
            android:text="@string/contents"
            android:textColor="@android:color/black"
            android:textAlignment="center"
            android:textSize="17sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/line1"
            app:layout_constraintVertical_bias="0.0" />

        <View
            android:id="@+id/line2"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_marginTop="8dp"
            android:background="@android:color/black"
            app:layout_constraintTop_toBottomOf="@+id/contentsText" />


        <android.support.v7.widget.RecyclerView
            android:id="@+id/contentList"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            app:layout_constraintTop_toBottomOf="@+id/line2"/>

    </android.support.constraint.ConstraintLayout>

</android.support.v4.widget.NestedScrollView>

</android.support.constraint.ConstraintLayout>

What it's causing this space? How can I remove it?

EDIT: ISSUE

Here you can see the error: https://www.youtube.com/watch?v=6nSc4l2c2jg

EDIT 2: RECYCLER

Adapter:

import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.ibosca.thub.R;
import com.ibosca.thub.models.Channel;
import com.ibosca.thub.models.Content;
import com.ibosca.thub.models.ContentList;
import com.squareup.picasso.Picasso;

import java.text.SimpleDateFormat;

import de.hdodenhof.circleimageview.CircleImageView;

public class ContentAdapter extends RecyclerView.Adapter<ContentAdapter.MyViewHolder> {

private ContentList contentList;

public class MyViewHolder extends RecyclerView.ViewHolder {
    public TextView title;
    public CircleImageView picture;
    public TextView channel;
    public TextView lastEdit;
    public ImageView badge;

    public MyViewHolder(View view) {
        super(view);
        title    = (TextView) view.findViewById(R.id.title);
        picture  = (CircleImageView) view.findViewById(R.id.picture);
        channel  = (TextView) view.findViewById(R.id.channel);
        lastEdit = (TextView) view.findViewById(R.id.lastEdit);
        badge    = (ImageView) view.findViewById(R.id.badge);
    }
}


public ContentAdapter(ContentList contentList) {
    this.contentList = contentList;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.content_row, parent, false);

    return new MyViewHolder(itemView);
}

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {

    //Get Content
    Content content = contentList.getContents().get(position);

    //Set title
    holder.title.setText(content.getTitle());

    //Set last edit, channel and picture
    holder.lastEdit.setText(new SimpleDateFormat("dd/MM/yy").format(content.getLastEdit()));
    Channel channel = contentList.findChannelById(content.getChannelId());
    String channelPicture = channel.getPicture();

    holder.channel.setText(channel.getName());
    Picasso.with(holder.picture.getContext()).load(channelPicture).into(holder.picture);

    holder.badge.setVisibility(View.VISIBLE);
    if(content.isRead()){
        holder.badge.setVisibility(View.GONE);
    }

}

@Override
public int getItemCount() {
    return contentList.getContents().size();
}


}

Recycler View (each row):

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:orientation="vertical"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp">

<de.hdodenhof.circleimageview.CircleImageView xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/picture"
    android:layout_width="55dp"
    android:layout_height="55dp"
    android:src="@drawable/ic_launcher_background"
    app:civ_border_color="#FF000000"
    app:civ_border_width="2dp"
    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="parent"
    app:layout_constraintVertical_bias="1.0" />

<TextView
    android:id="@+id/title"
    android:layout_height="27dp"
    android:layout_alignParentTop="true"
    android:layout_marginStart="8dp"
    android:layout_weight=".90"
    android:layout_width="0dp"
    android:ellipsize="end"
    android:maxLines="1"
    android:paddingLeft="5dp"
    android:paddingRight="5dp"
    android:singleLine="true"
    android:textColor="@android:color/black"
    android:textSize="15sp"
    android:textStyle="bold"
    app:layout_constraintBottom_toBottomOf="@+id/picture"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.0"
    app:layout_constraintStart_toEndOf="@+id/picture"
    app:layout_constraintTop_toTopOf="@+id/picture"
    app:layout_constraintVertical_bias="0.0" />

<TextView
    android:id="@+id/channel"
    android:layout_width="0dp"
    android:layout_height="23dp"
    android:layout_marginEnd="8dp"
    android:layout_marginStart="8dp"
    android:layout_weight=".90"
    android:ellipsize="end"
    android:maxLines="1"
    android:paddingLeft="5dp"
    android:paddingRight="5dp"
    android:singleLine="true"
    android:textSize="15sp"
    app:layout_constraintBottom_toBottomOf="@+id/picture"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.0"
    app:layout_constraintStart_toEndOf="@+id/picture"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintVertical_bias="0.51" />

<TextView
    android:id="@+id/lastEdit"
    android:layout_width="78dp"
    android:layout_height="23dp"
    android:gravity="bottom|end"
    android:textSize="12sp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="1.0"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintVertical_bias="1.0" />

<ImageView
    android:id="@+id/badge"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginEnd="8dp"
    android:layout_marginStart="8dp"
    android:contentDescription="notificationBadge"
    android:src="@drawable/orange_badge"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.09"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintVertical_bias="0.0" />

</android.support.constraint.ConstraintLayout>

Solution

  • In you xml file, change:

     <android.support.v4.widget.NestedScrollView
         android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true">
    

    to

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fillViewport="false">
    

    Or

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content">