0

I need to display data in tabletLayout from SQLite. The SQLite response is correct, the data is correct, I add them correct but it does not list them. It shows me only one :

TableLAyout.xml :

  <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Views.MarcadoXLoteActivity">

<Spinner
    android:id="@+id/spinner3"
    android:layout_width="105dp"
    android:background="@drawable/green_border"
    android:layout_height="36dp"
    android:layout_marginTop="8dp"
    app:layout_constraintStart_toStartOf="@+id/textView73"
    app:layout_constraintTop_toBottomOf="@+id/textView73" />

<ImageView
    android:id="@+id/imageView26x"
    android:layout_width="33dp"
    android:layout_height="46dp"
    android:layout_marginStart="-34dp"
    app:layout_constraintBottom_toBottomOf="@+id/spinner3"
    app:layout_constraintStart_toEndOf="@+id/spinner3"
    app:layout_constraintTop_toTopOf="@+id/spinner3"
    app:srcCompat="@drawable/baseline_arrow_drop_down_24" />

<androidx.appcompat.widget.Toolbar
    android:id="@+id/toolbarM"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:background="@color/white"
    android:minHeight="?attr/actionBarSize"
    android:theme="?attr/actionBarTheme"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:subtitleTextColor="@color/white"
    app:title="  Marcado de Avances Por Lote"
    app:titleTextAppearance="@style/TextAppearance.AppCompat.Display1"
    app:titleTextColor="@color/black">


</androidx.appcompat.widget.Toolbar>

<androidx.cardview.widget.CardView
    android:id="@+id/cardView2"
    android:layout_width="798dp"
    android:layout_height="wrap_content"
    android:layout_marginStart="1dp"
    android:layout_marginTop="32dp"
    android:layout_marginEnd="1dp"
    app:cardBackgroundColor="#DEF1DE"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/toolbarM">

    <TextView
        android:id="@+id/tvNomMarcado"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="     CIMENTACION"
        android:textColor="#11B818"
        android:textSize="24sp"
        android:textStyle="bold|italic" />

</androidx.cardview.widget.CardView>

<TextView
    android:id="@+id/textView72"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="80dp"
    android:layout_marginTop="24dp"
    android:text="Manzana"
    android:textColor="#000000"
    android:textSize="16sp"
    app:layout_constraintStart_toStartOf="@+id/cardView2"
    app:layout_constraintTop_toBottomOf="@+id/cardView2" />

<TextView
    android:id="@+id/textView73"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="24dp"
    android:layout_marginEnd="220dp"
    android:text="Rango de Lotes"
    android:textColor="#000000"
    android:textSize="16sp"
    app:layout_constraintEnd_toEndOf="@+id/cardView2"
    app:layout_constraintTop_toBottomOf="@+id/cardView2" />

<Spinner
    android:id="@+id/spinnerMan"
    android:layout_width="206dp"
    android:layout_height="36dp"
    android:layout_marginTop="8dp"
    android:background="@drawable/green_border"
    app:layout_constraintStart_toStartOf="@+id/textView72"
    app:layout_constraintTop_toBottomOf="@+id/textView72" />

<ImageView
    android:id="@+id/imageView26"
    android:layout_width="33dp"
    android:layout_height="46dp"
    android:layout_marginStart="-34dp"
    app:layout_constraintBottom_toBottomOf="@+id/spinnerMan"
    app:layout_constraintStart_toEndOf="@+id/spinnerMan"
    app:layout_constraintTop_toTopOf="@+id/spinnerMan"
    app:srcCompat="@drawable/baseline_arrow_drop_down_24" />

