在屏幕上不适合时缩小图像

时间:2019-09-16 11:52:38

标签: android imageview

我有一个简单的布局,图像和文本居中。我希望文本始终可见,然后将其余空间用于图像。如有必要,图像应按比例缩小。如您在第一张图片中所见,所有图片都非常适合纵向模式,但是在横向模式下,图片的一部分和文本的一部分被推出了屏幕。我怎样才能解决这个问题?我事先不知道图像的大小,但是我知道我的文本一直都在54dp的高度上。另外,文本必须始终在图像的正下方(它们之间没有空格)。查看最后一张图片。

我想单独使用XML是不可能的,我将不得不在Java方面做一些工作。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:gravity="center">

    <ImageView
            android:id="@+id/img"
            android:src="@drawable/tree"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="54dp"
            android:ellipsize="end"
            android:maxLines="3"
            android:text="In May 2019, Italian broadcaster RAI announced that it had begun planning the 2020 edition of the Sanremo Music Festival. It was not confirmed whether the festival would be used to select Italy's participant for 2020."
            android:gravity="center"
            android:textColor="#000000"
            android:textSize="16dp" />
</LinearLayout>

enter image description here

enter image description here

3 个答案:

答案 0 :(得分:1)

这是我提出的解决方案。绘制视图并确定其尺寸后,我会考虑图像的尺寸和可用区域,重新计算ImageView的尺寸。请参阅下面的图片以了解其工作原理。我也调整了布局。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:gravity="center">

    <ImageView
            android:id="@+id/img"
            android:layout_width="0dp"
            android:layout_height="0dp" />

    <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:lines="3"
            android:text="In May 2019, Italian broadcaster RAI announced that it had begun planning the 2020 edition of the Sanremo Music Festival. It was not confirmed whether the festival would be used to select Italy's participant for 2020."
            android:gravity="center"
            android:textSize="16sp" />
</LinearLayout>

import android.graphics.BitmapFactory
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.view.ViewGroup
import android.view.ViewTreeObserver
import android.widget.LinearLayout
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        img.setImageResource(R.drawable.tree)
        img.tag = R.drawable.tree
        img.viewTreeObserver.addOnGlobalLayoutListener(onGlobalLayoutListener)
    }

    private fun adjustImageViewSizeForImage(imgRes: Int) {
        val dimensions = BitmapFactory.Options()
        dimensions.inJustDecodeBounds = true
        BitmapFactory.decodeResource(resources, imgRes, dimensions)
        var imageViewWidth = dimensions.outWidth
        var imageViewHeight = dimensions.outHeight

        val availableWidth = (img.parent as ViewGroup).width
        val availableHeight = (img.parent as ViewGroup).height - text.height

        if (imageViewWidth > availableWidth) {
            val ratio = 1.0 * availableWidth / imageViewWidth
            imageViewWidth = availableWidth
            imageViewHeight = (ratio * imageViewHeight).toInt()
        }
        if (imageViewHeight > availableHeight) {
            val ratio = 1.0 * availableHeight / imageViewHeight
            imageViewHeight = availableHeight
            imageViewWidth = (ratio * imageViewWidth).toInt()
        }

        img.layoutParams = LinearLayout.LayoutParams(imageViewWidth, imageViewHeight)
    }

    private val onGlobalLayoutListener = object : ViewTreeObserver.OnGlobalLayoutListener {

        override fun onGlobalLayout() {
            // view dimensions are known at this point
            img.viewTreeObserver.removeOnGlobalLayoutListener(this)
            adjustImageViewSizeForImage(img.tag as Int)
        }
    }

}

答案 1 :(得分:0)

使用相同的文件名创建一个新的资源布局文件,添加限定符方向并选择横向。现在您有两个名称相同的资源,一个是默认名称,另一个是用于景观视图。还将相同的代码复制粘贴到那里,现在您可以在此处看到景观设计预览,只需调整代码即可解决问题。

答案 2 :(得分:0)

我认为最好的解决方案是用ConstraintLayout

替换您的布局

让我解释一下:

您知道您的textSize为54dp,但这是固定大小,在视图中使用它会导致屏幕无响应(这是因为不同的手机具有不同的屏幕大小,而{{1 }}在大型手机上可能看起来很小)

当然,您可以为每种屏幕尺寸创建一个布局,但是使用54dp可以创建一个响应式布局。


对于布局,您可以使用这些属性:

  • ConstraintLayout

  • app:layout_constraintWidth_percent

以相对于屏幕尺寸的百分比来管理视图尺寸。

例如,以下布局:

app:layout_constraintHeight_percent

在上述布局中,您的textView高度等于屏幕高度的15%。 您的textView和图像将在给定的每种屏幕尺寸下保持该比例。

布局将如下所示:

enter image description here

其他信息:

现在,在获得布局图之后,您必须对自己感到奇怪:“为什么我的文字被截断,他不是只是提到布局是如何响应的?”

我确实提到过它,如果您希望文本也适合屏幕显示,可以使用Autosizing TextViews