89

カスタム ListAdapter を使用してリスト内のビューを生成する単純な ListActivity があります。通常、ListAdapter はビューを TextViews で埋めるだけですが、ここではボタンも配置したいと考えています。

ただし、リスト項目にフォーカス可能なビューを配置すると、リスト項目がクリックされたときに ListActivity で onListItemClick() が起動されないことが私の理解と経験です。ボタンはリスト アイテム内で正常に機能しますが、ボタン以外の何かが押されたときに onListItemClick がトリガーされるようにします。

どうすればこれを機能させることができますか?

4

8 に答える 8

99

以前のコメントで書いたように、解決策はImageButtonにsetFocusable(false)を設定することです。

リスト要素のandroid:descendantFocusability="blocksDescendants" ルートレイアウトに追加してみる、さらに洗練されたソリューションがあります。これにより、ListItemのクリックが可能になり、個別にボタンまたはImageButtonのクリックを処理できます。

それが役に立てば幸い ;)

乾杯

于 2012-09-21T10:41:00.773 に答える
59

ここでお役に立てれば幸いです。listView アイテムのカスタム レイアウトがあり、このレイアウトはボタンとその他のビュー (TextView、ImageView など) で構成されていると仮定します。ここで、ボタンのクリック時に別のイベントを発生させ、それ以外のすべてのクリックに対して別のイベントを発生させたいとします。

ListActivity の onListItemClick() を使用せずにそれを実現できます。
これがあなたがしなければならないことです:

カスタム レイアウトを使用しているため、おそらくカスタム アダプタから getView() メソッドをオーバーライドしています。秘訣は、ボタンに異なるリスナーを設定し、ビュー全体 (行) に異なるリスナーを設定することです。例を見てください:

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 コンストラクターにさらにいくつかのパラメーターを追加することになるでしょう。
そして、重要なことの 1 つ - 上記の getView の実装はかなり醜いです。通常は、ViewHolder パターンを使用して findViewById 呼び出しを回避する必要があります。
私のcustom_row.xmlファイルは、ID「ボタン」のボタン、ID「テキスト」のTextView、およびID「画像」のImageViewを持つRelativeLayoutです-物事を明確にするためです。
よろしく!

于 2009-12-14T19:10:47.627 に答える
18

カスタム 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);
        …       
    }
}
于 2010-11-28T19:08:55.287 に答える
13

私は同じ問題を抱えています:OnListItemClickが起動されません![解決済み]
これは、ListActivityを拡張するクラスで発生し
ます。ListActivityのレイアウトでは、TextBoxとListViewがLinearLayout
にネストされ、行の別のレイアウト(CheckBoxとTextBoxがLineraLayoutにネストされています)が含まれます。

それはコードです:

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&lt;String&gt;(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

これがお役に立てば幸い
です...そして私の英語をお詫びします:(

于 2011-04-19T10:11:50.977 に答える
2

android:focusable="false"ボタンの属性の1つとして追加するだけです

于 2012-10-03T05:12:35.140 に答える
1
 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();
}
});
于 2011-06-29T13:08:46.223 に答える
1

ToggleButton でも同じ問題が発生しました。半日頭を壁にぶつけた後、ようやく解決しました。「android:focusable」を使用して、フォーカス可能なビューをフォーカス不可にするのと同じくらい簡単です。また、リスト行のフォーカス可能性とクリック可能性 (私は言葉を作っただけです) をいじるのも避けてください。デフォルト値のままにしておく必要があります。

もちろん、リスト行のフォーカス可能なビューはフォーカスできないため、キーボードを使用しているユーザーは問題を抱えている可能性があります。問題になることはまずありませんが、100% 完璧なアプリを作成したい場合に備えて、onItemSelected イベントを使用して、選択した行の要素をフォーカス可能にし、以前に選択した行の要素をフォーカス不可能にすることができます。

于 2010-10-29T23:42:08.237 に答える
-1

getListAdapter().getItem(position) を使用して、アイテム内に値を保持するオブジェクトをインスタンス化しました

MyPojo myPojo = getListAdapter().getItem(position);

次に myPojo の getter メソッドを使用して、 item 内の適切な値を呼び出します。

于 2011-06-06T09:42:19.633 に答える