Кнопка фрагмента обнаруживается с помощью findViewById Activity вместо раздутого представления Fragment. - PullRequest
0 голосов
/ 18 июня 2020

Я наблюдаю это странное поведение и не могу найти ничего похожего на это.

Итак, у меня есть родительский Activity, а внутри Fragment, который я включаю в родительский через include элемент, а затем в родительском onCreate, создайте Fragment и замените его этим макетом include (Скажите, правильно ли это? Я использовал FrameLayout, но затем переключился на include и определил an id к нему).

Activity

<androidx.constraintlayout.widget.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"
    android:fitsSystemWindows="true"
    tools:context="com.sourcey.materiallogindemo.CustomerDetailActivity"
    tools:ignore="MergeRootFrame">

    <com.google.android.material.appbar.AppBarLayout>

        <com.google.android.material.appbar.MaterialToolbar />

    </com.google.android.material.appbar.AppBarLayout>

    <include
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintTop_toBottomOf="@id/app_bar"
        app:layout_constraintBottom_toTopOf="@id/layout_bottom_bar"
        layout="@layout/fragment_customer_detail" />

    <androidx.coordinatorlayout.widget.CoordinatorLayout>

        <com.google.android.material.bottomappbar.BottomAppBar>

        </com.google.android.material.bottomappbar.BottomAppBar>

    </androidx.coordinatorlayout.widget.CoordinatorLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

Fragment

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context="com.sourcey.materiallogindemo.CustomerDetailFragment"
    android:layout_height="match_parent"
    android:layout_width="match_parent">

<!-- THIS IS THE CULPRIT -->
    <com.google.android.material.button.MaterialButton
        android:id="@+id/btn_update_position"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <com.google.android.material.button.MaterialButton />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/sku_list"
        app:layoutManager="LinearLayoutManager"
        tools:context="com.sourcey.materiallogindemo.CustomerDetailFragment"
        tools:listitem="@layout/fragment_s_k_u_item" />

</androidx.constraintlayout.widget.ConstraintLayout>

Fragment - это inflate d правильно, но когда я делаю это внутри onCreateView

rootView.btn_update_position.setOnClickListener {
    // ... log something
}

и нажмите Button, ничего не происходит? Несмотря на то, что большинство результатов привело к этому предположению, что я должен inflate view, а затем установить onClickListener.

, я также пробовал делать эти

rootView.findViewById<MaterialButton>(R.id.btn_update_position).setOnClickListener {
    // ... log something
}

и

val button = rootView.findViewById<MaterialButton>(R.id.btn_update_position)
button.setOnClickListener {
    // ... log something
}

, но ни один из них не работает.

Я также пробовал описанные выше подходы в onViewCreated, чтобы увидеть, может быть, я не получаю ссылку, но не было выдано никаких ошибок и никакой реакции не было.

Единственное, что работает, это

activity?.findViewById<MaterialButton>(R.id.btn_update_position)
    ?.setOnClickListener {
         // ... log something
}

Я пытаюсь понять, почему так происходит? Может ли это быть проблемой использования include Fragment?

ПРИМЕЧАНИЕ Я не профессионал в android, просто занимаюсь им хобби, так что не знаю очень глубоко об этом.

РЕДАКТИРОВАТЬ Как вы можете видеть, у меня есть макет RecyclerView в Fragment, я раздуваю макет, а затем устанавливаю его элементы адаптера, которые, кажется, работают нормально в отличие от кнопки.

rootView.sku_list.adapter = Adapter()

1 Ответ

0 голосов
/ 19 июня 2020

Я немного запутался в том, что вы хотите здесь сделать

Во-первых, <include> не создает новое представление, он просто включает xml в родительский xml файл, так что в основном это все еще активен, и вам нужна активность, чтобы найтиViewById

Во-вторых, по вашему вопросу, что отличается между FrameLayout и <include>.

С <include>, как я сказал выше, он просто добавляет xml файл в родительский файл, в основном используется для повторного использования макета (вы можете включить его где угодно).

С FrameLayout, из официального do c: «FrameLayout предназначен для блокировки области на экран для отображения одного элемента ». Например: вы хотите, чтобы ваш макет имел верхний и нижний колонтитулы для всего экрана, изменилась только средняя часть, поэтому поместите макет фрейма посередине, а затем загрузите другое представление для каждого экрана, потому что этот гибкий макет кадра обычно используется для фрагмента отображения (вы можете Google как для более подробной информации использовать макет фрейма)

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