Problemas com a adição de Tablerow dinamicamente vs getMeasuredHeight/GethEight
-
22-09-2019 - |
Pergunta
Eu tenho um problema.
Eu gostaria de adicionar linhas dinamicamente a um TableLayout
. Ao adicionar essas linhas, preciso obter o tamanho da vista, então tento executar isso durante onSizeChanged()
Mas as novas linhas não são exibidas. Então eu tentei onFinishInflate()
, mas então não tenho acesso ao tamanho (getMeasuredHeight returns 0)
.
A saída dos códigos a seguir mostra duas linhas initial row
+ onFinishInflate getMeasuredHeight=0
. Mas se eu usar o HierarchyViewer do SDK e pressione load view hierarchy
Então eu de repente vejo 3 linhas no emulador initial row
+ onFinishInflate getMeasuredHeight=0
+ onSizeChanged getMeasuredHeight=270
!.
Nota: Isso está usando o cenário do emulador 2.1 HVGA, código criado com o mais recente SDK, direcionando o 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");
}
}
Solução
Você teria bem a altura medida chamando a visualização.measure (int widthmeasurespec, int a altura -leasurespec) ( http://developer.android.com/reference/android/view/view.html#measure%28int ,%20int%29 ) Antes de ligar para o getMeasuredWidth/getMeasuredHeight.
Outras dicas
Eu tive o mesmo problema. Eventualmente, tropecei na seguinte "regra": você não pode/não deve solicitarLayout () durante um "passe de layout" (Onsizechanged ()), a maneira correta de fazê -lo é 'postar um executável' para fazê -lo um pouco mais tarde . Aqui está o meu código que eu uso quando meus acabamentos de substituição OnsizECHANGED () (eu redimensionei todos os meus botões)
// 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();
}
}
});
}