Android: элементы ListView с несколькими кликабельными кнопками
у меня есть ListView
, где каждый элемент в списке содержит TextView и две разные кнопки. Что-то вроде этого:
ListView
--------------------
[Text]
[Button 1][Button 2]
--------------------
[Text]
[Button 1][Button 2]
--------------------
... (and so on) ...
С помощью этого кода я могу создать OnItemClickListener
для всего элемента:
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> list, View view, int position, long id) {
Log.i(TAG, "onListItemClick: " + position);
}
}
});
однако я не хочу, чтобы весь элемент был кликабельным, а только две кнопки каждого элемента списка.
Итак, мой вопрос заключается в том, как реализовать onClickListener для этих двух кнопок со следующим параметры:
-
int button
(какая кнопка элемента была нажата) -
int position
(который является элементом в списке, на котором произошло нажатие кнопки)
обновление: я нашел решение, как описано в моем ответе ниже. Теперь я могу нажать / нажать кнопку с помощью сенсорного экрана. Однако, я не могу вручную выбрать его с помощью трекбола. Он всегда выбирает весь элемент списка и оттуда переходит непосредственно к следующий элемент списка игнорирует кнопки, хотя я установил .setFocusable(true)
и setClickable(true)
для кнопки getView()
.
я также добавил этот код в мой пользовательский адаптер списка:
@Override
public boolean areAllItemsEnabled() {
return false;
}
@Override
public boolean isEnabled(int position) {
return false;
}
это приводит к тому, что ни один элемент списка не выбирается вообще больше. Но это не помогло сделать вложенные кнопки выбираемыми.
кто-то идея?
8 ответов:
решение это на самом деле проще, чем я думал. Вы можете просто добавить в свой пользовательский адаптер
getView()
метод setOnClickListener () для кнопок, которые вы используете.любые данные, связанные с кнопкой должны быть добавлены с
myButton.setTag()
наgetView()
и можно получить доступ в onClickListener черезview.getTag()
Я разместил подробное решение на мой блог как учебник.
это своего рода придаток @znq ответ...
есть много случаев, когда вы хотите знать позицию строки на элемент, и вы хотите знать, какой вид в строке прослушивается. Это будет гораздо более важное значение в таблетки УИС.
вы можете сделать это с помощью следующего пользовательского адаптера:
private static class CustomCursorAdapter extends CursorAdapter { protected ListView mListView; protected static class RowViewHolder { public TextView mTitle; public TextView mText; } public CustomCursorAdapter(Activity activity) { super(); mListView = activity.getListView(); } @Override public void bindView(View view, Context context, Cursor cursor) { // do what you need to do } @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { View view = View.inflate(context, R.layout.row_layout, null); RowViewHolder holder = new RowViewHolder(); holder.mTitle = (TextView) view.findViewById(R.id.Title); holder.mText = (TextView) view.findViewById(R.id.Text); holder.mTitle.setOnClickListener(mOnTitleClickListener); holder.mText.setOnClickListener(mOnTextClickListener); view.setTag(holder); return view; } private OnClickListener mOnTitleClickListener = new OnClickListener() { @Override public void onClick(View v) { final int position = mListView.getPositionForView((View) v.getParent()); Log.v(TAG, "Title clicked, row %d", position); } }; private OnClickListener mOnTextClickListener = new OnClickListener() { @Override public void onClick(View v) { final int position = mListView.getPositionForView((View) v.getParent()); Log.v(TAG, "Text clicked, row %d", position); } }; }
для будущих читателей:
для выбора вручную кнопок с трекболом используйте:
myListView.setItemsCanFocus(true);
и отключить фокус на весь список товаров:
myListView.setFocusable(false); myListView.setFocusableInTouchMode(false); myListView.setClickable(false);
Он отлично работает для меня, я могу нажать на кнопки с сенсорным экраном, а также alows фокус щелчок с помощью клавиатуры
у меня нет большого опыта, чем выше пользователей, но я столкнулся с этой же проблемой, и я решил это с помощью решения ниже
<Button android:id="@+id/btnRemove" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_toRightOf="@+id/btnEdit" android:layout_weight="1" android:background="@drawable/btn" android:text="@string/remove" android:onClick="btnRemoveClick" />
btnRemoveClick Click event
public void btnRemoveClick(View v) { final int position = listviewItem.getPositionForView((View) v.getParent()); listItem.remove(position); ItemAdapter.notifyDataSetChanged(); }
Вероятно, вы нашли, как это сделать, но вы можете позвонить
ListView.setItemsCanFocus(true)
и теперь ваши кнопки будут ловить фокус
Я не уверен, что это лучший способ, но работает нормально, и весь код остается в вашем ArrayAdapter.
package br.com.fontolan.pessoas.arrayadapter; import java.util.List; import android.content.Context; import android.text.Editable; import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.ImageView; import br.com.fontolan.pessoas.R; import br.com.fontolan.pessoas.model.Telefone; public class TelefoneArrayAdapter extends ArrayAdapter<Telefone> { private TelefoneArrayAdapter telefoneArrayAdapter = null; private Context context; private EditText tipoEditText = null; private EditText telefoneEditText = null; private ImageView deleteImageView = null; public TelefoneArrayAdapter(Context context, List<Telefone> values) { super(context, R.layout.telefone_form, values); this.telefoneArrayAdapter = this; this.context = context; } @Override public View getView(int position, View convertView, ViewGroup parent) { LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(R.layout.telefone_form, parent, false); tipoEditText = (EditText) view.findViewById(R.id.telefone_form_tipo); telefoneEditText = (EditText) view.findViewById(R.id.telefone_form_telefone); deleteImageView = (ImageView) view.findViewById(R.id.telefone_form_delete_image); final int i = position; final Telefone telefone = this.getItem(position); tipoEditText.setText(telefone.getTipo()); telefoneEditText.setText(telefone.getTelefone()); TextWatcher tipoTextWatcher = new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { telefoneArrayAdapter.getItem(i).setTipo(s.toString()); telefoneArrayAdapter.getItem(i).setIsDirty(true); } }; TextWatcher telefoneTextWatcher = new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { telefoneArrayAdapter.getItem(i).setTelefone(s.toString()); telefoneArrayAdapter.getItem(i).setIsDirty(true); } }; tipoEditText.addTextChangedListener(tipoTextWatcher); telefoneEditText.addTextChangedListener(telefoneTextWatcher); deleteImageView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { telefoneArrayAdapter.remove(telefone); } }); return view; } }
Я знаю, что уже поздно, но это может помочь, это пример того, как я пишу пользовательский класс адаптера для разных действий щелчка
public class CustomAdapter extends BaseAdapter { TextView title; Button button1,button2; public long getItemId(int position) { return position; } public int getCount() { return mAlBasicItemsnav.size(); // size of your list array } public Object getItem(int position) { return position; } public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = getLayoutInflater().inflate(R.layout.listnavsub_layout, null, false); // use sublayout which you want to inflate in your each list item } title = (TextView) convertView.findViewById(R.id.textViewnav); // see you have to find id by using convertView.findViewById title.setText(mAlBasicItemsnav.get(position)); button1=(Button) convertView.findViewById(R.id.button1); button1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //your click action // if you have different click action at different positions then if(position==0) { //click action of 1st list item on button click } if(position==1) { //click action of 2st list item on button click } }); // similarly for button 2 button2=(Button) convertView.findViewById(R.id.button2); button2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //your click action }); return convertView; } }
разве платформа для этой реализации не использует контекстное меню, которое отображается при длительном нажатии?
знает ли автор вопроса о контекстных меню? Укладка кнопок в listview имеет последствия для производительности, будет загромождать ваш пользовательский интерфейс и нарушать рекомендуемый дизайн пользовательского интерфейса для платформы.
на обратной стороне; контекстные меню - по своей природе не имеющие пассивного представления - не очевидны для конечного пользователя. Рассмотрите возможность документирования поведение?
Это руководство должно дать вам хороший старт.
http://www.mikeplate.com/2010/01/21/show-a-context-menu-for-long-clicks-in-an-android-listview/