<TableLayout
    android:id="@+id/tlMarcado"
    android:layout_width="700dp"
    android:layout_height="789dp"
    android:layout_marginStart="16dp"
    android:layout_marginTop="8dp"
    android:layout_marginEnd="16dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/spinner3">

    <TableRow
        android:background="#51B435"
        android:padding="10dp">

        <TextView
            android:layout_width="120dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center"
            android:text="DESCRIPCIÓN"
            android:textColor="@color/white" />

        <TextView
            android:layout_width="78dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_weight="0.5"
            android:gravity="center"
            android:singleLine="false"
            android:text="PRECIO


            CONTRATISTA"
            android:textColor="@color/white" />

        <TextView
            android:id="@+id/tvTarjetaML"
            android:layout_width="wrap_content"
            android:layout_height="36dp"
            android:layout_gravity="center"
            android:layout_weight="0.5"
            android:gravity="center"
            android:text="015004001"
            android:textColor="@color/white" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="36dp"
            android:layout_gravity="center"
            android:layout_weight="0.5"
            android:gravity="center"
            android:text="015004001"
            android:textColor="@color/white" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="36dp"
            android:layout_gravity="center"
            android:layout_weight="0.5"
            android:gravity="center"
            android:text="015004001"
            android:textColor="@color/white" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="36dp"
            android:layout_gravity="center"
            android:layout_weight="0.5"
            android:gravity="center"
            android:text="015004001"
            android:textColor="@color/white" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="36dp"
            android:layout_gravity="center"
            android:layout_weight="0.5"
            android:gravity="center"
            android:text="015004001"
            android:textColor="@color/white" />
    </TableRow>

    <TableRow
        android:background="#F0F7F7"
        android:padding="5dp">

        <TextView
            android:id="@+id/tvDescML"
            android:layout_width="120dp"
            android:layout_height="55dp"
            android:layout_gravity="center"
            android:background="@drawable/tableborder"
            android:gravity="center"
            android:text="FAB. DE REGISTRO PLUBIAL" />

        <TextView
            android:id="@+id/tvPrecioML"
            android:layout_width="wrap_content"
            android:layout_height="60dp"
            android:layout_gravity="center"
            android:layout_weight="1"
            android:background="@drawable/tableborder"
            android:gravity="center"
            android:text=" $129.00" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="60dp"
            android:layout_weight="1"
            android:background="@color/blueM"
            android:padding="6dp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="60dp"
            android:layout_weight="1"
            android:background="@color/blueM"
            android:padding="6dp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="60dp"
            android:layout_weight="1"
            android:background="@color/blueM"
            android:padding="6dp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="60dp"
            android:layout_weight="1"
            android:background="@color/blueM"
            android:padding="6dp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="60dp"
            android:layout_weight="1"
            android:background="#2A42C6"
            android:padding="6dp" />

    </TableRow>

    <TableRow
        android:background="#F0F7F7"
        android:padding="5dp"/>

    <TableRow
        android:background="#F0F7F7"
        android:padding="6dp"/>

    <TableRow
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <TableRow
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <TableRow
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <TableRow
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</TableLayout>

<Button
    android:id="@+id/btnguardarmercado"
    android:layout_width="562dp"
    android:layout_height="72dp"
    android:layout_marginStart="352dp"
    android:layout_marginTop="30dp"
    android:layout_marginEnd="352dp"
    android:background="@drawable/btn_gray"
    android:text="GUARDAR AVANCE"
    android:textSize="30sp"
    app:backgroundTint="@null"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/tlMarcado" />

<Spinner
    android:id="@+id/spinner4"
    android:layout_width="105dp"
    android:layout_height="36dp"
    android:layout_marginStart="16dp"
    android:background="@drawable/green_border"
    app:layout_constraintStart_toEndOf="@+id/textView71"
    app:layout_constraintTop_toTopOf="@+id/spinner3" />

<ImageView
    android:id="@+id/imageView88"
    android:layout_width="33dp"
    android:layout_height="46dp"
    android:layout_marginStart="-34dp"
    app:layout_constraintBottom_toBottomOf="@+id/spinner4"
    app:layout_constraintStart_toEndOf="@+id/spinner4"
    app:layout_constraintTop_toTopOf="@+id/spinner4"
    app:srcCompat="@drawable/baseline_arrow_drop_down_24" />

