проблемы с добавлением TableRow динамически против getMeasuredHeight / getHeight - PullRequest
3 голосов
/ 24 февраля 2010

У меня проблема.

Я хочу динамически добавлять строки в TableLayout. При добавлении этих строк мне нужно иметь возможность получить размер представления, поэтому я пытаюсь выполнить это во время onSizeChanged(), но новые строки не отображаются. Поэтому я попытался onFinishInflate(), но у меня нет доступа к размеру (getMeasuredHeight returns 0).

Вывод следующих кодов показывает две строки initial row + onFinishInflate getMeasuredHeight=0. Но если я использую просмотрщик иерархии из SDK и нажимаю load view hierarchy, тогда я неожиданно вижу в эмуляторе 3 строки initial row + onFinishInflate getMeasuredHeight=0 + onSizeChanged getMeasuredHeight=270!

Примечание: это использует эмулятор 2.1 hvga landscape, код, созданный с последний sdk, таргетинг на android1.5.


<?xml version="1.0" encoding="utf-8"?>
<com.steelbytes.android.TableHeightTest.TestLinLay 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <TableLayout
        android:id="@+id/table1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
        <TableRow
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                >
                <TextView
                    android:text="initial row"
                />
            </TableRow>
        </TableLayout>
</com.steelbytes.android.TableHeightTest.TestLinLay>

package com.steelbytes.android.TableHeightTest;

import android.app.Activity;
import android.os.Bundle;

public class TableHeightTest extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

package com.steelbytes.android.TableHeightTest;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.LinearLayout;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

public class TestLinLay extends LinearLayout
{
 Context mContext;

 public TestLinLay(Context context, AttributeSet attrs)
 {
  super(context, attrs);
  mContext = context;
 }

    private void addRow(String funcName)
    {
        TableLayout tl = (TableLayout)findViewById(R.id.table1);
        TableRow tr = new TableRow(mContext);
        TextView tv = new TextView(mContext);
        tv.setText(funcName+" getMeasuredHeight="+tl.getMeasuredHeight());
        tr.addView(tv);
        tl.addView(tr);
    }

    @Override
    protected void onFinishInflate()
    {
        super.onFinishInflate();
        addRow("onFinishInflate");
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh)
    {
        super.onSizeChanged(w,h,oldw,oldh);
        addRow("onSizeChanged");
    }
}

Ответы [ 2 ]

1 голос
/ 22 ноября 2011

У меня была такая же проблема. В конце концов я наткнулся на следующее «правило»: Вы не можете / не должны requestLayout () во время «прохода макета» (onSizeChanged ()), правильный способ сделать это - «опубликовать Runnable», чтобы сделать это чуть позже. Вот мой код, который я использую, когда заканчивается переопределение onSizeChanged () (я изменил размеры всех своих кнопок)

// Note: 'posting a Runnable' is required to call requestLayout(),
// not supposed to call requestLayout() during a 
// layout pass (onSizeChanged())
private Handler handler;        // for posting request(s)

(In constructor code)
{
    handler = new Handler();
}

/*
 * Post request to run a loop requesting button layout so
 * the buttons will be drawn using their new size.
 */
private void postLayoutRequest() {
handler.post(new Runnable() {
    @Override public void run() {
    for(int i = BTN_BASE_ID; i <= TOP_BUTTON_ID; ++i) {
            ButtonEx btn = (ButtonEx)findViewById(i);
            btn.requestLayout();
        }
    }
});
}
1 голос
/ 14 января 2011

Хорошо бы получить измеренную высоту, вызвав View.measure (int widthMeasureSpec, int heightMeasureSpec) (http://developer.android.com/reference/android/view/View.html#measure%28int,%20int%29) до вызова getMeasuredWidth / getMeasuredHeight.

...