代码之家  ›  专栏  ›  技术社区  ›  Zar E Ahmer

处理Fragment中所有类型响应的通用方法

  •  0
  • Zar E Ahmer  · 技术社区  · 4 年前

    我创造了一个 通用片段 类来处理来自服务器的所有类型的响应。我想做点什么 数据表提供者<*> 拒绝任何形式的回应。

    我怎么能做到这一点。

    class TestFragmentActivity : AppCompatActivity(), DataTableProvider<Any> {
    
        protected val mTabPatientsFragment = TabPatientsFragment()
        protected val mTabObservationsFragment = TabObservationsFragment()
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_test_fragment)
    
            replaceFragment()
    
        }
    
        private fun replaceFragment(){
            supportFragmentManager.beginTransaction().replace(R.id.frame_container,
                mTabPatientsFragment).commit()
        }
    
        override fun getDataTableListener(mTableFragment: DataTableFragment<Any>): DataTableListener<Any> {
            val dataTableId = mTableFragment.dataTableId
            if (dataTableId.equals("observations"))
                return mTabObservationsFragment
            else return mTabPatientsFragment
        }
    
        override fun getDataTableConfig(mTableFragment: DataTableFragment<Any>): DataTableConfig {
            val dataTableId = mTableFragment.dataTableId
            val config = DataTableConfig()
    
            config.noRecordCell = R.layout.cell_no_record
            config.showSearch = false
            config.showAddButton = false
    
            if (dataTableId.equals("observations"))
            {
                config.cellResourceId = R.layout.home_observation_cell
            } else config.cellResourceId = R.layout.home_patient_cell
    
            return config
        }
    
    }
    

    getDataTableListener 上述片段中的回调有错误 类型不匹配所需DataTableListener找到TabObservationFragment

    标签观察片段

    class TabObservationFragment : AppBaseFragment(),DataTableListener<Observation>
    

    标签碎片

    class TabPatientFragment : AppBaseFragment(),DataTableListener<Patient>
    

    我如何设置它适用于所有类型的响应。

    我试过了 DataTableListener<*> 但未能实现

    错误状态

    不允许对超类型的直接参数进行投影

    如何使用DataTableProvider<*>适用于所有类型的响应

    编辑

    我在TestFragmentActivity中有几个带有fragmentViewpager的片段。

    我有一个结构,可以帮助实现分页、搜索和实现片段中的所有内容。但根据该结构,DataTableProvider必须在活动和tableId的基础上处理我更新的回调 getDataTableListener getDataTableListener

    上面的回调应该返回某种类型的

    是否有如下方法实现回调

    override fun getDataTableConfig(mTableFragment: DataTableFragment<*>?): DataTableConfig?
    
    override fun getDataTableListener(mTableFragment: DataTableFragment<*>?): DataTableListener<*>?
    
    0 回复  |  直到 4 年前
        1
  •  0
  •   Rafał Kuźmiński    4 年前

    快速回答,使用“out”修饰符:

    fun getDataTableListener(mTableFragment: DataTableFragment<Any>): DataTableListener<out Any>
    

    长答案:

    你正在寻找的是方差,你可以在kotlin的官方文档中读到它: https://kotlinlang.org/docs/reference/generics.html

    因为例如List接口看起来像这样:

    public interface List<out E>
    

    你可以这样做:

    val list: List<Any> = listOf(1,2,3)
    

    但不可能做到:

    val mutableList : MutableList<Any> = listOf(1,2,3)
    

    因为MutableList没有“out”修饰符。这是有道理的,因为MutableList是可以更改的,例如,您可以将其添加为MutableList,但它已经指向List。

    在您的示例中,如果且仅当DataTableListener不使用泛型类型作为输入时,您可以使用“out”修饰符。例如:

    interface DataTableListener<T>{
        fun assignValue(t:T)
        fun getValue():T
    }
    

    使用上述接口,您仍然可以在函数中使用“out”修饰符,但您将无法执行“assignValue”函数。

    整个示例:

    class Patient
    class Observation
    
    class DataTableFragment<T>
    interface DataTableListener<T> {
        fun assignValue(t: T)
        fun getValue(): T
    }
    
    class TabObservationFragment : DataTableListener<Observation> {
        override fun getValue(): Observation {
            TODO("Not yet implemented")
        }
    
        override fun assignValue(t: Observation) {
            TODO("Not yet implemented")
        }
    }
    
    class TabPatientFragment : DataTableListener<Patient> {
        override fun getValue(): Patient {
        }
    
        override fun assignValue(t: Patient) {
            TODO("Not yet implemented")
        }
    }
    
    val mTabObservationsFragment = TabObservationFragment()
    val mTabPatientsFragment = TabPatientFragment()
    
    fun getDataTableListener(mTableFragment: DataTableFragment<Any>): DataTableListener<out Any> {
        val test = "observations"
        if (test == "observations")
            return mTabObservationsFragment
        else return mTabPatientsFragment
    }
    
    fun getIt() {
        val listener = getDataTableListener(DataTableFragment())
        listener.assignValue("test")
    }