Onclicklistener在后来添加到视图的部分不起作用。

huangapple go评论72阅读模式
英文:

Onclicklistener not working in part that get's added to view later

问题

我在一个布局上有一个onclicklistener,其中包含两个include。其中一个include包含一个约束布局,在容器点击时将显示。如果我再次点击布局,它也应该变为不可见。如果我点击一直可见的部分,它可以正常工作。但是,如果我点击新添加的约束布局区域,什么都不会发生。onclick监听器不会触发。但是,如果我在include周围的任何地方点击,例如在左侧点击(原始布局中有一个边距),它会再次关闭。

以下是(简化的)布局:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:bind="http://schemas.android.com/apk/res-auto"
    xmlns:card_view="http://schemas.android.com/apk/res-auto">

    <data>
      <!-- ViewModel -->
    </data>

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

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="@{() -> viewModel.onClickItemContainer()}"
            android:clickable="true">

            <androidx.cardview.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:animateLayoutChanges="true">

                    <include
                        android:id="@+id/item_main"
                        layout="@layout/item_always_visible"
                        bind:viewModel="@{viewModel}"
                        bind:layout_constraintTop_toTopOf="parent"
                        bind:layout_constraintStart_toStartOf="parent"/>

                    <include
                        layout="@layout/item_details"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        bind:viewModel="@{viewModel}"
                        bind:layout_constraintTop_toBottomOf="@id/item_main"
                        bind:layout_constraintStart_toStartOf="parent" />
                </androidx.constraintlayout.widget.ConstraintLayout>
            </androidx.cardview.widget.CardView>

        </FrameLayout>

    </LinearLayout>

</layout>

包含的布局(可以切换开/关):

<?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">
    <data>
        <!-- ViewModel -->
        <import type="android.view.View" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/entry_details"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="@{viewModel.detailsVisible ? View.VISIBLE : View.GONE}"
        tools:visibility="visible"
        android:clickable="false">

        <androidx.recyclerview.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:adapter="@{viewModel.adapter}"
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:clickable="false"/>
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

在RecyclerView中使用的项目也设置为clickable="false"

<?xml version="1.0" encoding="utf-8"?>
<layout>
    <data>
    </data>
    <TextView
        android:id="@+id/detail_text"
        xmlns:android="http://schemas.android.com/apk/res/android"
        style="@style/Text.SecondaryText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:clickable="false"/>
</layout>
英文:

I have an onclicklistener on a layout, which contains two includes.
One of the includes contains a constraint layout which will be made visible on click of the container.
It should also be made invisible again, if I click on the layout again.
It works, if I click in the part that was always visible. However, if I click in the area of the newly added constraint layout, nothing happens.
The onclick-listener does not fire.
It works anywhere around the include though. E.g. clicking on the left of it (left there's a margin in original) it closes again.
Here are the (simplified) layouts:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;layout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:bind=&quot;http://schemas.android.com/apk/res-auto&quot;
    xmlns:card_view=&quot;http://schemas.android.com/apk/res-auto&quot;&gt;

    &lt;data&gt;
      //Viewmodel
    &lt;/data&gt;

    &lt;LinearLayout
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:orientation=&quot;vertical&quot;&gt;

        &lt;FrameLayout
            android:layout_width=&quot;match_parent&quot;
            android:layout_height=&quot;wrap_content&quot;
            android:onClick=&quot;@{() -&gt; viewModel.onClickItemContainer()}&quot;
            android:clickable=&quot;true&quot;&gt;

            &lt;androidx.cardview.widget.CardView
                android:layout_width=&quot;match_parent&quot;
                android:layout_height=&quot;wrap_content&quot;
              &gt;
                &lt;androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width=&quot;match_parent&quot;
                    android:layout_height=&quot;wrap_content&quot;
                    android:animateLayoutChanges=&quot;true&quot;&gt;

                    &lt;include
                        android:id=&quot;@+id/item_main&quot;
                        layout=&quot;@layout/item_always_visible&quot;
                        bind:viewModel=&quot;@{viewModel}&quot;
                        bind:layout_constraintTop_toTopOf=&quot;parent&quot;
                        bind:layout_constraintStart_toStartOf=&quot;parent&quot;/&gt;

                    &lt;include
                        layout=&quot;@layout/item_details&quot;
                        android:layout_width=&quot;match_parent&quot;
                        android:layout_height=&quot;wrap_content&quot;
                        bind:viewModel=&quot;@{viewModel}&quot;
                        bind:layout_constraintTop_toBottomOf=&quot;@id/item_main&quot;
                        bind:layout_constraintStart_toStartOf=&quot;parent&quot; /&gt;
                &lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;
            &lt;/androidx.cardview.widget.CardView&gt;

        &lt;/FrameLayout&gt;

    &lt;/LinearLayout&gt;

&lt;/layout&gt;

Included layout (that toggles on/off):

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;layout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    xmlns:tools=&quot;http://schemas.android.com/tools&quot;&gt;
    &lt;data&gt;
        //Viewmodel
        &lt;import type=&quot;android.view.View&quot; /&gt;
    &lt;/data&gt;

    &lt;androidx.constraintlayout.widget.ConstraintLayout
        android:id=&quot;@+id/entry_details&quot;
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;match_parent&quot;
        android:visibility=&quot;@{viewModel.detailsVisible? View.VISIBLE : View.GONE}&quot;
        tools:visibility=&quot;visible&quot;
        android:clickable=&quot;false&quot;&gt;

        &lt;androidx.recyclerview.widget.RecyclerView
            android:layout_width=&quot;match_parent&quot;
            android:layout_height=&quot;match_parent&quot;
            app:adapter=&quot;@{viewModel.adapter}&quot;
            app:layoutManager=&quot;androidx.recyclerview.widget.LinearLayoutManager&quot;
            app:layout_constraintStart_toStartOf=&quot;parent&quot;
            app:layout_constraintTop_toTopOf=&quot;parent&quot;
            android:clickable=&quot;false&quot;/&gt;

    &lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;
&lt;/layout&gt;

I've tried around with clickable="false" in a couple of places in the included layout already, because I found that suggestion in another question, but it did not help anything.
If it was affecting the whole extended area (also cardview below include, e.g) I'd be thinking it's a bug with Android not adapting click areas to layout changes, but since I can trigger the listener by clicking on left and below included part, it must be something else.

The items used in the recyclerview are also set to clickable = "false":

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;layout&gt;
    &lt;data&gt;
    &lt;/data&gt;
    &lt;TextView
        android:id=&quot;@+id/detail_text&quot;
        xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
        style=&quot;@style/Text.SecondaryText&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:clickable=&quot;false&quot;/&gt;
&lt;/layout&gt;

答案1

得分: 1

显然,这是recyclerviews已知的问题,它们捕获点击事件,因为它们用于滚动。
可以在以下链接找到一些解决方案:
https://stackoverflow.com/questions/30419898/parent-click-event-not-firing-when-recyclerview-clicked
在我的情况下,将recyclerview设置为不可触摸是一个合理的方法,因为所有元素已经位于另一个recyclerview中,所以它们永远不会被截断,而是填充所需的空间。

英文:

Apparently that is a known issue with recyclerviews, that they catch the click event, because they use it for scrolling.
A number of solutions can be found here:
https://stackoverflow.com/questions/30419898/parent-click-event-not-firing-when-recyclerview-clicked
In my case, making the recyclerview untouchable is a reasonable approach, because all elements are already in another recyclerview, so they will never get chopped and instead fill out the space required.

huangapple
  • 本文由 发表于 2023年7月31日 18:34:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76802773.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定