kotlin View.OnClickListener? was expected [duplicate] - android

This question already has answers here:
Android - How to achieve setOnClickListener in Kotlin?
(32 answers)
Closed 1 year ago.
I am trying to get this toggle button to work - All I want to do is print in console "hello" but am getting this error
Type mismatch: inferred type is Unit but View.OnClickListener? was expected
package com.radiomedia.drn1
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity(){
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
playButton.setOnClickListener(
print("hello")
)
}
}

Change setOnClickListener() method as any of the below options:
Option 1:
playButton.setOnClickListener{
print("hello")
}
Option 2:
playButton.setOnClickListener(object : View.OnClickListener {
override fun onClick(view: View?) {
print("hello")
}
})
Option 3:
playButton.setOnClickListener(View.OnClickListener { view ->
print("hello")
})

You need to use braces instead, like this:
playButton.setOnClickListener{
print("hello")
}

either
playButton.setOnClickListener {
print("hello")
}
or
playButton.setOnClickListener(object: View.OnClickListener {
override fun onClick(v: View?) {
TODO("Not yet implemented")
}
})

Related

How to move from Secondactivity to Mainactivity after animation is complete?

Sorry I am a bit new to stack overflow but hopefully the question is understandable!
I talked to a staff memeber/community member who showed me Intent to go from 1 activity(in my case GlobeActivity where my animation is stored) to another activity( MainActivity where username/password is stored). But the animation does not show up, instead it cuts directly to MainActivity.
Anyone got some suggestions to why and how to make it so that when animation is finished, it re-directs/ transitions to MainActivity without use of buttons?
Here is my code so far:
GlobeActivity( my SecondActivity):
package com.example.testerino2022
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
class GlobeActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_globe)
supportActionBar?.hide()
val textView = findViewById<TextView>(R.id.textGlobeScreen)
textView.animate().translationX(1050F).setDuration(1000).setStartDelay(2500)
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
finish()
}
}
MainActivity(has default code in it );
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
You can use animation listener
textView.animate().translationX(1050F).setDuration(1000).setStartDelay(2500).setListener(
object: Animator.AnimatorListener{
override fun onAnimationStart(p0: Animator?) {
TODO("Not yet implemented")
}
override fun onAnimationEnd(p0: Animator?) {
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
finish()
}
override fun onAnimationCancel(p0: Animator?) {
TODO("Not yet implemented")
}
override fun onAnimationRepeat(p0: Animator?) {
TODO("Not yet implemented")
}
}
)
You can do this easily with the ViewPropertyAnimator stuff you're already using - just add withEndAction:
textView.animate()
.translationX(1050F)
.setDuration(1000)
.setStartDelay(2500)
.withEndAction {
startActivity(Intent(context, MainActivity::class.java))
finish()
}
textView.animate()
.translationX(1050F)
.setDuration(1000)
.setStartDelay(2500)
.withEndAction {
startActivity(Intent(context, MainActivity::class.java))
finish()
}
Have you changed the launcher activity from MainActivity to GlobeActivity in the app's manifest?
You should listen to the view or element that is being animated, assuming an ImageView. You can do this with the ViewPropertyAnimator.
ImageView imageview = findViewById(R.id.imageView);
imageView.animate()
.translationX(1050F)
.setDuration(2000)
.setStartDelay(1000)
.withEndAction {
startActivity(Intent(context, MainActivity::class.java))
finish()
}
Explanation
translationX(float value) - This method will cause the View's translationX property to be animated to the specified value
setDuration(long duration) - Sets the duration for the underlying animator that animates the requested properties.
setStartDelay(long startDelay) - Sets the startDelay for the underlying animator that animates the requested properties.
withEndAction(Runnable runnable) - Specifies an action to take place when the next animation ends.
For more information on this, check this out : -> ViewPropertyAnimator

kotlin-android-extensions not working. what will be the problem?

