0

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)
    }
}
2
  • 1
    You cannot create activities yourself, so there is no way to pass an interface in at construction like that. It's unclear what you are trying to do though with this interface anyway. Commented Aug 3, 2022 at 22:36
  • 1
    "i want to send my data to a Fragment, if you know any better approach please guide me" -- call a function on the fragment. Or, have the fragment and the activity share a ViewModel. Or, have the fragment's ViewModel and the activity's ViewModel share a common repository. FWIW, I cover some of those techniques in this free book. Commented Aug 3, 2022 at 23:48

2 Answers 2

2

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)
Sign up to request clarification or add additional context in comments.

Comments

0

Your MainClass must extend the interface for implementing

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

Now you can override your function sendData in MainActivity class

Comments

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.