Как запустить onListItemClick в Listactivity с кнопками в списке? - PullRequest
89 голосов
/ 30 ноября 2009

У меня есть простая ListActivity, которая использует собственный ListAdapter для генерации представлений в списке. Обычно ListAdapter просто заполняет представления с помощью TextViews, но теперь я также хочу поместить туда кнопку.

Однако, насколько я понимаю, я знаю, что размещение фокусируемого представления в элементе списка предотвращает срабатывание onListItemClick () в ListActivity при нажатии на элемент списка. Кнопка по-прежнему нормально функционирует в элементе списка, но когда что-то, кроме кнопки, нажимается, я хочу, чтобы onListItemClick срабатывал.

Как я могу сделать эту работу?

Ответы [ 8 ]

99 голосов
/ 21 сентября 2012

как я писал в предыдущий комментарий решение состоит в том, чтобы установитьFocusable (false) на ImageButton.

Существует еще более элегантное решение, попробуйте добавить android:descendantFocusability="blocksDescendants" в корневой макет элемента списка. Это сделает возможным клики по списку элементов и отдельно вы можете обрабатывать нажатия кнопок или ImageButton

Надеюсь, это поможет;)

Приветствия

59 голосов
/ 14 декабря 2009

Я надеюсь, что смогу помочь здесь. Я предполагаю, что у вас есть пользовательский макет для элементов listView, и этот макет состоит из кнопки и некоторых других представлений - таких как TextView, ImageView или что-то еще. Теперь вы хотите, чтобы другое событие срабатывало при нажатии кнопки, а другое событие - при нажатии на все остальное.

Вы можете достичь этого, не используя onListItemClick () вашего ListActivity.
Вот что вам нужно сделать:

Вы используете пользовательский макет, поэтому, вероятно, вы переопределяете метод 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.
И одна важная вещь - реализация getView, показанная выше, довольно уродлива, обычно вы должны использовать шаблон ViewHolder, чтобы избежать вызовов findViewById ... но вы, вероятно, уже знаете что.
Мой файл custom_row.xml - это RelativeLayout с Button of id «кнопка», TextView с идентификатором «text» и ImageView с идентификатором «image» - просто чтобы прояснить ситуацию.
Привет!

18 голосов
/ 28 ноября 2010

Когда пользовательский 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);
        …       
    }
}
13 голосов
/ 19 апреля 2011

У меня та же проблема: 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
min Версия SDK: 3

Надеюсь, это полезно
...и извините за мой английский :(

2 голосов
/ 03 октября 2012

просто добавьте android:focusable="false" как один из атрибутов вашей кнопки

1 голос
/ 29 июня 2011
 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();
}
});
1 голос
/ 30 октября 2010

У меня была такая же проблема с ToggleButton. После полдня ударов головой о стену я наконец решил это. Это так же просто, как сделать фокусируемый вид не сфокусированным, используя «android: focusable». Вам также следует избегать игры с фокусируемостью и кликабельностью (я только что составил слова) строки списка, просто оставьте для них значение по умолчанию.

Конечно, теперь, когда ваши фокусируемые виды в строке списка не фокусируются, у пользователей, использующих клавиатуру, могут возникнуть проблемы, ну, в общем, их фокусировка. Это вряд ли будет проблемой, но на случай, если вы хотите написать 100% безупречные приложения, вы можете использовать событие onItemSelected, чтобы сделать элементы выбранной строки фокусируемыми, а элементы ранее выбранной строки - не фокусируемыми.

0 голосов
/ 06 июня 2011

Я использовал getListAdapter (). GetItem (position), создающий экземпляр объекта, который хранит мои значения в элементе

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

затем использовал метод получения из myPojo, он вызовет правильные значения внутри элемента.

...