Android 自定义view-正方形、可设置宽高比ImageView

简单分析

这个比较简单,就是重新计算ImageView的宽高。这里可以设置宽高的比例,所以多加一个自定义view中的自定义属性。假设我们的这个控件已经写好了,那么我们会在布局文件xml中使用,我们会在xml使用我们自定义的属性来设置宽高比,在控件的java类中拿到我们xml文件中自定义属性的值,然后计算出控件的宽高实例大小,最后保存。over。

 

实现步骤

  1. 自定义属性,目的是在xml中使用该属性赋值
  2. 得到在xml中自定义属性的值。
  3. 通过自定义属性的值计算出实际的宽高
  4. 保存计算得到的宽高

 

代码实现

  • 1、自定义属性,在values下新建一个名为:attrs 的资源文件(鼠标右键→new→Values Resource file),然后写上你要自定的属性
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!--自定义属性的名称,额。。可以理解成类名 如:class user-->
    <declare-styleable name="ScaleImageView">
        <!--name:属性名称  format:属性类型,额。。可以理解用类的成员 如:String name-->
        <attr name="heightScale" format="float" />
        <attr name="widthScale" format="float" />
    </declare-styleable>
</resources>

 2、3、4嗯。。。直接看代码

/**
 * create by ts_xiaoa
 * create Time 2018/9/11
 * description: 可以设置宽高比的ImageView
 */
public class ScaleImageView extends android.support.v7.widget.AppCompatImageView {

    //高度 : 宽度 = heightScale 0f不做处理
    private float heightScale = 0f;
    //宽度 : 高度 = widthScale 0f不做处理
    private float widthScale = 0f;

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

    /**
     * 两个参数的构造方法,在xml文件中使用该控件的时候回调
     * 我们这里就是在xml中直接使用所以把我们要做的初始化操作写这儿,比如初始化宽高比
     *
     * @param context
     * @param attrs
     */
    public ScaleImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        //通过context.obtainStyledAttributes,得到TypedArray对象,该对象中可以得到自定义属性对应的值
        //context.obtainStyledAttributes第一个参数就是构造方法的attrs
        //context.obtainStyledAttributes第一个参数就是你自定义的属性
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ScaleImageView);
        //得到xml文件中widthScale属性的值
        widthScale = typedArray.getFloat(R.styleable.ScaleImageView_widthScale, 0f);
        //得到xml文件中heightScale属性的值
        heightScale = typedArray.getFloat(R.styleable.ScaleImageView_heightScale, 0f);
        //回收typedArray对象
        typedArray.recycle();
    }
    
    public ScaleImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ScaleImageView);
        widthScale = typedArray.getFloat(R.styleable.ScaleImageView_widthScale, 0f);
        heightScale = typedArray.getFloat(R.styleable.ScaleImageView_heightScale, 0f);
        typedArray.recycle();
    }

    /**
     * 控件的测量方法,该方法实现控件的测量规则,
     * 并在该方法最后调用setMeasuredDimension(widthSize,heightSize)
     * 或者super.onMeasure(widthMeasureSpec, heightMeasureSpec)
     * 保存最终测量的控件大小
     *
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //默认测量规则
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //限制开发者只能设置了一个比例(比例得有一个实际大小的参照,比如宽200,heightScale=1f,那么高度的值=200)
        if (widthScale != 0f && heightScale != 0f) {
            throw new IllegalArgumentException("宽高比例只能设置一个");
        }
        //得到默认测量规则下测量到的宽度
        int measuredWidth = getMeasuredWidth();
        //得到默认测量规则下测量到的高度
        int measuredHeight = getMeasuredHeight();
        //判断开发者设置的宽高比
        if (widthScale != 0) {
            //开发者设置的是宽度比例,通过比例和实际高度计算实际的宽度
            measuredWidth = (int) (widthScale * measuredHeight);
            //保存测量的最终结果setMeasuredDimension()或者super.onMeasure()
            setMeasuredDimension(measuredWidth, measuredHeight);
//            super.onMeasure(MeasureSpec.makeMeasureSpec(measuredWidth, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(measuredHeight, MeasureSpec.EXACTLY));
        } else if (heightScale != 0) {
            //开发者设置的是高度比例,通过比例和实际宽度计算实际的高度
            measuredHeight = (int) (heightScale * measuredWidth);
            //保存测量的最终结果setMeasuredDimension()或者super.onMeasure()
            setMeasuredDimension(measuredWidth, measuredHeight);
//            super.onMeasure(MeasureSpec.makeMeasureSpec(measuredWidth, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(measuredHeight, MeasureSpec.EXACTLY));
        }
    }
}

:三个参数的构造方法里面可以不用写我上面贴的代码,反正也没用到。。。。

 

使用

比如高占宽的一半:设置宽度=具体值,match_parent,wrap_centent都行,然后设置比例 heightScale=0.5就行了  

    <com.ts_xiaoa.tsxiaoa_lib.widget.ScaleImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#ff0000"
        android:src="@mipmap/ic_launcher"
        app:heightScale="0.5f" />

 

运行效果

懒得截图。。。。。

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值