<TextView
    android:id="@+id/textView71"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="7dp"
    android:text="Al"
    android:textColor="#040404"
    android:textSize="20sp"
    app:layout_constraintBottom_toBottomOf="@+id/spinner3"
    app:layout_constraintStart_toEndOf="@+id/spinner3"
    app:layout_constraintTop_toBottomOf="@+id/textView73" />

</androidx.constraintlayout.widget.ConstraintLayout>

Kotlin code:

 private fun llenartabla() {
        val tableLayout = findViewById<TableLayout>(R.id.tlMarcado)
        val obraS = SharedApp.prefs.obra
        val obraSt = obraS.toString()

        val dbHelper = DBHandler(this)
        val db = dbHelper.readableDatabase

        val cursor: Cursor = db.rawQuery("select distinct dstarjeta, insumo, cantidad, precio_insumo, lote, manzana, id_detalle_kontrol from ActividadesM where obra = '" + obraSt + "'", null)

cursor.moveToFirst()
    do{
        val a = TableRow(this)
        a.layoutParams = TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT)

        val tvCodigo = tableLayout.findViewById<View>(R.id.tvDescML) as TextView
        tvCodigo.text = cursor.getString(0)
        if (tvCodigo.getParent() != null) {
            (tvCodigo.getParent() as ViewGroup).removeView(tvCodigo) // <- fix
        }
        a.addView(tvCodigo)

        val tvDescripcion = tableLayout.findViewById<View>(R.id.tvTarjetaML) as TextView
        tvDescripcion.text = cursor.getString(6)
        if (tvDescripcion.getParent() != null) {
            (tvDescripcion.getParent() as ViewGroup).removeView(tvDescripcion) // <- fix
        }
        a.addView(tvDescripcion)

        val tvPrecio = tableLayout.findViewById<View>(R.id.tvPrecioML) as TextView
        tvPrecio.text = cursor.getString(2)
        if (tvPrecio.getParent() != null) {
            (tvPrecio.getParent() as ViewGroup).removeView(tvPrecio) // <- fix
        }
        a.addView(tvPrecio)

        tableLayout.addView(a)
    }while (cursor.moveToNext())    }

I can't get it to work:

enter image description here

3
  • 1
    I'm a java rather than koitlin person, but it look to me like your code is creating a new row but then moving 3 textviews into that row and adding it to the table. You should be creating textviews each time for the new row or all your code is doing is emptying the data out from the last row and you'll only ever see one. Commented Jun 19, 2023 at 10:03
  • Hi Matt, do you have an example where I can guide me? Commented Jun 19, 2023 at 14:40
  • 2
    Can't you just use a RecyclerView instead? Commented Jun 19, 2023 at 18:12

2 Answers 2

2
+100

I would also recommend to use "RecyclerView". But in case if you need to use the tablelayout, please consider following

I created a sample app based on your issue.

a) Update the table TableLayout as follows

<?xml version="1.0" encoding="utf-8"?>

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".sobounty.SoBountctivity">
<TableLayout
    android:id="@+id/test_table"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <TableRow
        android:background="#51B435"
        android:padding="10dp">

        <TextView
            android:layout_width="120dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center"
            android:text="DESCRIPCIÓN"
            android:textColor="@color/white" />

        <TextView
            android:layout_width="78dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_weight="0.5"
            android:gravity="center"
            android:singleLine="false"
            android:text="PRECIO


        CONTRATISTA"
            android:textColor="@color/white" />

        <TextView
            android:id="@+id/tvTarjetaML"
            android:layout_width="wrap_content"
            android:layout_height="36dp"
            android:layout_gravity="center"
            android:layout_weight="0.5"
            android:gravity="center"
            android:text="015004001"
            android:textColor="@color/white" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="36dp"
            android:layout_gravity="center"
            android:layout_weight="0.5"
            android:gravity="center"
            android:text="015004001"
            android:textColor="@color/white" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="36dp"
            android:layout_gravity="center"
            android:layout_weight="0.5"
            android:gravity="center"
            android:text="015004001"
            android:textColor="@color/white" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="36dp"
            android:layout_gravity="center"
            android:layout_weight="0.5"
            android:gravity="center"
            android:text="015004001"
            android:textColor="@color/white" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="36dp"
            android:layout_gravity="center"
            android:layout_weight="0.5"
            android:gravity="center"
            android:text="015004001"
            android:textColor="@color/white" />
    </TableRow>


