0

I have a custom view use kotlin android extension to find sub view, everything work well on real device and virtual device. When use custom view in Android Sutdio Layout preview throw java.lang.NullPointerException

clear and rebuild have done many times

Android studio: 3.2.1

kotlin : 1.2.50-71

But same code work properly on Android studio 3.1.4

This not a simple NPE problem, this may cause by Android Studio Layout Preview

Custom View:

    import android.content.Context
    import android.util.AttributeSet
    import android.view.View
    import android.widget.RelativeLayout
    import com.youzan.retail.stock.R
    import kotlinx.android.synthetic.main.stock_item_setting_icon.view.*


    internal class ItemSettingIcon : RelativeLayout {
        constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
            initLayout(context, attrs)
        }

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

        private fun initLayout(context: Context?, attrs: AttributeSet?) {
            if (context == null || attrs == null)
                return

            View.inflate(context, R.layout.stock_item_setting_icon, this)
            val typedArray = context.obtainStyledAttributes(attrs, R.styleable.ItemSettingIcon)
            item_icon.setImageResource(typedArray.getResourceId(R.styleable.ItemSettingIcon_item_icon, -1)) //NPE here
            item_title.setText(typedArray.getResourceId(R.styleable.ItemSettingIcon_item_title, -1))
            typedArray.recycle()
        }
    }

R.layout.stock_item_setting_icon:

    <?xml version="1.0" encoding="utf-8"?>
    <merge xmlns:android="http://schemas.android.com/apk/res/android">

        <ImageView
            android:id="@+id/item_icon"
            android:layout_width="@dimen/stock_setting_item_icon_size"
            android:layout_height="@dimen/stock_setting_item_icon_size"
            android:layout_alignParentLeft="true"
            android:layout_centerVertical="true"
            android:layout_marginLeft="@dimen/stock_content_left_margin" />


        <TextView
            android:id="@+id/item_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="@dimen/stock_10dp"
            android:layout_toRightOf="@id/item_icon"
            android:text="@string/stock_query"
            android:textColor="@color/stock_setting_item_text_color"
            android:textSize="@dimen/stock_setting_item_text_size" />


        <ImageView
            android:id="@+id/item_end_icon"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="@dimen/stock_15dp"
            android:src="@drawable/stock_icon_right_arrow" />

    </merge>

R.styleable.ItemSettingIcon:

<declare-styleable name="ItemSettingIcon">
    <attr name="item_icon" format="reference" />
    <attr name="item_title" format="string" />
</declare-styleable>

Error log:

java.lang.NullPointerException
        at com.youzan.retail.stock.view.ItemSettingIcon.initLayout(ItemSettingIcon.kt:30)
        at com.youzan.retail.stock.view.ItemSettingIcon.<init>(ItemSettingIcon.kt:17)
        at sun.reflect.GeneratedConstructorAccessor968.newInstance(Unknown Source)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at org.jetbrains.android.uipreview.ViewLoader.createNewInstance(ViewLoader.java:401)
        at org.jetbrains.android.uipreview.ViewLoader.loadClass(ViewLoader.java:184)
        at org.jetbrains.android.uipreview.ViewLoader.loadView(ViewLoader.java:142)
        at com.android.tools.idea.rendering.LayoutlibCallbackImpl.loadView(LayoutlibCallbackImpl.java:229)
        at android.view.BridgeInflater.loadCustomView(BridgeInflater.java:421)
        at android.view.BridgeInflater.loadCustomView(BridgeInflater.java:432)
        at android.view.BridgeInflater.createViewFromTag(BridgeInflater.java:336)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730)
        at android.view.LayoutInflater.rInflate_Original(LayoutInflater.java:863)
        at android.view.LayoutInflater_Delegate.rInflate(LayoutInflater_Delegate.java:72)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:837)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
        at android.view.LayoutInflater.rInflate_Original(LayoutInflater.java:866)
        at android.view.LayoutInflater_Delegate.rInflate(LayoutInflater_Delegate.java:72)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:837)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
        at android.view.LayoutInflater.rInflate_Original(LayoutInflater.java:866)
        at android.view.LayoutInflater_Delegate.rInflate(LayoutInflater_Delegate.java:72)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:837)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:394)
        at com.android.layoutlib.bridge.impl.RenderSessionImpl.inflate(RenderSessionImpl.java:327)
        at com.android.layoutlib.bridge.Bridge.createSession(Bridge.java:386)
        at com.android.tools.idea.layoutlib.LayoutLibrary.createSession(LayoutLibrary.java:193)
        at com.android.tools.idea.rendering.RenderTask.createRenderSession(RenderTask.java:450)
        at com.android.tools.idea.rendering.RenderTask.lambda$inflate$3(RenderTask.java:590)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

Is there some mistakes do I make ?

Fantasy_RQG
  • 133
  • 1
  • 12

1 Answers1

0
import kotlinx.android.synthetic.main.stock_item_setting_icon.view.*

This is probably the problem. Kotlin Android plugin only works on Activity and Fragment. You can use findViewById with context.

Joshua
  • 4,757
  • 1
  • 23
  • 45
  • This work with custom view , decompilation code : `((ImageView)this._$_findCachedViewById(id.item_icon)).setImageResource(typedArray.getResourceId(styleable.ItemSettingIcon_item_icon, -1));` – Fantasy_RQG Dec 04 '18 at 06:23