Android TableLayout Header Row
-
18-09-2019 - |
Pergunta
Ok, então eu tenho esse tablelayout e está cheio de dados - com todas as linhas adicionadas programaticamente. Eu tenho o tableLayout dentro de um HorizontalsCrollView, que por sua vez está dentro de um scrollView - isso me dá rolagem horizontal e verticalmente. O que estou tentando fazer agora é adicionar uma linha de cabeçalho a ele que não rolam. Eu tentei mover as coisas para que as duas visualizações de rolagem estivessem realmente dentro do tablelayout e adicionando os Tablerows ao HorizontalsCrollView; Minha esperança era poder adicionar a linha do cabeçalho fora das visualizações de rolagem.
A única outra coisa que consigo pensar é ter um layout da segunda tabela apenas para a linha do cabeçalho, mas fazer com que as colunas alinhem parecem que seria difícil. Alguma ideia?
Solução
Uma abordagem é incorporar um tablelayout na linha de outro tablelayout e colocando o cabeçalho na linha anterior, como visto abaixo. Alinhando os dados e o cabeçalho exige que a propriedade Layout_Width dos objetos de exibição do cabeçalho e os objetos de visualização dos dados sejam definidos com os mesmos valores de mergulho. Além disso, a propriedade Layout_Weight dos objetos de exibição do TableLayout interno deve corresponder ao cabeçalho correspondente. Agora, no XML abaixo, coloquei 3 visualizações de texto no tablelayout interno em uma única linha para combinar com os cabeçalhos da coluna. Isso é apenas para mostrar como o alinhamento pode ser feito. Você pode preencher esses dados programaticamente inflando um layout e adicionando -os em tempo de execução.
<?xml version="1.0" encoding="utf-8"?>
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TableRow>
<TextView android:text="Name"
android:layout_width="100dp"
android:layout_column="0"
android:layout_weight="1"/>
<TextView android:text="Score"
android:layout_width="30dp"
android:layout_column="1"
android:layout_weight="1">
</TextView>
<TextView android:text="Level"
android:layout_width="30dp"
android:layout_column="2"
android:layout_weight="1">
</TextView>
</TableRow>
<ScrollView android:layout_height="120dp">
<TableLayout android:id="@+id/score_table"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TableRow>
<TextView android:text="Al"
android:layout_width="100dp"
android:layout_column="0"
android:layout_weight="1">
</TextView>
<TextView android:text="1000"
android:layout_width="30dp"
android:layout_column="1"
android:layout_weight="1">
</TextView>
<TextView android:text="2"
android:layout_width="30dp"
android:layout_column="2"
android:layout_weight="1">
</TextView>
</TableRow>
</TableLayout>
</ScrollView>
</TableLayout>
Outras dicas
Na verdade, criei outra maneira decente de fazer isso.
Basta construir a tabela normalmente com a linha do cabeçalho como a primeira linha, dentro de uma orientação vertical linearlayout. Em seguida, remova programaticamente a primeira linha e adicione -a como o primeiro filho ao LinearLayout. Isso funcionou como um charme.
EDIT: Isso também funciona sem precisar especificar as larguras estáticas da coluna.
Eu sei que a pergunta é antiga, mas foi a primeira, que o Google me deu, pois tive o mesmo problema. E como acho que encontrei uma solução melhor, gostaria de compartilhá -la.
IDEIA: Coloque o tableLayout (dentro do scrollView) no RelativeLayout e crie uma sobreposição, que atrairia a primeira linha (cabeçalho) sobre todo o resto.
Aqui está Layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/table_wrapper"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:ignore="UselessParent"
>
<TableLayout
android:id="@+id/table"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</ScrollView>
</RelativeLayout>
E aqui está o código:
TableLayout table = (TableLayout)view.findViewById(R.id.table);
final TableRow headerRow = new TableRow(context);
table.addView(headerRow);
table.addView(new TableRow(context));
table.addView(new TableRow(context));
table.addView(new TableRow(context));
RelativeLayout tableWrapper = (RelativeLayout)view.findViewById(R.id.table_wrapper);
View fakeHeaderView = new View(context) {
@Override
public void draw(Canvas canvas) {
headerRow.draw(canvas);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = headerRow.getMeasuredWidth();
int height = headerRow.getMeasuredHeight();
widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
};
tableWrapper.addView(fakeHeaderView);
Para aqueles que não estão felizes em ter que predefinir seus tamanhos, encontrei um hack que está funcionando para mim.
Basicamente, faça uma tabela separada para o título e coloque -a sobre sua tabela principal, mas com o mesmo alinhamento superior, crie duas cópias da linha do título e depois de adicionar uma à tabela principal, adicione a outra à tabela de título e defina A LayoutParams da Visualização da criança para a linha forma a tabela principal.
Aqui está o meu exemplo básico.
em seu layout:
<HorizontalScrollView
android:id="@+id/table_horizontal_scroll_view"
android:layout_alignParentTop="true"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:clickable="false">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<ScrollView
android:layout_alignParentTop="true"
android:layout_marginTop="0dp"
android:id="@+id/table_vertical_scroll_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/grid_table_layout"
/>
</ScrollView>
<TableLayout
android:layout_alignLeft="@+id/table_vertical_scroll_view"
android:layout_alignRight="@+id/table_vertical_scroll_view"
android:layout_alignStart="@+id/table_vertical_scroll_view"
android:layout_alignEnd="@+id/table_vertical_scroll_view"
android:layout_alignParentTop="true"
android:background="@color/grid_view_background"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/grid_floating_row_layout"
/>
</RelativeLayout>
</HorizontalScrollView>
Então, quando você adiciona suas linhas:
//clear out any views
tableLayout.removeAllViews();
floatingRowLayout.removeAllViews();
TableRow[] rows = getTableContentRows() // content of your table
TableRow[] titleRows = {getTitleRow(), getTitleRow()}; //two copies of your title row
tableLayout.addView(titleRows[0]); // first add the first title to the main table
addRows(rows) // add any other rows
floatingRowLayout.addView(titleRows[1]); // floatingRowLayout is connected to id/grid_floating_row_layout
titleRows[0].setVisibility(View.INVISIBLE); // make the title row added to the main table invisible
// Set the layoutParams of the two title rows equal to each other.
// Since this is done after the first is added to the main table, they should be the correct sizes.
for(int i = 0; i < titleRows[0].getChildCount(); i++) {
titleRows[1].getChildAt(i).setLayoutParams(titleRows[0].getChildAt(i).getLayoutParams());
}
Use dois tablelayout um em ScrollView como dar android:stretchColumns="*"
<RelativeLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:paddingTop="5dp"
android:layout_height="match_parent"
android:layout_below="@+id/llSpinner">
<TableLayout
android:layout_width="match_parent"
android:id="@+id/tableHead"
android:stretchColumns="*"
android:layout_height="wrap_content">
</TableLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/tableTotal"
android:layout_below="@+id/tableHead"
android:id="@+id/scrolltable">
</ScrollView>
<TableLayout
android:layout_width="match_parent"
android:id="@+id/tableTotal"
android:stretchColumns="*"
android:layout_alignParentBottom="true"
android:layout_height="wrap_content">
</TableLayout>
</RelativeLayout>
Em seguida, crie uma visão comum para linhas e menção mais importante android:layout_width="0dp"
<TableRow
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:focusable="true"
android:focusableInTouchMode="false"
android:clickable="true"
android:background="@android:drawable/list_selector_background">
<TextView
android:text="S.No"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/tbsNo"
android:layout_weight="1"
android:gravity="center"
android:layout_column="1" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Date"
android:layout_weight="1"
android:gravity="center"
android:id="@+id/tbDate"
android:layout_column="2" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Count"
android:layout_weight="1"
android:gravity="center"
android:id="@+id/tbMrCount"
android:layout_column="3" />
</TableRow>
Agora em atividade
Tablelayout tableHeading =(TableLayout)findViewById(R.id.tableHead);
Tablelayout table =(TableLayout) findViewById(R.id.table_repots);
trHeading = (TableRow) getLayoutInflater().inflate(R.layout.table_row_item, null);
trHeading.setBackgroundColor(Color.parseColor("#6688AC"));
trHeading.setPadding(0,10,0,10);
TextView tv;
tv = (TextView) trHeading.findViewById(R.id.tbsNo);
tv.setText("S.No");
tv = (TextView) trHeading.findViewById(R.id.tbDate);
tv.setText("Date");
table.addView(tv);