我有一个简单的 ListActivity,它使用自定义 ListAdapter 来生成列表中的视图。通常 ListAdapter 只会用 TextViews 填充视图,但现在我也想在那里放一个按钮。
然而,我的理解和经验是,在列表项中放置一个可聚焦的视图可以防止在单击列表项时在 ListActivity 中触发 onListItemClick()。该按钮仍然在列表项中正常运行,但是当按下按钮之外的其他内容时,我希望触发 onListItemClick。
我怎样才能使这项工作?
我有一个简单的 ListActivity,它使用自定义 ListAdapter 来生成列表中的视图。通常 ListAdapter 只会用 TextViews 填充视图,但现在我也想在那里放一个按钮。
然而,我的理解和经验是,在列表项中放置一个可聚焦的视图可以防止在单击列表项时在 ListActivity 中触发 onListItemClick()。该按钮仍然在列表项中正常运行,但是当按下按钮之外的其他内容时,我希望触发 onListItemClick。
我怎样才能使这项工作?
正如我在之前的评论中所写的解决方案是在 ImageButton 上设置焦点(假)。
还有更优雅的解决方案尝试添加列表元素android:descendantFocusability="blocksDescendants"
的根布局。这将使点击 onListItem 成为可能,并且您可以单独处理 Button 或 ImageButton 点击
希望能帮助到你 ;)
干杯
我希望我能在这里提供帮助。我假设您有 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 构造函数添加更多参数。
还有一件重要的事情——上面显示的 getView 的实现非常难看,通常你应该使用 ViewHolder 模式来避免 findViewById 调用。但你可能已经知道了。
我的 custom_row.xml 文件是具有 id 为“button”的 Button、id 为“text”的 TextView 和 id 为“image”的 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 的类上,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<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
min SDK 版本:3
我希望这会有所帮助
......对不起我的英语:(
只需添加android:focusable="false"
为按钮的属性之一
我对 ToggleButton 也有同样的问题。经过半天的头撞墙后,我终于解决了。就像使用'android:focusable'使可聚焦视图无法聚焦一样简单。您还应该避免使用列表行的可聚焦性和可点击性(我只是编造单词),只需将它们保留为默认值即可。
当然,既然列表行中的可聚焦视图无法聚焦,使用键盘的用户可能会遇到问题,好吧,聚焦它们。这不太可能是一个问题,但如果您想编写 100% 完美的应用程序,您可以使用 onItemSelected 事件使选定行的元素可聚焦,而先前选定行的元素不可聚焦。
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();
}
});
我使用 getListAdapter().getItem(position) 实例化一个在项目中保存我的值的对象
MyPojo myPojo = getListAdapter().getItem(position);
然后使用 myPojo 中的 getter 方法,它将在 item 中调用其正确的值。