图片加载的区域显示

问题描述:

一个imageview 控件宽高 640*280 ,通过glide加载要显示的图片,,图片始终显示在imageview 的右边和下边,图片的宽高可能小于或者大于imageview 控件的宽高,如何在imageview 显示图片:如果图片的宽高大于imageview 的宽高可以只显示图片对应的右下部分(此时imageview 宽或者高小于图片的),如果图片的宽高小于imageview 的宽高,可以在imageview 的右边和下边显示图片

讲的很笼统,大概的意思就是imageview空间要显示的图片宽高不是固定的,图片如果小的话,可以完全显示,如果图片比较大的话,imageview会显示部分的图片,当然,此刻imageview的宽或者高可能会填充,显示图片的一部分,那这些的话应该怎么实现呢,先回顾一些imageview的一些知识:

ImageView 的scaleType 分析讲解

ImageView 的 scaleType 属性是 Android 开发中非常关键的一个属性,它决定了图片如何被缩放(或不变)以适应 ImageView 的大小。scaleType 提供了多种模式来应对不同的布局需求。下面是对 ImageView 中 scaleType 属性的详细分析讲解:

1. matrix

  • 描述:使用图像矩阵(Image Matrix)来缩放和移动图片。这通常与 setImageMatrix(Matrix matrix) 方法结合使用,以实现复杂的图片变换效果。
  • 特点:提供了最大的灵活性,但也需要开发者手动计算矩阵变换。

2. fitXY

  • 描述:拉伸图片以完全适应 ImageView 的边界。这可能会导致图片的宽高比失真。
  • 特点:简单直接,但可能会破坏图片的原始比例。

3. fitStart

  • 描述:保持图片的宽高比,将图片的左上角与 ImageView 的左上角对齐,然后缩放图片以适应 ImageView 的宽度或高度(取决于哪个更小)。
  • 特点:图片可能会在 ImageView 的底部或右侧留下空白。

4. fitEnd

  • 描述:与 fitStart 类似,但将图片的右下角与 ImageView 的右下角对齐。
  • 特点:同样保持图片的宽高比,但空白区域会出现在 ImageView 的顶部或左侧。

5. fitCenter

  • 描述:保持图片的宽高比,将图片缩放以使其完全适应 ImageView 的边界(至少一边相等),然后将图片居中显示。
  • 特点:这是最常用的 scaleType 之一,因为它既保持了图片的宽高比,又确保了图片在 ImageView 中居中显示。

6. center

  • 描述:将图片的中心与 ImageView 的中心对齐,不进行缩放。如果图片的宽高比与 ImageView 的宽高比不匹配,图片将不会覆盖整个 ImageView
  • 特点:适用于不需要缩放图片,但需要确保图片中心与 ImageView 中心对齐的场景。

7. centerCrop

  • 描述:保持图片的宽高比,但裁剪图片的边界以完全覆盖 ImageView 的边界。这通常意味着图片的某些部分将被裁剪掉。
  • 特点:常用于需要图片填满整个 ImageView,且可以接受部分裁剪的场景,如用户头像或图片轮播。

8. centerInside

  • 描述:保持图片的宽高比,将图片缩放以使其完全适应 ImageView 的边界(但不超过 ImageView 的边界),然后将图片居中显示。
  • 特点:这确保了图片不会超出 ImageView 的边界,但可能会留下空白区域。

总结

ImageView 的 scaleType 属性提供了多种模式来适应不同的布局需求。开发者应根据具体场景选择合适的 scaleType,以确保图片以最佳方式展示在 ImageView 中。

centerCrop() fitCenter() centerInside() circleCrop() 的区别和使用

在Android开发中,尤其是使用图片加载库(如Glide、Picasso等)时,centerCrop()fitCenter()centerInside(), 和 circleCrop() 是常见的变换选项,用于控制图片如何被缩放以适应ImageView的边界。下面我将详细解释每个选项的区别和使用场景。

1. centerCrop()

  • 作用:将图片的中心部分裁剪(Crop)到ImageView的边界内,同时保持图片的宽高比。这意呀着图片的某些部分可能会被裁剪掉,以确保图片的整个宽度或高度(取决于图片的宽高比和ImageView的宽高比)都完全填满ImageView。
  • 使用场景:当你希望图片充满整个ImageView,且不介意图片的部分内容被裁剪时,这个选项很有用。例如,在展示用户头像或者图片轮播时。

2. fitCenter()

  • 作用:将图片按比例缩放,使得图片的宽度或高度(取决于图片的宽高比和ImageView的宽高比)之一等于ImageView的相应尺寸,而另一个尺寸则按比例缩放以保持图片的宽高比。缩放后的图片会居中显示在ImageView中,可能会留下空白边缘。
  • 使用场景:当你希望图片保持完整,不希望任何部分被裁剪,但可以接受图片不完全填满ImageView时,这个选项是合适的。例如,在展示产品图片或文章配图时。

