Контекст Android NullPointerException: попытка вызвать виртуальный метод для ссылки на пустой объект - PullRequest
0 голосов
/ 16 мая 2018

Я хочу создать TableLayout в своем фрагменте для вставки данных. Я использовал для этого этот метод ниже.

Мне нужно вызвать метод updateTable вне метода onCreated view.

Но я всегда получаю эту ошибку:

java.lang.NullPointerException: попытка вызвать виртуальный метод 'android.content.res.Resources android.content.Context.getResources ()' для ссылки на пустой объект

Полный код ошибки:

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.tharwa.tdm2_exo2, PID: 5480
                  java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
                      at android.view.ViewConfiguration.get(ViewConfiguration.java:364)

                      ...

                      at com.tharwa.tdm2_exo2.TableAgent.TablePresentation.updateTable(TablePresentation.kt:61)

Я пробовал несколько способов избежать этой ошибки, но все равно появляется всегда. Я тоже пытался получить контекст от onCreatedView, но не работает.

Вот моя функция:

class TablePresentation : DialogFragment(),tableContract.View
{
    ....

     override fun updateTable(temps: ArrayList<Double>)
     {
         for (i in 0 until temps.size) {
        val row =  TableRow(activity)
        row.setLayoutParams(LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT))
        row.setWeightSum(2.0f)
        val tv1 = TextView(activity)
        val tv2= TextView(activity)

        ...

        table!!.addView(row, i)
        }
     }

}

Вот полный код класса:

class TablePresentation : DialogFragment(),tableContract.View
{

    var table: TableLayout?=null

    override fun onCreateView(inflater: LayoutInflater?, parent: ViewGroup?, state: Bundle?): View? {
        super.onCreateView(inflater, parent, state)
        val view = activity.layoutInflater.inflate(R.layout.table_fragment, parent, false)
        view.findViewById<View>(R.id.button_close)?.setOnClickListener({ dismiss() })
        return view
    }

    override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        table = view?.findViewById<View>(R.id.simpleTableLayout) as TableLayout
    }


    override fun onCreate(savedInstanceState: Bundle?) {
     ...
    }

    override fun onStart() {
      ...
    }


     override fun updateTable(temps: ArrayList<Double>)
     {
        ....
     }

}

и вот как я прикрепляю вид к контроллеру:

class PaletteController
{
    var father: FatherController?=null
    val view: PaletterPresentation
    var model:PaletteAbstraction?=null
    var TableSon:TableController?=null

    constructor(view:PaletterPresentation)
    {
        this.view=view
        view.controller=this
        this.model= PaletteAbstraction()

    }
    ....

    fun notifyTableChild()
    {
        TableSon= TableController(view.getTableChild())
        setChildSFather()
        TableSon?.updateTable( father!!.giveTemps())
    }
}

Вот почему я создаю фрагмент:

class PaletterPresentation: Fragment(), PaletteContract.View
{
    var views: View? = null
    var controller: PaletteController?=null

    val tablePresentation=TablePresentation()

    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        views = inflater!!.inflate(R.layout.palette_fragement, container, false)
        return views
    }
    override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        fab.setOnClickListener { view ->
            val ft = childFragmentManager.beginTransaction()
            tablePresentation.show(ft, ContentValues.TAG)
            controller?.notifyTableChild()
        }
    }


    override fun getTableChild(): TablePresentation {
        return tablePresentation
    }

}

Я действительно не знаю, как решить эту проблему.

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

@ Деннис К weel, мы можем вызвать метод из onAttach или даже из onViewCreated. Я знаю, что это прекрасно работает.

Но мой вопрос заключался в том, почему мы не можем сделать это ** вызовом метода, который я имею в виду ** вне этих двух методов. Почему мы не можем этого сделать?

Наконец, потому что я не нашел ответа на свой вопрос, почему я вызвал свой метод из onViewCreated.or, даже для onAttached.like, вы сказали @Dennis K.

Вот звонок

 override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        table = view?.findViewById<View>(R.id.simpleTableLayout) as TableLayout
        updateTable()
    }

Вот функция

fun updateTable()
     {
         val temps=controller?.getTemps()
         for (i in 0 until temps!!.size) {
        val row =  TableRow( activity)
        row.setLayoutParams(LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT))
        row.setWeightSum(2.0f)
        val tv1 = TextView( activity)
        val tv2= TextView(activity)

        tv1.setLayoutParams(TableRow.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f))
        tv2.setLayoutParams(TableRow.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f))

        tv1.setGravity(Gravity.CENTER)
        tv2.setGravity(Gravity.CENTER)

        tv1.setText((i+1).toString())
        tv2.setText(temps.get(i).toString())

        // finally add our textviews to TableRow
        row.addView(tv1)
        row.addView(tv2)
        //finally add our TableRow to Tablelayout
        table!!.addView(row, i)
        }
     }

Почему, почему, почему за пределами onAttach / onViewCreated мы не можем получить допустимое действие (которое является контекстом).

0 голосов
/ 16 мая 2018

Ваш фрагмент не прикреплен.

Вы делаете это:

    TableSon= TableController(view.getTableChild())
    setChildSFather()
    TableSon?.updateTable( father!!.giveTemps())

Где getTableChild возвращает то, что было инициализировано следующим образом:

val tablePresentation=TablePresentation()

Это создает «мошеннический» фрагмент, который ни к чему не привязан.

Один из способов решения этой конкретной проблемы - запомнить массив во фрагменте TablePresentation и вызвать updateTable из onAttach.

РЕДАКТИРОВАТЬ: Под "запомнить" я имею в виду сохранить его в аргументах, а не просто сохранить в элементе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...