-3

I'm a newbie in Android and Kotlin and I'm facing a problem that I can't solve it. I have a activity_main.xml file that contains a seekBar and a TextView. When I'm changing the seekBar I want to display the changed value in the TextView in realtime. To learn new things and practicing Kotlin I create a new class that contains a Seekbar.OnSeekBarChangeListener and that class reacts the seekBar changes. But the problem is when I set the TextView to the new seekBar value it's cause a findViewById NullPointException.

FATAL EXCEPTION: main
Process: kotlindemo1.kristof.kotlin_1demo, PID: 24410 
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.Window.findViewById(int)' on a null object reference
at android.app.Activity.findViewById(Activity.java:2090)
at kotlindemo1.kristof.kotlin_1demo.seekB._$_findCachedViewById(seekB.kt:0)
at kotlindemo1.kristof.kotlin_1demo.seekB.onProgressChanged(seekB.kt:15)
at android.widget.SeekBar.onProgressRefresh(SeekBar.java:93)

This is the MainActivity class:

package kotlindemo1.kristof.kotlin_1demo

import android.app.Activity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*


open class MainActivity : Activity() {

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    sB1.setOnSeekBarChangeListener(seekB())
}
}

Class that handle the SeekBar changes:

package kotlindemo1.kristof.kotlin_1demo

import android.app.Activity
import android.os.Bundle
import android.widget.SeekBar
import kotlinx.android.synthetic.main.activity_main.*

class seekB : SeekBar.OnSeekBarChangeListener, Activity(){
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
}

override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
    if(fromUser) tW1.text = getString(R.string.max_gen_number, progress) //java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.Window.findViewById(int)' on a null object reference
}

override fun onStartTrackingTouch(seekBar: SeekBar?) {
}

override fun onStopTrackingTouch(seekBar: SeekBar?) {
}
}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/cL"
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="kotlindemo1.kristof.kotlin_1demo.MainActivity"
>

<SeekBar
    android:id="@+id/sB1"
    android:progress="100"
    android:max="200"
    android:layout_width="182dp"
    android:layout_height="21dp"
    android:layout_marginTop="60dp"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    tools:layout_constraintRight_creator="1"
    tools:layout_constraintLeft_creator="1"
    />

<TextView
    android:id="@+id/tW1"
    android:layout_width="139dp"
    android:layout_height="wrap_content"
    android:text=""
    android:textAlignment="center"
    android:layout_marginTop="20dp"
    app:layout_constraintTop_toBottomOf="@+id/sB1"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintHorizontal_bias="0.502"
    tools:layout_constraintRight_creator="1"
    tools:layout_constraintLeft_creator="1" />

</android.support.constraint.ConstraintLayout>

In Java it's easy, using the FindViewById and SetContentView methods to referencing a widget but in Kotlin if we importing kotlinx.android.synthetic.main.activity_main.* than we don't need to use findViewById. I tried to pass the context from the MainActivity but that's not helped.

guenhter
  • 11,255
  • 3
  • 35
  • 66
Kristof
  • 3
  • 1
  • 4

2 Answers2

1

Bro i did from most easy way for you. My Android Studio version is 3.0 Canary 5.If you not update your Android Studio, you may get exception.

MainActivity.kt In onCreate

val textView = findViewById<TextView>(R.id.tv)
    val seekBar = findViewById<SeekBar>(R.id.seekBar)

    seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener{
        override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) {

            textView.text = p1.toString()

        }

        override fun onStartTrackingTouch(p0: SeekBar?) {
        }

        override fun onStopTrackingTouch(p0: SeekBar?) {
        }
    })

activity_main.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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.kt.seekbar.MainActivity">

<TextView
    android:id="@+id/tv"
    android:layout_centerInParent="true"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

<SeekBar
    android:id="@+id/seekBar"
    android:layout_centerInParent="true"
    android:max="100"
    android:layout_below="@id/tv"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />


</RelativeLayout>
Kristof
  • 3
  • 1
  • 4
Kemal Turk
  • 2,160
  • 1
  • 14
  • 15
  • Thank you, but the question is not that how to solve this problem the most easiest way. I'm just practicing and wondering how to access widgets from custom classes, that's why I'm creating a `seekBar` listening class and that class causing a `NullPointException`. I'm using a latest Android Studio. – Kristof Jul 03 '17 at 12:53
  • Ok i understand give me 10 minutes. – Kemal Turk Jul 03 '17 at 13:20
0

Its working i tried.I added TextView reference to seekB's constructor.

MainActivity

class MainActivity : AppCompatActivity() {

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

    val textView = findViewById<TextView>(R.id.tv)
    val seekBar = findViewById<SeekBar>(R.id.seekBar)

    seekBar.setOnSeekBarChangeListener(seekB(textView))


}
}

seekB class

class seekB(val tv: TextView) : SeekBar.OnSeekBarChangeListener{

override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: 
Boolean) {
    if(fromUser) tv.text = progress.toString()
}

override fun onStartTrackingTouch(seekBar: SeekBar?) {
}

override fun onStopTrackingTouch(seekBar: SeekBar?) {
}
}
Kemal Turk
  • 2,160
  • 1
  • 14
  • 15
  • Still not working. When I'm change the `SeekBar` value I get an error: `java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference` – Kristof Jul 03 '17 at 14:16
  • Exactly the same of yours, that's what you paste upper. – Kristof Jul 03 '17 at 15:45