recyclerview is not fit for all screen sizes
Asked Answered
T

2

1

I am using recylerview and gridlayout manager with cardviews for each row, my row view(childview) is not responsive at all.

I want to show 15 cardviews in such a way that in portrait mode all my 15 childview should be visible and my recyclerview should not be scrollable whereas in landscape mode it should act vise versa( should be scrollable)

I have tried many soultions suggested on SO but nothing seems to be working.

current behaviour on different screen sizes are as follows

enter image description here

In the above attached screen shot ,the 3rd column, 4th and 5th row are not visible

enter image description here

In the above given screen my ui fits perfectly in portrait mode but in landscape i can't see all the cardviews.

enter image description here

in the screenshot attached above ,5th row is not visible and in the landscape mode there are some responsivness errors. cardview.xml

<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:cardview="http://schemas.android.com/apk/res-auto"
    android:layout_width="127dp"
    android:layout_height="118dp"
    android:layout_margin="5dp"
    cardview:cardCornerRadius="4dp">

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

            <ImageView
                android:id="@+id/mReminder_Image_Id"
                android:layout_width="match_parent"
                android:layout_height="90dp"
                android:scaleType="fitXY"
                android:background="#ffffff"/>
            <TextView
                android:id="@+id/mReminder_Text_Id"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"
                android:textColor="#2d2d2d"
                android:textSize="13sp"
                android:text="Reminder texts"/>
        </LinearLayout>
</android.support.v7.widget.CardView>

fragment_reminders.xml

<LinearLayout 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:orientation="vertical"
    tools:context=".Fragments.Reminders">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@color/colorPrimary"
        app:layout_scrollFlags="scroll|enterAlways"
        app:popupTheme="@style/AppTheme.PopupOverlay">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Reminders"
            android:textSize="20dp"
            android:textStyle="bold"
            android:textColor="@color/tab_background"
            android:layout_gravity="center" />
    </android.support.v7.widget.Toolbar>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/mRecyclerView_id"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </android.support.v7.widget.RecyclerView>

</LinearLayout>

Can anyone guide me to solve this . Thanks .

Tetrapody answered 27/4, 2018 at 16:7 Comment(5)
@Kling Klang do you have any idea in this issueTetrapody
there is a way bit you might not like it,you should create different layouts for different screen sizes or use Coordinator layout,also use wrap content rather then set specific valuesKaryolymph
We can design apps for supporting multiple screen sizes ,Then Why should I have multiple designs for different screens.Tetrapody
if you can design supporting multiple screen sizes it should workKaryolymph
In short, you need to design different layouts for different screen sizes. There is good documentation on the topic at the [Android Developer Website][1] The reason why you see this behavior, however, is because you specifically define the size of the ImageView in XML as 90dp with a TextView at 13sp so no matter the orientation your view size for each card will be about 103dp. [1]: developer.android.com/training/multiscreen/screensizesAnnihilation
F
0

you can use this:

recyclerView.setLayoutManager(new RecyclerView.GridLayoutManager(this, span_count)

You could have a res/values/ints.xml file with <integer> elements, giving the integer a name (name attribute) and value (text of the <integer> node). You could also have res/values-w600dp/ints.xml or res/values-land or other variations of the resource, where you provide different values to use for different screen sizes. Then, at runtime, call getResources().getInteger() to retrieve the correct value of the resource to use for the current device, and use that in your GridLayoutManager constructor. Now, you are in control over how many columns there are, by controlling how many spans are supplied to the constructor.

https://developer.android.com/training/multiscreen/screensizes

Another approach, suggested by Chiu-Ki Chan, is to create a subclass of RecyclerView, on which you provide a custom attribute for a desired approximate column width. Then, in your subclass’ onMeasure() method, you can calculate the number of spans to use to give you the desired column width.

https://developer.android.com/reference/android/support/v7/widget/GridLayoutManager.html#GridLayoutManager(android.content.Context,%20int)

https://developer.android.com/reference/android/support/v7/widget/RecyclerView#setlayoutmanager

Fasano answered 27/4, 2018 at 16:55 Comment(3)
already I have it recyclerView.setLayoutManager(new GridLayoutManager(getActivity(),3));Tetrapody
@Tetrapody you can use resource <integer> tag and differentiate between landscape and portrait or screen sizesFasano
I am not aware of that please explain something about that or give me any referenceTetrapody
O
0

create a class as follows:

    import android.graphics.Rect;
    import android.support.v7.widget.GridLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.view.View;

    public class EqualSpacingItemDecoration extends RecyclerView.ItemDecoration {
      private final int spacing;
      private int displayMode;

      public static final int HORIZONTAL = 0;
      public static final int VERTICAL = 1;
      public static final int GRID = 2;

      public EqualSpacingItemDecoration(int spacing) {
        this(spacing, -1);
      }

      public EqualSpacingItemDecoration(int spacing, int displayMode) {
        this.spacing = spacing;
        this.displayMode = displayMode;
      }

      @Override
      public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        int position = parent.getChildViewHolder(view).getAdapterPosition();
        int itemCount = state.getItemCount();
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        setSpacingForDirection(outRect, layoutManager, position, itemCount);
      }

      private void setSpacingForDirection(Rect outRect,
                                          RecyclerView.LayoutManager layoutManager,
                                          int position,
                                          int itemCount) {

        // Resolve display mode automatically
        if (displayMode == -1) {
          displayMode = resolveDisplayMode(layoutManager);
        }

        switch (displayMode) {
          case HORIZONTAL:
            outRect.left = spacing;
            outRect.right = position == itemCount - 1 ? spacing : 0;
            outRect.top = spacing;
            outRect.bottom = spacing;
            break;
          case VERTICAL:
            outRect.left = spacing;
            outRect.right = spacing;
            outRect.top = spacing;
            outRect.bottom = position == itemCount - 1 ? spacing : 0;
            break;
          case GRID:
            if (layoutManager instanceof GridLayoutManager) {
              GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
              int cols = gridLayoutManager.getSpanCount();
              int rows = itemCount / cols;

              outRect.left = spacing;
              outRect.right = position % cols == cols - 1 ? spacing : 0;
              outRect.top = spacing;
              outRect.bottom = position / cols == rows - 1 ? spacing : 0;
            }
            break;
        }
      }

      private int resolveDisplayMode(RecyclerView.LayoutManager layoutManager) {
        if (layoutManager instanceof GridLayoutManager) return GRID;
        if (layoutManager.canScrollHorizontally()) return HORIZONTAL;
        return VERTICAL;
      }
    }

and for using it with your recycler view:

1)for grid view:

recyclerView.addItemDecoration(new EqualSpacingItemDecoration(<sizeofpixels>, EqualSpacingItemDecoration.GRID));

2)for vertical view:

recyclerView.addItemDecoration(new EqualSpacingItemDecoration(<sizeofpixels>, EqualSpacingItemDecoration.VERTICAL));

3)for horizontal view: recyclerView.addItemDecoration(new EqualSpacingItemDecoration(<sizeofpixels>, EqualSpacingItemDecoration.HORIZONTAL));

hope this helps you.

Outbound answered 28/4, 2018 at 7:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.