list.pointToPosition を使用して、ユーザーの指が触れているリスト項目の位置を特定しようとしています。私のリストには、 a の後に aがTextView
続きます。私が発見した問題は、pointToPosition が を持っているという事実を無視しているように見え、アイテムの間違った位置を返すことです。ListView
RelativeLayout
TextView
返されるもののいくつかの写真といくつかのサンプルを使用して、さらに説明しましょう。指のタッチを追跡できるデバッグ機能を有効にしました。次の画像の青い線で表示されます。
次の画像では、画面の上部に "LIGHTS" というラベルの付いた TextView があることに気付くでしょう。そのすぐ下に私の ListView があります。指のタッチとスライドを追跡する青い線を見てください。「Front Porch」というラベルの付いた行の上部付近から始まっていることがわかります。その位置で「pointToPosition」を実行すると、正しい値 4 が返されます。
ただし、同じ行の途中でタッチを開始すると、pointToPosition は 5 の値を返します。次のスクリーン ショットでタッチ/ドラッグを確認できます。
TextView のサイズを高さ 1dp に変更すると、問題はなくなります。したがって、 pointToPosition メソッドは、私の ListView がページ上の唯一のものであると想定していると信じています。
ハックを実装して、TextView によって引き起こされたオフセットを計算することでこれに対処することもできますが、このバグ (バグであると仮定) が修正されると、最終的にはこれが戻ってくると思います。私が疑問に思っているのは、それを修正する適切な方法があるかどうかです。
ソースコードのサンプル:
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());
}
...
}