這裏是SimpleListView
類的實現。我知道這是低效的,我很確定它包含錯誤,但它顯示瞭如何測量列表視圖的寬度。我也建議您閱讀this article。
public class SimpleListView extends AdapterView<ListAdapter> {
private ListAdapter adapter;
private Drawable divider;
private int dividerHeight;
private boolean clipDivider;
public SimpleListView(final Context context)
{
this(context, null);
}
public SimpleListView(final Context context, final AttributeSet attrs)
{
this(context, attrs, android.R.attr.listViewStyle);
}
public SimpleListView(final Context context, final AttributeSet attrs, final int defStyle)
{
super(context, attrs, defStyle);
final TypedArray array =
context.obtainStyledAttributes(attrs, R.styleable.SimpleListView, defStyle, 0);
final Drawable dividerAttribute =
array.getDrawable(R.styleable.SimpleListView_android_divider);
if(dividerAttribute != null) {
setDivider(dividerAttribute);
}
final int dividerHeightAttribute =
array.getDimensionPixelSize(R.styleable.SimpleListView_android_dividerHeight, 0);
if(dividerHeightAttribute != 0) {
setDividerHeight(dividerHeightAttribute);
}
array.recycle();
}
public Drawable getDivider()
{
return this.divider;
}
public void setDivider(final Drawable newDivider)
{
if(newDivider != null) {
this.dividerHeight = newDivider.getIntrinsicHeight();
this.clipDivider = newDivider instanceof ColorDrawable;
} else {
this.dividerHeight = 0;
this.clipDivider = false;
}
this.divider = newDivider;
requestLayout();
}
public int getDividerHeight()
{
return this.dividerHeight;
}
public void setDividerHeight(final int newHeight)
{
this.dividerHeight = newHeight;
requestLayout();
}
@Override
public ListAdapter getAdapter()
{
return this.adapter;
}
@Override
public void setAdapter(final ListAdapter adapter)
{
this.adapter = adapter;
removeAllViewsInLayout();
requestLayout();
}
@Override
public View getSelectedView()
{
throw new UnsupportedOperationException(
"SimpleListView.getSelectedView() is not supported");
}
@Override
public void setSelection(final int position)
{
throw new UnsupportedOperationException(
"SimpleListView.setSelection(int) is not supported");
}
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int innerWidth = 0;
int innerHeight = 0;
final int itemCount = this.adapter == null ? 0 : this.adapter.getCount();
if(itemCount > 0
&& (widthMode != MeasureSpec.EXACTLY || heightMode != MeasureSpec.EXACTLY)) {
for(int i = 0; i < itemCount; ++i) {
final View convertView = getChildAt(i);
final View child = this.adapter.getView(i, convertView, this);
if(convertView == null) {
LayoutParams params = child.getLayoutParams();
if(params == null) {
params = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
child.setLayoutParams(params);
}
addViewInLayout(child, i, params);
}
if(child.getLayoutParams() instanceof MarginLayoutParams) {
measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
} else {
measureChild(child, widthMeasureSpec, heightMeasureSpec);
}
innerWidth = Math.max(innerWidth, child.getMeasuredWidth());
innerHeight += child.getMeasuredHeight();
}
innerHeight += (itemCount - 1) * this.dividerHeight;
}
if(widthMode != MeasureSpec.EXACTLY) {
final int newWidthSize = getPaddingLeft() + getPaddingRight() + innerWidth;
widthSize =
widthMode == MeasureSpec.AT_MOST ? Math.min(widthSize, newWidthSize)
: newWidthSize;
}
if(heightMode != MeasureSpec.EXACTLY) {
final int newHeightSize = getPaddingTop() + getPaddingBottom() + innerHeight;
heightSize =
heightMode == MeasureSpec.AT_MOST ? Math.min(heightSize, newHeightSize)
: newHeightSize;
}
setMeasuredDimension(widthSize, heightSize);
}
@Override
protected void onLayout(final boolean changed, final int left, final int top, final int right,
final int bottom)
{
super.onLayout(changed, left, top, right, bottom);
if(this.adapter == null) {
return;
}
positionItems();
invalidate();
}
private void positionItems()
{
int top = getPaddingTop();
final int left = getPaddingLeft();
for(int i = 0, count = getChildCount(); i < count; ++i) {
final View child = getChildAt(i);
final int width = child.getMeasuredWidth();
final int height = child.getMeasuredHeight();
child.layout(left, top, left + width, top + height);
top += height + this.dividerHeight;
}
}
@Override
protected void dispatchDraw(final Canvas canvas)
{
final boolean drawDividers = this.dividerHeight > 0 && this.divider != null;
if(drawDividers) {
final int left = getPaddingLeft();
final int right = getWidth() - getPaddingRight();
final Rect dividerBounds = new Rect(left, 0, right, 0);
for(int i = 0, count = getChildCount(); i < count - 1; ++i) {
final View child = getChildAt(i);
dividerBounds.top = dividerBounds.bottom + child.getMeasuredHeight();
dividerBounds.bottom = dividerBounds.top + this.dividerHeight;
drawDivider(canvas, dividerBounds);
}
}
super.dispatchDraw(canvas);
}
private void drawDivider(final Canvas canvas, final Rect bounds)
{
if(!this.clipDivider) {
this.divider.setBounds(bounds);
} else {
canvas.save();
canvas.clipRect(bounds);
}
this.divider.draw(canvas);
if(this.clipDivider) {
canvas.restore();
}
}
}
感謝分享! – shiami 2010-12-01 02:26:14
我寫了一個'SimpleListView'類來擴展'AdapterView'類。它的性能很差,但可以根據其子女的寬度改變其寬度。如果你願意,我可以分享源代碼。 – Michael 2010-12-01 19:06:55
小精靈,你能分享你的答案嗎 – pengwang 2010-12-02 06:45:15