Эталонный вид из включенного макета

У меня есть макет фрагмента со следующим тегом include:

<include
    android:id="@+id/ivRemoveData"
    layout="@layout/item_menu"
    android:layout_width="48dp"
    android:layout_height="48dp"
    android:layout_margin="16dp"
    android:visibility="visible"/>

item_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<ImageView
    android:id="@+id/ivIcon"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="48dp"
    android:layout_height="48dp"
    android:layout_centerInParent="true"

    android:visibility="gone"
    android:background="@drawable/not_passed_circle_level_item"
    android:clipChildren="false"
    android:clipToPadding="false"/>

Мне нужно использовать метод ivIcon.setImageResource().

Мой класс фрагмента:

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import kotlinx.android.synthetic.main.fragment_options.*
import kotlinx.android.synthetic.main.item_menu.view.*

class OptionsFragment : BaseFragment(), OptionsMVP.View
{
    override fun onCreateView(inflater : LayoutInflater, container : ViewGroup?, savedInstanceState : Bundle?) : View?
    {
        val view = inflater.inflate(R.layout.fragment_options, container, false)
        return view
    }

    override fun onViewCreated(view : View?, savedInstanceState : Bundle?)
    {
        super.onViewCreated(view, savedInstanceState)

        ivRemoveData.ivIcon.setImageResource(R.drawable.ic_delete)
    }
}

Я получаю сообщение об ошибке:

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setImageResource(int)' on a null object reference
      at hobbajt.com.BubbleQuiz.Options.OptionsFragment.onViewCreated(OptionsFragment.kt:29)
      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1314)

Кажется, что ivIcon имеет значение null, хотя оно находится во включенном макете. Как я могу ссылаться на этот ImageView?


person Hobbajt    schedule 06.06.2017    source источник
comment
Вы используете расширения kotlin?   -  person Raghunandan    schedule 06.06.2017
comment
Да, в моем модуле есть gradle: apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-android'   -  person Hobbajt    schedule 06.06.2017


Ответы (1)


Если вы укажете идентификатор для тега <include/>, он переопределит идентификатор родительского включенного макета.

В вашем случае most probably

android:id="@+id/ivRemoveData"

переопределяет идентификатор вашего imageView. И id ivIcon найти не удалось.

Вы можете изменить свой xml следующим образом:

<include
    android:id="@+id/ivIcon"
    layout="@layout/item_menu"
    android:layout_width="48dp"
    android:layout_height="48dp"
    android:layout_margin="16dp"
    android:visibility="visible"/>
person Oğuzhan Döngül    schedule 06.06.2017
comment
Я удалил идентификатор из тега include, а затем использовал ivIcon.setImageResource(R.drawable.ic_delete) - person Hobbajt; 06.06.2017
comment
^ Это то, что я собирался предложить. Этот ответ хорошо объясняет проблему, но вместо того, чтобы переименовывать тег включения, я бы просто отбросил идентификатор и использовал встроенные из включенного макета (это то, к чему пришел OP). - person AdamMc331; 06.06.2017
comment
@Hobbajt это было другое решение. Это тоже сработает. - person Oğuzhan Döngül; 06.06.2017
comment
Я также нашел другое решение. Я удалил идентификатор из item_menu и добавил приведение: (ivRemoveData as ImageView).setImageResource(R.drawable.ic_delete) - person Hobbajt; 06.06.2017
comment
@ AdamMc331 AdamMc331 Это не сработает, если один и тот же макет элемента включен несколько раз. В этом случае хитрость заключается в том, чтобы обернуть макет элемента (Imageview) относительным или линейным макетом. - person denvercoder9; 05.04.2018