Search code examples
androidkotlinspinner

I have problem with spinneradapter in fragment


I'm working android app with kotlin. I'm set the selected value wtih 3 spinners in AddDebtFragment and 3 String arrays in resources file. but when i try to navigate from my HomeFragment to this fragment, the application is terminated and it shows problem on Logcat in the fragment

and Here is my spinners in fragment_add_debt.xml

<Spinner
    android:id="@+id/debtCategorySpinner"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    style="@style/SpinnerStyle"
    android:spinnerMode="dialog" 
    android:entries="@array/debtCategoryList"/>

<Spinner
    android:id="@+id/financialNameSpinner"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:spinnerMode="dialog"
    style="@style/SpinnerStyle"
    android:entries="@array/financialNameList"/>
<Spinner
        android:id="@+id/rateTypeSpinner"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="@style/SpinnerStyle"
        android:spinnerMode="dialog"
        android:entries="@array/rateTypeList"/>

The string-array in resource file

<string-array name="financialNameList">
        <item>Bangkok Bank</item>
        <item>Kasikorn Bank</item>
        <item>Krung Thai Bank</item>
        <item>The Siam Commercial Bank</item>
        <item>TMB Bank</item>
        <item>Bank of Ayudhya</item>
    </string-array>

    <string-array name="debtCategoryList">
        <item>Personal Loan</item>
        <item>Vehicle Loan</item>
        <item>Indonesia</item>
        <item>Mortgage</item>
        <item>Student Loan</item>
        <item>Credit Card</item>
    </string-array>

    <string-array name="rateTypeList">
        <item>Effective Rate</item>
        <item>Flat Rate</item>
        <item>Fixed Rate</item>
        <item>MRR</item>
        <item>MOR</item>
        <item>MLR</item>
        <item>Student Rate</item>
        <item>Credit Card</item>
        <item>Ceiling</item>
        <item>Default</item>
    </string-array>

AddDebtFragment

import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.ArrayAdapter
import com.example.debtrearragement.R
import kotlinx.android.synthetic.main.fragment_add_debt.*
class AddDebtFragment : Fragment(), AdapterView.OnItemSelectedListener {

    private val financialSpinner = financialNameSpinner
    private val debtSpinner = debtCategorySpinner
    private val rateSpinner = rateTypeSpinner

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_add_debt, container, false)
    }

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

        ArrayAdapter.createFromResource(context, R.array.financialNameList, android.R.layout.simple_spinner_item)
            .also { adapter ->
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
            financialSpinner.adapter
            financialSpinner.onItemSelectedListener
        }

        ArrayAdapter.createFromResource(this.context, R.array.debtCategoryList, android.R.layout.simple_spinner_dropdown_item)
            .also { adapter ->
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
            debtSpinner.adapter
            debtSpinner.onItemSelectedListener
        }

        ArrayAdapter.createFromResource(this.context, R.array.rateTypeList, android.R.layout.simple_spinner_dropdown_item)
            .also { adapter ->
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
            rateSpinner.adapter
            rateSpinner.onItemSelectedListener
        }

    }

    override fun onNothingSelected(parent: AdapterView<*>) {

    }
    override fun onItemSelected(parent: AdapterView<*>, view: View,position: Int, id: Long) {

    }
}

Edit : 1 - Here is Logcat

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.debtrearragement, PID: 29305
    java.lang.IllegalStateException: financialSpinner must not be null
        at com.example.debtrearragement.view.ui.debt.AddDebtFragment.onViewCreated(AddDebtFragment.kt:34)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:892)
        at androidx.fragment.app.FragmentManagerImpl.addAddedFragments(FragmentManagerImpl.java:2097)
        at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1871)
        at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1827)
        at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
        at androidx.fragment.app.FragmentManagerImpl$2.run(FragmentManagerImpl.java:150)
        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/Process: Sending signal. PID: 29305 SIG: 9
Application terminated.

Edit : 2 - and i just see it shows on complier too.

enter image description here


Solution

  • You don't need to declare new variables for the Spinners as you are using kotlin synthetic properties. Just remove

    private val financialSpinner = financialNameSpinner
    private val debtSpinner = debtCategorySpinner
    private val rateSpinner = rateTypeSpinner
    

    and replace financialSpinner with financialNameSpinner, debtSpinner with debtCategorySpinner and rateSpinner with rateTypeSpinner in your code.

    You can find more about Kotlin Android Extension from the docs

    Fix for the warning

    You're getting this warning because the ArrayAdapter.createFromResource requires a Context object while context(From getContext) returns a nullable Context object. What you can do is convert the nullable object to a non-null object using !!

    ArrayAdapter.createFromResource(context!!, R.array.financialNameList, android.R.layout.simple_spinner_item)
    

    Read this doc to find out more about Null Safety in Kotlin