listView pointToPosition不正确'一半时间'

时间:2013-07-20 18:23:01

标签: android

我正在尝试使用list.pointToPosition来确定用户手指触摸的列表项位置。我的列表包含TextView,后跟ListView中的RelativeLayout。我发现的问题是pointToPosition似乎忽略了这样一个事实:我有一个TextView并返回错误的项目位置。

让我进一步解释一些图片和一些返回的样本。我启用了调试功能,让我跟踪手指触摸。您将在以下图像的蓝线中看到它。

在下图中,您会注意到屏幕顶部是一个标有“LIGHTS”的TextView。就在我的ListView下面。看看跟踪我的手指触摸和滑动的蓝线 - 你会发现它从标有“Front Porch”的行的顶部附近开始。在该位置执行“pointToPosition”将返回正确的值4。

Correct pointToPosition

然而,现在,如果我在同一行的中间开始触摸,则pointToPosition返回值5.您可以在下面的屏幕截图中看到我的触摸/拖动。

Wrong position

当我将TextView的大小更改为高度为1dp时,问题就消失了;因此我认为pointToPosition方法假定我的ListView是页面上唯一的东西。

我可以实现一个hack并通过计算TextView引起的偏移来解决这个问题,但我的感觉是,当这个bug(假设它是一个bug)得到修复时,这最终会回来咬我。我想知道的是,是否有适当的方法来解决它。

源代码示例:

layout.xml

<com.mls.util.RelativeLayoutTouchInterceptor xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:background="@drawable/app_bg"
android:id="@+id/rlRoot" android:clickable="true"
tools:context=".DeviceListActivity" >

<TextView android:id="@+id/list_header"
          style="?android:listSeparatorTextViewStyle"
          android:text="Lights"
          android:layout_width="match_parent"
          android:layout_height="wrap_content">
</TextView>

<ListView
        android:id="@+id/dlList"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="65dp"
        android:layout_below="@+id/list_header"
        android:layout_alignParentLeft="true">
</ListView>

</com.mls.util.RelativeLayoutTouchInterceptor>

RelativeLayoutTouchInterceptor.java

public class RelativeLayoutTouchInterceptor extends RelativeLayout {
    ...

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {

    switch(event.getAction()) {
        case MotionEvent.ACTION_DOWN: {

            downStart = MotionEvent.obtain(event);

            ListView list = (ListView)this.findViewById(R.id.dlList);
            int position = list.pointToPosition((int)downStart.getX(), (int)downStart.getY());
    }

 ...

}

2 个答案:

答案 0 :(得分:1)

发生这种情况的原因是因为您覆盖了onInterceptTouchEvent的{​​{1}},而不是RelativeLayout。它报告布局本身的y坐标,其中包括ListView

如果您想仅获取相对于TextView的坐标,您可以为ListView本身覆盖它。它是ListView的间接子类,因此它可以访问该方法。

没有任何错误可以解决,它会像它应该的那样工作。

答案 1 :(得分:0)

我继续前进并添加了感知黑客来解决这个问题,即将TextView的高度添加到提供给pointToPosition的Y位置