</TableLayout>

I am using it as layout so, I used ScrollView as root container.

b) Create a second layout file (table_row_layout)as follows (add your styles etc in it, I have removed few of them to make things simple). This contains the row views.

<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
    android:id="@+id/tvDescML"
    android:layout_width="120dp"
    android:layout_height="55dp"
    android:layout_gravity="center"
    android:gravity="center"
    android:text="FAB. DE REGISTRO PLUBIAL" />

<TextView
    android:id="@+id/tvPrecioML"
    android:layout_width="wrap_content"
    android:layout_height="60dp"
    android:layout_gravity="center"
    android:layout_weight="1"
    android:gravity="center"
    android:text=" $129.00" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="60dp"
    android:layout_weight="1"
    android:padding="6dp" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="60dp"
    android:layout_weight="1"
    android:padding="6dp" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="60dp"
    android:layout_weight="1"
    android:padding="6dp" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="60dp"
    android:layout_weight="1"
    android:padding="6dp" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="60dp"
    android:layout_weight="1"
    android:background="#2A42C6"
    android:padding="6dp" />
 </TableRow>

c) Activity code (Adjust the logic as per your need) Here, we will inflate the table_row_layout and then add it to the viewgroup

class SoBountctivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_so_bountctivity)
    // tableLayout i which we want to insert view
    val tableLayout = findViewById<TableLayout>(R.id.test_table)
    // Fake data
    val fruitList = returnFruitList()
    // layoutInflater
    val layoutInflater = layoutInflater

    // Your cursor can replace the forEach. Looping over the data
    fruitList.forEach {

        // Get the new row_layout
        val view = layoutInflater.inflate(R.layout.table_row_layout, tableLayout, false)
        // Get the views in which you want to add the data
        val textView = view.findViewById<TextView>(R.id.tvDescML)
        // Set the data
        textView.text = it
        // Add the row view in tableLayout
        tableLayout.addView(view)
    }


    for (rowIndex in 0 until tableLayout.childCount) {
        val rowView: TableRow = tableLayout.getChildAt(rowIndex) as TableRow
        for (colIndex in 0 until rowView.childCount) {
            val view = rowView.getChildAt(colIndex)
            view.setOnClickListener {
                // For listeners.
                onTableCellClicked(rowIndex, colIndex)

            }
        }
    }
}

private fun returnFruitList() = listOf("Apple", "Banana", "Pineapple", "Guava", "Berries", "JackFruit", "Tomato", "Papaya")

private fun onTableCellClicked(rowIndex: Int, colIndex: Int) {
    Toast.makeText(this, "I AM CLICKED row $rowIndex col $colIndex", Toast.LENGTH_SHORT).show()
}
}

However I too would take note of the comment left by @marcpetitvecino on the question. Using RecyclerView is a better approach, as it is very flexible, memory efficient, has smooth scrolling as it recycles / reuses views and is very modular / customisable.

Result : Sample

enter image description here

Sign up to request clarification or add additional context in comments.

2 Comments

