简体   繁体   中英

Lateinit property mScrollView has not been initialized

I don't understand why I have this kind of error :

kotlin.UninitializedPropertyAccessException: lateinit property mScrollView has not been initialized

I mean I have this kind of code :

@BindView(R.id.scroll_view)
lateinit var mScrollView: ScrollView

And here you can find on onCreateView

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    AndroidSupportInjection.inject(this)
    val view = inflater.inflate(R.layout.fragment_delete_account_reason, container, false)

    mUnbinder = ButterKnife.bind(this, view)
    ViewUtils.setupUI(view, activity)
    hideNextBtnOnKeyboardOpens(mScrollView, mNextBtn)

    setupLayout()
    mPresenter.getReasonKeyOfDeleteAccount()

    return view
}

private fun setupLayout() {
    mScrollView.viewTreeObserver.addOnGlobalLayoutListener {
        val r = Rect()
        mScrollView.getWindowVisibleDisplayFrame(r)
        val screenHeight = mScrollView.rootView.height
        val keypadHeight = screenHeight - r.bottom

        if (keypadHeight > screenHeight * 0.15 && mInput.hasFocus()) { // Keyboard is visible
            val bottom = mNbCharactersMax.getBottom() + mNbCharactersMax.getPaddingBottom()
            val sy = mScrollView.scrollY
            val sh = mScrollView.height
            val delta = bottom - (sy + sh)
            mScrollView.smoothScrollBy(0, delta)
        }
    }
}

You can find here my xml. All other ID work (everyID match) but I have only a problem with scrollView, I dont know why. If I remove ScrollView, everything will work but I need this.

<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">

<ScrollView
    android:id="@+id/scroll_view"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:animateLayoutChanges="true"
    android:layout_marginBottom="@dimen/general_padding"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toTopOf="@id/delete_account_next"
    android:fillViewport="true">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/delete_account_description"
            fontPath="fonts/SourceSansPro-SemiBold.ttf"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="@dimen/general_padding"
            android:layout_marginTop="@dimen/general_padding"
            android:layout_marginEnd="@dimen/general_padding"
            android:letterSpacing="@dimen/general_letter_spacing"
            android:text="@string/delete_account_reason_description"
            android:textColor="@color/vision"
            android:textSize="18dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            tools:ignore="MissingPrefix,SpUsage" />

        <RadioGroup
            android:id="@+id/delete_account_radio_group"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_marginEnd="@dimen/two_third_padding"
            android:layout_marginStart="@dimen/two_third_padding"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/delete_account_description">

        </RadioGroup>

        <android.support.design.widget.TextInputLayout
            android:id="@+id/delete_account_input_reason_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/delete_account_reason_specify_hint"
            android:layout_marginStart="17dp"
            android:layout_marginEnd="17dp"
            android:layout_marginTop="@dimen/general_padding"
            android:visibility="invisible"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toBottomOf="@id/delete_account_radio_group">

            <android.support.v7.widget.AppCompatEditText
                android:id="@+id/delete_account_input_password"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                fontPath="fonts/SourceSansPro-SemiBold.ttf"
                tools:ignore="MissingPrefix,SpUsage"
                android:imeOptions="actionDone"
                android:textColor="@color/jiren"
                android:textSize="16dp" />

        </android.support.design.widget.TextInputLayout>

        <TextView
            android:id="@+id/delete_account_reason_nb_caracters"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            fontPath="fonts/SourceSansPro-SemiBold.ttf"
            app:layout_constraintTop_toBottomOf="@id/delete_account_input_reason_layout"
            app:layout_constraintEnd_toStartOf="@id/delete_account_reason_nb_caracters_max"
            android:layout_marginEnd="@dimen/quarter_padding"
            android:textColor="@color/wolverine"
            android:textSize="14dp"
            android:text="0"
            android:visibility="invisible"
            android:letterSpacing="@dimen/general_letter_spacing"
            tools:ignore="HardcodedText,MissingPrefix,SpUsage"/>

        <TextView
            android:id="@+id/delete_account_reason_nb_caracters_max"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            fontPath="fonts/SourceSansPro-SemiBold.ttf"
            app:layout_constraintTop_toBottomOf="@id/delete_account_input_reason_layout"
            app:layout_constraintEnd_toEndOf="parent"
            android:layout_marginEnd="@dimen/general_padding"
            android:text="@string/delete_account_reason_specify_max_characters"
            android:textColor="@color/wolverine"
            android:textSize="14dp"
            android:visibility="invisible"
            android:letterSpacing="@dimen/general_letter_spacing"
            tools:ignore="MissingPrefix,SpUsage"/>

    </android.support.constraint.ConstraintLayout>

</ScrollView>

<Button
    style="?borderlessButtonStyle"
    android:id="@+id/delete_account_next"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:minWidth="0dp"
    android:minHeight="0dp"
    android:textSize="17dp"
    android:paddingTop="@dimen/half_padding"
    android:paddingBottom="@dimen/half_padding"
    android:paddingStart="@dimen/one_half_padding"
    android:paddingEnd="@dimen/one_half_padding"
    android:textAllCaps="false"
    android:layout_marginTop="@dimen/double_padding"
    android:layout_marginBottom="@dimen/one_half_padding"
    android:textColor="@color/white"
    android:textAlignment="center"
    android:background="@drawable/button_blue"
    android:letterSpacing="@dimen/general_letter_spacing"
    android:text="@string/delete_account_next_label"
    android:enabled="false"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    fontPath="fonts/SourceSansPro-SemiBold.ttf"
    tools:ignore="MissingPrefix,SpUsage"/>

do you understand why ?

In onCreateView() initialize mScrollView :

mScrollView = view.findViewById<ScrollView>(R.id.scroll_view)
setupLayout()

In Kotlin you can also use Kotlin extensions to do view bindings. Configure the dependency in your gradle follow this link

Then, import your layout views ids by using import kotlinx.android.synthetic.main.<layout>.* You'll get rid of Butterknife and you'll have your views always bound in the code without any findviewbyids or @BindViews annotations

I suggest get rid of ButterKnife in Android with Kotlin cause it has inbuild synthetic feature. In your case you can use view with name scroll_view directly in your code:

private fun setupLayout() {
    scroll_view.viewTreeObserver.addOnGlobalLayoutListener {
        val r = Rect()
        scroll_view.getWindowVisibleDisplayFrame(r)
        val screenHeight = scroll_view.rootView.height
        val keypadHeight = screenHeight - r.bottom

        if (keypadHeight > screenHeight * 0.15 && mInput.hasFocus()) { // Keyboard is visible
            val bottom = mNbCharactersMax.getBottom() + mNbCharactersMax.getPaddingBottom()
            val sy = scroll_view.scrollY
            val sh = scroll_view.height
            val delta = bottom - (sy + sh)
            scroll_view.smoothScrollBy(0, delta)
        }
    }
}

Of cause scroll_view is not Java/Kotlin name convention so you can rename it in XML to something like scrollView and you don't require class variable at all. You just need an import something like import kotlinx.android.synthetic.main.main_activity.* but IDE will generate it automatically.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM