【问题标题】:Android percent screen width in RecyclerView itemRecyclerView项目中的Android百分比屏幕宽度
【发布时间】:2018-07-06 00:12:15
【问题描述】:

如何让 RecyclerView 的项目高度为屏幕高度的 30%?

我不能简单地使用 ConstraintLayout 或 PercentFrameLayout/PercentRelativeLayout,因为这些位置子布局相对于父布局,其大小可能与屏幕不匹配。

最好用纯 XML 执行此操作(不必使用任何 Runnables 来动态获取屏幕高度)。

编辑

澄清一下,由于很多解决方案都建议限制 RecyclerView 的高度,这不是本意。 RecyclerView 仍应填充屏幕。这就是我所说的,使用屏幕宽度(而不是高度):

这个想法是将卡片的宽度设为屏幕宽度的 33%,同时保持 RecyclerView 的宽度在水平滚动经过屏幕时保持不变。

【问题讨论】:

  • 如果这个解释不清楚,请告诉我:我知道你可以根据封闭的 PercentLayout 或 ConstraintLayout 的大小设置百分比。但是,由于我正在处理 RecyclerView 中的项目,所以封闭布局都不是。
  • 这个问题和这个有什么关系?

标签: android android-recyclerview android-constraintlayout


【解决方案1】:

您可以覆盖RecyclerView 使用的LayoutManager 方法之一以强制指定大小:

recyclerView.setLayoutManager(new LinearLayoutManager(this){
    @Override
    public boolean checkLayoutParams(RecyclerView.LayoutParams lp) {
        // force height of viewHolder here, this will override layout_height from xml
        lp.height = getHeight() / 3;
        return true;
    }
});

这是假设您的 RecyclerView 适合屏幕。

如果您想要更复杂的解决方案(自定义布局管理器,可直接从 XML 中控制每个项目和百分比膨胀),请参阅 this answer

【讨论】:

  • 严重低估的答案
  • 我爱你。也不是一般的“好答案”。真爱。我给你送花
  • 漂亮的解决方案!
  • 这很优雅。我更喜欢这个而不是选定的答案。
  • 这个解决方案比在recyclerview中传递上下文来用widnowManager计算宽度或高度要好。
【解决方案2】:

据我所知,在 XML 中没有办法做到这一点。但是,您可以通过在适配器的 onCreateViewHolder() 方法中返回 ViewHolder 之前设置您的 ViewHolderitemViewLayoutParams 在 Java 中执行此操作(没有任何 Runnables 等):

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

    ViewGroup.LayoutParams layoutParams = itemView.getLayoutParams();
    layoutParams.height = (int) (parent.getHeight() * 0.3);
    itemView.setLayoutParams(layoutParams);

    return new MyViewHolder(itemView);
}

【讨论】:

  • 如何将其应用于我的宽度?我想在屏幕上显示 80% 的卡片,并在它旁边显示下一张卡片内容。有没有办法通过 recycler view 来做到这一点,作为轮播?
  • 你认为parent.getHeight()parent.getWidth()可以返回0,尤其是如果你把RecyclerView放在ConstraintLayout里面:<androidx.recyclerview.widget.RecyclerView android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"/>
  • 声明layout_width="0dp",然后设置约束来定义宽度,将导致getWidth() 为实数值,而不是0。
  • @BenP。自己试试吧,它当然是一个真正的值,但不会很快,当onCreateViewHolder被调用时它会是0,但是稍后它会是一个真正的值
  • 这不是一个有效的答案。这不适用于水平滚动行为。它减小了视图宽度
【解决方案3】:

您可以使用显示指标

在构造函数中定义显示指标,或使用任何其他静态方法初始化。

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

现在你可以在onCreateViewHolder()

中使用它了
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);

//setting the height programmatically
itemView.getLayoutParams().height = metrics.heightPixels/3;
itemView.requestLayout();

或者您可以在布局的父布局上使用 onBindViewHolder()

