英文:
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:
<?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>
Included layout (that toggles on/off):
<?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>
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":
<?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>
答案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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论