I was following some guide(download android studio today) of kotlin and I have use the setText and it's not working.
what will be the problem?
package com.example.basic
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button.setOnClickListener {
Toast.makeText(applicationContext, "button was pressed.", Toast.LENGTH_LONG).show()
}
button2.setOnClickListener {
val input = editTextTextPersonName.text.toString()
TextView.setText("entered value: ${input}")
}
}
}
(I had tried replace setText to text but it's still red and can't save it)
Unresolved reference: setText(error)
TextView is the name of the class. You need to apply setText on an instance of the class. just like you did
editTextTextPersonName.text.toString()
instead of
EditText.text.toString()
I don't know that your TextView is called but you then need to do
instanceOfYourTextView.setText("entered value: ${input}")
As Mayur Gajra did mention you are not using the view from the XML but instead you are using the TextView class and this is your problem, what you need to have instead is something like this:
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
/>
And then your MainActivity should look like the following:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button.setOnClickListener {
Toast.makeText(applicationContext, "button was pressed.", Toast.LENGTH_LONG).show()
}
button2.setOnClickListener {
val input = editTextTextPersonName.text.toString()
text.setText("entered value: ${input}")
}
}
}

Android Studio - Kotlin Project's "Unsolved reference" problem

I add a textView in layout but when I'm trying to use Kotlin Android Extensions but I get Unsolved reference error on my TextView:
package com.normal.ff
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
fun first(a:Int, b:Int){
textView.text
}
Add import kotlinx.android.synthetic.main.activity_main.* at the top of your activity.
You are almost there, you just need a reference from layout file for that text view.
something like below
class MainActivity : AppCompatActivity() {
lateinit var textView: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
textView = findViewById<TextView>(R.id.textView)
}
}
fun first (a:Int, b:Int){
val text = textView.text
}

how to force a method to infer a generic type

