Kotlin是否有办法将接口的实现委派给另一个类?

时间:2018-08-28 11:25:17

标签: android kotlin

我正在为应用程序使用一项活动和三个片段

每个片段都有一个用于与逻辑通信的接口

该活动实现此接口,并使用相同的参数调用逻辑对象(一个持久性片段),因此它看起来像这样:

class Child : Fragment() {

     private fun userInteraction() {
          (activity as? ChildInteraction)?.askStuff()
     }

     interface ChildInteraction {
          fun askStuff():Unit
     }


}


class ParentActivity : AppCompatActivity(), ChildInteraction {

    override fun askStuff() {
        (supportFragmentManager.findFragmentByTag("LOGIC") as? ChildInteraction).askStuff()
    }
}


class LogicFragment : Fragment(), ChildInteraction {

     override fun askStuff() {
         //do some work here
     }

 }

问题是,每个交互都具有5-10个方法,而ParentActivity所做的只是传递消息,有没有办法简化传递?

我知道您无法使用Java做到这一点,但我希望Kotlin可以做到这一点

2 个答案:

答案 0 :(得分:1)

看看setTargetFragmentgetTargetFragment。这是片段到片段通信的示例:

interface ChildInteraction {
    companion object

    fun askStuff()
}

fun ChildInteraction.Companion.wrap(f: Fragment) = (f.targetFragment as? ChildInteraction)

class Child1 : Fragment() {

    private fun userInteraction() {
        ChildInteraction.wrap(this)?.askStuff()
    }
}

class Child2 : Fragment() {

    private fun userInteraction() {
        ChildInteraction.wrap(this)?.askStuff()
    }
}

class LogicFragment : Fragment(), ChildInteraction {

    override fun askStuff() {
        //do some work here
    }
}

class ParentActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val logic ...

        val child1 ...
        child1.setTargetFragment(logic, 0)

        val child2 ...
        child2.setTargetFragment(logic, 0)
    }
}

答案 1 :(得分:0)

现在我知道这可能对我有用,因此我仍会接受另一个答案,因为它教会了我一些我不知道的东西。

但是经过一些工作,我的处理方式是这样:

附着的片段如下:

class Child : Fragment() {

    private var parent: ChildInteraction? = null

    override fun onAttach(context: Context?) {
        super.onAttach(context)
        //this should throw an exception if it is not implemented correctly
        parent = (context as LogicProvider).logic!! as Child.ChildInteraction
    }

    private fun userInteraction() {
        parent!!.askStuff()
    }

    interface ChildInteraction {
        fun askStuff():Unit
    }
}

然后我有一个LogicProvider界面,如下所示:

interface LogicProvider {
    val logic: Any?
}

然后父级将实现传递参数的逻辑提供程序

class ParentActivity : AppCompatActivity(), LogicProvider {
  override var logic: Logic? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        var frag: Fragment? = supportFragmentManager.findFragmentByTag("parent_logic")
        if (frag == null) {
            frag = Logic()
            supportFragmentManager.beginTransaction().add(frag, "parent_logic").commitNow()
        }
        logic = frag as Logic
    }

    override fun onPause() {
        super.onPause()
        if (isFinishing)
            supportFragmentManager.beginTransaction().remove(supportFragmentManager.findFragmentByTag("parent_logic")).commitNow()
    }

}

那样,逻辑片段是唯一必须实现接口的片段

class Logic : Fragment(), Child.ChildInteraction, Child2.ChildInteraction2 {
    override fun askStuff() {
        //do stuff here
    }
    override fun askStuff2() {
        //do other stuff here
    }

}