【问题标题】:How to set both min and max size for an ImageView in Android如何在 Android 中为 ImageView 设置最小和最大尺寸
【发布时间】:2012-03-28 20:03:25
【问题描述】:

我想指定两个最小值。宽度/高度和最大。 ImageView 的宽度/高度。应缩放图像以适合。

这样做:

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:minWidth="100dp"
    android:maxWidth="200dp"
    android:minHeight="100dp"
    android:maxHeight="200dp"
    android:src="@drawable/ic_launcher" />

最小。宽度和高度按应有的方式执行,但最大。宽度和高度被忽略。

如果我设置 android:adjustViewBounds="true":

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:adjustViewBounds="true"
    android:scaleType="fitCenter"
    android:minWidth="100dp"
    android:maxWidth="200dp"
    android:minHeight="100dp"
    android:maxHeight="200dp"
    android:src="@drawable/ic_launcher" />

比,最大值。宽度和高度按应有的方式执行,但最小。宽度和高度被忽略。

有没有办法两者兼得?

【问题讨论】:

    标签: android android-layout android-imageview


    【解决方案1】:

    最后,我创建了自己的视图,它扩展了 ImageView 并覆盖了 onMeasure():

    public class ResizingImageView extends ImageView {
    
        private int mMaxWidth;
        private int mMaxHeight;
    
        public ResizingImageView(Context context) {
            super(context);
        }
    
        public ResizingImageView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public ResizingImageView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        @Override
        public void setMaxWidth(int maxWidth) {
            super.setMaxWidth(maxWidth);
            mMaxWidth = maxWidth;
        }
    
        @Override
        public void setMaxHeight(int maxHeight) {
            super.setMaxHeight(maxHeight);
            mMaxHeight = maxHeight;
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    
            Drawable drawable = getDrawable();
            if (drawable != null) {
    
                int wMode = MeasureSpec.getMode(widthMeasureSpec);
                int hMode = MeasureSpec.getMode(heightMeasureSpec);
                if (wMode == MeasureSpec.EXACTLY || hMode == MeasureSpec.EXACTLY) {
                    return;
                }
    
                // Calculate the most appropriate size for the view. Take into
                // account minWidth, minHeight, maxWith, maxHeigh and allowed size
                // for the view.
    
                int maxWidth = wMode == MeasureSpec.AT_MOST
                        ? Math.min(MeasureSpec.getSize(widthMeasureSpec), mMaxWidth)
                        : mMaxWidth;
                int maxHeight = hMode == MeasureSpec.AT_MOST
                        ? Math.min(MeasureSpec.getSize(heightMeasureSpec), mMaxHeight)
                        : mMaxHeight;
    
                int dWidth = Helpers.dipsToPixels(drawable.getIntrinsicWidth());
                int dHeight = Helpers.dipsToPixels(drawable.getIntrinsicHeight());
                float ratio = ((float) dWidth) / dHeight;
    
                int width = Math.min(Math.max(dWidth, getSuggestedMinimumWidth()), maxWidth);
                int height = (int) (width / ratio);
    
                height = Math.min(Math.max(height, getSuggestedMinimumHeight()), maxHeight);
                width = (int) (height * ratio);
    
                if (width > maxWidth) {
                    width = maxWidth;
                    height = (int) (width / ratio);
                }
    
                setMeasuredDimension(width, height);
            }
        }
    }
    

    这个视图现在可以像这样使用:

    <my.package.ResizingImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:minWidth="100dp"
        android:maxWidth="200dp"
        android:minHeight="100dp"
        android:maxHeight="200dp"
        android:src="@drawable/ic_launcher" />
    

    这如我所愿,但不应该有更简单的解决方案吗?

    【讨论】:

    • 你是对的。我厌倦了无法用 Android 做简单的事情。
    【解决方案2】:

    这在过去仅使用 XML 几乎是不可能的,但现在使用 ConstraintLayout,这非常简单。

    <androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
    
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintWidth_min="100dp"
            app:layout_constraintWidth_max="200dp"
            app:layout_constraintHeight_min="100dp"
            app:layout_constraintHeight_max="200dp"
            app:layout_constrainedWidth="true"
            app:layout_constrainedHeight="true"
            android:scaleType="centerCrop" />
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    您可以使用scaleTypefitXYcenterCrop;其他人不会强制图像适合ImageView

    【讨论】:

      【解决方案3】:
              <LinearLayout
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:minWidth="150dp"
                  android:minHeight="150dp"
                  >
      
                  <RelativeLayout
                      android:id="@+id/imageLayout"
                      android:layout_width="match_parent"
                      android:layout_height="wrap_content"
                      android:background="@color/white"
                      android:layout_gravity="center_vertical"
                      >
      
                      <ImageView
                          android:id="@+id/image"
                          android:layout_width="match_parent"
                          android:layout_height="wrap_content"
                          android:adjustViewBounds="true"
                          android:src="@drawable/trump"
      
                          />
      
                      <ProgressBar
                          android:id="@+id/progressBar"
                          android:layout_width="wrap_content"
                          android:layout_height="wrap_content"
                          android:layout_centerInParent="true"
                          android:visibility="gone" />
                  </RelativeLayout>
              </LinearLayout>
      

      请参阅为容器布局提供最小高度和宽度,并将 adjustViewBounds 放入 Imageview。这样您的任务将通过简单的步骤完成。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-01-24
        • 2020-10-31
        • 2022-08-04
        • 1970-01-01
        • 2014-05-21
        • 2018-11-08
        • 2022-01-18
        相关资源
        最近更新 更多