如何使用列表中的按钮触发Listactivity中的onListItemClick?

时间:2009-11-30 19:27:34

标签: android android-widget android-listview

我有一个简单的ListActivity,它使用自定义ListAdapter在列表中生成视图。通常ListAdapter只会用TextViews填充视图,但现在我想在那里放一个按钮。

然而,根据我的理解和经验,在列表项中放置可聚焦视图可防止在单击列表项时在ListActivity中触发onListItemClick()。按钮仍然在列表项中正常运行,但是当按下按钮之外的其他内容时,我希望触发onListItemClick。

我该如何做到这一点?

8 个答案:

答案 0 :(得分:99)

我在previous comment解决方案中写的是

在ImageButton上的setFocusable(false)。

更优雅的解决方案是尝试在list element的根布局中添加android:descendantFocusability="blocksDescendants" 。这将使点击onListItem成为可能,并且你可以单独处理Button或ImageButton点击

希望它有所帮助;)

干杯

答案 1 :(得分: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构造函数添加更多参数。
一个重要的事情 - 上面显示的getView的实现非常难看,通常你应该使用ViewHolder模式来避免findViewById调用..但你可能已经知道。
我的custom_row.xml文件是RelativeLayout,其Button为id“button”,TextView为id“text”,ImageView为id“image” - 只是为了清楚。 此致!

答案 2 :(得分: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);
        …       
    }
}

答案 3 :(得分: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
min SDK版本:3

我希望这对你有帮助 ...对不起我的英语:(

答案 4 :(得分:2)

只需添加android:focusable="false"作为按钮的一个属性

答案 5 :(得分:1)

我在使用ToggleButton时遇到了同样的问题。在我的头撞墙后半天,我终于解决了。 使用'android:focusable'就像使可聚焦视图无法聚焦一样简单。您还应该避免使用列表行的可聚焦性和可点击性(我只是编写单词),只需保留默认值。

当然,既然列表行中的可聚焦视图不可聚焦,使用键盘的用户可能会遇到问题,好吧,关注它们。这不太可能是一个问题,但是如果您想要编写100%完美无瑕的应用程序,您可以使用onItemSelected事件使所选行的元素可聚焦,并且先前选定行的元素不可聚焦。

答案 6 :(得分: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();
}
});

答案 7 :(得分:-1)

我使用getListAdapter()。getItem(position)实例化一个在项目中保存我的值的Object

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

然后使用myPojo中的getter方法,它将在项目中调用其正确的值。