将视图动态添加到具有 wrap_content 高度的 LinearLayout 不会显示任何内容

Posted

技术标签:

【中文标题】将视图动态添加到具有 wrap_content 高度的 LinearLayout 不会显示任何内容【英文标题】:Dynamically adding a View to a LinearLayout with height of wrap_content doesn't display anything 【发布时间】:2021-08-13 05:26:22 【问题描述】:

我正在尝试使用wrap_content 高度动态地将视图添加到LinearLayout。但是,除非我添加定义的dp 高度,例如300dp,否则它不起作用。为什么我不能以编程方式添加视图并让父 LinearLayout 包装内容?

我要添加的视图:

public class ImageCanvas extends View 

    private static final String TAG = "ImageCanvas";

    private Bitmap icon;

    public ImageCanvas(Context context) 
        super(context);

        Drawable drawable = ContextCompat.getDrawable(context, R.drawable.piggy);
        if(drawable != null)
            icon = ((BitmapDrawable) drawable).getBitmap();
        
        Log.d(TAG, "ImageCanvas: " + icon);
    

    public ImageCanvas(Context context, @Nullable AttributeSet attrs) 
        super(context, attrs);
    

    public ImageCanvas(Context context, @Nullable AttributeSet attrs, int defStyleAttr) 
        super(context, attrs, defStyleAttr);
    


    @Override
    protected void onDraw(Canvas canvas) 
        super.onDraw(canvas);


        canvas.drawBitmap(icon, 0, 0, null);
    

LinearLayout 我正在尝试将上述视图添加到:

             <LinearLayout
                android:id="@+id/drawingPad"
                android:layout_
                android:layout_
                app:layout_constraintTop_toBottomOf="@+id/btn_create_image"
                app:layout_constraintBottom_toBottomOf="parent"
                android:paddingBottom="32dp"
                android:orientation="vertical"
                android:paddingTop="32dp"/>             

以编程方式创建视图并添加它:

LinearLayout drawingPad = findViewById(R.id.drawingPad);

ImageCanvas imageCanvas = new ImageCanvas(context);
drawingPad.addView(imageCanvas);

当我将 XML LinearLayout 设置为像 200dp 这样的定义高度时它可以工作,但它不适用于 wrap_content,我怎样才能让它与 wrap_content 一起这样做?

_________________________________________________________

更新 1:

我将所有内容简化为 XML 布局,结果问题出在父 NestedScrollView

<?xml version="1.0" encoding="utf-8"?>

<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_
    android:layout_>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/parentLayout"
        android:layout_
        android:layout_
        android:orientation="vertical">

        <Button
            android:id="@+id/btn_create_image"
            android:layout_
            android:layout_
            android:layout_marginStart="16dp"
            android:layout_marginEnd="16dp"
            android:text="Create image"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <LinearLayout
            android:id="@+id/drawingPad"
            android:layout_
            android:layout_
            android:orientation="vertical"
            android:paddingTop="32dp"
            android:paddingBottom="32dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/btn_create_image" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.core.widget.NestedScrollView>

这是整个布局。当您添加NestedScrollView 并尝试以编程方式添加视图时,位图将不会在屏幕上绘制。当您删除NestedScrollView 时,将出现位图。如果有人知道如何使用NestedScrollView 进行操作,请分享!

【问题讨论】:

什么是“小猪”drawable?可以发一下吗? imgur.com/a/PN4kjvc 这个。为什么在这种情况下drawable很重要? drawable 可能有些不寻常,但 jpg 非常简单。您可能会遇到 ConstraintLayout 问题而不是可绘制问题。无论如何,我将您的代码放入一个空白项目中,并且可以正常处理包装内容。如果您感到困惑并且没有得到好的答案,MCVE 会有所帮助。 @Cheticamp 是的,你是对的。这不是代码的问题。在我将所有内容简化为一个最小示例之后,结果证明将 NestedScrollView 作为根布局是一个问题,这会导致位图根本不出现(更新了上面的完整布局)。仍在尝试使用NestedScrollView 找出解决方案 【参考方案1】:

您需要使用 onMeasure() 覆盖来提供 ImageCanvas 的测量值:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
    setMeasuredDimension(icon.getWidth(),icon.getHeight());

见Custom View Components。

当您明确提供高度时,该高度会在自定义组件中设置。对于换行内容,高度设置为零,因为它既没有指定也没有明确测量。上面的代码将提供正确的测量值。

icon.getHeight() 是您真正需要的,对应于wrap_content。根据您的设计,您可能需要为icon.getWidth() 设置不同的值。)

不知道为什么 NestedScrollView 有任何效果,但上面的代码会有所帮助。

【讨论】:

我试过你的答案,但它似乎仍然没有显示位图。这是我的完整代码pastebin.com/xyciUTNe 一切正常,直到您将NestedScrollView 添加为根视图。删除它,它可以正常显示位图。 @DIRTYDAVE 我对你的 pastebin 代码感到困惑。它甚至没有LinearLayout,而drawingPad是那里的ImageView,而不是问题中的LinearLayout。 对不起,我不得不稍微改变一下,因为我无法让它工作 @DIRTYDAVE 我理解,但这个问题似乎并不能反映当前的情况。我也没有在 pastebin 中看到 onMeasure() 代码。附带说明一下,我还将取出 ConstraintLayout 的直接子级中的所有 match_parent 尺寸,并将其替换为具有适当约束的0dp。 match_parent 在 ConstraintLayout 中确实是非法的,尽管没有对其进行 lint 检查。 match_parent 可能会导致奇怪的问题。 ....我知道这是疯狂的随机,但是在我将android:fillViewport="true" 添加到NestedScrollView 之后,位图会加载。我都快要放弃了【参考方案2】:

问题可能在于您的约束布局。 对于约束布局 >= 1.1

app:layout_constrainedHeight=”true"
android:layout_ 

用于约束布局

android:layout_ 
app:layout_constraintHeight_default="wrap"

这总是让我着迷,也许它让你着迷。 (编辑)这需要在约束布局的孩子而不是约束布局本身,即LinearLayout。

【讨论】:

您好,感谢您的回复!我将所有内容简化为一个非常简单的布局(上面有问题的更新),结果证明将NestedScrollView 作为父级是一个问题。我尝试将您的解决方案添加到约束布局中的 xml,但这没有帮助。

以上是关于将视图动态添加到具有 wrap_content 高度的 LinearLayout 不会显示任何内容的主要内容,如果未能解决你的问题,请参考以下文章

将视图放置在高度为 wrap_content 的相对布局的底部

如何在 iOS 中将 UIView 添加到 UIScrollView 中(具有动态内容的视图)

在 Android 中如何获取设置为 Wrap_Content 的 Textview 的宽度

动态添加 UIView,还是创建 UITableView? IOS

在具有动态高度的视图末尾添加一个 UIButton

实现 UITableView (Slave) 的动态高度,它作为子视图添加到另一个具有动态高度的 UITableView (Master) 的自定义单元格中