gridlayout - tablas dinamicas en android studio
¿Cómo puedo crear una tabla con bordes en Android? (16)
¿Qué hay sobre anular el método onDraw y luego pintar líneas en el lienzo?
for(int i = 0; i < rows; i++)
{
canvas.drawLine(0, i * m_cellHeight, m_totalWidth, i * m_cellHeight, paint);
}
for(int i = 0; i < m_columns; i++){
canvas.drawLine(i* m_cellWidth, 0, i * m_cellWidth, m_cellHeight * rows, paint);
}
Utilizo un diseño de tabla para mostrar datos como tabla, pero quiero una tabla con columnas definidas por el usuario y filas con bordes. Sugerencias?
Aquí hay una excelente manera de resolver este problema:
Crea un rectángulo dibujable con esquinas redondeadas como este:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<stroke android:width="2dp"
android:color="#888888"/>
<corners android:bottomRightRadius="6dp"
android:bottomLeftRadius="6dp"
android:topLeftRadius="6dp"
android:topRightRadius="6dp"/>
</shape>
guárdelo en la carpeta dibujable con el nombre rounded_border.xml
A continuación, cree un diseño relativo que use rounded_border como un fondo como este:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/rounded_border">
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
guárdelo en su carpeta de diseño y asígnele el nombre table_with_border.xml
luego, cada vez que necesite una tabla así, extráigala a una vista utilizando la sintaxis include como esta:
<include
android:id="@+id/rounded_table"
android:layout_width="match_parent"
android:layout_height="wrap_content"
layout="@layout/table_with_border" />
Probablemente desees agregar algo de espacio alrededor de los bordes, así que simplemente envuelve el include en LinearLayout y agrega algo de relleno alrededor de los bordes.
Manera simple y fácil de obtener un lindo borde alrededor de una mesa.
Creo que es mejor crear una imagen de 1px de nueve parches, y usar el atributo showDividers en TableRow y TableLayout ya que ambos son LinearLayouts
Después de una larga búsqueda y horas de prueba, este es el código más simple que podría hacer:
ShapeDrawable border = new ShapeDrawable(new RectShape());
border.getPaint().setStyle(Style.STROKE);
border.getPaint().setColor(Color.BLACK);
tv.setBackground(border);
content.addView(tv);
tv es una vista de texto con un texto simple y el contenido es mi contenedor (LinearLayout en este caso). Eso es un poco más fácil.
El trazo se duplica en las secciones medias, usé esta lista de capas dibujables:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:top="0dp" android:left="0dp" android:bottom="0dp" android:right="0dp">
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="@color/grey" />
</shape>
</item>
<item android:top="1dp" android:left="1dp" android:bottom="1dp" android:right="1dp">
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="@color/lightgrey" />
</shape>
</item>
</layer-list>
Lo que quería era una mesa como esta
Añadí esto en mi styles.xml :
<style name="Divider">
<item name="android:layout_width">1dip</item>
<item name="android:layout_height">match_parent</item>
<item name="android:background">@color/divider_color</item>
</style>
<style name="Divider_invisible">
<item name="android:layout_width">1dip</item>
<item name="android:layout_height">match_parent</item>
</style>
Luego en el diseño de mi mesa :
<TableLayout
android:id="@+id/table"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:stretchColumns="*" >
<TableRow
android:id="@+id/tableRow1"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:background="#92C94A" >
<TextView
android:id="@+id/textView11"
android:paddingBottom="10dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingTop="10dp" />
<LinearLayout
android:layout_width="1dp"
android:layout_height="match_parent" >
<View style="@style/Divider_invisible" />
</LinearLayout>
<TextView
android:id="@+id/textView12"
android:paddingBottom="10dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingTop="10dp"
android:text="@string/main_wo_colon"
android:textColor="@color/white"
android:textSize="16sp" />
<LinearLayout
android:layout_width="1dp"
android:layout_height="match_parent" >
<View style="@style/Divider" />
</LinearLayout>
<TextView
android:id="@+id/textView13"
android:paddingBottom="10dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingTop="10dp"
android:text="@string/side_wo_colon"
android:textColor="@color/white"
android:textSize="16sp" />
<LinearLayout
android:layout_width="1dp"
android:layout_height="match_parent" >
<View style="@style/Divider" />
</LinearLayout>
<TextView
android:id="@+id/textView14"
android:paddingBottom="10dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingTop="10dp"
android:text="@string/total"
android:textColor="@color/white"
android:textSize="16sp" />
</TableRow>
<!-- display this button in 3rd column via layout_column(zero based) -->
<TableRow
android:id="@+id/tableRow2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#6F9C33" >
<TextView
android:id="@+id/textView21"
android:padding="5dp"
android:text="@string/servings"
android:textColor="@color/white"
android:textSize="16sp" />
<LinearLayout
android:layout_width="1dp"
android:layout_height="match_parent" >
<View style="@style/Divider" />
</LinearLayout>
..........
.......
......
Mi solución para este problema es poner un recurso xml drawable en el campo de fondo de cada celda. De esta manera, podría definir una forma con el borde que desea para todas las celdas. El único inconveniente es que los límites de las celdas extremas tienen la mitad de ancho que los otros, pero no es un problema si la tabla ocupa toda la pantalla.
Un ejemplo:
drawable / cell_shape.xml
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape= "rectangle" >
<solid android:color="#000"/>
<stroke android:width="1dp" android:color="#ff9"/>
</shape>
layout / my_table.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TableRow
android:id="@+id/tabla_cabecera"
android:layout_width="match_parent"
android:layout_height="match_parent"></TableRow>
<TableLayout
android:id="@+id/tabla_cuerpo"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TableRow
android:id="@+id/tableRow1"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/cell_shape"
android:padding="5dp"
android:text="TextView"
android:textAppearance="?android:attr/textAppearanceMedium"></TextView>
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/cell_shape"
android:padding="5dp"
android:text="TextView"
android:textAppearance="?android:attr/textAppearanceMedium"></TextView>
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/cell_shape"
android:padding="5dp"
android:text="TextView"
android:textAppearance="?android:attr/textAppearanceMedium"></TextView>
</TableRow>
<TableRow
android:id="@+id/tableRow2"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/cell_shape"
android:padding="5dp"
android:text="TextView"
android:textAppearance="?android:attr/textAppearanceMedium"></TextView>
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/cell_shape"
android:padding="5dp"
android:text="TextView"
android:textAppearance="?android:attr/textAppearanceMedium"></TextView>
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/cell_shape"
android:padding="5dp"
android:text="TextView"
android:textAppearance="?android:attr/textAppearanceMedium"></TextView>
</TableRow>
<TableRow
android:id="@+id/tableRow3"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/cell_shape"
android:padding="5dp"
android:text="TextView"
android:textAppearance="?android:attr/textAppearanceMedium"></TextView>
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/cell_shape"
android:padding="5dp"
android:text="TextView"
android:textAppearance="?android:attr/textAppearanceMedium"></TextView>
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/cell_shape"
android:padding="5dp"
android:text="TextView"
android:textAppearance="?android:attr/textAppearanceMedium"></TextView>
</TableRow>
<TableRow
android:id="@+id/tableRow4"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/cell_shape"
android:padding="5dp"
android:text="TextView"
android:textAppearance="?android:attr/textAppearanceMedium"></TextView>
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/cell_shape"
android:padding="5dp"
android:text="TextView"
android:textAppearance="?android:attr/textAppearanceMedium"></TextView>
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/cell_shape"
android:padding="5dp"
android:text="TextView"
android:textAppearance="?android:attr/textAppearanceMedium"></TextView>
</TableRow>
</TableLayout>
</LinearLayout>
Editar: un ejemplo
Edit2: Otro ejemplo (con más elementos: esquinas del círculo, degradados ...)
He explicado este problema con más detalles en http://blog.intelligenia.com/2012/02/programacion-movil-en-android.html#more . Está en español, pero hay algunos códigos e imágenes de tablas más complejas.
Otra solución es usar diseños lineales y establecer divisores entre filas y celdas como esta:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="#8000"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
<View
android:layout_width="@dimen/border"
android:layout_height="match_parent"
android:background="#8000"
android:layout_marginTop="1px"
android:layout_marginBottom="1px"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
></LinearLayout>
<View
android:layout_width="@dimen/border"
android:layout_height="match_parent"
android:background="#8000"
android:layout_marginTop="1px"
android:layout_marginBottom="1px"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"></LinearLayout>
<View
android:layout_width="@dimen/border"
android:layout_height="match_parent"
android:background="#8000"
android:layout_marginTop="1px"
android:layout_marginBottom="1px"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="#8000"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
<View
android:layout_width="@dimen/border"
android:layout_height="match_parent"
android:background="#8000"
android:layout_marginTop="1px"
android:layout_marginBottom="1px"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
></LinearLayout>
<View
android:layout_width="@dimen/border"
android:layout_height="match_parent"
android:background="#8000"
android:layout_marginTop="1px"
android:layout_marginBottom="1px"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"></LinearLayout>
<View
android:layout_width="@dimen/border"
android:layout_height="match_parent"
android:background="#8000"
android:layout_marginTop="1px"
android:layout_marginBottom="1px"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="#8000"/>
</LinearLayout>
Es una solución sucia, pero es simple y también funciona con fondos y bordes transparentes.
Para hacer un borde de colapso de 1dp alrededor de cada celda sin escribir un código java y sin crear otro diseño xml con la etiqueta <shape...>
, puedes probar esta solución:
En <TableLayout...>
add android:background="#CCC"
y android:paddingTop="1dp"
y android:stretchColumns="0"
En <TableRow...>
add android:background="#CCC"
y android:paddingBottom="1dp"
y android:paddingRight="1dp"
En cada célula / niño en TableRow, es decir, <TextView...>
add android:background="#FFF"
y android:layout_marginLeft="1dp"
Es muy importante seguir los rellenos y los márgenes como se describe. Esta solución dibujará una frontera de 1dp, también conocida como colapso de borde, en (X) HTML / CSS.
El color de fondo en <TableLayout...>
y <TableRow...>
representa un color y fondo de línea de borde en <TextView...>
llena una celda de la tabla. Puede poner algo de relleno en las celdas si es necesario.
Un ejemplo está aquí:
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#CCC"
android:paddingTop="1dp"
android:stretchColumns="0"
android:id="@+id/tlTable01">
<TableRow
android:background="#CCC"
android:paddingBottom="1dp"
android:paddingRight="1dp">
<TextView
android:layout_marginLeft="1dp"
android:padding="5dp"
android:background="#FFF"
android:text="Item1"/>
<TextView
android:layout_marginLeft="1dp"
android:padding="5dp"
android:background="#FFF"
android:gravity="right"
android:text="123456"/>
</TableRow>
<TableRow
android:background="#CCC"
android:paddingBottom="1dp"
android:paddingRight="1dp">
<TextView
android:layout_marginLeft="1dp"
android:padding="5dp"
android:background="#FFF"
android:text="Item2"/>
<TextView
android:layout_marginLeft="1dp"
android:padding="5dp"
android:background="#FFF"
android:gravity="right"
android:text="456789"/>
</TableRow>
</TableLayout>
Sé que esta es una vieja pregunta ... de todos modos ... si quieres mantener tu xml simple y agradable, puedes extender TableLayout y anular el dibujo de envío para hacer un dibujo personalizado.
Aquí hay una implementación rápida y sucia que dibuja un rectángulo alrededor de la vista de tabla, así como barras horizontales y verticales:
public class TableLayoutEx extends TableLayout {
private Paint linePaint = null;
private Rect tableLayoutRect;
public TableLayoutEx(Context context) {
super(context);
}
public TableLayoutEx(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
float strokeWidth = this.getContext().getResources().getDisplayMetrics().scaledDensity * 1;
linePaint = new Paint(0);
linePaint.setColor(0xff555555);
linePaint.setStrokeWidth(strokeWidth);
linePaint.setStyle(Paint.Style.STROKE);
Rect rect = new Rect();
int paddingTop= getPaddingTop();
this.getDrawingRect(rect);
tableLayoutRect = new Rect(rect.left, rect.top + paddingTop, rect.right, rect.bottom);
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
Rect rect = new Rect();
if (linePaint != null) {
canvas.drawRect(tableLayoutRect, linePaint);
float y = tableLayoutRect.top;
for (int i = 0; i < getChildCount() - 1; i++) {
if (getChildAt(i) instanceof TableRow) {
TableRow tableRow = (TableRow) getChildAt(i);
tableRow.getDrawingRect(rect);
y += rect.height();
canvas.drawLine(tableLayoutRect.left, y, tableLayoutRect.right, y, linePaint);
float x = tableLayoutRect.left;
for (int j = 0; j < tableRow.getChildCount() - 1; j++) {
View view = tableRow.getChildAt(j);
if (view != null) {
view.getDrawingRect(rect);
x += rect.width();
canvas.drawLine(x, tableLayoutRect.top, x, tableLayoutRect.bottom, linePaint);
}
}
}
}
}
}
}
ejemplo xml con la tercera columna que ajusta el texto:
<com.YOURPACKAGE.TableLayoutEx
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:shrinkColumns="2"
android:paddingTop="6dp">
<TableRow>
<TextView
android:text="@string/my_text_0_0"
android:padding="@dimen/my_padding"/>
<TextView
android:text="@string/my_text_0_1"
android:padding="@dimen/my_padding"/>
<TextView
android:text="@string/my_text_0_2_to_wrap"
android:padding="@dimen/my_padding"/>
</TableRow>
<!--more table rows here-->
</com.YOURPACKAGE.TableLayoutEx>
También puede hacer esto de forma progamatica, en lugar de a través de xml, pero es un poco más "hackish". Pero no le de a un hombre opciones y no le dejas ninguna opción: p .. Aquí está el código:
TableLayout table = new TableLayout(this);
TableRow tr = new TableRow(this);
tr.setBackgroundColor(Color.BLACK);
tr.setPadding(0, 0, 0, 2); //Border between rows
TableRow.LayoutParams llp = new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
llp.setMargins(0, 0, 2, 0);//2px right-margin
//New Cell
LinearLayout cell = new LinearLayout(this);
cell.setBackgroundColor(Color.WHITE);
cell.setLayoutParams(llp);//2px border on the right for the cell
TextView tv = new TextView(this);
tv.setText("Some Text");
tv.setPadding(0, 0, 4, 3);
cell.addView(tv);
tr.addView(cell);
//add as many cells you want to a row, using the same approach
table.addView(tr);
Tengo que estar de acuerdo con Brad. Esa fue una respuesta horrible. La documentación de Android establece que los contenedores de TableLayout no muestran líneas de borde, por lo que enviarlos al sitio de Android no los ayudará un poco. Pude encontrar una solución "sucia" en droidnova, que implica establecer un color de fondo para TableLayout, luego establecer un color de fondo diferente para TableRow y agregar layout_margin a la fila. No me gusta esta solución, pero funciona para los bordes de las filas. Supongo que podrías hacer lo mismo con los elementos que componen cada elemento de "celda" pero no he verificado.
Un ejemplo similar al de DroidNova:
<TableLayout android:background="#000000"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TableRow android:background="#FFFFFF"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="1dp">
...
</TableRow>
</TableLayout>
Un límite entre celdas se duplica en las respuestas anteriores. Entonces, puedes probar esta solución:
<item
android:left="-1dp"
android:top="-1dp">
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#fff"/>
<stroke
android:width="1dp"
android:color="#ccc"/>
</shape>
</item>
TableRow
esta solución: en TableRow
, creé para cada celda LinearLayout
con línea vertical y celda real en él, y después de cada TableRow
, agregué una línea horizontal.
Mira el código a continuación:
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:shrinkColumns="1">
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<LinearLayout
android:orientation="horizontal"
android:layout_height="match_parent"
android:layout_weight="1">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_height="match_parent"
android:layout_weight="1">
<View
android:layout_height="match_parent"
android:layout_width="1dp"
android:background="#BDCAD2"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"/>
</LinearLayout>
</TableRow>
<View
android:layout_height="1dip"
android:background="#BDCAD2" />
<!-- More TableRows -->
</TableLayout>
Espero que ayude
Si solo está tratando de tener una línea entre las filas (por ejemplo, justo encima de una fila "Total"), entonces hay una solución fácil: simplemente agregue un TableRow con un color de fondo y un layout_height específico como este:
<TableRow android:layout_height="1px" android:background="#BDBDBD">
<TextView android:layout_span="2" android:layout_height="1px"
android:layout_width="fill_parent" android:text="">
</TextView>
</TableRow>
Set android:layout_height="1px"
o por más grueso que quieras que sea el borde. Complete tantas columnas vacías de TextView como necesite para unir el resto de su tabla, o simplemente use una junto con android:layout_span
como lo he demostrado.
La salida se verá algo como esto:
Si intenta agregar bordes más complicados, las otras respuestas ya publicadas son más apropiadas.
Aquí he diseñado la lista por la siguiente imagen de diseño. Mi nombre de archivo listitem es Propertylistitem.xml y cellborder.xml se utiliza forma dibujable para la salida del borde de la celda, se muestran en esta imagen. código necesario que agregué aquí.
FileName: propertylistitem.xml
<TableLayout... >
<TableRow... >
<TextView ...
android:background="@drawable/cellborder"
android:text="Amount"/>
</TableRow>
<TableRow... >
<TextView...
android:background="@drawable/cellborder"
android:text="5000"/>
</TableRow>
</TableLayout>
nombre de archivo: cellborder.xml Aquí solo quiero solo borde en mi diseño, así que puse el comentario en la etiqueta de color sólido.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<!-- <solid android:color="#dc6888"/> -->
<stroke android:width="0.1dp" android:color="#ffffff"
/>
<padding android:left="0dp" android:top="0dp"
android:right="0dp" android:bottom="0dp" />
</shape>