カスタムListAdapterを使用してリスト内のビューを生成する単純なListActivityがあります。通常、ListAdapterはビューをTextViewで埋めるだけですが、今度はボタンも配置したいと思います。
ただし、リストアイテムにフォーカス可能なビューを配置すると、リストアイテムがクリックされたときにListActivityでonListItemClick()が発生しなくなります。ボタンはまだリスト項目内で正常に機能しますが、ボタン以外の何かが押されたときに、onListItemClickがトリガーされるようにします。
どうすればこの作品を作ることができますか?
前のコメント で書いたように、解決策はImageButtonのsetFocusable(false)です。
リスト要素のAndroid:descendantFocusability="blocksDescendants"
ルートレイアウトを追加しようとする、よりエレガントなソリューションがあります。これにより、onListItemのクリックが可能になり、ボタンまたはImageButtonのクリックを個別に処理できます
それが役に立てば幸い ;)
乾杯
ここで助けていただければ幸いです。 listViewアイテムのカスタムレイアウトがあり、このレイアウトはボタンとTextView、ImageViewなどのその他のビューで構成されていると仮定します。ここで、ボタンクリックで異なるイベントを発生させ、他のすべてのクリックで異なるイベントを発生させたいとします。
ListActivityのonListItemClick()を使用せずにこれを実現できます。
これがあなたがしなければならないことです:
カスタムレイアウトを使用しているため、カスタムアダプタのgetView()メソッドをオーバーライドしている可能性があります。秘Theは、ボタンに異なるリスナーを設定し、ビュー全体(行)に異なるリスナーを設定することです。例を見てみましょう:
private class MyAdapter extends ArrayAdapter<String> implements OnClickListener {
public MyAdapter(Context context, int resource, int textViewResourceId,
List<String> objects) {
super(context, resource, textViewResourceId, objects);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
String text = getItem(position);
if (null == convertView) {
convertView = mInflater.inflate(R.layout.custom_row, null);
}
//take the Button and set listener. It will be invoked when you click the button.
Button btn = (Button) convertView.findViewById(R.id.button);
btn.setOnClickListener(this);
//set the text... not important
TextView tv = (TextView) convertView.findViewById(R.id.text);
tv.setText(text);
//!!! and this is the most important part: you are settin listener for the whole row
convertView.setOnClickListener(new OnItemClickListener(position));
return convertView;
}
@Override
public void onClick(View v) {
Log.v(TAG, "Row button clicked");
}
}
OnItemClickListenerクラスは、次のように宣言できます。
private class OnItemClickListener implements OnClickListener{
private int mPosition;
OnItemClickListener(int position){
mPosition = position;
}
@Override
public void onClick(View arg0) {
Log.v(TAG, "onItemClick at position" + mPosition);
}
}
もちろん、OnItemClickListenerコンストラクターにいくつかのパラメーターを追加することになるでしょう。
重要なこと-上記のgetViewの実装は非常に見苦しく、通常はViewHolderパターンを使用してfindViewById呼び出しを回避する必要があります。
custom_row.xmlファイルは、「button」というIDのボタン、「text」というIDのTextView、および「image」というIDのImageViewを持つRelativeLayoutです。
よろしく!
カスタムListViewにフォーカス可能な要素が含まれている場合、onListItemClickは機能しません(期待される動作だと思います)。カスタムビューからフォーカスを削除するだけで、トリックが実行されます。
例えば:
public class ExtendedCheckBoxListView extends LinearLayout {
private TextView mText;
private CheckBox mCheckBox;
public ExtendedCheckBoxListView(Context context, ExtendedCheckBox aCheckBoxifiedText) {
super(context);
…
mText.setFocusable(false);
mText.setFocusableInTouchMode(false);
mCheckBox.setFocusable(false);
mCheckBox.setFocusableInTouchMode(false);
…
}
}
私は同じ問題を抱えています:OnListItemClickが起動しません! [解決しよう]
ListActivityを拡張するクラスで発生します。
TextActivityとListViewがLinearLayoutにネストされているListActivityのレイアウト
と行の別のレイアウト(LineraLayoutにネストされたCheckBoxとTextBox)。
それはコードです:
res/layout/configpage.xml(ListActivityのメイン)
<LinearLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:orientation="vertical"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent" >
<TextView
Android:id="@+id/selection"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:text="pippo" />
<ListView
Android:id="@Android:id/list"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:drawSelectorOnTop="false"
Android:background="#aaFFaa" >
</ListView>
<LinearLayout>
res/layout/row.xml (layout for single row)
<LinearLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content">
<CheckBox
Android:id="@+id/img"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
**Android:focusable="false"**
**Android:focusableInTouchMode="false"** />
<TextView
Android:id="@+id/testo"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
**Android:focusable="false"**
**Android:focusableInTouchMode="false"** />
</LinearLayout>
src /.../.../ConfigPage.Java
public class ConfigPage extends ListActivity
{
TextView selection;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.configpage);
// loaded from res/value/strings
String[] azioni = getResources().getStringArray(R.array.ACTIONS);
setListAdapter(new ArrayAdapter<String>(this, R.layout.row,
R.id.testo, azioni));
selection = (TextView) findViewById(R.id.selection);
}
public void onListItemClick(ListView parent, View view, int position, long id)
{
selection.setText(" " + position);
}
}
これは、row.xmlに追加したときに機能し始めます
Android:focusable="false"
Android:focusableInTouchMode="false"
Eclipse 3.5.2を使用します
Android SDK 10.0.1
最小SDKバージョン:3
これがお役に立てば幸いです
...そして私の英語:(
ボタンの属性の1つとしてAndroid:focusable="false"
を追加するだけです
ListView lv = getListView();
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// When clicked, show a toast with the TextView text
Toast.makeText(getApplicationContext(), ((TextView) view).getText(),
Toast.LENGTH_SHORT).show();
}
});
ToggleButtonでも同じ問題が発生しました。壁に頭をぶつけて半日後、ようやく解決しました。 「Android:focusable」を使用して、フォーカス可能なビューを非フォーカスにするのと同じくらい簡単です。また、リスト行のフォーカス可能性およびクリック可能性(私は単語を作成しただけ)で遊ぶのを避け、デフォルト値のままにしてください。
もちろん、リスト行のフォーカス可能なビューはフォーカスできないため、キーボードを使用しているユーザーは問題を抱えている可能性があります。問題になることはほとんどありませんが、100%完璧なアプリを作成したい場合は、onItemSelectedイベントを使用して、選択した行の要素をフォーカス可能にし、以前に選択した行の要素をフォーカス不可にすることができます。