【问题标题】:Using ViewStub within ListViews causes onItemClick problems在 ListViews 中使用 ViewStub 会导致 onItemClick 问题
【发布时间】:2015-07-06 15:41:54
【问题描述】:

我有一个有趣的困境。我有一个ListView,我用它来包含CardViews。但是,每个CardView 实际上是一对两个:一张默认(正面)卡片,然后是一张背面卡片,我在用户单击卡片时将其设置为翻转动画。由于用户可能不会点击任何列表项,因此我使用ViewStub 作为后卡,并且会在点击列表项时懒惰地膨胀。

因此,当用户第一次单击卡片以翻转到背面时,一切看起来都很好并且翻转工作正常(通过单击卡片内的任意位置调用onItemClick())。但是,任何进一步尝试再次翻转到前面都不会触发onItemClick() 调用,除非我单击视图的最顶部(列表项)。

我已经进行了大量调试(更改可聚焦性和大小),并发现这仅是在 ViewStub 通货膨胀之后引起的。使正面和背面卡都正常CardViews 可以让onItemClick() 每次都能成功触发。

那么ViewStub 对我的onItemClick() 感到厌烦的原因是什么?有没有办法解决它,而不是让我的所有观点自动膨胀?

这是我正在使用的代码:

card_container_layout.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="5dp">

    <include layout="@layout/card_front_view"
        android:id="@+id/main_card_view_layout" />

    <ViewStub android:id="@+id/stub_flipped_card"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:inflatedId="@+id/flipped_card"
        android:layout="@layout/card_back_view" />
</FrameLayout>

card_front_view.xml

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent" android:layout_height="wrap_content"
    card_view:cardCornerRadius="5dp"
    android:id="@+id/card_view"
    android:descendantFocusability="blocksDescendants" >

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

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="@dimen/card_view_height">
            <ImageView android:id="@+id/img_main_card"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:src="@drawable/my_image"
                android:background="#ff10fffd" />

            <TextView
                android:id="@+id/lbl_name"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Name"
                style="@style/main_card_title_text"
                android:layout_alignParentBottom="true"
                android:padding="15dp"
                android:background="#5b000000"/>

        </RelativeLayout>

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_gravity="center_horizontal"
            android:padding="4dp" >

            <TextView
                android:id="@+id/lbl_item_count"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                style="@style/main_card_text" />

            <ImageView android:id="@+id/img_sync_state"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_alignParentEnd="true"
                android:layout_marginEnd="10dp"
                android:layout_marginRight="10dp"
                android:layout_centerVertical="true"/>
        </RelativeLayout>
    </LinearLayout>
</android.support.v7.widget.CardView>

card_back_view.xml

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    card_view:cardCornerRadius="5dp"
    android:id="@+id/flipped_card"
    android:alpha="0"
    android:descendantFocusability="blocksDescendants">

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

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Here are the items:"
            android:gravity="center"
            style="@style/card_flipped_title_text"
            android:background="#ad000000"/>
        <GridView android:id="@+id/grid_images"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:numColumns="3">
            <!-- make believe there were items here -->
        </GridView>
    </LinearLayout>
</android.support.v7.widget.CardView>

【问题讨论】:

  • 您在哪个视图上调用设置点击监听器?我敢打赌它是main_card_view_layout 或者里面的东西。
  • 我已将card_container_layout 设置为列表项并从子卡片中移除焦点,因此onItemClick() 应通过单击该布局中的任意位置来触发。
  • 我有同样的问题...在 ListView 中使用 ViewStub 和自定义 CursorAdapter ...第一次 ViewStub 膨胀...工作正常...但是滚动列表视图时;调用 getView 并在 BindView 和所有 ViewStub 之后更改,就好像它是视图和 id 的一个实例一样 ..??我正在调试这个,我想它和你一样的问题

标签: android xml listview android-listview viewstub


【解决方案1】:

好的,我做了更多的研究,似乎根本不是 ViewStub 导致它,但实际上是 GridView。由于我无法弄清楚的原因,GridView 继续劫持所有触摸事件,尽管将可聚焦和可点击设置为 false 并阻止后代可聚焦性,如上面的示例 XML 所示。

因此我解决它的hacky方法是拦截来自GridView和onTouchListener()内的所有触摸事件,如果我检测到MotionEvent.ACTION_UP,表明我一直在触摸屏幕并刚刚释放,然后我将手动执行与CardView 其余部分相同的操作。

itemGrid.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View grid, MotionEvent event) {
            // hacky way to make sure that we absorb the GridView's focus stealing and still do the right thing
            if (MotionEvent.ACTION_UP == event.getAction()) doExpectedStuff();
            return true; // absorb the touch here
        }
});

很抱歉,这不是最优雅的解决方案,并同意捕获 up 事件对于大多数人来说并不是一种万能的方法,但它在我的具体情况下有所帮助。希望这仍然可以帮助其他人。

【讨论】:

    猜你喜欢
    • 2016-09-08
    • 2011-02-19
    • 2019-06-21
    • 1970-01-01
    • 2010-12-02
    • 2021-01-21
    • 2021-08-30
    • 2014-09-14
    • 1970-01-01
    相关资源
    最近更新 更多