/**
* 可以设置自身宽高比的ConstraintLayout。
* 宽高比的确定是根据横竖屏确定的,如果是横屏的话就根据高度和比例确定宽度,如果是竖屏就根据宽度和比例确定高度。
* 默认有点击缩放效果,可以设置是否有缩放效果。
*/
public class RatioConstraintLayout extends ConstraintLayout {
private boolean canScale;
private double mHeightRatio;
private double mWidthRatio;
public RatioConstraintLayout(Context context) {
this(context, null);
}
public RatioConstraintLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RatioConstraintLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.RatioConstraintLayout);
canScale = ta.getBoolean(R.styleable.RatioConstraintLayout_canScale, true);
String ratio = ta.getString(R.styleable.RatioConstraintLayout_wh_ratio);
if (!TextUtils.isEmpty(ratio)) {
String[] wh = ratio.split("\\:");
if (wh.length == 2) {
mWidthRatio = Double.valueOf(wh[0]);
mHeightRatio = Double.valueOf(wh[1]);
}
}
ta.recycle();
}
@Override
public ViewGroup.LayoutParams getLayoutParams() {
ViewGroup.LayoutParams layoutParams = super.getLayoutParams();
// //获取屏幕方向
// int orientation = getContext().getResources().getConfiguration().orientation;
// if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
// layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT;
// layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
// } else {
// layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
// layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
// }
return layoutParams;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getDefaultSize(0, widthMeasureSpec), getDefaultSize(0, heightMeasureSpec));
int[] specs = new int[2];
if (mWidthRatio == 0 || mHeightRatio == 0) {
specs[0] = widthMeasureSpec;
specs[1] = heightMeasureSpec;
}
//获取屏幕方向
int orientation = getContext().getResources().getConfiguration().orientation;
//根据横竖屏来确定宽高
//横屏
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
int measuredHeight = this.getMeasuredHeight();
int width = (int) (measuredHeight * (mWidthRatio / mHeightRatio));
specs[0] = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
specs[1] = heightMeasureSpec;
} else {
int measuredWidth = this.getMeasuredWidth();
int height = (int) (measuredWidth * (mHeightRatio / mWidthRatio));
specs[0] = widthMeasureSpec;
specs[1] = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
}
super.onMeasure(specs[0], specs[1]);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
startScalePress(this);
break;
case MotionEvent.ACTION_OUTSIDE:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
startScaleRelease(this);
break;
default:
break;
}
return super.onTouchEvent(event);
}
public static void startScale(View view, float scaleValue, float defaultScale, int duration) {
AnimatorSet animatorSet = new AnimatorSet();
ObjectAnimator animationScaleX = ObjectAnimator.ofFloat(view, "scaleX", scaleValue, defaultScale);
ObjectAnimator animationScaleY = ObjectAnimator.ofFloat(view, "scaleY", scaleValue, defaultScale);
animationScaleX.setDuration(duration);
animationScaleY.setDuration(duration);
animatorSet.playTogether(animationScaleX, animationScaleY);
animatorSet.start();
}
public static void startScalePress(View view) {
startScale(view, 1F, 0.92F, 250);
}
public static void startScaleRelease(View view) {
startScale(view, 0.92F, 1F, 250);
}
}
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--动画开关-->
<attr name="canScale" format="boolean" />
<!--宽高比-->
<attr name="wh_ratio" format="string" />
<declare-styleable name="RatioConstraintLayout">
<attr name="canScale" />
<attr name="wh_ratio" />
</declare-styleable>
</resources>
<com.kotlin.myapplication.RatioConstraintLayout xmlns:app="http://schemas.android.com/apk/res-auto"
<!--竖屏就根据宽度和比例确定高度-->
android:layout_width="@dimen/x200"
<!--横屏就根据高度和比例确定宽度-->
android:layout_height="@dimen/x500"
app:canScale="true"
app:wh_ratio="0.618:1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="MissingConstraints">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@color/colorAccent" />
</com.kotlin.myapplication.RatioConstraintLayout>
竖屏: