2016-11-27 9 views
2

子ビューにロングクリックリスナーが設定されているListViewがあります。子ビューを長押しすると、ダイアログが表示されます。なぜダイアログが表示されたらイベントに触れないのですか?

問題は、ダイアログボックスが表示された後に指を押したままにしておくと、ListViewがダイアログの後ろにあるにもかかわらず、ListViewをスクロールできることです。デバッグでは、ユーザーが最後に指を離すまで、すべてのタッチイベント(例:ACTION_MOVEACTION_UP)が元のウィンドウで受信されていることがわかりました。

はここで短い再現可能な例です:アンドロイド6.0、7.0で

package foo; 

import android.app.Activity; 
import android.app.AlertDialog; 
import android.content.Context; 
import android.os.Bundle; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.BaseAdapter; 
import android.widget.ListView; 
import android.widget.TextView; 

public class MainActivity extends Activity { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     ListView listView = new ListView(this); 
     listView.setAdapter(new FooAdapter()); 
     setContentView(listView); 
    } 
} 

class FooAdapter extends BaseAdapter { 
    @Override 
    public int getCount() { 
     return 100; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     final Context context = parent.getContext(); 

     TextView textView = new TextView(context); 
     textView.setText("Text"); 
     textView.setOnLongClickListener(new View.OnLongClickListener() { 
      @Override 
      public boolean onLongClick(View view) { 
       new AlertDialog.Builder(context) 
        .setMessage("Hi") 
        .show(); 
       return true; 
      } 
     }); 

     return textView; 
    } 

    @Override 
    public Object getItem(int position) { 
     return null; 
    } 

    @Override 
    public long getItemId(int position) { 
     return 0; 
    } 
} 

、および7.1、ListViewコントロールは、ダイアログは、ユーザーが子ビューで行くことができますことはありません場合はフォーカスを取得した後もスクロール可能であり続けています。これは、ダイアログが初めて表示されたとき(アクティビティが再度作成されるまで)に発生するようです。

  1. これはAndroidのバグです:

    私は2つの質問がありますか?ウィンドウがACTION_UPより前にフォーカスを失っても、タッチジェスチャーが完了するまで(ACTION_DOWNからACTION_UPまで)実行されていることが起こります。私はこれが常に望ましい行動であるとは想像できません。

  2. ここで最善の解決策は何ですか?以下の溶液(ウィンドウがフォーカスを失った後、すべてのタッチイベントを無視する)は動作しますが、私はもっと良いものがあるのだろうか。後にすべてのタッチイベントを無視することで、この問題を解決し、私はAbsListView.setOnItemLongClickListenerを使用できないことを

    public class MainActivity extends Activity { 
        ... 
    
        @Override 
        public void dispatchTouchEvent(MotionEvent event) { 
         if (hasWindowFocus()) { 
          return super.dispatchTouchEvent(event); 
         } else { 
          return true; // suppress 
         } 
        } 
    } 
    

    注意、あまりにも柔軟性がないため、長いクリックが検出されました。

+0

を有効にします.Builder'インスタンスです。 – Emmanuel

+0

@Emmanuel 'setCancelable(false)'を使うときと同じ問題です。 –

+0

あなたは解決策を見つけることができましたか? –

答えて

0

Androidでイベントがどのように機能するかわかりません。 私の考えでは、画面上をクリックして座標を基準にして、アンドロイドがこのイベントを処理するビューを指定します。ユーザーはまだスクロールビューイベントを解放しないので、このビューはこのイベントを処理していると見なされます。

ダイアログを表示する前に、listView.setEnable(true)を回避するだけです。

ベストプラクティス、リスナーとの対話を作成するために、カスタムダイアログやUTILを作成します。

ショーの前に - >無効のListView 前に解任 - > `AlertDialogに` `setCancelable(false)を呼び出してみたListView

関連する問題