关于数据收集的简化思考:结构化View数据自动跟随UI变化而更新

本文介绍了一种用于收集界面中被选中元素信息的方法。通过两种主要途径实现:一是标记选中状态并在提交时遍历元素;二是实时更新选择结果,简化外部访问流程。提供了具体的实现代码示例。

如下图所示,需要收集界面上哪些元素被选中了。且需要返回选中的Item的完整信息,没有选中的需要返回空,但该行其他信息需要返回,比如title: Processing speed等。
常规的方法有2种,
第一,点击选中,标记当前Item isSelected为true。点击提交时,遍历所有元素,找到isSelected为true的数据。
第二,每次选中元素,自动更新选择结果,在选择动作发生时计算当前结果,外部访问(比如提交数据)只需要直接访问最后的结果即可。

在这里插入图片描述

关键代码:

//ListView getView部分代码
// 结构化View初始化
            if (viewHolder.scv_labels != null && itemData != null) {
                boolean hasReviewLabelDTOList = itemData.reviewLabelDTOList != null && itemData.reviewLabelDTOList.size() > 0;
                if (hasReviewLabelDTOList) {  // 设置数据
                    viewHolder.scv_labels.setData(itemData);
                }
                if (itemData.proDescEval > NO_STAR && hasReviewLabelDTOList) { // 显示隐藏
                    viewHolder.scv_labels.setVisibility(View.VISIBLE);
                } else {
                    viewHolder.scv_labels.setVisibility(View.GONE);
                }
            }


//点击Item,自动计算当前选择结果
inner class LabelItemClickImpl: ILabelItemClickListener {
        override fun onItemClick() {
            curViewData?.selectedLabelData = getStructuredLabelData()
        }
    }

fun getStructuredLabelData(): Any {
            if (curViewData == null || curViewData?.reviewLabelDTOList == null || curViewData?.reviewLabelDTOList?.size == 0) {
                return ""
            }
            curViewData?.reviewLabelDTOList?.let {
                val selectedLabelData : ArrayList<StructuredLabelItem> = ArrayList()
                for (i in it.indices) {
                    val itemData = adapterList[i]?.getSelectedItem()
                    selectedLabelData.add(StructuredLabelItem(it[i].labelId, it[i].labelName, itemData))
                }
                return JSONObject.toJSON(selectedLabelData)
            }
            return ""
        }

fun getSelectedItem(): ArrayList<ValueOptionItem?> {
        if (currentSelectedIndex >= 0 && currentSelectedIndex < data.size) {
            val selectedList = ArrayList<ValueOptionItem?>()
            selectedList.add(data[currentSelectedIndex])
            return selectedList
        }
        return ArrayList()
    }

代码思路:
StructuredCommentView.kt

// 结构化评价整体View
class StructuredCommentView : LinearLayout {
    private lateinit var recyclerView: RecyclerView
    private lateinit var adapter: CommentsItemAdapter
    private var curViewData: LeaveFeedbackFragment.ViewData? = null

    constructor(context: Context) : super(context) {
        init()
    }
    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
        init()
    }
    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
        init()
    }

    private fun init() {
        val view = LayoutInflater.from(context).inflate(R.layout.m_myorder_frag_leave_feedback_structured_comment, this)
        recyclerView = view.findViewById(R.id.rv_structured_comments)
        val layoutManager = LinearLayoutManager(context)
        layoutManager.orientation = LinearLayoutManager.VERTICAL
        recyclerView.layoutManager = layoutManager
    }

    fun setData(viewData: LeaveFeedbackFragment.ViewData) {
        if (curViewData != viewData) {
            curViewData = viewData
            curViewData?.reviewLabelDTOList?.let { setDataInner(it) }
        }
    }

    private fun setDataInner(structuredLabelItems: ArrayList<StructuredLabelItem>) {
        adapter = CommentsItemAdapter(structuredLabelItems, context)
        recyclerView.adapter = adapter
    }

    fun getStructuredLabelData(): Any {
        return adapter.getStructuredLabelData()
    }

    inner class CommentsItemAdapter(val data: List<StructuredLabelItem>, val context: Context) :
        RecyclerView.Adapter<CommentsItemAdapter.ViewHolder>() {
        val adapterList = arrayOfNulls<StructuredCommentItemAdapter>(data.size)

        inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
            var titleView: TextView = itemView.findViewById(R.id.tv_title)
            var recyclerView: RecyclerView = itemView.findViewById(R.id.rv_structured_comment)
            fun bind(structuredLabelItem: StructuredLabelItem?, position: Int) {
                if (structuredLabelItem == null) {
                    return
                }
                titleView.text = structuredLabelItem.labelName
                structuredLabelItem.labelValueOptions?.let {
                    if (it.size > 0) {
                        val layoutManager = LinearLayoutManager(context)
                        layoutManager.orientation = LinearLayoutManager.HORIZONTAL
                        recyclerView.layoutManager = layoutManager
                        val adapter = StructuredCommentItemAdapter(it, context)
                        adapter.setLabelItemClickListener(LabelItemClickImpl())
                        recyclerView.adapter = adapter
                        adapterList[position] = adapter
                    }
                }
            }
        }

        override fun onCreateViewHolder(p0: ViewGroup, p1: Int): ViewHolder {
            val view = LayoutInflater.from(context).inflate(R.layout.m_myorder_frag_leave_feedback_structured_comment_item, null)
            return ViewHolder(view)
        }

        override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
            viewHolder.bind(data[position], position)
        }

        override fun getItemCount(): Int {
            return data.size
        }

        fun getStructuredLabelData(): Any {
            if (curViewData == null || curViewData?.reviewLabelDTOList == null || curViewData?.reviewLabelDTOList?.size == 0) {
                return ""
            }
            curViewData?.reviewLabelDTOList?.let {
                val selectedLabelData : ArrayList<StructuredLabelItem> = ArrayList()
                for (i in it.indices) {
                    val itemData = adapterList[i]?.getSelectedItem()
                    selectedLabelData.add(StructuredLabelItem(it[i].labelId, it[i].labelName, itemData))
                }
                return JSONObject.toJSON(selectedLabelData)
            }
            return ""
        }
    }
    interface ILabelItemClickListener {
        fun onItemClick()
    }

    inner class LabelItemClickImpl: ILabelItemClickListener {
        override fun onItemClick() {
            curViewData?.selectedLabelData = getStructuredLabelData()
        }
    }

}

