0

問題

スワイプ ジェスチャで ListView アイテムの「コンテキスト アクション」を開発しているときに、Android が MotionEvents を ViewGroup の子にディスパッチする方法について少し混乱しました。

ドキュメントによると、すべてのことはViewGroupd.dispatchTouchEvent(MotionEvent)メソッド呼び出しから始まります。次に、ビュー グループは、特定のモーション イベントをインターセプトする必要があるかどうか、またはそれを子にディスパッチできるかどうかを尋ねます。これはあらゆる種類のスクロールでうまく機能するため、垂直スクロールと水平スクロールの間の競合を効率的に解決できます (たとえば、ViewPager 内の ListView)。

ただし、この方法ではリスト ビューで単純なクリック イベントを正常に処理できません。モーション イベントのディスパッチ トレースは次のようになります

  1. ListView.dispatchTouchEvent(DOWN)
  2. ListView.onInterceptTouchEvent(DOWN) 戻りますfalse
  3. QuickActionView.dispatchTouchEvent(DOWN)
  4. QuickActionView.onTouchEvent(DOWN) MotionEvent.ACTION_DOWNtrueはジェスチャの開始を示しており、水平スクロールである可能性があり、この場合はユーザーにクイック アクション レイアウトを表示する必要があるため、戻ります。falseここから戻るMotionEvent.ACTION_DOWNと、他のタッチ イベントが ListView のこの子にディスパッチされるのを防ぎます。
  5. ステップ4のQuickActionView.dispatchTouchEvent(DOWN) 返品によるtrue
  6. ステップ5のListView.dispatchTouchEvent(DOWN) 返品によるtrue

その結果、ListView はタッチ ターゲットを記憶します。したがって、次のメッセージはこのようにディスパッチされます。

  1. ListView.dispatchTouchEvent(UP)
  2. ListView.onInterceptTouchEvent(UP) 戻りますfalse
  3. QuickActionView.dispatchTouchEvent(UP)
  4. QuickActionView.onTouchEvent(UP) falseジェスチャが終了し、スクロールやフリングなどではないことがわかったので、戻ります。
  5. ステップ4のQuickActionView.dispatchTouchEvent(UP) 返品によるfalse
  6. ステップ5のListView.dispatchTouchEvent(UP) 返品によるfalse

onTouchEvent(MotionEvent)そのため、ListView が項目のクリックを処理する機会はありません。これは、ステップ 5 の UP アクションの後、モーション イベントが ListView のメソッドに向けられていないためです。

また、ListView 内で ACTION_UP を使用してタッチ イベントを「インターセプト」しようとしましたが、Android のドキュメントによると、インターセプト後のモーション イベントのみが ViewGroup のonTouchEvent(MotionEvent)メソッドに送信され、現在のイベントは送信されないことに気付きました。

質問

ListView のネイティブ アイテム クリック処理と、MotionEvents を ListItem ビューにディスパッチする機能の両方をサポートするにはどうすればよいですか (水平スクロール可能で、画像ボタンがあります)。

そのような問題解決の経験がある人から話を聞くか、特定の紛争解決でどのように機能するように設計されているかについてより深い理解を持っていることが望ましいです。

4

1 に答える 1

0

現時点では、この問題に対する2つの解決策があります

  1. QuickActionView (実際には ListView アイテム) を 2 つのセクションに分割します。
 ____________________
| clickable      |  |   
|________________|__|
                   ^
                   |
                  scrollable

そのため、最初の ACTION_DOWN モーション イベントがクリック可能な領域から開始された場合に ListView アイテムをスクロールすることはできませんが、リスト ビューはアイテムのクリックをネイティブに処理します。また、スクロール可能な領域内のリスト項目をクリックすることはできませんが、スクロール可能な領域からジェスチャーを開始すると、スクロールしてクイックアクションを表示できます。

  1. 2 番目の解決策はややハックですが、最初の制限を回避します ListView 内では、MotionEvent.obtain(MotionEvent)メソッドを介してすべてのタッチ イベントを記憶できます。次に、ACTION_UP MotionEvent を待って、ジェスチャーが処理されたかどうかを listItem ビューに問い合わせます。リスト項目がジェスチャが処理されていないことを示している場合は、プライベート メソッドListView.cancelTouchTarget()を呼び出し、保存されているすべての MotionEvents を listView 経由でポストします。super.dispatchTouchEvent(MotionEvent)
于 2013-07-10T10:59:07.397 に答える