3. centerInside()

  • 作用:将图片按比例缩放,确保图片的宽度和高度都小于或等于ImageView的相应尺寸,同时保持图片的宽高比。缩放后的图片会居中显示在ImageView中,且图片的边界完全位于ImageView的内部,不会有任何裁剪,但可能会留下较大的空白边缘。
  • 使用场景:当你希望图片完全显示在ImageView中,且不希望图片被裁剪或缩放得太大以至于失真时,这个选项是最佳选择。它适用于需要展示清晰、完整图片的场景。

4. circleCrop()

  • 作用:将图片裁剪成圆形,并尝试将图片的重要部分(通常是中心部分)保留在圆内。这通常涉及到对图片的缩放和裁剪,以确保整个圆形区域都被图片覆盖,且尽可能保留图片的宽高比。然而,由于裁剪成圆形,图片的某些边缘部分可能会被裁剪掉。
  • 使用场景:当你希望展示圆形图片时,如用户头像或某些需要圆形图标的应用场景。这个选项可以确保图片以圆形形式展示,且尽可能保持图片的清晰度和重要内容。

总结

  • centerCrop() 适用于需要图片填满整个ImageView,且可以接受部分裁剪的场景。
  • fitCenter() 适用于需要图片保持完整,不希望被裁剪,但可以接受不完全填满ImageView的场景。
  • centerInside() 适用于需要图片完全显示在ImageView中,不希望被裁剪或缩放得太大而导致失真的场景。
  • circleCrop() 适用于需要将图片裁剪成圆形展示的场景。

实现方法

要实现你的需求,可以通过以下调整来正确显示图片:

  1. 确保图片不被放大:避免在 ImageView 中放大图片,应该只在需要时对图片进行裁剪。
  2. 保持图片的原始比例:只有当图片的尺寸大于 ImageView 时,才进行裁剪操作。

我们可以简化处理,使用 GlidefitCenter 结合 Matrix 来实现这一效果。

代码实现

  1. 设置 ImageViewScaleTypeMatrix:使用 Matrix 进行图像变换,以便精确控制图片的显示位置。

  2. 使用 Glide 加载图片:加载图片,并确保在 ImageView 中进行手动调整。

自定义 ImageView 处理

首先,为了更好地控制图片的位置,我们需要设置 ImageViewMatrix

val imageView: ImageView = findViewById(R.id.your_image_view)
Glide.with(this)
    .asBitmap()
    .load("your_image_url")
    .into(object : CustomTarget<Bitmap>() {
        override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
            imageView.setImageBitmap(resource)
            
            // 获取图片和 ImageView 的尺寸
            val imageWidth = resource.width
            val imageHeight = resource.height
            val viewWidth = imageView.width
            val viewHeight = imageView.height

            // 计算比例
            val scale = Math.min(viewWidth.toFloat() / imageWidth, viewHeight.toFloat() / imageHeight)

            // 创建 Matrix
            val matrix = Matrix()
            matrix.setScale(scale, scale)

            // 移动图片到右下角
            val dx = viewWidth - imageWidth * scale
            val dy = viewHeight - imageHeight * scale
            matrix.postTranslate(dx, dy)

            imageView.imageMatrix = matrix
        }

        override fun onLoadCleared(placeholder: Drawable?) {
            // Handle cleanup if needed
        }
    })

xml 文件

<ImageView
    android:id="@+id/your_image_view"
    android:layout_width="640dp"
    android:layout_height="280dp"
    android:scaleType="matrix"
    android:background="#CCCCCC"/>

解释

  • CustomTarget<Bitmap>: 通过这个 Target,我们可以在图片加载完成后获取到 Bitmap,从而手动调整 Matrix
  • Matrix: 使用 Matrix 来缩放并移动图片,确保它位于 ImageView 的右下角。
  • Scale: 计算一个合适的缩放比例,确保图片不会被放大,只在需要时进行缩小。

这样设置后,当图片尺寸小于 ImageView 时,图片会保持原比例并显示在右下角;如果图片尺寸大于 ImageView,则会裁剪并显示图片的右下部分。

但是以上代码并没有达到我的需求,如下修改

调整1:

<FrameLayout
    android:layout_width="640dp"
    android:layout_height="280dp"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintBottom_toBottomOf="parent">

    <ImageView
        android:id="@+id/iv_guide_doctor"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="matrix"
        android:background="#CCCCCC"
        android:layout_gravity="right|bottom"/>
</FrameLayout>

为了实现这个效果,需要对 ImageView 的布局和 Glide 的设置进行一些调整。具体来说,我们将不使用 centerCrop(),而是通过 Matrix 手动控制图片的显示方式,以确保图片始终位于 ImageView 的右下角并且按照你的要求裁剪。

