Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make width of horizontal recycler view items 70% of screen width

I am trying to create this effect

Design image

I am using a recycler view but my issue, is that each card is 100% of the width of the screen as apposed to 70%.

Here is the xml code for each item

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rowLayout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="@dimen/scale_20dp">

    <LinearLayout
        android:id="@+id/button_parent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <android.support.v7.widget.CardView
            android:id="@+id/card_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <LinearLayout
                android:id="@+id/currentYear"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:background="@drawable/paymentscreengrey"
                android:gravity="center"
                android:orientation="vertical"
                android:paddingLeft="35dp"
                android:paddingTop="@dimen/scale_50dp">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/scale_20dp"
                    android:text="****   ****   ****   5432"
                    android:textColor="@color/white"
                    android:textSize="@dimen/scale_20dp" />

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="2345"
                    android:textColor="@color/white"
                    android:textSize="@dimen/scale_16dp" />
like image 752
Adam Katz Avatar asked Jul 29 '16 07:07

Adam Katz


3 Answers

If you want the first item to be left-aligned (i.e., reproduce what's in the screenshot), subclass LinearLayoutManager and override the three generate*LayoutParams methods. Here's how I did it: https://gist.github.com/bolot/6f1838d29d5b8a87b5fcadbeb53fb6f0.

class PeekingLinearLayoutManager : LinearLayoutManager {
    @JvmOverloads
    constructor(context: Context?, @RecyclerView.Orientation orientation: Int = RecyclerView.VERTICAL, reverseLayout: Boolean = false) : super(context, orientation, reverseLayout)

    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)

    override fun generateDefaultLayoutParams() =
        scaledLayoutParams(super.generateDefaultLayoutParams())

    override fun generateLayoutParams(lp: ViewGroup.LayoutParams?) =
        scaledLayoutParams(super.generateLayoutParams(lp))

    override fun generateLayoutParams(c: Context?, attrs: AttributeSet?) =
        scaledLayoutParams(super.generateLayoutParams(c, attrs))

    private fun scaledLayoutParams(layoutParams: RecyclerView.LayoutParams) =
        layoutParams.apply {
            when(orientation) {
                HORIZONTAL -> width = (horizontalSpace * ratio).toInt()
                VERTICAL -> height = (verticalSpace * ratio).toInt()
            }
        }

    private val horizontalSpace get() = width - paddingStart - paddingEnd

    private val verticalSpace get() = height - paddingTop - paddingBottom

    private val ratio = 0.9f // change to 0.7f for 70%
}

This solution is based on/inspired by the spanning (i.e., fit all items to screen) linear layout manager https://gist.github.com/heinrichreimer/39f9d2f9023a184d96f8.

Btw, if you just want to show the items to the left and to the right, while the current item is centered, you can add padding to the recycler view and set clipToPadding to false. In this case you don't even need a custom layout manager.

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recycler_view"
    android:paddingStart="16dp"
    android:paddingEnd="16dp"
    android:clipToPadding="false"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager">
like image 135
bolot Avatar answered Nov 11 '22 23:11

bolot


I needed to have the items in my horizontal RecyclerView to be 70% of the width of the recyclerview. It can be easily done in onCreateViewHolder():

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(context).inflate(R.layout.row, parent, false);
        view.layoutParams = ViewGroup.LayoutParams((parent.width * 0.7).toInt(),ViewGroup.LayoutParams.MATCH_PARENT)
        return ViewHolder(view);
    }

Result

like image 24
Peterdk Avatar answered Nov 11 '22 22:11

Peterdk


Two ways of doing this really.

1)Use a custom view for your the recycled view. Override onMeasure to return its width as 70 percent of the screen.

2)In your Recycler View adapter, when you create the view set its width to be 70 percent of the screen's width.

In either case you get the screen size from the Display and just multiply the width by .7. In the first case you set that as the EXACT measured width, in the second you set it in the layout param. The second is probably a bit easier.

like image 11
Gabe Sechan Avatar answered Nov 11 '22 23:11

Gabe Sechan