0

I have a ConstraintLayout file called R.layout.new_plan which contains the Views needed to display a PlanItem object. I'd like to display a list of R.layout.new_plan's in a RelativeLayout root view.

My RelativeLayout parent/root is like so:

<RelativeLayout
        android:id="@+id/rl_plan_items"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        <!-- other properties here -->
</RelativeLayout>

In other words, I have a List<PlanItem> and I'd like to display this list, using a R.layout.new_plan view to display each PlanItem, in rl_plan_items. My current way of doing it is to loop for each PlanItem in the list, set TextViews in R.layout.new_plan according to the attributes of the current PlanItem, and adding it to rl_plan_items using RelativeLayout.LayoutParams somehow.

The code is like this:

private fun PlanItem.addToRootView(rootView: RelativeLayout, pos: Int) {
    val planItemView: ConstraintLayout = inflater
        .inflate(R.layout.new_plan, rootView, false) as ConstraintLayout

    planItemView.id = pos

    with(planItemView) {
        tv_title.text = name
        tv_desc.setTextAndGoneIfEmpty(description)
        tv_date.text = getDateToDisplay(resources)
        tv_subject.setTextAndGoneIfEmpty(subject?.name)
    }

    val params = planItemView.layoutParams as RelativeLayout.LayoutParams

    val idOfBelow: Int = if (pos > 0) planItemView.id - 1 else rootView.id
    params.addRule(RelativeLayout.BELOW, idOfBelow)

    rootView.addView(planItemView, params)
}

in my fragment:

for (i in planItems.indices) {
    planItems[i].addToRootView(rl_plan_items, i)
}

This does show all PlanItems, but they are shown on top of each other, not going down to the bottom.

enter image description here

enter image description here

How can I display the plan item views in order going down, not crunched together?

Fawwaz Yusran
  • 1,260
  • 2
  • 19
  • 36

1 Answers1

0

The key thing that I needed to do is to set the planItemView id to an id that's never used in my app. so I created a number constant that's unlikely to be used by other Views, and use it as a base for the 2nd, 3rd, 4th, etc. plan item view.

After that the RelativeLayout root is showing the individual plan item view correctly.

  1. add to top of class

    companion object {
        private const val BASE_PLAN_ITEM_ID = 164
    }
    
  2. Update method

    private fun PlanItem.addToRootView(
        rootView: RelativeLayout,
        pos: Int,
        r: Resources
    ) {
        val planItemView: ConstraintLayout = inflater
            .inflate(R.layout.new_plan, rootView, false) as ConstraintLayout
    
        planItemView.id = BASE_PLAN_ITEM_ID + pos
    
        with(planItemView) {
            tv_title.text = name
            tv_desc.setTextAndGoneIfEmpty(description)
            tv_date.text = getDateToDisplay(resources)
            tv_subject.setTextAndGoneIfEmpty(subject?.name)
        }
    
        val params = planItemView.layoutParams as RelativeLayout.LayoutParams
    
        val idOfBelow: Int
    
        if (planItemView.id > BASE_PLAN_ITEM_ID) {
            idOfBelow = planItemView.id - 1
    
            // If it is the 2nd or more item in the list, add a margin above it
            params.setMargins(
                params.leftMargin,
                calculatePx(16, r),
                params.rightMargin,
                params.bottomMargin
            )
        } else {
            idOfBelow = rootView.id
        }
        params.addRule(RelativeLayout.BELOW, idOfBelow)
    
        rootView.addView(planItemView, params)
    }
    
Fawwaz Yusran
  • 1,260
  • 2
  • 19
  • 36