使用 Glide 加载图片并手动设置 Matrix

val imageView: ImageView = findViewById(R.id.iv_guide_doctor)

Glide.with(mContext)
    .asBitmap()
    .load(url)
    .error(R.mipmap.icon_guide_doctor)
    .into(object : CustomTarget<Bitmap>() {
        override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
            // 获取图片和 ImageView 的尺寸
            val imageWidth = resource.width
            val imageHeight = resource.height
            val viewWidth = imageView.width
            val viewHeight = imageView.height

            // 计算比例,确保图片不会被放大
            val scale = Math.max(
                viewWidth.toFloat() / imageWidth,
                viewHeight.toFloat() / imageHeight
            )

            // 计算平移量,使图片的右下部分显示
            val dx = viewWidth - imageWidth * scale
            val dy = viewHeight - imageHeight * scale

            // 设置图片的 Matrix
            val matrix = Matrix()
            matrix.setScale(scale, scale)
            matrix.postTranslate(dx, dy)
            imageView.imageMatrix = matrix
            imageView.setImageBitmap(resource)
        }

        override fun onLoadCleared(placeholder: Drawable?) {
            // Handle cleanup if needed
        }
    })

解释

  • scaleType="matrix": 设置 ImageViewscaleTypematrix,允许我们手动控制图片的缩放和平移。

  • 计算 scale: 使用 Math.max 来计算缩放比例,确保图片在缩放后覆盖整个 ImageView,且不会放大到超出 ImageView 尺寸。

  • 计算 dxdy: 平移量的计算确保图片的右下部分位于 ImageView 的右下角。

  • 设置 Matrix: 最后,使用 Matrix 进行缩放和平移操作,确保图片按照你预期的方式显示。

通过这个方法,图片将按照你的要求显示在 ImageView 的右下角,如果图片的高度或宽度大于 ImageView,只会显示右下部分,而不会显示超出 ImageView 的部分。

这个方法可以尝试,但涉及到矩阵和大小的关系,算上去可能比较麻烦,这边还有一个最简单粗暴的方法,直接在onResourceReady 的方法中,动态设置一下imageview的宽高为获取到的图片的宽高,然后直接显示图片。这样可以确保图片以其原始尺寸显示在 ImageView 中,而无需进行缩放或裁剪。以下是如何实现这个功能的代码示例。

修改后的 Java 代码

import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.ImageView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ImageView imageView = findViewById(R.id.iv_guide_doctor);
        String url = "your_image_url"; // Replace with your image URL

        Glide.with(this)
                .asBitmap()
                .load(url)
                .error(R.mipmap.icon_guide_doctor)
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .into(new CustomTarget<Bitmap>() {
                    @Override
                    public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
                        // Get the dimensions of the loaded bitmap
                        int imageWidth = resource.getWidth();
                        int imageHeight = resource.getHeight();

                        // Set the ImageView's layout parameters to match the image dimensions
                        ViewGroup.LayoutParams params = imageView.getLayoutParams();
                        params.width = imageWidth;
                        params.height = imageHeight;
                        imageView.setLayoutParams(params);

                        // Set the ImageView's image to the loaded bitmap
                        imageView.setImageBitmap(resource);
                    }

                    @Override
                    public void onLoadCleared(@Nullable Drawable placeholder) {
                        // Handle cleanup if needed
                    }
                });
    }
}
        <FrameLayout
            android:layout_width="@dimen/px640"
            android:layout_height="@dimen/px280"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintBottom_toBottomOf="parent">
            <ImageView
                android:id="@+id/iv_guide_doctor"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="fitEnd"
                android:layout_gravity="right|bottom"
               />
        </FrameLayout>

解释

  1. onResourceReady 方法中动态设置 ImageView 的宽高:

    • 使用 Bitmap 对象的 getWidth()getHeight() 方法来获取加载的图片的实际宽高。
    • 通过获取 ImageViewLayoutParams,然后设置宽高为图片的宽高。
    • 最后,调用 setLayoutParams 方法将更新后的布局参数应用到 ImageView 上。
  2. 直接显示图片:

    • 设置 ImageView 的宽高之后,使用 setImageBitmap(resource) 方法将图片直接显示在 ImageView 中。

结果

这样做的结果是:

  • ImageView 将会动态调整它的宽高,以适应加载的图片的实际尺寸。
  • 图片将以原始大小显示在 ImageView 中,不会进行缩放或裁剪。
  • ImageView 将自动调整并显示在 FrameLayout 的右下角(因为你设置了 layout_gravity="right|bottom")。

通过这种方法,你可以确保图片始终以其原始尺寸显示,并且 ImageView 也会根据图片的尺寸进行调整。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值