使用FrameLayout來適配ImageViw按比例展示

一、佈局文件:

<com.hsc.googleplay.ui.view.RatioLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:ratio="2.43">
    <ImageView
        android:id="@+id/iv_pic"
        android:src="@drawable/subject_default"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</com.hsc.googleplay.ui.view.RatioLayout>

再創建attrs.xml文件:

<resources>

    <declare-styleable name="RatioLayout">
        <attr name="ratio" format="float"/>
    </declare-styleable>
    
</resources>

/**
 * 自定義控件,按比例來決定佈局高度 做了讓View支持wrap_content與padding
 * Created by 15827 on 2017/5/22.
 */

public class RatioLayout extends FrameLayout {

    private float mRatio;

    public RatioLayout(Context context) {
        super(context);
    }

    public RatioLayout( Context context,  AttributeSet attrs) {
        super(context, attrs);
        //獲取屬性值
        //當自定義屬性時,系統會自動生成屬性相關id,此id通過R.styleable來引用
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RatioLayout);

        // id = 屬性名_具體屬性字段名稱
        //系統自動生成RatioLayout_ratio,根據兩個name        mRatio = typedArray.getFloat(R.styleable.RatioLayout_ratio, -1);//寬高比例值
        typedArray.recycle();//回收,提高具體性能
        //LogUtils.i("ratio=" + mRatio); //佈局中的app:ratio=“2.43” 來自這裏 也可以利用圖片的真實寬高
    }

    public RatioLayout( Context context,  AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // 1 獲取寬度
        // 2 根據寬度和比例ratio,計算控件的高度
        // 3 重新測量控件
        LogUtils.d("widthMeasureSpec: "+widthMeasureSpec);

        // MeasureSpec.AT_MOST; 至多模式, 控件有多大顯示多大, wrap_content
        // MeasureSpec.EXACTLY; 確定模式, 類似寬高寫死成dip, match_parent
        // MeasureSpec.UNSPECIFIED; 未指定模式.
        
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);//獲取寬度模式
        int width = MeasureSpec.getSize(widthMeasureSpec); // 獲取寬度值

        int heightMode = MeasureSpec.getMode(heightMeasureSpec);//獲取高度模式
        int height = MeasureSpec.getSize(heightMeasureSpec); // 獲取高度值

        //寬度確定,高度不確定,mRatio合法,才計算高度值
        if (widthMode == MeasureSpec.EXACTLY && heightMode != MeasureSpec.EXACTLY && mRatio > 0) {
            //圖片寬度 = 控件寬度 - 左側內邊距 - 右側內邊距
            int imageWidth = width - getPaddingLeft() - getPaddingRight();

            //圖片高度 = 圖片寬度 / 寬高比例
            int imageHeight = (int) (imageWidth / mRatio + 0.5f);

            // 控件高度 = 圖片高度 + 上側內邊距 + 下側內邊距
            height = imageHeight + getPaddingTop() + getPaddingBottom();

            //根據最新的高度重新生成 heightMeasureSpec (高度模式是確定模式)
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
        }
        //按照最新的高度測量控件
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章