Tal*_*alL 76
我实现了FixedAspectRatioFrameLayout,所以我可以重用它并让任何托管视图具有固定的宽高比:
public class FixedAspectRatioFrameLayout extends FrameLayout
{
private int mAspectRatioWidth;
private int mAspectRatioHeight;
public FixedAspectRatioFrameLayout(Context context)
{
super(context);
}
public FixedAspectRatioFrameLayout(Context context, AttributeSet attrs)
{
super(context, attrs);
init(context, attrs);
}
public FixedAspectRatioFrameLayout(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs)
{
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FixedAspectRatioFrameLayout);
mAspectRatioWidth = a.getInt(R.styleable.FixedAspectRatioFrameLayout_aspectRatioWidth, 4);
mAspectRatioHeight = a.getInt(R.styleable.FixedAspectRatioFrameLayout_aspectRatioHeight, 3);
a.recycle();
}
// **overrides**
@Override protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)
{
int originalWidth = MeasureSpec.getSize(widthMeasureSpec);
int originalHeight = MeasureSpec.getSize(heightMeasureSpec);
int calculatedHeight = originalWidth * mAspectRatioHeight / mAspectRatioWidth;
int finalWidth, finalHeight;
if (calculatedHeight > originalHeight)
{
finalWidth = originalHeight * mAspectRatioWidth / mAspectRatioHeight;
finalHeight = originalHeight;
}
else
{
finalWidth = originalWidth;
finalHeight = calculatedHeight;
}
super.onMeasure(
MeasureSpec.makeMeasureSpec(finalWidth, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(finalHeight, MeasureSpec.EXACTLY));
}
}
Run Code Online (Sandbox Code Playgroud)
Sha*_*hiM 38
对于新用户,这是一个更好的非代码解决方案:
Android SDK v22中 提供了一个名为Percent Support Library的新支持库(MinAPI是7我认为,不确定):
src:android-developers.blogspot.in
百分比支持库提供基于百分比的维度和边距,以及此版本的新功能,可以通过app:aspectRatio设置自定义宽高比.通过仅设置单个宽度或高度并使用aspectRatio,PercentFrameLayout或PercentRelativeLayout将自动调整其他维度,以便布局使用设置的宽高比.
要包含将此添加到build.gradle:
compile 'com.android.support:percent:23.1.1'
Run Code Online (Sandbox Code Playgroud)
现在换了你的观点(即需要是方形的)PercentRelativeLayout
/ PercentFrameLayout
:
<android.support.percent.PercentRelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
app:layout_aspectRatio="100%"
app:layout_widthPercent="100%"/>
</android.support.percent.PercentRelativeLayout>
Run Code Online (Sandbox Code Playgroud)
你可以在这里看到一个例子.
Eug*_*sov 20
为了不使用第三方解决方案并考虑到在26.0.0中不推荐使用PercentFrameLayout和PercentRelativeLayout这一事实,我建议您考虑使用ConstraintLayout作为网格项的根布局.
你item_grid.xml
可能看起来像:
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/imageview_item"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintDimensionRatio="H,1:1" />
</android.support.constraint.ConstraintLayout>
Run Code Online (Sandbox Code Playgroud)
结果你得到这样的东西:
我最近为这个问题做了一个帮助类,并写了一篇关于它的博客文章.
代码的内容如下:
/**
* Measure with a specific aspect ratio<br />
* <br />
* @param widthMeasureSpec The width <tt>MeasureSpec</tt> passed in your <tt>View.onMeasure()</tt> method
* @param heightMeasureSpec The height <tt>MeasureSpec</tt> passed in your <tt>View.onMeasure()</tt> method
* @param aspectRatio The aspect ratio to calculate measurements in respect to
*/
public void measure(int widthMeasureSpec, int heightMeasureSpec, double aspectRatio) {
int widthMode = MeasureSpec.getMode( widthMeasureSpec );
int widthSize = widthMode == MeasureSpec.UNSPECIFIED ? Integer.MAX_VALUE : MeasureSpec.getSize( widthMeasureSpec );
int heightMode = MeasureSpec.getMode( heightMeasureSpec );
int heightSize = heightMode == MeasureSpec.UNSPECIFIED ? Integer.MAX_VALUE : MeasureSpec.getSize( heightMeasureSpec );
if ( heightMode == MeasureSpec.EXACTLY && widthMode == MeasureSpec.EXACTLY ) {
/*
* Possibility 1: Both width and height fixed
*/
measuredWidth = widthSize;
measuredHeight = heightSize;
} else if ( heightMode == MeasureSpec.EXACTLY ) {
/*
* Possibility 2: Width dynamic, height fixed
*/
measuredWidth = (int) Math.min( widthSize, heightSize * aspectRatio );
measuredHeight = (int) (measuredWidth / aspectRatio);
} else if ( widthMode == MeasureSpec.EXACTLY ) {
/*
* Possibility 3: Width fixed, height dynamic
*/
measuredHeight = (int) Math.min( heightSize, widthSize / aspectRatio );
measuredWidth = (int) (measuredHeight * aspectRatio);
} else {
/*
* Possibility 4: Both width and height dynamic
*/
if ( widthSize > heightSize * aspectRatio ) {
measuredHeight = heightSize;
measuredWidth = (int)( measuredHeight * aspectRatio );
} else {
measuredWidth = widthSize;
measuredHeight = (int) (measuredWidth / aspectRatio);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我使用TalL的答案创建了一个布局库。随意使用它。
将此添加到文件的顶部
repositories {
maven {
url "http://dl.bintray.com/riteshakya037/maven"
}
}
dependencies {
compile 'com.ritesh:ratiolayout:1.0.0'
}
Run Code Online (Sandbox Code Playgroud)
在布局中的根视图上定义“app”命名空间
xmlns:app="http://schemas.android.com/apk/res-auto"
Run Code Online (Sandbox Code Playgroud)
在您的布局中包含此库
<com.ritesh.ratiolayout.RatioRelativeLayout
android:id="@+id/activity_main_ratio_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:fixed_attribute="WIDTH" // Fix one side of the layout
app:horizontal_ratio="2" // ratio of 2:3
app:vertical_ratio="3">
Run Code Online (Sandbox Code Playgroud)
随着ConstraintLayout 的引入,您不必编写一行代码或使用第三方或依赖PercentFrameLayout
于 26.0.0 中已弃用的第三方。
以下是如何使用ConstraintLayout
以下命令为布局保持 1:1 纵横比的示例:
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginEnd="0dp"
android:layout_marginStart="0dp"
android:layout_marginTop="0dp"
android:background="@android:color/black"
app:layout_constraintDimensionRatio="H,1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</LinearLayout>
</android.support.constraint.ConstraintLayout>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
42372 次 |
最近记录: |