Android片段活动:用getActivity()替换“ this”会引发错误:ClassCastException

时间:2019-03-27 13:55:49

标签: android kotlin

我尝试按照教程制作Todo-App。该应用程序正常运行。但是现在我想扩展教程并将MainActivity转换为片段,在MainActivity(ToDoActivity)中调用该片段。我读到一个片段没有上下文,因此应使用MainActivity的上下文。因此,我在片段中将this更改为getActivity()

上下文将切换到TaskAdapter类,该类是一个自定义BaseAdapter()。 TaskAdapter在上下文之外创建TaskRowListener接口。这与活动配合使用,但是转换为片段后会引发错误“ ToDoActivity”,无法将其强制转换为“ TaskAdapter $ TaskRowListener”

此片段中出现错误:
_adapter = TaskAdapter(getActivity(), _taskList!!)

,然后在适配器中: var _rowListener: TaskRowListener = context as TaskRowListener

如果我在原始代码中打印this,则结果为: com.Info_DH.sgru_rchr.UniversityGoesAgile.ToDoActivity@cbaaca4

如果我在转换后的片段中打印getActivity(),结果将是:com.Info_DH.sgru_rchr.UniversityGoesAgile.ToDoActivity@8aa307d

所以我更加困惑为什么它不起作用。 如果有人知道问题可能出在哪里,我将非常感激。

主要(ToDoActivity):

class ToDoActivity : FragmentActivity() {



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



        if (savedInstanceState == null) {
            supportFragmentManager
                .beginTransaction()
                .add(R.id.canvas, Todofragment.newInstance(), "Test")
                .commit()
        }


片段:

class Todofragment : Fragment(), TaskRowListener {

    var _taskList: MutableList<Task>? = null

    lateinit var _adapter: TaskAdapter

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        super.onCreate(savedInstanceState)

        _taskList = mutableListOf<Task>()

        _adapter = TaskAdapter(getActivity(), _taskList!!)

..............

}

TaskAdapter:

class TaskAdapter(context: Context, taskList: MutableList<Task>) : BaseAdapter() {

    private val _inflater: LayoutInflater = LayoutInflater.from(context)
    private var _taskList = taskList
     var _rowListener: TaskRowListener = context as TaskRowListener

.........
}

TaskRowListener:

interface TaskRowListener {

    fun onTaskChange(objectId: String, isDone: Boolean)
    fun onTaskDelete(objectId: String)
    fun onTaskEdit(objectId: String, taskDesc:String)

}

日志:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.Info_DH.sgru_rchr.UniversityGoesAgile, PID: 14117
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.Info_DH.sgru_rchr.UniversityGoesAgile/com.Info_DH.sgru_rchr.UniversityGoesAgile.ToDoActivity}: java.lang.ClassCastException: com.Info_DH.sgru_rchr.UniversityGoesAgile.ToDoActivity cannot be cast to com.Info_DH.sgru_rchr.UniversityGoesAgile.TaskAdapter$TaskRowListener
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
        at android.app.ActivityThread.-wrap12(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6077)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
     Caused by: java.lang.ClassCastException: com.Info_DH.sgru_rchr.UniversityGoesAgile.ToDoActivity cannot be cast to com.Info_DH.sgru_rchr.UniversityGoesAgile.TaskAdapter$TaskRowListener
        at com.Info_DH.sgru_rchr.UniversityGoesAgile.TaskAdapter.<init>(TaskAdapter.kt:19)
        at com.Info_DH.sgru_rchr.UniversityGoesAgile.Todofragment.onCreate(Todofragment.kt:89)
        at android.support.v4.app.Fragment.performCreate(Fragment.java:2339)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1377)
        at android.support.v4.app.FragmentTransition.addToFirstInLastOut(FragmentTransition.java:1109)
        at android.support.v4.app.FragmentTransition.calculateFragments(FragmentTransition.java:996)
        at android.support.v4.app.FragmentTransition.startTransitions(FragmentTransition.java:99)
        at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2364)
        at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2322)
        at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2229)
        at android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3221)
        at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3171)
        at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:192)
        at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:560)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1248)
        at android.app.Activity.performStart(Activity.java:6679)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2609)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707) 
        at android.app.ActivityThread.-wrap12(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:154) 
        at android.app.ActivityThread.main(ActivityThread.java:6077) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756) 

1 个答案:

答案 0 :(得分:0)

这是因为您期望TaskRowListener类中有TaskAdapter

class TaskAdapter(context: Context, taskList: MutableList<Task>) : BaseAdapter() {

    ..
     // here you're expecting a TaskRowListener
     var _rowListener: TaskRowListener = context as TaskRowListener

.........
}

但是您的活动不是TaskRowListener。因此,您需要修改活动以实现TaskRowListener,如下所示:

class ToDoActivity : FragmentActivity(), TaskRowListener {
  ...
}

尽管我认为您根本不应该使用活动来保持适配器仅由TodoFragment处理并继续使用:

_adapter = TaskAdapter(this, _taskList!!)