【讨论】:

    【解决方案4】:

    您不能仅通过 XML 设置项目的百分比高度。原因是 将在运行时膨胀的项目,它不是像这样的活动 布局。您在 XML 中编写的内容。

    所以现在我告诉你两种实现百分比/重量的方法

    第一种首选方式是在 onCreateViewHolder() 方法中覆盖 Adapter 中的高度

    private int height = 0; // declared height globally in Adapter class to reuse it.
    
    @Override
    public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
        if (height == 0)
            height = (int) (parent.getMeasuredHeight() * .3);
        itemView.setMinimumHeight(height);
        return new ItemViewHolder(itemView);
    }
    

    第二次破解是使用SDP 库。

    sdp 中使用 XML 中的项目高度,例如 _160sdp。它不会给你 30% 的准确结果。但它可以根据屏幕进行调整。

    【讨论】:

    • 不,这是在数千个 UI 进程中添加的一个小逻辑。
    • 如果您仍然提到我们多次获得measuredHeight,那么您可以将第一个保存在全局变量中。然后重复使用它。
    • 如果您不检查 null 并重用它,您建议的编辑不会产生影响。我会编辑它。
    • @salman 已经改进,还有另一个针对 parent.getContext() 的修复。
    【解决方案5】:

    我通过在我的自定义 RecyclerView 项目布局中执行以下操作来实现这一点:

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val newMeasuredWidth =
            (MeasureSpec.getSize(widthMeasureSpec) * WIDTH_ADJUSTMENT_RATIO).toInt()
        super.onMeasure(
            MeasureSpec.makeMeasureSpec(newMeasuredWidth, MeasureSpec.EXACTLY),
            heightMeasureSpec
        )
    }
    

    【讨论】:

      【解决方案6】:
          DisplayMetrics displayMetrics = new DisplayMetrics();
          ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
          int devicewidth = (int) (displayMetrics.widthPixels * 0.8);
          view.getLayoutParams().width = devicewidth;
          return new YourAdapter.ViewHolder(view);
      

      【讨论】:

        【解决方案7】:

        试试这个方法。就一次

        inner class MyFeatureProductViewHolder(val v: View) : RecyclerView.ViewHolder(v) {
            val tvName = v.findViewById<TextView>(R.id.tvName)
            val tvPrice = v.findViewById<TextView>(R.id.tvPrice)
            val tvItemUploadTime = v.findViewById<TextView>(R.id.tvItemUploadTime)
            val ivItem = v.findViewById<ImageView>(R.id.ivItem)
        
            init {
                v.layoutParams.width =  itemView.measuredWidth - 20
                v.requestLayout()
            }
        }
        

        【讨论】:

          【解决方案8】:

          如果您不介意确切的百分比,您可以通过设置android:paddingLeftandroid:paddingRight 以及将android:clipToPadding 设置为false 来获得所需的视图。 这也使第一个和最后一个项目居中对齐。

          【讨论】:

            【解决方案9】:

            好吧,我只是尝试解决您遇到的问题。我玩的东西很少。步骤如下:

            1. MainActivity 视图 RecyclerView 的高度正好是屏幕的 30%。
            2. Recycler View 项目的高度和宽度必须为 match_parent。

            那里发生了什么?

            1. recyclerHolder 的高度是屏幕高度的 30% 毫无疑问。

            2. recyclerHolder 内部,我们有 RecyclerView,它占据了父级的所有 30% 高度并占据了全宽。

            3. ListItem Layout 采用父级的全高和全宽,其中父级是 RecyclerView,它正好是屏幕高度的 30%。

            我试过了,效果很好。在那里你可以找到 2 个空视图来测试它们是否完全适合顶部和底部,结果是的。将任何内容放在列表项中,它将占用屏幕高度的 30%。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-05-31
              • 1970-01-01
              • 2017-08-24
              • 1970-01-01
              • 2012-08-31
              • 1970-01-01
              相关资源
              最近更新 更多