我编写了一个自定义ViewGroup,以矩阵样式组织子视图(垂直和水平间隔相等)。但我有一个让我发疯的问题。视图组正确绘制了第一个级别的子级,但每个子视图都是不可见的。
这是布局代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:matrix="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.vincejin.timekiller.viewgroups.MatrixLayout
android:id="@+id/matrix"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#efefef"
matrix:ml_columns="2"
matrix:ml_horizontal_space="5dp"
matrix:ml_square="true"
matrix:ml_vertical_space="5dp" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#628465" >
<TextView
android:id="@+id/txv_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/text_default" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#763965" >
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#872438" >
</LinearLayout>
</com.vincejin.timekiller.viewgroups.MatrixLayout>
</LinearLayout>
结果就是这个
http://i40.tinypic.com/256tsw1.png
正如您所看到的,第一个布局内部有一个textview但未显示...
以下是viewgroup的代码
代码:
package com.vincejin.timekiller.viewgroups;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import com.vincejin.timekiller.R;
public class MatrixLayout extends ViewGroup {
private boolean square;
private int columns ;
private int horizontalSpace ;
private int verticalSpace;
private int cellHeight;
private int cellWidth;
public MatrixLayout(Context context) {
super(context);
}
public MatrixLayout(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.MatrixLayout);
square = arr.getBoolean(R.styleable.MatrixLayout_ml_square,false);
columns = arr.getInteger(R.styleable.MatrixLayout_ml_columns, 4);
horizontalSpace = arr.getDimensionPixelSize(R.styleable.MatrixLayout_ml_horizontal_space, 3);
verticalSpace = arr.getDimensionPixelSize(R.styleable.MatrixLayout_ml_vertical_space, 3);
arr.recycle();
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
adjustChildren(l, t, r, b);
}
private void adjustChildren(int l, int t, int r, int b) {
int count = getChildCount();
int gone = 0;
for (int i = 0; i < count; i++) {
View currentChild = getChildAt(i);
if (currentChild.getVisibility() == View.GONE) {
gone++;
return;
}
Rect currentCellPosition = calculatePositionOf(l,t,r,b,coordinatesFromIndex(i
- gone));
currentChild.layout(
currentCellPosition.left,
currentCellPosition.top,
currentCellPosition.right,
currentCellPosition.bottom);
}
}
private Rect calculatePositionOf(int parentLeft, int parentTop, int parentRight, int parentBottom, int[] coordinates) {
int row = coordinates[0];
int col = coordinates[1];
Rect result = new Rect();
result.left = parentLeft + (col * (cellWidth + horizontalSpace));
result.right = result.left + cellWidth;
result.top = parentTop + (row * (cellHeight + verticalSpace));
result.bottom = result.top + cellHeight;
return result;
}
private int[] coordinatesFromIndex(int index) {
int[] result = new int[2];
result[0] = index / columns;
result[1] = index % columns;
return result;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int w = MeasureSpec.getSize(widthMeasureSpec);
int h = MeasureSpec.getSize(heightMeasureSpec);
if (square) {
w = Math.min(w, h);
h = Math.min(w, h);
}
// Cell size calculus
int rows = getRowsCount();
cellWidth = (w / (columns)) ;
if(rows==0)
cellHeight = 0;
else
cellHeight = (h/ rows) ;
setMeasuredDimension(w, h);
}
private int getRowsCount() {
int childCount = getChildCount();
int gone = 0;
for (int i = 0; i < childCount; i++)
if (getChildAt(i).getVisibility() == View.GONE)
gone++;
if((childCount-gone)%columns==0)
return (childCount - gone) / columns;
return ((childCount - gone) / columns) + 1;
}
public boolean isSquare() {
return square;
}
public void setSquare(boolean square) {
this.square = square;
}
public int getColumns() {
return columns;
}
public void setColumns(int columns) {
this.columns = columns;
}
}
这是可设置的
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MatrixLayout">
<attr name="ml_columns" format="integer" />
<attr name="ml_square" format="boolean" />
<attr name="ml_vertical_space" format="dimension" />
<attr name="ml_horizontal_space" format="dimension" />
</declare-styleable>
</resources>
答案 0 :(得分:0)
我在 pskink 的帮助下解决了。 有必要在onMeasure方法中测量每个子节点,所以我在方法的末尾添加了以下行。
cellWidthMeasure = MeasureSpec.makeMeasureSpec(cellWidth, MeasureSpec.EXACTLY);
cellHeightMeausure = MeasureSpec.makeMeasureSpec(cellHeight, MeasureSpec.EXACTLY);
int childCount = getChildCount();
for(int i=0;i<childCount;i++){
View child= getChildAt(i);
if(child.getVisibility()!=View.GONE)
child.measure(cellWidthMeasure,cellHeightMeausure);
}