我有一个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; }
这导致任何列表项都不再可选.但它没有帮助使嵌套按钮可选.
有人有想法吗?
对此的解决方案实际上比我想象的要容易.您可以在自定义适配器的getView()
方法中为您正在使用的按钮添加setOnClickListener().
任何与该按钮相关的数据都必须添加到该按钮myButton.setTag()
中,getView()
并且可以在onClickListener中访问view.getTag()
我在博客上发布了一个详细的解决方案作为教程.
这是一种附属物@ znq的回答......
在许多情况下,您希望知道所单击项目的行位置,并且您想知道该行中的哪个视图被点击.这在平板电脑UI中将变得更加重要.
您可以使用以下自定义适配器执行此操作:
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);
它对我来说很好,我可以点击带触摸屏的按钮,也可以使用键盘点击一下
我没有比上述用户更多的经验,但我遇到了同样的问题,我用下面的解决方案解决了这个问题
btnRemoveClick Click事件
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{ private TelefoneArrayAdapter telefoneArrayAdapter = null; private Context context; private EditText tipoEditText = null; private EditText telefoneEditText = null; private ImageView deleteImageView = null; public TelefoneArrayAdapter(Context context, List 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; } }