一,实现效果(注意图片本身的格式会有很大的影响)
当宽度match_parent,设置宽高的比例值,确定高度值
当高度match_parent,设置宽高的比例值,确定宽度.
写二个自定义属性,ration比值,相对于谁?
<declare-styleable name="RatioLayout">
<attr name="mRatio" format="float"></attr>
<attr name="mRelative" format="enum">
<enum name="width" value="0"></enum>
<enum name="height" value="1"></enum>
</attr>
</declare-styleable>
二.代码实现
<pre name="code" class="java">/**
* 支持宽高自适应的组件,把需要适配的view作为它的孩子即可
*/
public class RatioLayout extends FrameLayout {
private float mRatio = 2.426f;//默认2.42
public static final int RELATIVE_WIDHT = 0;
public static final int RELATIVE_HEIGHT = 1;
private int mRelative = RELATIVE_WIDHT;//默认宽度match
public void setRatio(float ratio) {
mRatio = ratio;
}
public void setRelative(int relative) {
mRelative = relative;
}
public RatioLayout(Context context) {
this(context,null);
}
public RatioLayout(Context context, AttributeSet attrs) {
super(context, attrs);
//从xml中获取自定义属性
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RatioLayout);
mRatio = typedArray.getFloat(R.styleable.RatioLayout_mRatio,mRatio);
mRelative = typedArray.getInt(R.styleable.RatioLayout_mRelative,RELATIVE_WIDHT);
typedArray.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//1.获取信息
int width = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
//模式对应关系,matchparent/60dp ---- EXACTLY; wrapcontent-----> MeasureSpec.AT_MOST
if(widthMode == MeasureSpec.EXACTLY && mRelative == RELATIVE_WIDHT){
//情形一:宽度填充父窗体,高度自适应
//TODO:计算height,按照2.426的比例计算
int totalHeight = (int) (width / mRatio);
//2.测量孩子imageview
int childWidth = width - getPaddingLeft() - getPaddingRight(); //让自定义view支持padding功能
int childHeight = totalHeight - getPaddingTop() - getPaddingBottom();
int childWidthSpec = MeasureSpec.makeMeasureSpec(childWidth,MeasureSpec.EXACTLY);
int childHeightSpec = MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.EXACTLY);
measureChildren(childWidthSpec, childHeightSpec);
//3.决定自己的宽高
setMeasuredDimension(width, totalHeight);
}else if(heightMode == MeasureSpec.EXACTLY && mRelative == RELATIVE_HEIGHT){
//情形二:高度固定,宽度自适应
int totalWidth = (int) (height * mRatio);
//2.测量孩子imageview
int childWidth = totalWidth - getPaddingLeft() - getPaddingRight(); //让自定义view支持padding功能
int childHeight = height - getPaddingTop() - getPaddingBottom();
int childWidthSpec = MeasureSpec.makeMeasureSpec(childWidth,MeasureSpec.EXACTLY);
int childHeightSpec = MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.EXACTLY);
measureChildren(childWidthSpec, childHeightSpec);
//3.决定自己的宽高
setMeasuredDimension(totalWidth, height);
}else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
measureChildren(widthMeasureSpec,heightMeasureSpec);
}
}
}
三总布局
<pre name="code" class="java"> <com.example.administrator.textdemo.RatioLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:mRelative="height"
app:mRatio="5"
>
<ImageView
android:src="@drawable/a"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</com.example.administrator.textdemo.RatioLayout>