【问题标题】:Different layout for different rows using listView/recyclerView (showing either image or text)使用 listView/recyclerView 对不同行进行不同布局(显示图像或文本)
【发布时间】:2018-10-05 09:25:38
【问题描述】:

您好,我是 android 开发新手,目前正在开发我的第一个应用程序。假设现在我从上次活动中获得了一些数据——四个字符串数组列表——药物名称、图像的 URL 链接、颜色、形状。我想以这样的格式显示这些信息:

四列来自四个arrayLists中的项目。药物的数量取决于 arrayLists 的大小,我想向下滚动以查看每种药物。我在想也许可以使用 recyclerView 来完成这个。有两个问题:

  1. 如何自定义每一行,只让一行显示图片,其他行显示文字?我在网上查找,似乎客户适配器以相同的布局自定义每一行。

  2. 如果每次运行应用程序时药物 n 的数量都不同,如何在 .xml 文件中编写布局,因为它取决于上次活动的结果?我不能简单地在.xml文件中写固定数量的ListView。

有人可以给我一些建议吗?非常感谢!

【问题讨论】:

    标签: java android listview android-recyclerview


    【解决方案1】:

    您需要为您正在使用的项目定义视图类型。

    data class MedicineItem(val name, val imageUrl, val viewType)
    

    然后将列表传递给您的适配器

    覆盖适配器中的 getViewItemType() 方法。作为设计,我认为您将需要三种类型的医学项目视图。第一个是标题,第二个是普通项目,第三个是带有图像的医学项目。

    可以自己定义viewType的值,比如我刚做的

    class Constants {
      const val TITLE = 1
      const val NORMAL_ITEM = 2
      const val IMAGE_ITEM = 3
    }
    
     override fun getItemViewType(position: Int): Int {
        val item : MedicineItem = list[position]
        if(item.viewType == Constants.TITLE) 
           return Constants.TITLE
        else if(item.viewType == Constant.NORMAL_ITEM)
           return Constants.NORMAL_ITEM
        else if(item.viewType == Constant.NORMAL_ITEM)
           return Constants.IMAGE_ITEM
    }
    

    对于每个视图项的不同布局,您需要为每种类型创建三个布局(xml 文件)和三个 ViewHolder 类。然后定义要显示的布局。

    首先,在 onCreatViewHolder() 中,决定哪个 ViewHolder 将用于每个视图项。可以看到viewType的返回值。

     override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): RecyclerView.ViewHolder {
        if(viewType == Constants.TITLE) {
            return MedicineTitleViewHolder()
    
        } else if(viewType == Constants.NORMAL_ITEM) {
            return MedicineNormalViewHolder()
    
        } else if(viewType == Constants.IMAGE_ITEM) {
            return MedicineIamgeViewHolder()
    
        }
    
    }
    

    最后,现在在onBindViewHolder()中返回每个item的视图持有者进行回收,你可以看到bind()方法接收到单个数据,你可以传递一个MedicinItem数据对象来显示。

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder?, position: Int) {
        if (holder is MedicineTitleViewHolder) {
            (holder as MedicineTitleViewHolder).bind(list[position])
    
        } else if(holder as MedicineNormalViewHolder){
            (holder as MedicineNormalViewHolder).bind(list[position])
    
        } else if(viewType == Constants.IMAGE_ITEM) {
            (holder as MedicineIamgeViewHolder).bind(list[position]) 
    
        }
    }
    

    【讨论】:

      【解决方案2】:

      RecyclerView::Adapter 有一个 getItemViewType(position) 方法,你可以重写它并返回不同的视图类型。而在 createViewHolder(viewType) 中,您可以根据视图类型创建不同的视图。

      【讨论】:

        【解决方案3】:

        我认为您需要在回收站视图中创建一个回收站视图。您只需要创建包含 Medicine No 和另一个回收器视图的父回收器视图的项目布局文件。然后,您需要为包含可变数量药物的内部回收器视图创建项目布局文件。这回答了你的第 2 部分。

        对于第 1 部分,请参阅此链接。 How to create RecyclerView with multiple view type?

        【讨论】:

        • 把 recyclerview 放在另一个 recyclerview 里面是一个非常非常糟糕的主意。
        • 许多应用程序在另一个回收器中使用回收器来实现复杂的布局。
        • 这是可行的但非常糟糕的主意,尤其是对于线性列表。当您想在垂直列表中显示各种水平的 recyclerview 时,可以考虑在 recyclerview 中使用 recyclerview 的选项。例如,谷歌应用程序就做到了。但是,对于一个垂直列表,这不是一个好主意,因为如果您想更改项目 UI 或实施更多操作,例如更新项目的状态,那可能会很痛苦。
        猜你喜欢
        • 2012-03-28
        • 2012-07-23
        • 2016-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多