Android Cannot use wrap_content with SwipeRefreshLayout, how to implement custom one

  android, java, swiperefreshlayout

RecyclerView wrap_content not working.TextView after it not showing and RecyclerView in SwipeRefreshLayout not "wrap_content" DID NOT SOLVE MY ISSUE

Hello, i try to build a little app where i want to display cards inside a SwipeRefreshLayout. As you may know, the wrap_content attr doesn’t work properly with this particular layout (see this question). The answer provided blames the layout for a behaviour that it takes up all space it can (or maybe a fixed size). So the problem basically is that i can’t put a second layout into a SwipeRefreshLayout that should wraps it’s children because it fills the parent layout. (Putting the SRL in a Linear- or RelativeLayout didn’t help).

I have found this on Github and the functionality shown in the README kind of looks like what i want to achieve and use. But the files are outdated and i can’t implement the project from within gradle (the repository isn’t available anymore).

Now i try to update this adjusted version of the SwipeRefreshLayout in a library. Copy-pasting would be an approach, but i want to understand what needs to get changed or rather what code is malfunctioning (if we would say the "wrap-contentable"-layout was the goal).
So i copied both of the contents into a separate file, removed the imports and leading comments and ran diff, which outputs:

diff SwipeRefreshLayout.java WrapContentableSwipeRefreshLayout.java 
1,2c1,2
< public class SwipeRefreshLayout extends ViewGroup implements NestedScrollingParent,
<         NestedScrollingChild {
---
> public class WrapContentableSwipeRefreshLayout extends ViewGroup implements NestedScrollingParent,
>     NestedScrollingChild {
4a5
> 
8c9,12
<     public static final int DEFAULT_SLINGSHOT_DISTANCE = -1;
---
>     private final ArrayList<View> mMatchParentChildren = new ArrayList<>(1);
> 
>     @ViewDebug.ExportedProperty(category = "measurement")
>     boolean mMeasureAllChildren = false;
24,25c28
<     // Max amount of circle that can be filled by progress during swipe gesture,
<     // where 1.0 is a full circle
---
>     // Max amount of circle that can be filled by progress during swipe gesture, where 1.0 is a full circle
27d29
< 
29d30
< 
31d31
< 
33d32
< 
42c41
<     OnRefreshListener mListener;
---
>     SwipeRefreshLayout.OnRefreshListener mListener;
47,49c46
<     // If nested scrolling is enabled, the total amount that needed to be
<     // consumed by this as the nested scrolling parent is used in place of the
<     // overscroll determined by MOVE events in the onTouch handler
---
>     // If nested scrolling is enabled, the total amount that needed to be consumed by this as the nested scrolling parent is used in place of the overscroll determined by MOVE events in the onTouch handler
72c69
<         android.R.attr.enabled
---
>             android.R.attr.enabled
75c72
<     CircleImageView mCircleView;
---
>     WrapContentableCircleImageView mCircleView;
86,87d82
<     int mCustomSlingshotDistance;
< 
107c102
<     private OnChildScrollUpCallback mChildScrollUpCallback;
---
>     private WrapContentableSwipeRefreshLayout.OnChildScrollUpCallback mChildScrollUpCallback;
170,173c165,166
<      * The refresh indicator starting and resting position is always positioned
<      * near the top of the refreshing content. This position is a consistent
<      * location, but can be adjusted in either direction based on whether or not
<      * there is a toolbar or actionbar present.
---
>      * The refresh indicator starting and resting position is always positioned near the top of the refreshing content.
>      * This position is a consistent location, but can be adjusted in either direction based on whether or not there is a toolbar or actionbar present.
179,186c172,175
<      * @param scale Set to true if there is no view at a higher z-order than where the progress
<      *              spinner is set to appear. Setting it to true will cause indicator to be scaled
<      *              up rather than clipped.
<      * @param start The offset in pixels from the top of this view at which the
<      *              progress spinner should appear.
<      * @param end The offset in pixels from the top of this view at which the
<      *            progress spinner should come to rest after a successful swipe
<      *            gesture.
---
>      * @param scale Set to true if there is no view at a higher z-order than where the progress spinner is set to appear.
>      *              Setting it to true will cause indicator to be scaled up rather than clipped.
>      * @param start The offset in pixels from the top of this view at which the progress spinner should appear.
>      * @param end The offset in pixels from the top of this view at which the progress spinner should come to rest after a successful swipe gesture.
198,199c187
<      * @return The offset in pixels from the top of this view at which the progress spinner should
<      *         appear.
---
>      * @return The offset in pixels from the top of this view at which the progress spinner should appear.
206,207c194
<      * @return The offset in pixels from the top of this view at which the progress spinner should
<      *         come to rest after a successful swipe gesture.
---
>      * @return The offset in pixels from the top of this view at which the progress spinner should come to rest after a successful swipe gesture.
214,217c201,202
<      * The refresh indicator resting position is always positioned near the top
<      * of the refreshing content. This position is a consistent location, but
<      * can be adjusted in either direction based on whether or not there is a
<      * toolbar or actionbar present.
---
>      * The refresh indicator resting position is always positioned near the top of the refreshing content.
>      * This position is a consistent location, but can be adjusted in either direction based on whether or not there is a toolbar or actionbar present.
219,224c204,206
<      * @param scale Set to true if there is no view at a higher z-order than where the progress
<      *              spinner is set to appear. Setting it to true will cause indicator to be scaled
<      *              up rather than clipped.
<      * @param end The offset in pixels from the top of this view at which the
<      *            progress spinner should come to rest after a successful swipe
<      *            gesture.
---
>      * @param scale Set to true if there is no view at a higher z-order than where the progress spinner is set to appear.
>      *              Setting it to true will cause indicator to be scaled up rather than clipped.
>      * @param end The offset in pixels from the top of this view at which the progress spinner should come to rest after a successful swipe gesture.
233,244d214
<      * Sets a custom slingshot distance.
<      *
<      * @param slingshotDistance The distance in pixels that the refresh indicator can be pulled
<      *                          beyond its resting position. Use
<      *                          {@link #DEFAULT_SLINGSHOT_DISTANCE} to reset to the default value.
<      *
<      */
<     public void setSlingshotDistance(@Px int slingshotDistance) {
<         mCustomSlingshotDistance = slingshotDistance;
<     }
< 
<     /**
245a216,217
>      *
>      * @param size size
268c240
<      * @param context
---
>      * @param context context
270c242
<     public SwipeRefreshLayout(@NonNull Context context) {
---
>     public WrapContentableSwipeRefreshLayout(@NonNull Context context) {
277,278c249,250
<      * @param context
<      * @param attrs
---
>      * @param context context
>      * @param attrs attrs
280c252
<     public SwipeRefreshLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
---
>     public WrapContentableSwipeRefreshLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
285,286c257
<         mMediumAnimationDuration = getResources().getInteger(
<                 android.R.integer.config_mediumAnimTime);
---
>         mMediumAnimationDuration = getResources().getInteger(android.R.integer.config_mediumAnimTime);
329c300
<         mCircleView = new CircleImageView(getContext(), CIRCLE_BG_LIGHT);
---
>         mCircleView = new WrapContentableCircleImageView(getContext(), CIRCLE_BG_LIGHT);
338,339c309,311
<      * Set the listener to be notified when a refresh is triggered via the swipe
<      * gesture.
---
>      * Set the listener to be notified when a refresh is triggered via the swipe gesture.
>      *
>      * @param listener listener
341c313
<     public void setOnRefreshListener(@Nullable OnRefreshListener listener) {
---
>     public void setOnRefreshListener(@Nullable SwipeRefreshLayout.OnRefreshListener listener) {
346,347c318
<      * Notify the widget that refresh state has changed. Do not call this when
<      * refresh is triggered by a swipe gesture.
---
>      * Notify the widget that refresh state has changed. Do not call this when refresh is triggered by a swipe gesture.
369c340
<     private void startScaleUpAnimation(AnimationListener listener) {
---
>     private void startScaleUpAnimation(Animation.AnimationListener listener) {
371c342,346
<         mProgress.setAlpha(MAX_ALPHA);
---
>         if (android.os.Build.VERSION.SDK_INT >= 11) {
>             // Pre API 11, alpha is used in place of scale up to show the progress circle appearing.
>             // Don't adjust the alpha during appearance otherwise.
>             mProgress.setAlpha(MAX_ALPHA);
>         }
433,434c408
<                 mProgress.setAlpha(
<                         (int) (startingAlpha + ((endingAlpha - startingAlpha) * interpolatedTime)));
---
>                 mProgress.setAlpha((int) (startingAlpha + ((endingAlpha - startingAlpha) * interpolatedTime)));
446a421,422
>      *
>      * @param colorRes colorRes
465c441
<      * @param color
---
>      * @param color color
472a449,450
>      *
>      * @param colors colors
481,482c459
<      * The first color will also be the color of the bar that grows in response
<      * to a user swipe gesture.
---
>      * The first color will also be the color of the bar that grows in response to a user swipe gesture.
484c461
<      * @param colorResIds
---
>      * @param colorResIds colorResIds
496,498c473
<      * Set the colors used in the progress animation. The first
<      * color will also be the color of the bar that grows in response to a user
<      * swipe gesture.
---
>      * Set the colors used in the progress animation. The first color will also be the color of the bar that grows in response to a user swipe gesture.
500c475
<      * @param colors
---
>      * @param colors colors
508,509c483
<      * @return Whether the SwipeRefreshWidget is actively showing refresh
<      *         progress.
---
>      * @return Whether the SwipeRefreshWidget is actively showing refresh progress.
532c506
<      * @param distance
---
>      * @param distance distance
559,560c533
<         mCircleView.layout((width / 2 - circleWidth / 2), mCurrentTargetOffsetTop,
<                 (width / 2 + circleWidth / 2), mCurrentTargetOffsetTop + circleHeight);
---
>         mCircleView.layout((width / 2 - circleWidth / 2), mCurrentTargetOffsetTop, (width / 2 + circleWidth / 2), mCurrentTargetOffsetTop + circleHeight);
564,565c537
<     public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
<         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
---
>     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
568a541
> 
572,577c545,598
<         mTarget.measure(MeasureSpec.makeMeasureSpec(
<                 getMeasuredWidth() - getPaddingLeft() - getPaddingRight(),
<                 MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(
<                 getMeasuredHeight() - getPaddingTop() - getPaddingBottom(), MeasureSpec.EXACTLY));
<         mCircleView.measure(MeasureSpec.makeMeasureSpec(mCircleDiameter, MeasureSpec.EXACTLY),
<                 MeasureSpec.makeMeasureSpec(mCircleDiameter, MeasureSpec.EXACTLY));
---
> 
>         int childCount = getChildCount();
>         final boolean measureMatchParentChildren = MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.EXACTLY || MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY;
>         mMatchParentChildren.clear();
> 
>         int maxHeight = 0;
>         int maxWidth = 0;
>         int childState = 0;
> 
>         for (int i = 0; i < childCount; i++) {
>             final View child = getChildAt(i);
>             if (mMeasureAllChildren || child.getVisibility() != GONE) {
>                 measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
>                 final ViewGroup.LayoutParams layoutParams = child.getLayoutParams();
>                 maxWidth = Math.max(maxWidth, child.getMeasuredWidth());
>                 maxHeight = Math.max(maxHeight, child.getMeasuredHeight());
>                 childState = combineMeasuredStates(childState, child.getMeasuredState());
>                 if (measureMatchParentChildren) {
>                     if (layoutParams.width == FrameLayout.LayoutParams.MATCH_PARENT || layoutParams.height == FrameLayout.LayoutParams.MATCH_PARENT) {
>                         mMatchParentChildren.add(child);
>                     }
>                 }
>             }
>         }
> 
>         maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
>         maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
>         setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState), resolveSizeAndState(maxHeight, heightMeasureSpec, childState << MEASURED_HEIGHT_STATE_SHIFT));
> 
>         childCount = mMatchParentChildren.size();
>         if (childCount > 1) {
>             for (int i = 0; i < childCount; i++) {
>                 final View child = mMatchParentChildren.get(i);
>                 final LayoutParams layoutParams = child.getLayoutParams();
> 
>                 final int childWidthMeasureSpec;
>                 if (layoutParams.width == ViewGroup.LayoutParams.MATCH_PARENT) {
>                     childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(Math.max(0, getMeasuredWidth()), MeasureSpec.EXACTLY);
>                 } else {
>                     childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec, 0, layoutParams.width);
>                 }
> 
>                 final int childHeightMeasureSpec;
>                 if (layoutParams.height == ViewGroup.LayoutParams.MATCH_PARENT) {
>                     childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(Math.max(0, getMeasuredHeight()), MeasureSpec.EXACTLY);
>                 } else {
>                     childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec, 0, layoutParams.height);
>                 }
> 
>                 child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
>             }
>         }
> 
>         mCircleView.measure(MeasureSpec.makeMeasureSpec(mCircleDiameter, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(mCircleDiameter, MeasureSpec.EXACTLY));
579c600
<         // Get the index of the circleview.
---
> 
587a609,616
>     @Override
>     protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed) {
>         final LayoutParams layoutParams = child.getLayoutParams();
>         final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec, widthUsed, layoutParams.width);
>         final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec, heightUsed, layoutParams.height);
>         child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
>     }
> 
589,590c618
<      * Get the diameter of the progress circle that is displayed as part of the
<      * swipe to refresh layout.
---
>      * Get the diameter of the progress circle that is displayed as part of the swipe to refresh layout.
599,600c627
<      * @return Whether it is possible for the child view of this layout to
<      *         scroll up. Override this if the child view is a custom view.
---
>      * @return Whether it is possible for the child view of this layout to scroll up. Override this if the child view is a custom view.
613,614c640,641
<      * Set a callback to override {@link SwipeRefreshLayout#canChildScrollUp()} method. Non-null
<      * callback will return the value provided by the callback and ignore all internal logic.
---
>      * Set a callback to override {@link SwipeRefreshLayout#canChildScrollUp()} method.
>      * Non-null callback will return the value provided by the callback and ignore all internal logic.
617c644
<     public void setOnChildScrollUpCallback(@Nullable OnChildScrollUpCallback callback) {
---
>     public void setOnChildScrollUpCallback(@Nullable WrapContentableSwipeRefreshLayout.OnChildScrollUpCallback callback) {
632,633c659
<         if (!isEnabled() || mReturningToStart || canChildScrollUp()
<                 || mRefreshing || mNestedScrollInProgress) {
---
>         if (!isEnabled() || mReturningToStart || canChildScrollUp() || mRefreshing || mNestedScrollInProgress) {
681,683c707
<         // if this is a List < L or another view that doesn't support nested
<         // scrolling, ignore this request so that the vertical scroll event
<         // isn't stolen
---
>         // if this is a List < L or another view that doesn't support nested scrolling, ignore this request so that the vertical scroll event isn't stolen
696,697c720
<         return isEnabled() && !mReturningToStart && !mRefreshing
<                 && (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;
---
>         return isEnabled() && !mReturningToStart && !mRefreshing && (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;
712,713c735
<         // If we are in the middle of consuming, a scroll, then we want to move the spinner back up
<         // before allowing the list to scroll
---
>         // If we are in the middle of consuming, a scroll, then we want to move the spinner back up before allowing the list to scroll
725,728c747,748
<         // If a client layout is using a custom start position for the circle
<         // view, they mean to hide it again before scrolling the child view
<         // If we get back to mTotalUnconsumed == 0 and there is more to go, hide
<         // the circle so it isn't exposed if its blocking content is moved
---
>         // If a client layout is using a custom start position for the circle view, they mean to hide it again before scrolling the child view
>         // If we get back to mTotalUnconsumed == 0 and there is more to go, hide the circle so it isn't exposed if its blocking content is moved
762,763c782
<     public void onNestedScroll(final View target, final int dxConsumed, final int dyConsumed,
<             final int dxUnconsumed, final int dyUnconsumed) {
---
>     public void onNestedScroll(final View target, final int dxConsumed, final int dyConsumed, final int dxUnconsumed, final int dyUnconsumed) {
765,766c784
<         dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed,
<                 mParentOffsetInWindow);
---
>         dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, mParentOffsetInWindow);
808,811c826,827
<     public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed,
<             int dyUnconsumed, int[] offsetInWindow) {
<         return mNestedScrollingChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed,
<                 dxUnconsumed, dyUnconsumed, offsetInWindow);
---
>     public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) {
>         return mNestedScrollingChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow);
816,817c832
<         return mNestedScrollingChildHelper.dispatchNestedPreScroll(
<                 dx, dy, consumed, offsetInWindow);
---
>         return mNestedScrollingChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
821,822c836
<     public boolean onNestedPreFling(View target, float velocityX,
<             float velocityY) {
---
>     public boolean onNestedPreFling(View target, float velocityX, float velocityY) {
828c842
<             boolean consumed) {
---
>                                  boolean consumed) {
853,861c867,869
<         float slingshotDist = mCustomSlingshotDistance > 0
<                 ? mCustomSlingshotDistance
<                 : (mUsingCustomStart
<                         ? mSpinnerOffsetEnd - mOriginalOffsetTop
<                         : mSpinnerOffsetEnd);
<         float tensionSlingshotPercent = Math.max(0, Math.min(extraOS, slingshotDist * 2)
<                 / slingshotDist);
<         float tensionPercent = (float) ((tensionSlingshotPercent / 4) - Math.pow(
<                 (tensionSlingshotPercent / 4), 2)) * 2f;
---
>         float slingshotDist = mUsingCustomStart ? mSpinnerOffsetEnd - mOriginalOffsetTop : mSpinnerOffsetEnd;
>         float tensionSlingshotPercent = Math.max(0, Math.min(extraOS, slingshotDist * 2) / slingshotDist);
>         float tensionPercent = (float) ((tensionSlingshotPercent / 4) - Math.pow((tensionSlingshotPercent / 4), 2)) * 2f;
878,879c886
<             if (mProgress.getAlpha() > STARTING_PROGRESS_ALPHA
<                     && !isAnimationRunning(mAlphaStartAnimation)) {
---
>             if (mProgress.getAlpha() > STARTING_PROGRESS_ALPHA && !isAnimationRunning(mAlphaStartAnimation)) {
908d914
< 
1019c1025
<     private void animateOffsetToCorrectPosition(int from, AnimationListener listener) {
---
>     private void animateOffsetToCorrectPosition(int from, Animation.AnimationListener listener) {
1031c1037
<     private void animateOffsetToStartPosition(int from, AnimationListener listener) {
---
>     private void animateOffsetToStartPosition(int from, Animation.AnimationListener listener) {
1074,1075c1080
<         public void applyTransformation(float interpolatedTime, Transformation t) {
<             moveToStart(interpolatedTime);
---
>         public void applyTransformation(float interpolatedTime, Transformation t) {moveToStart(interpolatedTime);
1079,1080c1084
<     private void startScaleDownReturnToStartAnimation(int from,
<             Animation.AnimationListener listener) {
---
>     private void startScaleDownReturnToStartAnimation(int from, Animation.AnimationListener listener) {
1117,1118c1121
<      * Classes that wish to be notified when the swipe gesture correctly
<      * triggers a refresh should implement this interface.
---
>      * Classes that wish to be notified when the swipe gesture correctly triggers a refresh should implement this interface.
1128,1129c1131
<      * Classes that wish to override {@link SwipeRefreshLayout#canChildScrollUp()} method
<      * behavior should implement this interface.
---
>      * Classes that wish to override {@link SwipeRefreshLayout#canChildScrollUp()} method behavior should implement this interface.
1133,1134c1135
<          * Callback that will be called when {@link SwipeRefreshLayout#canChildScrollUp()} method
<          * is called to allow the implementer to override its behavior.
---
>          * Callback that will be called when {@link SwipeRefreshLayout#canChildScrollUp()} method is called to allow the implementer to override its behavior.
1141c1142
<         boolean canChildScrollUp(@NonNull SwipeRefreshLayout parent, @Nullable View child);
---
>         boolean canChildScrollUp(@NonNull WrapContentableSwipeRefreshLayout parent, @Nullable View child);

I still don’t have any idea what the authour changed in order to make the layout behave like any other. Maybe some of you know what attributes are responsible for that.


I used the androidx SwipeRefreshLayout version 1.1.0


activity_xml.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:clipToPadding="false"
    tools:context=".MainActivity">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:elevation="2dp"
        android:gravity="center"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:title="@string/app_name"
        app:titleTextAppearance="@style/Theme.CovidHub.Toolbar" />

    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:id="@+id/swipeToRefresh"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintTop_toBottomOf="@id/toolbar"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:background="@drawable/card_background"
        android:elevation="5dp">

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

            <TextView
                android:id="@+id/location"
                android:layout_gravity="center_horizontal"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginVertical="30dp"
                android:textSize="40sp"
                tools:text="County" />

            <TextView
                android:id="@+id/showData"
                android:layout_gravity="center_horizontal"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:textFontWeight="900"
                android:textSize="76sp"
                tools:text="150,0" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_gravity="center_horizontal"
                android:layout_height="wrap_content"
                android:text="@string/str_cases_100K_per7"
                android:textSize="34sp"
                tools:text="@string/str_cases_100K_per7" />

        </LinearLayout>

    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

The LinearLayout should wrap around the TextViews and leave enough space below it for another layout, but strangly it completly fills the parent view

Source: Android Questions

LEAVE A COMMENT