如何制作方形框架布局?
How to make a Square Frame Layout?
我尝试通过扩展 android.widget.FrameLayout 来制作自定义 MySquareFrame class 并通过传递自定义宽度和高度来覆盖 onMeasure 方法。
public class MySquareFrame extends FrameLayout {
public MySquareFrame(Context context) {
super(context);
}
public MySquareFrame(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MySquareFrame(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public MySquareFrame(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
int size = width > height ? height : width;
setMeasuredDimension(size, size);
}
}
并在 xml 中像这样使用它
<com.example.akash.view.MySquareFrame
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background3">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/fuel_meter"
android:rotation="120"
/>
<com.triggertrap.seekarc.SeekArc
android:id="@+id/seekArc"
android:layout_width="match_parent"
android:layout_height="match_parent"
seekarc:max="120"
android:padding="70dp"
seekarc:rotation="180"
seekarc:startAngle="30"
seekarc:sweepAngle="300"
seekarc:touchInside="false"
seekarc:clockwise="false"
seekarc:thumb="@drawable/nob" />
</com.example.akash.view.MySquareFrame>
以及我得到的
所以我希望 MySquareFrame class 在 xml 中查看 Square。请帮忙..
--------------------更新------------------------ -
DisplayMetrics displaymetrics = new DisplayMetrics();
((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int width = displaymetrics.widthPixels;
int size = width > height ? height : width;
setMeasuredDimension(size, size);
这帮助我根据屏幕尺寸获得方形框架。
查看 SquareLayout,一个 Android 库 ,它为不同的布局提供了一个包装器 class,在不丢失任何尺寸的情况下渲染它们的方形尺寸核心功能。
尺寸是在渲染布局之前计算的,因此一旦获得视图就没有重新渲染或任何类似的调整。
要使用图书馆,请将其添加到您的 build.gradle:
repositories {
maven {
url "https://maven.google.com"
}
}
dependencies {
compile 'com.github.kaushikthedeveloper:squarelayout:0.0.3'
}
您可以从 android 开发者网站查看 SquareFrameLayout
的实现:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthSize == 0 && heightSize == 0) {
// If there are no constraints on size, let FrameLayout measure
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// Now use the smallest of the measured dimensions for both dimensions
final int minSize = Math.min(getMeasuredWidth(), getMeasuredHeight());
setMeasuredDimension(minSize, minSize);
return;
}
final int size;
if (widthSize == 0 || heightSize == 0) {
// If one of the dimensions has no restriction on size, set both dimensions to be the
// on that does
size = Math.max(widthSize, heightSize);
} else {
// Both dimensions have restrictions on size, set both dimensions to be the
// smallest of the two
size = Math.min(widthSize, heightSize);
}
final int newMeasureSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
super.onMeasure(newMeasureSpec, newMeasureSpec);
}
我找到了很多 "reduced" 解决方案。如下创建您自己的 OneOneFrameLayout,然后将此 FrameLayout 添加到您的 xml:
public class OneOneFrameLayout extends FrameLayout {
public OneOneFrameLayout(@NonNull Context context) {
super(context);
}
public OneOneFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public OneOneFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public OneOneFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int snHeight = MeasureSpec.getSize(widthMeasureSpec);
int snHeightSpec = MeasureSpec.makeMeasureSpec(snHeight, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, snHeightSpec);
}
}
为了使用 GridLayoutManager
获得正方形视图,Koopa 有一个很好的答案,但您已经有了 widthMeasureSpec
。
宽度很重要,然后让高度与宽度相匹配:
package com.my.package;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class SquareFrameLayout extends FrameLayout {
public SquareFrameLayout(@NonNull Context context) {
super(context);
}
public SquareFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public SquareFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec); //<-- Width + Width...
}
}
只需在xml布局文件中使用即可:
<?xml version="1.0" encoding="utf-8"?>
<com.my.package.SquareFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center">
//<!--Views..-->
</com.my.package.SquareFrameLayout>
我尝试通过扩展 android.widget.FrameLayout 来制作自定义 MySquareFrame class 并通过传递自定义宽度和高度来覆盖 onMeasure 方法。
public class MySquareFrame extends FrameLayout {
public MySquareFrame(Context context) {
super(context);
}
public MySquareFrame(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MySquareFrame(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public MySquareFrame(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
int size = width > height ? height : width;
setMeasuredDimension(size, size);
}
}
并在 xml 中像这样使用它
<com.example.akash.view.MySquareFrame
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background3">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/fuel_meter"
android:rotation="120"
/>
<com.triggertrap.seekarc.SeekArc
android:id="@+id/seekArc"
android:layout_width="match_parent"
android:layout_height="match_parent"
seekarc:max="120"
android:padding="70dp"
seekarc:rotation="180"
seekarc:startAngle="30"
seekarc:sweepAngle="300"
seekarc:touchInside="false"
seekarc:clockwise="false"
seekarc:thumb="@drawable/nob" />
</com.example.akash.view.MySquareFrame>
以及我得到的
所以我希望 MySquareFrame class 在 xml 中查看 Square。请帮忙..
--------------------更新------------------------ -
DisplayMetrics displaymetrics = new DisplayMetrics();
((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int width = displaymetrics.widthPixels;
int size = width > height ? height : width;
setMeasuredDimension(size, size);
这帮助我根据屏幕尺寸获得方形框架。
查看 SquareLayout,一个 Android 库 ,它为不同的布局提供了一个包装器 class,在不丢失任何尺寸的情况下渲染它们的方形尺寸核心功能。
尺寸是在渲染布局之前计算的,因此一旦获得视图就没有重新渲染或任何类似的调整。
要使用图书馆,请将其添加到您的 build.gradle:
repositories {
maven {
url "https://maven.google.com"
}
}
dependencies {
compile 'com.github.kaushikthedeveloper:squarelayout:0.0.3'
}
您可以从 android 开发者网站查看 SquareFrameLayout
的实现:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthSize == 0 && heightSize == 0) {
// If there are no constraints on size, let FrameLayout measure
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// Now use the smallest of the measured dimensions for both dimensions
final int minSize = Math.min(getMeasuredWidth(), getMeasuredHeight());
setMeasuredDimension(minSize, minSize);
return;
}
final int size;
if (widthSize == 0 || heightSize == 0) {
// If one of the dimensions has no restriction on size, set both dimensions to be the
// on that does
size = Math.max(widthSize, heightSize);
} else {
// Both dimensions have restrictions on size, set both dimensions to be the
// smallest of the two
size = Math.min(widthSize, heightSize);
}
final int newMeasureSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
super.onMeasure(newMeasureSpec, newMeasureSpec);
}
我找到了很多 "reduced" 解决方案。如下创建您自己的 OneOneFrameLayout,然后将此 FrameLayout 添加到您的 xml:
public class OneOneFrameLayout extends FrameLayout {
public OneOneFrameLayout(@NonNull Context context) {
super(context);
}
public OneOneFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public OneOneFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public OneOneFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int snHeight = MeasureSpec.getSize(widthMeasureSpec);
int snHeightSpec = MeasureSpec.makeMeasureSpec(snHeight, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, snHeightSpec);
}
}
为了使用 GridLayoutManager
获得正方形视图,Koopa 有一个很好的答案,但您已经有了 widthMeasureSpec
。
宽度很重要,然后让高度与宽度相匹配:
package com.my.package;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class SquareFrameLayout extends FrameLayout {
public SquareFrameLayout(@NonNull Context context) {
super(context);
}
public SquareFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public SquareFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec); //<-- Width + Width...
}
}
只需在xml布局文件中使用即可:
<?xml version="1.0" encoding="utf-8"?>
<com.my.package.SquareFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center">
//<!--Views..-->
</com.my.package.SquareFrameLayout>