我有以下代码:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Test 1"
android:textSize="24sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Test 2"
android:textSize="24sp" />
</LinearLayout>
结果:
如何将View的高度与其宽度相等(由layout_weight
产生)?
答案 0 :(得分:7)
您必须覆盖onMeasure方法设置与高度相同的高度。请看这个问题:Simple way to do dynamic but square layout
这是我提出的完整解决方案:
SquareLinearLayout.java:
public class SquareLinearLayout extends LinearLayout {
public SquareLinearLayout(Context context) {
super(context);
}
public SquareLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquareLinearLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
int widthDesc = MeasureSpec.getMode(widthMeasureSpec);
int heightDesc = MeasureSpec.getMode(heightMeasureSpec);
int size = 0;
if (widthDesc == MeasureSpec.UNSPECIFIED
&& heightDesc == MeasureSpec.UNSPECIFIED) {
size = getContext().getResources().getDimensionPixelSize(R.dimen.default_size); // Use your own default size, for example 125dp
} else if ((widthDesc == MeasureSpec.UNSPECIFIED || heightDesc == MeasureSpec.UNSPECIFIED)
&& !(widthDesc == MeasureSpec.UNSPECIFIED && heightDesc == MeasureSpec.UNSPECIFIED)) {
//Only one of the dimensions has been specified so we choose the dimension that has a value (in the case of unspecified, the value assigned is 0)
size = width > height ? width : height;
} else {
//In all other cases both dimensions have been specified so we choose the smaller of the two
size = width > height ? height : width;
}
setMeasuredDimension(size, size);
}
}
activity_my.xml:
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:listitem="@layout/item"
tools:context=".MyActivity">
</ListView>
item.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent">
<com.appsrise.squarelinearlayout.SquareLinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@android:color/holo_blue_bright">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Test 1"
android:textSize="24sp" />
</com.appsrise.squarelinearlayout.SquareLinearLayout>
<com.appsrise.squarelinearlayout.SquareLinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@android:color/holo_green_light">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Test 2"
android:textSize="24sp" />
</com.appsrise.squarelinearlayout.SquareLinearLayout>
</LinearLayout>
MyActivity.java:
public class MyActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
ListView listView = (ListView) findViewById(R.id.listview);
listView.setAdapter(new BaseAdapter() {
private LayoutInflater mInflater = LayoutInflater.from(MyActivity.this);
@Override
public int getCount() {
return 100;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null)
convertView = mInflater.inflate(R.layout.item, parent, false);
return convertView;
}
});
}
}
答案 1 :(得分:6)
更简单的解决方案是在调用onMeasure
时将宽度测量规范传递到高度规范中(或者如果您希望高度确定方形大小,则将其传递给高度规范)。
import android.content.Context;
import android.util.AttributeSet;
import android.widget.LinearLayout;
public class SquareLinearLayout extends LinearLayout{
public SquareLinearLayout(Context context) {
super(context);
}
public SquareLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquareLinearLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
// or super.onMeasure(heightMeasureSpec, heightMeasureSpec);
}
}
答案 2 :(得分:1)
Xamarin版
[Register("SquareFrameLayout")]
public class SquareFrameLayout : LinearLayout
{
public SquareFrameLayout(Context context) : base(context)
{
}
public SquareFrameLayout(Context context, IAttributeSet attrs) : base(context, attrs)
{
}
public SquareFrameLayout(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
{
}
protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
var width = MeasureSpec.GetSize(widthMeasureSpec);
var height = MeasureSpec.GetSize(heightMeasureSpec);
var widthDesc = MeasureSpec.GetMode(widthMeasureSpec);
var heightDesc = MeasureSpec.GetMode(heightMeasureSpec);
if (widthDesc == MeasureSpecMode.Unspecified && heightDesc == MeasureSpecMode.Unspecified)
{
//size = Context.Resources.GetDimensionPixelSize(Resource.Dimension.default_size); // Use your own default size, for example 125dp
height = width = 0;
}
else if(heightDesc != MeasureSpecMode.Unspecified && widthDesc == MeasureSpecMode.Unspecified)
{
width = height;
}
else if (widthDesc != MeasureSpecMode.Unspecified && heightDesc == MeasureSpecMode.Unspecified)
{
height = width;
}
else
{
//In all other cases both dimensions have been specified so we choose the smaller of the two
var size = width > height ? height : width;
width = height = size;
}
SetMeasuredDimension(width, height);
}
和
[Register("SquareLinearLayout")]
public class SquareLinearLayout : LinearLayout
{
public SquareLinearLayout(Context context) : base(context)
{
}
public SquareLinearLayout(Context context, IAttributeSet attrs) : base(context, attrs)
{
}
public SquareLinearLayout(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
{
}
protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
var width = MeasureSpec.GetSize(widthMeasureSpec);
var height = MeasureSpec.GetSize(heightMeasureSpec);
var widthDesc = MeasureSpec.GetMode(widthMeasureSpec);
var heightDesc = MeasureSpec.GetMode(heightMeasureSpec);
if (widthDesc == MeasureSpecMode.Unspecified && heightDesc == MeasureSpecMode.Unspecified)
{
//size = Context.Resources.GetDimensionPixelSize(Resource.Dimension.default_size); // Use your own default size, for example 125dp
height = width = 0;
}
else if(heightDesc != MeasureSpecMode.Unspecified && widthDesc == MeasureSpecMode.Unspecified)
{
width = height;
}
else if (widthDesc != MeasureSpecMode.Unspecified && heightDesc == MeasureSpecMode.Unspecified)
{
height = width;
}
else
{
//In all other cases both dimensions have been specified so we choose the smaller of the two
var size = width > height ? height : width;
width = height = size;
}
SetMeasuredDimension(width, height);
}
}
答案 3 :(得分:0)
你也可以这样做,如果你只需要一个TextView需要是正方形:
ViewTreeObserver vto = textview.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
textview.getViewTreeObserver().removeGlobalOnLayoutListener(this);
int width = textview.getMeasuredWidth();
int height = textview.getMeasuredHeight();
ViewGroup.LayoutParams params = textview.getLayoutParams();
if (width > height)
params.height = width;
else
params.width = height;
textview.setLayoutParams(params);
}
});
答案 4 :(得分:-1)
您可以将LinearLayout
划分为两个相等的LinearLayout
,就像这样..
<LinearLayout android:orientation="horizontal" android:layout_height="fill_parent" android:layout_width="fill_parent">
<LinearLayout android:layout_weight="1" android:layout_height="fill_parent" android:layout_width="fill_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Test 1"
android:textSize="24sp" />
</LinearLayout>
<LinearLayout android:layout_weight="1" android:layout_height="fill_parent" android:layout_width="fill_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Test 1"
android:textSize="24sp" />
</LinearLayout>
</LinearLayout>
这会将LinearLayout
划分为两个相等的LinearLayouts
,其中每个LinearLayouts
都会包含TextView
s