RecyclerView项目layout_weight,尺寸未更新 [英] RecyclerView item layout_weight, sizes not updating

查看:79
本文介绍了RecyclerView项目layout_weight,尺寸未更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的RecyclerView项目中并排有两个文本视图.其中一个视图具有layout_weight ="1",以便在宽视图时使另一个视图可见.

I have two text views side by side in my RecyclerView item. One of the views has layout_weight="1" to keep another view visible if the view is wide.

问题是视图回收时视图大小没有更新,所以当我滚动列表时,textView id:name宽度不正确.

The problem is that the the view sizes are not updating when the views got recycled, so to textView id:name width is not correct when i scroll the list.

我应该以某种方式强制视图更新布局吗?

Should I somehow force the view to update the layout?

我的RecyclerView项目:

My RecyclerView item:

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginLeft="16dp"
    android:gravity="center_vertical"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/name"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginRight="8dp"
        android:layout_weight="1"
        android:ellipsize="end"
        android:maxLines="1" />

    <LinearLayout
        android:id="@+id/code_container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:background="@drawable/background_code"
        android:orientation="vertical">

        <TextView
            android:id="@+id/code"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:paddingBottom="1dp"
            android:paddingLeft="7dp"
            android:paddingRight="7dp"
            android:paddingTop="1dp"
            android:singleLine="true"/>

    </LinearLayout>

</LinearLayout>

我正在使用RecyclerView v.23.4.0.

Im using RecyclerView v. 23.4.0.

更新

1..我试图在适配器onBindViewHolder()的末尾调用我的RecyclerView项目布局根requestLayout.

1. I have tried to call my RecyclerView item layout root requestLayout at the end of the adapter onBindViewHolder().

这没有任何影响,我的视图未更新.

This does not any have affect, my views are not updated.

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    ...
    viewHolder.mLayoutRoot.requestLayout();
}

2..也许是我调用requestLayout时视图还没有完全绘制出来?所以我试图设置GlobalLayoutListener并在那里调用requestLayout.我认为这无济于事,但即使我有足够的物品,列表中也不是所有视图都会更新. Owerall在我的清单中,我最多可容纳10件物品.

2. Maybe the problem is that the view is not yet completely drawn when I call requestLayout? So I tried to set GlobalLayoutListener and call requestLayout there. I think this helps little, but still if I have enough items, in my list not all views are updated. Owerall in my list I have around max 10 items.

ViewTreeObserver vto = viewHolder.mLayoutRoot.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        viewHolder.mLayoutRoot.requestLayout();
    }
});

3..我尝试将TableLayout与rinkeColumns属性一起使用,以实现相似的布局,但是结果是相同的.并非总是正确设置名称文本视图宽度.而且,requestLayout看起来根本没有任何影响(或者我在错误的地方叫它吗?)

3. I tried to use TableLayout with shrinkColumns property to approach similar layout, but the result is same. Name text view widht is not always correctly set. Also, it looks like requestLayout has no affect at all (or am I calling it in wrong place?)

4. (28/8/2016)

我将代码精简到最低限度,以重现此问题.

I stripped down my code to bare minimum to reproduce this.

我设法使用setIsRecyclable(false)来解决此问题,就像dosssik所建议的那样,但是我认为从性能角度来看这不是一个很好的解决方案?

I managed to fix this using setIsRecyclable(false), like dosssik suggests, but I think it is not very good solution in terms of performance?

这是我的完整清单项目:

Here is my full list item:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="150dp"
    android:layout_marginLeft="16dp"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/name"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginRight="8dp"
        android:layout_weight="1"
        android:ellipsize="end"
        android:maxLines="1" />

    <TextView
        android:id="@+id/code"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/background_stop_code_small"
        android:ellipsize="end"
        android:paddingBottom="1dp"
        android:paddingLeft="7dp"
        android:paddingRight="7dp"
        android:paddingTop="1dp"
        android:singleLine="true"
        android:textSize="11sp"/>

</LinearLayout>

我的适配器代码:

我也尝试调用invalidate(),但看不到任何影响.

I also tried to call invalidate(), but can not see any affect.

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    Item item = getItem(position);
    NormalViewHolder viewHolder = (NormalViewHolder) holder;

    viewHolder.mName.setText(item.getName());
    //viewHolder.mName.invalidate(); // No help
    viewHolder.mCode.setText(item.getCode());
    //viewHolder.mCode.invalidate(); // No help
}

预期行为:

+----------------------------------------+
|[Name][Code]                            |
+----------------------------------------+
|[Name qwertyuiopasdfghjklzxcvb...][Code]|
+----------------------------------------+

如果我向上/向下滚动列表,这就是现在的工作方式.因此,布局不会更新,并且代码也没有名称权.同样,名称并不会占用足够的空间.

This is how works right now if I scroll list up/down. So the layout is not updated and code is not alignet right to name. Also name is not taking always enough space.

+----------------------------------------+
|[Name][Code]                            |
+----------------------------------------+
|[Name qwer...]                [Code]    |
+----------------------------------------+
|[Name qwertyuiopa][Code]                |
+----------------------------------------+
|[Name qwe]        [Code]                |
+----------------------------------------+

推荐答案

此xml对我有效,而无需使用setIsRecyclable(false);
在某些Android版本(如kitkat)中,代码:android:ellipsize="end"仅与android:singleLine="true"一起使用,因此将其添加到第一个TextView"@ + id/name"中,它将起作用!

This xml works for me without using setIsRecyclable(false);
In some android versions (like kitkat) the code: android:ellipsize="end" only works with android:singleLine="true", so add this to the first TextView "@+id/name" and it will works!

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="150dp"
android:layout_marginLeft="16dp"
android:orientation="horizontal">
   <TextView
    android:id="@+id/name"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginRight="8dp"
    android:layout_weight="1"
    android:ellipsize="end"
    android:singleLine="true"
    android:maxLines="1"
    />
   <TextView
    android:id="@+id/code"
    android:layout_weight="0"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/background_stop_code_small"
    android:ellipsize="end"
    android:paddingBottom="1dp"
    android:paddingLeft="7dp"
    android:paddingRight="7dp"
    android:paddingTop="1dp"
    android:singleLine="true"
    android:textSize="11sp"/>
</LinearLayout>


结果:


The result:

这篇关于RecyclerView项目layout_weight,尺寸未更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