in the below code, i have 2 fragments FragmentLeft and FragmentRight both extends from Fragment class.
according to the extenstion methods below, i am trying to use a generic data type as a parameter to the method, so that when i use this method it should accept either instances of FragmentLeft or FragmentRight.....
however, the code below generates an error stated in the comment
please let me know how to solve it
code
var fragTransactionInstance = getFragmentManagerInstance()?.let {
it.getFragmentTransactionInstance()
?.replaceTransaction(R.id.fragLeft, fragmentLeft)//no enough
information to infer type variable T
?.replaceTransaction(R.id.fragRight, fragmentRight)////no
enough information to infer type variable T
}?.also {
it.commit()
}
}
fun initViews() : Unit {
fragmentLeft = FragmentLeft()
fragmentRight = FragmentRight()
}
fun <T : Fragment> FragmentTransaction.replaceTransaction(layout: Int, t:
Fragment?): FragmentTransaction {
return this.replace(layout, t)
}
classes:
import android.os.Bundle
import android.support.v4.app.Fragment
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.kotlindynmaicfragment_v1.MainActivity
import com.example.kotlindynmaicfragment_v1.R
import kotlinx.android.synthetic.main.activity_main.view.*
class FragmentRight : Fragment() {
val LOG_TAG = this::class.java.name
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d(LOG_TAG, "onCreate")
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
Log.d(LOG_TAG, "onActivityCreated")
}
///////////////////
class FragmentLeft : Fragment() {
val LOG_TAG = this::class.java.name
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d(LOG_TAG, "onCreate")
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
Log.d(LOG_TAG, "onActivityCreated")
}
I think the issue comes from the fact that you defined your replaceTransaction method as generic, but you're not using T at all in that method, so type inference doesn't know what type to use in place of T.
To give you a simpler example, this will cause the same error:
fun <T> foo() {
println("Hello, world!")
}
fun main() {
foo()
}
That happens because T cannot be inferred, so you need to explicitly tell what type to use (even though it's not used at all in foo):
fun main() {
foo<Unit>() // I used Unit, but any other type would do
}
Given that, do you need T at all in your code? Both FragmentRight and FragmentLeft extend from Fragment, so unless you need to use specific functionalities from those classes, you can discard T and use the parent type Fragment (as you're already doing).
Instead of using t:Fragment, change the type of t to T, not Fragment
Try to write your extension function this way:
fun <T : Fragment> FragmentTransaction.replaceTransaction(layout: Int, t:
T): FragmentTransaction {
return this.replace(layout, t)
}

How to properly implement an interface in android fragment?

folks. I have been working on a project with kotlin and I need to make a fragment that comunicate with the parent activity... I followed exactly what google and other websites suggested but I still get an error "activity does not override anything"... All of the other solutions are not working for me... here is the code .
FRAGMENT
package com.me.assistan.assistant
import android.app.Activity
import android.app.DatePickerDialog
import android.app.TimePickerDialog
import android.content.Context
import android.content.Intent
import android.graphics.drawable.GradientDrawable
import android.os.Bundle
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.CompoundButton
import android.widget.LinearLayout
import android.widget.ToggleButton
import kotlinx.android.synthetic.main.content_newplan.*
import java.util.*
class addingTask : Fragment(), View.OnClickListener{
var func = Functions
var globalTask = GlobalTask
private lateinit var listener: OnTimeSettedListener
override fun onAttach(context: Context?) {
super.onAttach(context)
if (context is OnTimeSettedListener) {
listener = context
} else {
throw ClassCastException(context!!.toString() + " must implement
OnTimeSettedListener.")
}
}
companion object {
fun newInstance(): addingTask {
return addingTask()
}
}
override fun onCreateView(inflater: LayoutInflater?, container:
ViewGroup?,
savedInstanceState: Bundle?): View? {
val view: View = inflater!!.inflate(R.layout.fragment_adding_task,
container,
false)
val activity = activity
view.theTime.setOnClickListener { v ->
listener.onTimeSetListtedener("test")
}
return view
}
interface OnTimeSettedListener{
fun onTimeSetListtedener(comic : String){
println("ok")
}
}
}// Required empty public constructor
And not the MAIN ACTIVITY
class Newplan : AppCompatActivity(), addingTask.OnTimeSettedListener {
var posx = 0f
private var startx = 0f
private var posy = 0f
private var starty = 0f
var backIntent = Intent();
var func = Functions
var globalTask = GlobalTask
val fragment = addingTask()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_newplan)
if(savedInstanceState === null){
var args = Bundle()
supportFragmentManager.beginTransaction()
.add(R.id.taskMain, addingTask.newInstance(),"newTask")
.commit()
}
}
override fun onTimeSettedListener(comic : String){
println("params")
}
}
I get the error on the activity class... When I remove the "override?, the error is gone but nothing happen when I click on the button... What am I doing wrong?
I think you shouldn't add method body to your interface method. It is not allowed in Java. In Kotlin there is no error that showing method body is restricted. But you should remove body. Change your interface like
interface OnTimeSettedListener{
fun onTimeSetListtedener(comic : String)
}
Also actually you are not overriding your Listener's method. Method name in OnTimeSettedListener is onTimeSetListtedener but you are overriding onTimeSettedListener which is not really exist in your code.
Also as #albodelu mentioned answer and #chris mentioned in comments, you cannot write methods in methods. It is not correct usage.
As #chris commented, you need to move the lines below outside of onCreate() method:
override fun onTimeSettedListener(comic: String) {
println("params")
}
You also need to match names replacing
interface OnTimeSettedListener {
fun onTimeSetListtedener(comic : String){
println("ok")
}
}
by
interface OnTimeSettedListener {
fun onTimeSettedListener(comic: String) {
println("ok")
}
}
Update
If you fix the name typo and remove the default implementation of the onTimeSettedListener declaration in the interface inside your fragment, as your activity implements it and Android Studio warns you about the missing override, it's possible to click it and select that the IDE implements it for you to avoid errors doing it:
interface OnTimeSettedListener{
fun onTimeSettedListener(comic : String)
}
You also need to fix the call replacing:
listener.onTimeSetListtedener("test")
by
listener.onTimeSettedListener("test")

Categories

Resources