m_myorder_frag_leave_feedback_structured_comment.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_structured_comments"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

StructuredCommentItemAdapter.kt

class StructuredCommentItemAdapter(val data: List<ValueOptionItem?>, val context: Context) :
    RecyclerView.Adapter<StructuredCommentItemAdapter.ViewHolder>() {
    private val ITEM_NUM = 3
    private val itemWidth = (AndroidUtil.getScreenWidth(context) - AndroidUtil.dp2px(context, 48f)) / ITEM_NUM
    private var currentSelectedIndex = -1
    private var labelItemClickListener : StructuredCommentView.ILabelItemClickListener? = null

    fun getSelectedItem(): ArrayList<ValueOptionItem?> {
        if (currentSelectedIndex >= 0 && currentSelectedIndex < data.size) {
            val selectedList = ArrayList<ValueOptionItem?>()
            selectedList.add(data[currentSelectedIndex])
            return selectedList
        }
        return ArrayList()
    }

    fun setLabelItemClickListener(listener: StructuredCommentView.ILabelItemClickListener) {
        labelItemClickListener = listener
    }

    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var titleView: TextView = itemView.findViewById(R.id.tv_title)
        var container: FrameLayout = itemView.findViewById(R.id.ll_container)
        fun bind(valueOptionItem: ValueOptionItem?, position: Int) {
            if (valueOptionItem == null) {
                return
            }
            titleView.text = valueOptionItem.labelValueName
            container.setOnClickListener {
                if (position != currentSelectedIndex) {
                    currentSelectedIndex = position
                    setSelectedIndex()
                    labelItemClickListener?.onItemClick()
                }
            }
            if (valueOptionItem.isSelected == true) {
                currentSelectedIndex = position
                container.setBackgroundResource(R.drawable.m_myorder_bg_structured_label_focused)
                titleView.setTextColor(Color.parseColor("#FD384F"))
            } else {
                container.setBackgroundResource(R.drawable.m_myorder_bg_structured_label_unfocused)
                titleView.setTextColor(Color.parseColor("#191919"))
            }
        }
    }

    @SuppressLint("NotifyDataSetChanged")
    private fun setSelectedIndex() {
        for (valueOptionItem : ValueOptionItem? in data) {
            if (valueOptionItem == null) {
                continue
            }
            valueOptionItem.isSelected = false
        }
        data[currentSelectedIndex]?.isSelected = true
        notifyDataSetChanged()
    }

    override fun onCreateViewHolder(parent: ViewGroup, p1: Int): ViewHolder {
        val view = LayoutInflater.from(context).inflate(R.layout.m_myorder_frag_leave_feedback_structured_comment_label_item, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
        viewHolder.itemView.layoutParams.width = itemWidth
        val layoutParams = viewHolder.itemView.layoutParams as RecyclerView.LayoutParams
        val marginRight = if (position == ITEM_NUM -1) 0 else AndroidUtil.dp2px(context, 8f)
        layoutParams.setMargins(0, 0, marginRight, 0)
        viewHolder.bind(data[position], position)
    }

    override fun getItemCount(): Int {
        return data.size
    }
}

m_myorder_frag_leave_feedback_structured_comment_label_item.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_container"
    android:layout_width="109dp"
    android:layout_height="32dp"
    android:layout_marginRight="8dp"
    android:paddingHorizontal="4dp"
    android:paddingVertical="4dp"
    android:background="@drawable/m_myorder_bg_structured_label_unfocused"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:textColor="#191919"
        android:autoSizeMaxTextSize="12sp"
        android:autoSizeMinTextSize="10sp"
        android:maxLines="2"
        android:ellipsize="end"
        android:autoSizeTextType="uniform"
        android:text="Sluggish"/>

</FrameLayout>

StructuredLabelItem.kt

data class StructuredLabelItem(var labelId: String?, var labelName: String?, var labelValueOptions: ArrayList<ValueOptionItem?>?) : Serializable

ValueOptionItem.kt

data class ValueOptionItem(var labelValueId: String?, var labelValueName: String?, var displayOption: String?, var score: String?, var isSelected: Boolean? = false) : Serializable
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值