繁体   English   中英

使水平回收器视图项目的宽度为屏幕宽度的 70%

[英]Make width of horizontal recycler view items 70% of screen width

我正在尝试创造这种效果

设计形象

我正在使用回收站视图,但我的问题是每张卡片都是屏幕宽度的 100% 而不是 70%。

这是每个项目的 xml 代码

<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" />

如果您希望第一个项目左对齐(即重现屏幕截图中的内容),请LinearLayoutManager并覆盖三个generate*LayoutParams方法。 这是我的做法: 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%
}

该解决方案基于/启发于跨越(即,将所有项目适合屏幕)线性布局管理器https://gist.github.com/heinrichreimer/39f9d2f9023a184d96f8

顺便说一句,如果您只想向左和向右显示项目,而当前项目居中,您可以向回收器视图添加填充并将clipToPadding设置为false 在这种情况下,您甚至不需要自定义布局管理器。

<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">

我需要将水平 RecyclerView 中的项目设为 recyclerview 宽度的 70%。 它可以在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);
    }

结果

有两种方法可以做到这一点。

1)为您的回收视图使用自定义视图。 覆盖 onMeasure 以将其宽度返回为屏幕的 70%。

2) 在您的 Recycler View 适配器中,当您创建视图时,将其宽度设置为屏幕宽度的 70%。

无论哪种情况,您都可以从 Display 获得屏幕尺寸,然后将宽度乘以 0.7。 在第一种情况下,您将其设置为精确测量宽度,在第二种情况下,您将其设置在布局参数中。 第二个可能更容易一些。

我有一个类似的问题,我有一个带有水平 RecyclerView 的片段,并希望每个视图项的宽度是用户屏幕的三分之一。 通过在我们的 ViewHolder 类的构造函数中添加以下内容来解决它:

    private class OurViewHolder extends RecyclerView.ViewHolder {
        ...

        public OurViewHolder (LayoutInflater inflater, ViewGroup parent) {
            super (inflater.inflate (R.layout.list_item_layout, parent, false));

            // This code is used to get the screen dimensions of the user's device
            DisplayMetrics displayMetrics = new DisplayMetrics();
            getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
            int width = displayMetrics.widthPixels;
            int height = displayMetrics.heightPixels;

            // Set the ViewHolder width to be a third of the screen size, and height to wrap content
            itemView.setLayoutParams(new RecyclerView.LayoutParams(width/3, RecyclerView.LayoutParams.WRAP_CONTENT));

            ...
        }

        ...

对于 row.xml 父级,您必须使用wrap_content作为其宽度,然后添加此属性。

android:paddingLeft="25dp"

你会得到同样的结果

刚刚通过添加边距并从资源中获取 displayMetrics 来更新答案以使其干净:

inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        fun bind(product: StyleMaster) = with(itemView) {
            val width = context.resources.displayMetrics?.widthPixels
            if (width != null) {
                val params = RecyclerView.LayoutParams(width / 2, RecyclerView.LayoutParams.WRAP_CONTENT)
                params.setMargins(2, 2, 2, 2)
                itemView.layoutParams = params
            }
// Rest of the code goes here...

尝试使用PercentRelativeLayout更改LinearLayout以“包装” RecyclerView ,然后将其宽度设置为 70%。

改变这个:

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

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

</LinearLayout>

有了这个:

<android.support.percent.PercentRelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

        <android.support.v7.widget.RecyclerView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            app:layout_widthPercent="70%"
            android:id="@+id/rv"
            />

编辑

由于百分比支持库随 Android 支持库 23 一起提供,因此请确保您已将 SDK 管理器中的 Android 支持库更新到最新版本(实际上是 24)。 然后在build.gradle文件中添加如下依赖build.gradle

compile 'com.android.support:percent:24.0.0'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM