Search code examples
androidlistviewkotlinlistadapter

An error occurred when scroll down on ListView in android (kotlin)


I got an error when I scroll down the list view. When scroll reached to bottom of activity, the error occurred. And one strange thing is here. On kotlin code, there is "DataController.getDataList()" function. This function get 10 data list as ArrayList, but I got only 9 data in my emulator. What's wrong with my code?

activity_spiral_test_list.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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=".spiralTestListActivity"
    android:background="@color/Background">

    <ListView
        android:id="@+id/patientList"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <ViewStub
        android:id="@+id/empty"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:layout="@layout/empty"/>

    <android.support.design.widget.FloatingActionButton
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:src="@drawable/add"
        android:layout_margin="40dp"
        android:scaleType="center"
        android:tint="@android:color/white"
        android:backgroundTint="@color/Primary"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:borderWidth="0dp"/>

</android.support.constraint.ConstraintLayout>

patient_list_item.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">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="30dp"
            android:orientation="vertical">

            <TextView
                android:id="@+id/patientName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Test Patient"
                android:textSize="40sp"
                android:textColor="@android:color/black"
                android:textStyle="bold"/>

            <TextView
                android:id="@+id/patientDescription"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Test Explanation"
                android:textSize="25sp"/>
        </LinearLayout>

        <View
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_weight="1" />

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:layout_marginEnd="40dp"
            android:orientation="vertical">

            <ImageView
                android:layout_width="60dp"
                android:layout_height="60dp"
                android:src="@drawable/assignment"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Test"
                android:textSize="20sp"/>

        </LinearLayout>
    </LinearLayout>
</LinearLayout>

spiralTestListActivity.kt

import android.content.Context
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.TextView
import myPackage.DataController
import myPackage.PatientData
import kotlinx.android.synthetic.main.activity_spiral_test_list.*

class spiralTestListActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_spiral_test_list)

        patientList.adapter = patientAdapter(this, DataController.getDataList())
        patientList.emptyView = empty
    }

    private inner class ViewHolder {
        lateinit var name: TextView
        lateinit var description: TextView
    }

    inner class patientAdapter(context: Context, val listItem: ArrayList<PatientData>) : BaseAdapter() {
        private val mInflator: LayoutInflater = LayoutInflater.from(context)

        override fun getCount(): Int {
            return this.listItem.size
        }

        override fun getItemId(position: Int): Long {
            return position.toLong()
        }

        override fun getItem(position: Int): Any {
            return this.listItem[position]
        }

        override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
            val view: View
            val holder: ViewHolder

            if (convertView == null) {
                view = mInflator.inflate(R.layout.patient_list_item, parent, false)

                holder = ViewHolder()
                holder.name = view.findViewById(R.id.patientName) as TextView
                holder.description = view.findViewById(R.id.patientDescription) as TextView
            }
            else {
                view = convertView
                holder = convertView.tag as ViewHolder
            }

            val patient = getItem(position) as PatientData
            val name = holder.name
            val description = holder.description

            name.text = patient.name
            description.text = patient.description

            return view
        }
    }
}

Solution

  • I solve this problem. This problem is occurred because of thread. Surely, controller of data is adapter. But, I add data in my dialog class.(There are some different part of code above. I changed it..) So, when thread ask to get data from adapter, the data is different with ListView's data. It occurred an error.

    I fix the code in my adapter class and dialog class. In the adapter class, I add a function named add.

    fun add(data: PatientData) {
        DataController.addData(data)
    }
    

    Also, there is one more thing. In SpiralTestListActivity.ky, I don't add

    convertView.tag = holder
    

    above the else part in Adapter class..!!

    These parts make my app work correctly..!