Search code examples
androidxmlmaterial-designandroid-flexboxlayout

Flexbox doesn't support cardview inside?


I want to create many cardviews inside flexbox layout. But i it always return NullPointerException. What error console said

android.view.InflateException: Binary XML file line #17: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:764) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730) at android.view.LayoutInflater.rInflate(LayoutInflater.java:863) at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824) at android.view.LayoutInflater.rInflate(LayoutInflater.java:866) at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824) at android.view.LayoutInflater.inflate(LayoutInflater.java:515) at android.view.LayoutInflater.inflate(LayoutInflater.java:423) at com.tribunnews.app.utils.CommonViewKt.inflate(CommonView.kt:193) at com.tribunnews.app.itemview.DetailTagsViewHolder.onBind(DetailTagsViewHolder.kt:34) at com.tribunnews.app.adapter.DetailAdapter.onBindViewHolder(DetailAdapter.kt:118) at com.tribunnews.app.adapter.DetailAdapter.onBindViewHolder(DetailAdapter.kt:17) at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7263) at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7343) at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6204) at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6470) at androidx.recyclerview.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:288) at androidx.recyclerview.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:345) at androidx.recyclerview.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:361) at androidx.recyclerview.widget.GapWorker.prefetch(GapWorker.java:368) at androidx.recyclerview.widget.GapWorker.run(GapWorker.java:399) at android.os.Handler.handleCallback(Handler.java:873) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:6669) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

i have tried manually create in layout xml still return crash, like this

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

    <com.google.android.flexbox.FlexboxLayout
        android:id="@+id/flexbox_parent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:visibility="visible"
        android:layout_marginTop="16dp"
        app:flexWrap="wrap">

        <androidx.appcompat.widget.AppCompatTextView
            android:layout_width="wrap_content"
            android:layout_height="32dp"
            android:layout_margin="4dp"
            android:drawablePadding="2dp"
            android:fontFamily="sans-serif"
            android:gravity="center"
            android:text="Tags"
            android:textColor="?attr/textcolorsecondary"
            android:textSize="14dp"
            android:textStyle="bold"
            app:drawableLeftCompat="@drawable/ic_tag_gray"
            app:drawableTint="@color/colorPrimary"/>


        <androidx.cardview.widget.CardView 
            android:layout_height="40dp"
            android:layout_width="wrap_content"
            android:paddingLeft="8dp"
            android:paddingRight="8dp"
            android:layout_margin="4dp"
            app:cardCornerRadius="@dimen/_4dp">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:background="@color/colorSeparatorLight"
                android:orientation="horizontal">

                <view
                    android:id="@+id/color_tags"
                    android:layout_width="3dp"
                    android:layout_height="match_parent"
                    android:background="#ff1000"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_gravity="center_vertical"
                    android:layout_marginStart="@dimen/_4dp"
                    android:layout_marginEnd="@dimen/_4dp"
                    android:gravity="center"
                    android:fontFamily="sans-serif"
                    android:text="UU Cipta kerja"
                    android:textColor="@color/colorPrimary"
                    android:textSize="14dp"
                    android:textStyle="bold"
                    android:clickable="true"
                    android:focusable="true"
                    android:id="@+id/tag_text"
                    android:background="@color/colorSeparatorLight"/>
            </LinearLayout>

        </androidx.cardview.widget.CardView>

    </com.google.android.flexbox.FlexboxLayout>

</LinearLayout>

Update Actually i want to create layoutInflater for cardview and add that items inside flexboxlayout. This is my viewholder where the inflater begin

class DetailTagsViewHolder(private val readActivity: ReadActivity,
                           val site : String?,
                           view: View) : DetailItemViewHolder(view) {

    private val ctx = view.context

    private val lsColor = listOf<Int>(R.color.tag_one, R.color.tag_two, R.color.tag_three,R.color.tag_four )

    override fun onBind(data: DetailItemUIModel) {

        (data as? DetailItemUIModel.TagList)?.let {
            val tags = it.list
            itemView.run {

                var tipsC = 0
                tags?.forEachIndexed { index, trendingTag ->
                    if (tipsC > index) {
                        tipsC = 0
                    }
                    val cardTag = ctx.inflate(R.layout.item_card_tag, flexbox_parent) as CardView

                    cardTag?.let {
                        if (!trendingTag.title.isNullOrEmpty()) {
                            val tipColorTag = cardTag.findViewById<View>(R.id.color_tags)
                            tipColorTag.setBackgroundColor(ContextCompat.getColor(context, lsColor[tipsC]))

                            val tagText = cardTag.findViewById<TextView>(R.id.tag_text)
                            tagText.text = trendingTag.title

                            cardTag.setOnClickListener {
                                readActivity.gotoPopularActivity(site,
                                        trendingTag.alias, site != "tribunnews",
                                        Constant.API_TYPE_TAG_QUERY, trendingTag.title)
                            }
                            tipsC++
                        }
                        flexbox_parent.addView(cardTag)
                    }
                }
            }
        }

    }
    override fun onRecycled() {}
}

and Extension function for inflate is

fun Context.inflate(layout: Int, parent: ViewGroup?): View {
    return LayoutInflater.from(this).inflate(layout, parent, false)
}

Solution

  • It's an issue of view.

    replace it with View in XML file.

    <View
       android:id="@+id/color_tags"
       android:layout_width="3dp"
       android:layout_height="match_parent"
       android:background="#ff1000"/>
    

    view is used with class attribute to define customview. Like this,

    <view
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        class="com.package.YourCustomView" />