子ビューにロングクリックリスナーが設定されているListViewがあります。子ビューを長押しすると、ダイアログが表示されます。なぜダイアログが表示されたらイベントに触れないのですか?
問題は、ダイアログボックスが表示された後に指を押したままにしておくと、ListViewがダイアログの後ろにあるにもかかわらず、ListViewをスクロールできることです。デバッグでは、ユーザーが最後に指を離すまで、すべてのタッチイベント(例:ACTION_MOVE
とACTION_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コントロールは、ダイアログは、ユーザーが子ビューで行くことができますことはありません場合はフォーカスを取得した後もスクロール可能であり続けています。これは、ダイアログが初めて表示されたとき(アクティビティが再度作成されるまで)に発生するようです。
これはAndroidのバグです:
私は2つの質問がありますか?ウィンドウが
ACTION_UP
より前にフォーカスを失っても、タッチジェスチャーが完了するまで(ACTION_DOWN
からACTION_UP
まで)実行されていることが起こります。私はこれが常に望ましい行動であるとは想像できません。ここで最善の解決策は何ですか?以下の溶液(ウィンドウがフォーカスを失った後、すべてのタッチイベントを無視する)は動作しますが、私はもっと良いものがあるのだろうか。後にすべてのタッチイベントを無視することで、この問題を解決し、私は
AbsListView.setOnItemLongClickListener
を使用できないことをpublic class MainActivity extends Activity { ... @Override public void dispatchTouchEvent(MotionEvent event) { if (hasWindowFocus()) { return super.dispatchTouchEvent(event); } else { return true; // suppress } } }
注意、あまりにも柔軟性がないため、長いクリックが検出されました。
を有効にします.Builder'インスタンスです。 – Emmanuel
@Emmanuel 'setCancelable(false)'を使うときと同じ問題です。 –
あなたは解決策を見つけることができましたか? –