Home > Blockchain >  adding interface in MainActivity Kotlin
adding interface in MainActivity Kotlin

Time:08-05

I'm new to android, please help me

i made a interface in MainActivity and tried to initialize it like => class MainActivity(private val sender: DateSender) but it has to have it's defualt constractor or such.

it was the compile error =>

java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.shohadav1/com.example.shohadav1.MainActivity}: java.lang.InstantiationException: class com.example.shohadav1.MainActivity has no zero argument constructor

i want to send my data to a Fragment, if you know any better approach please guide me. thanks

here is my main Activity =>

package com.example.shohadav1

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AlertDialog
import com.example.shohadav1.databinding.ActivityMainBinding
import com.example.shohadav1.databinding.AddItemDialogBinding

class MainActivity(private val sender: DateSender) : AppCompatActivity() {    

    private lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        binding = ActivityMainBinding.inflate(layoutInflater)
        super.onCreate(savedInstanceState)
        setContentView(binding.root)
        //set AppName text
    
        //set Navi button
        val actionBarDrawerToggle = ActionBarDrawerToggle(    
            this,    
            binding.drawerLayoutMain,
            binding.toolbarMain,
            R.string.open,
            R.string.close
        )
        binding.drawerLayoutMain.addDrawerListener(actionBarDrawerToggle)
        actionBarDrawerToggle.syncState()

        //Fragment setting
        var transaction = supportFragmentManager.beginTransaction()
        transaction.replace(R.id.fragment_container_main, MainItemsViewerFrag())
        transaction.commit()

        //add Item
        binding.toolbarMain.setOnMenuItemClickListener {
            when (it.itemId){
                R.id.addItem_toolbar -> {  additem()}
                R.id.search_btn_toolbar -> { }
            }    
            true
        }


    }
    fun additem(){

        var addDialog = AlertDialog.Builder(this).create()
        var addDialogBinding = AddItemDialogBinding.inflate(layoutInflater)
        addDialog.setView(addDialogBinding.root)
        addDialog.show()
        addDialogBinding.acceptBtnAddDialog.setOnClickListener {    
            var newName = addDialogBinding.addNameAddDialog.text.toString()
            var birthdate = addDialogBinding.addBirthDateAddDialog.text.toString()
            var deadDate = addDialogBinding.addDeadDateAddDialog.text.toString()
            var vasiatname = addDialogBinding.addVasiatnameAddDialog.text.toString()
            var newData = Data(newName, birthdate, deadDate, vasiatname)    
            sender.sendData(newData)

        }
        addDialogBinding.cancelBtnAddDialog.setOnClickListener { addDialog.dismiss() }
    }

    interface DateSender {
        fun sendData (newData : Data)
    }
}

CodePudding user response:

If you're trying to implement an interface in an Activity, you do it like this:

// you could put this inside the class, but since it's not tied to MainActivity,
// it makes more sense to put it outside, as a general interface
// (DateSender isn't a great name btw - isn't it more of a DateReceiver? Or DateListener)
interface DateSender {
    fun sendData (newData : Data)
}

// interfaces go on this line, after the superclass constructor (if any)
class MainActivity : AppCompatActivity(), DateSender {

    // implement the function the interface requires
    override fun sendData(newData: Data) {
        // do stuff
    }
}

Then you can pass that to your Fragment if you get a reference to it:

// inside the fragment - when this is set the Fragment can call dateSender.sendData
var dateSender: DateSender? = null

Or the Fragment can assume that its parent Activity is a DateSender:

(activity as? DateSender)?.sendData(whatever)

The interface makes it general - you can pass it any object that implements DateSender, and the Fragment can use it as one (i.e. call sendData on it). That's why it doesn't make sense to tie it to MainActivity specifically and put it inside, so it's a MainActivity.DateSender. At that point you may as well just put your sendData function in MainActivity as a normal, non-interface function since you're assuming your parent Activity is going to be that class anyway:

// activity
// No interface implementation
class MainActivity : AppCompatActivity() {
    // no override since it's a normal function
    fun sendData(newData: Data) {}

// fragment
(activity as? MainActivity)?.sendData(stuff)

CodePudding user response:

Your MainClass must extend the interface for implementing

class MainActivity() : AppCompatActivity(), DateSender {}

Now you can override your function sendData in MainActivity class

  • Related