Hi avinash, how can i access those rowindex from my main class, Before the change I did it like this for (rowIndex in 0 until MarkedTable.childCount) { val tableRow = markedTable.getChildAt(rowIndex) as TableRow for (cellIndex in 0 until tableRow.childCount) { val cellView = tableRow.getChildAt(cellIndex) cellView.setOnClickListener { // Handle click event onTableCellClicked(rowIndex, cellIndex) } } } But now with the new layout I can't access them
@MexiCano : This seems strange, I am able to set the click listeners in same way as you pointed out. "onTableCellClicked" is some kind of callback/method of interface ? I have added the updated code for your reference.
1

1. The problem with the code lies in how it is accessing the TextViews within the TableLayout.

This is a simplified look at the TableLayout.xml which shows the following structure:

<TableLayout
  android:id="@+id/tlMarcado"
  .....>
  <TableRow
     .....>
     <TextView
       android:id="@+id/tvTarjetaML"
       ...../>
  </TableRow>
</TableLayout>

The TextViews with IDs (tvDescML, tvTarjetaML, tvPrecioML) are not direct children of TableLayout. They are in fact children of TableRow within TableLayout

2. The code is attempting to source the TextViews by their IDs within the TableLayout view:

val tvCodigo = tableLayout.findViewById<View>(R.id.tvDescML) as TextView
tvCodigo.text = cursor.getString(0)
if (tvCodigo.getParent() != null) {
  (tvCodigo.getParent() as ViewGroup).removeView(tvCodigo) // <- fix
}
a.addView(tvCodigo)

To resolve this issue, the code needs to find the TableRow first, then find the TextView within that TableRow:

val a = TableRow(this)
a.layoutParams = TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT)

val tvCodigo = a.findViewById<TextView>(R.id.tvDescML)
tvCodigo.text = cursor.getString(0)
if (tvCodigo.getParent() != null) {
  (tvCodigo.getParent() as ViewGroup).removeView(tvCodigo) // <- fix
}
a.addView(tvCodigo)

3. Remove the 'if' condition and the subsequent removeView() call

This code checks if the tvCodigo TextView has a parent view and removes it:

if (tvCodigo.getParent() != null) {
  (tvCodigo.getParent() as ViewGroup).removeView(tvCodigo) // <- fix
}

The context provided above is to add the tvCodigo TextView to a new TableRow and add that TableRow to the TableLayout. The removeView() method is used to remove a view from its parent view hierarchy.

However, since the code is creating a new TableRow (a) and the tvCodigo TextView is set as the child, there is no possibility for the TextView to have an existing parent. This code is unnecessary and should be removed, this will not affect the functionality of the code and will make it cleaner:

val a = TableRow(this)
a.layoutParams = TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT)

val tvCodigo = a.findViewById<TextView>(R.id.tvDescML)
tvCodigo.text = cursor.getString(0)
a.addView(tvCodigo)

4. Make the Code more Performant

The addView() method is called multiple times, modifying the view hierarchy frequently can have a performance impact. So only apply the method to the TableLayout at the end of the do block :

cursor.moveToFirst()
  do{
    val a = TableRow(this)
    a.layoutParams = TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT)

    val tvCodigo = a.findViewById<TextView>(R.id.tvDescML)
    tvCodigo.text = cursor.getString(0)

    val tvDescripcion = a.findViewById<TextView>(R.id.tvTarjetaML)
    tvDescripcion.text = cursor.getString(6)

    val tvPrecio = a.findViewById<TextView>(R.id.tvPrecioML)
    tvPrecio.text = cursor.getString(2)

    tableLayout.addView(a)
  } while (cursor.moveToNext())

This answers the question, however I would take note of the comment left by @marcpetitvecino on the question.
Using RecyclerView is a better approach, as it is very flexible, memory efficient, has smooth scrolling as it recycles / reuses views and is very modular / customisable.

3 Comments

result is error, values ​​are always null, never get cursor value Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
@MixiCano - ok - can you advise whether this fails after changes at the end of step 2 ?
Yes, I made the changes and that was when it failed, I debug and look at the val tvcodigo etc, they are always null, they never take a value

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.