Ошибка получения ссылки на нулевой объект при использовании BottomSheetBehavior - PullRequest
0 голосов
/ 13 июля 2020

Я создал стандартный нижний лист xml файл и включил нижний лист xml внутрь фрагмента CoordinatorLayout.

после компиляции и запуска приложения

Я обнаружил эту ошибку

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.ourdesign, PID: 8015
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.ViewGroup$LayoutParams android.view.View.getLayoutParams()' on a null object reference
    at com.google.android.material.bottomsheet.BottomSheetBehavior.from(BottomSheetBehavior.java:1479)
    at com.example.ourdesign.design.LowDesignFragment.onCreateView(LowDesignFragment.kt:55)
    at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2600)
    at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
    at androidx.fragment.app.FragmentManagerImpl.addAddedFragments(FragmentManagerImpl.java:2100)
    at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1874)
    at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1830)
    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)

Не удалось найти причину

этот код является частью фрагмента kotlin файла.

class LowDesignFragment : Fragment() {
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null

// binding
private lateinit var binding: FragmentLowDesignBinding

// buttonSheet
private lateinit var bottomSheetBehavior : BottomSheetBehavior<LinearLayout>
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    arguments?.let {
        param1 = it.getString(ARG_PARAM1)
        param2 = it.getString(ARG_PARAM2)
    }
}

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    binding = DataBindingUtil.inflate(inflater, R.layout.fragment_low_design, container, false)
    bottomSheetBehavior = BottomSheetBehavior.from<LinearLayout>(standardBottomSheet)
    bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED)
    binding.include.toggleButton.setOnCheckedChangeListener { _, isChecked ->
        if (isChecked) {
            bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED)
        } else {
            bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED)
        }
    }
    return binding.root
}

Этот код является фрагментом xml файла.

<?xml version="1.0" encoding="utf-8"?>
<layout 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"
    tools:context=".MainActivity">

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <!-- TODO: Update blank fragment layout -->
        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/constraintLayout2"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

        </androidx.constraintlayout.widget.ConstraintLayout>

        <include
            android:id="@+id/include"
            layout="@layout/low_design_bottom_sheet"
            app:layout_anchorGravity="top|center" />

        <ImageView
            android:id="@+id/imageView"
            android:layout_width="403dp"
            android:layout_height="659dp"
            android:layout_marginStart="16dp"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="16dp"
            android:layout_marginBottom="16dp"
            app:layout_anchorGravity="center"
            tools:srcCompat="@tools:sample/backgrounds/scenic" />

    </androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>

Этот код - нижний лист xml файл.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/standardBottomSheet"
    style="@style/bottom_sheet_row_style"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:behavior_hideable="true"
    app:behavior_peekHeight="?actionBarSize"
    app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="?actionBarSize"
        android:orientation="horizontal">

        <ToggleButton
            android:id="@+id/toggleButton"
            android:layout_width="36dp"
            android:layout_height="36dp"
            android:background="@drawable/ic_expand_less_black_36dp"
            android:textOff=""
            android:textOn=""
            android:text="" />

        <TextView
            android:id="@+id/editTool"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Edit Tool"
            android:textAlignment="center" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <LinearLayout
            style="@style/bottom_sheet_row_style"
            android:layout_gravity="center">

            <ImageView
                style="@style/bottom_sheet_element_image_style"
                android:contentDescription="@string/text"
                android:src="@drawable/ic_text_format_black_48dp" />

            <TextView
                style="@style/bottom_sheet_element_text_style"
                android:text="@string/text" />
        </LinearLayout>

        <LinearLayout style="@style/bottom_sheet_row_style">

            <ImageView
                style="@style/bottom_sheet_element_image_style"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:contentDescription="@string/text"
                android:src="@drawable/ic_text_format_black_48dp" />

            <TextView
                style="@style/bottom_sheet_element_text_style"
                android:text="@string/image_size" />
        </LinearLayout>

        <LinearLayout style="@style/bottom_sheet_row_style">

            <ImageView
                style="@style/bottom_sheet_element_image_style"
                android:src="@drawable/ic_text_format_black_48dp" />

            <TextView
                style="@style/bottom_sheet_element_text_style"
                android:text="@string/template" />
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

Вы знаете, как решить эту проблему?

1 Ответ

0 голосов
/ 13 июля 2020

kotlin-android-extensions могли помешать вам. Это не сработает, так как ваше представление не привязано к экземпляру фрагмента в это время.

Убедитесь, что только создаете представление в методе onCreateView(...) и используйте его в onViewCreated(...). Он вызывается сразу после этого, поэтому вы не потеряете время и фрагмент не начнется неинициализированным.

В идеале ваш код будет выглядеть так:

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
) = DataBindingUtil.inflate<FragmentLowDesignBinding>(inflater, R.layout.fragment_low_design, container, false)
    .also { binding = it }
    .root

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    bottomSheetBehavior = BottomSheetBehavior.from<LinearLayout>(binding.standardBottomSheet)
    bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED)
    binding.include.toggleButton.setOnCheckedChangeListener { _, isChecked ->
        if (isChecked) {
            bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED)
        } else {
            bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED)
        }
    }
    // continue
}

Если вы хотите обойти весь этот шаблон, не стесняйтесь использовать teanity :) Это делает эти вещи очень простыми.

...