【问题标题】:ImageView height relative to widthImageView 高度相对于宽度
【发布时间】:2014-03-17 15:04:19
【问题描述】:

我有这个布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/AppTheme.Widgets.Box"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:scaleType="centerCrop"
        android:background="#eee"/>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="7dp"
        android:gravity="center"/>

</LinearLayout>

所以,我正在将远程图像从网络加载到 ImageView 中。我知道图像的尺寸,所以我知道宽度:高度比。现在,当我初始化布局时,我需要以某种方式应用此定量,这样它就不会在应用程序中像疯了一样跳跃。

【问题讨论】:

    标签: android android-layout imageview android-imageview


    【解决方案1】:

    对于这种情况,我创建了一个自定义的 ImageView,它保持相对于宽度的高度。它具有自定义属性“height_ratio”,该属性乘以宽度以获得高度:

    DynamicHeightImageView.java:

    /**
     * An {@link android.widget.ImageView} layout that maintains a consistent width to height aspect ratio.
     */
    public class DynamicHeightImageView extends ImageView {
    
        private float mHeightRatio;
    
        public DynamicHeightImageView(Context context, AttributeSet attrs) {
            super(context, attrs);
            TypedArray ta = context.getTheme().obtainStyledAttributes(attrs, R.styleable.DynamicHeightImageView, 0, 0);
            try {
                mHeightRatio = ta.getFloat(R.styleable.DynamicHeightImageView_height_ratio, 0.0f);
            } finally {
                ta.recycle();
            }
        }
    
        public DynamicHeightImageView(Context context) {
            super(context);
        }
    
        public void setHeightRatio(float ratio) {
            if (ratio != mHeightRatio) {
                mHeightRatio = ratio;
                requestLayout();
            }
        }
    
        public double getHeightRatio() {
            return mHeightRatio;
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            if (mHeightRatio > 0.0f) {
                // set the image views size
                int width = MeasureSpec.getSize(widthMeasureSpec);
                int height = (int) (width * mHeightRatio);
                setMeasuredDimension(width, height);
            }
            else {
                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            }
        }
    }
    

    attrs.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <declare-styleable name="DynamicHeightImageView">
            <attr name="height_ratio" format="float"/>
        </declare-styleable>
    </resources>
    

    用法:

    <com.melnykov.android.views.DynamicHeightImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scaleType="centerCrop"
        custom:height_ratio="0.6"/>
    

    【讨论】:

      【解决方案2】:

      如果您使用 CENTER_INSIDE 作为缩放类型,图像将被缩放,以便保留纵横比并且图像适合您使用 layout_width 和 layout_height 定义的图像视图的“框架”。但是你确定你想让你的图像最大 2dp 高吗?

      【讨论】:

        【解决方案3】:

        因为您知道图像的尺寸。您可以设置图像视图的尺寸,以编程方式将像素转换为 dp

        参考这个Convert Pixels to DP

        【讨论】:

        • 但是 imageview 有一些宽度。我有 2 列布局,取决于屏幕大小是列的宽度。有了这个宽度,我需要计算高度。
        【解决方案4】:

        作为对makovkastar's answer 的改进(我认为):

        我试图让整个事情变得更简单一点,用 Kotlin 编写它并使它的高度和宽度方面设置为整数,以便通过使用分数而不是浮点数来更精确:

        /**
         * An [android.widget.ImageView] layout that maintains a consistent width to height aspect ratio.
         */
        class DynamicHeightImageView @JvmOverloads constructor(
            context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
        ) : ImageView(context, attrs, defStyleAttr) {
        
        private var heightFactor : Int
        private var widthFactor : Int
        
        init {
            context.theme.obtainStyledAttributes(attrs, R.styleable.DynamicHeightImageView, 0, 0).apply {
                heightFactor = getInt(R.styleable.DynamicHeightImageView_heightFactor, 1)
                widthFactor = getInt(R.styleable.DynamicHeightImageView_widthFactor, 1)
            }
        }
        
        /**
         * Adjusts the [getHeight] relative to the [getWidth], according to [heightFactor] and [widthFactor].
         */
        override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
            super.onLayout(changed, left, top, right, bottom)
            layoutParams.height = (width.toFloat() * heightFactor / widthFactor).toInt()
        }
        

        <?xml version="1.0" encoding="utf-8"?>
        <resources>
            <declare-styleable name="DynamicHeightImageView">
                <attr name="heightFactor" format="integer"/>
                <attr name="widthFactor" format="integer"/>
            </declare-styleable>
        </resources>
        

        【讨论】:

          猜你喜欢
          • 2018-06-01
          • 1970-01-01
          • 2023-03-23
          • 2018-06-02
          • 2015-01-09
          • 1970-01-01
          • 2017-04-24
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多