【问题标题】:ImageButton within row of ListView android not workingListView android行内的ImageButton不起作用
【发布时间】:2015-04-23 09:28:36
【问题描述】:

我有一个 ListView,其中一行有一个 ImageButton。 我可以点击一个特定的行,这很有效:新的预期活动开始了。 但是,如果我单击 ImageButton,并且这是该行中的一个项目,则不会发生任何事情。 imageButton 被突出显示,但在 ImageButton 的 onClick 中的打印输出没有被执行。 谁能告诉我如何解决这个问题? 这是我的代码:

    SimpleCursorAdapter menuItems2 = new SimpleCursorAdapter(
            this, R.layout.todo_row, matrixCursor, columnNames, to);
    ToDolv.setAdapter(menuItems2);

    ToDolv.setClickable(true);

    ToDolv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
          @Override
          public void onItemClick(AdapterView<?> arg0, View arg1, final int position, long arg3) { 
               final String article = (String) todoIDArray.get(position);
               globalVariable.setArtID(article);
               Intent intent1 = new Intent(MainActivity.this, AddToDo.class);
               startActivity(intent1);
               finish();

               ImageButton chkDone = (ImageButton) findViewById(R.id.chkDone);
               chkDone.setOnClickListener(new View.OnClickListener() {              
               @Override
                  public void onClick(View v) {
                     // TODO Auto-generated method stub
                     View parentRow = (View) v.getParent();
                     ListView listView = (ListView) parentRow.getParent();
                     final int position = listView.getPositionForView(parentRow);
                     System.out.println("I am in position "+ position);
               }
             });

          }

        });

这是 ImageButton 所在行的 XML:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:padding="6dip"
android:background = "#5a9b3e"
android:alpha = "0.7"
android:descendantFocusability="blocksDescendants"
>
    <TextView 
    android:id="@+id/id"
    android:textColor="#5a9b3e"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"

    />
    <TextView
        android:id="@+id/heading"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:textColor="#FFFFFF"
        android:textStyle="bold"
        android:alpha = "1.0"
        android:layout_alignParentTop="true"
        android:ellipsize="marquee"
        android:singleLine="false"
        android:textSize="12sp"
        />


   <ImageView
        android:id="@+id/icon"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:padding="2dp"
        android:layout_toRightOf="@+id/heading"
        android:layout_toEndOf="@+id/heading"

        />

   <ImageView 
       android:id="@+id/lights"
       android:layout_width= "20dp"
       android:layout_height="20dp"
       android:padding="2dp"
       android:layout_toRightOf="@+id/icon"
       android:layout_toEndOf="@+id/icon"
       />

    <ImageButton
    android:id="@+id/chkDone"
    android:layout_width="20dp"
    android:layout_height="20dp"
    android:padding="0dp"
    android:background="?android:attr/listChoiceBackgroundIndicator"
    android:layout_toRightOf="@+id/lights"
    android:layout_toEndOf="@+id/lights"
    android:src ="@drawable/checkbox"
    android:scaleType="fitXY"
    android:focusable="false"
    android:focusableInTouchMode="false"
    />
   <TextView 
       android:id="@+id/date"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:textColor="#FFFFFF"
       android:textStyle="bold"
       android:alpha = "1.0"
       android:layout_marginStart="2sp"
       android:layout_marginLeft="2sp"
       android:layout_marginTop="2sp"
       android:textSize="12sp" 
       android:layout_toRightOf="@+id/chkDone"
       android:layout_toEndOf="@+id/chkDone"/>
</RelativeLayout>

非常感谢!

编辑

根据建议,我创建了一个自定义适配器类来显示该行。所以我将代码更改如下: Main 活动现在有以下几行代码:

      ListView yourListView = (ListView) findViewById(R.id.list);
      SimpleCursorAdapter menuItems2 = new SimpleCursorAdapter(
            this, R.layout.todo_row, matrixCursor, columnNames, to);

      CustomListViewAdapter customAdapter = new CustomListViewAdapter(this, R.layout.todo_row, menuItems2);
      yourListView .setAdapter(customAdapter);

CustomListViewAdapter 看起来像:

public class CustomListViewAdapter extends ArrayAdapter<RowItem> {
Context context;
public CustomListViewAdapter(Context context, int resourceId,
        SimpleCursorAdapter menuItems2) {
    super(context, resourceId);
    this.context = context;
    System.out.println("I am in the custom Adapter class "+ context);
}
@Override
public View getView(int position, View convertView, ViewGroup parent){
    System.out.println("This is the get view");
    View row = convertView;
    if (row == null) {
       LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
       row = mInflater.inflate(R.layout.todo_row, parent, false);
    }

    ImageButton chkDone = (ImageButton) row.findViewById(R.id.chkDone);
    chkDone.setOnClickListener(new View.OnClickListener() {              
          @Override
          public void onClick(View v) {
                View parentRow = (View) v.getParent();
                ListView listView = (ListView) parentRow.getParent();
                final int position =   listView.getPositionForView(parentRow);
                System.out.println("I am in position "+ position);
          }
     });

    return row;
}
}

XML 是一样的。

它编译了,但它什么也没做,现在甚至不显示该行... 如果您需要我发布构建 matrixCursor 的代码,请告诉我。

非常感谢,非常感谢。

【问题讨论】:

  • 您仅在单击该行时才设置按钮的单击侦听器(因为您是从 ToDolv.setOnItemClickListener 中调用它,这是行不通的。您需要查看创建自定义您的列表视图的适配器并在那里为您的图像视图设置点击事件。此链接可能会有所帮助stackoverflow.com/questions/8166497/…
  • 发布你的适配器类。
  • 他正在使用SimpleCursorAdapter,他还没有为列表创建自定义适配器,这是主要问题
  • @Dreagen,你是对的。如何为列表视图创建自定义适配器?
  • @user3079872 我在第一条评论中的链接有一个很好的例子来说明如何做到这一点。如果我将其作为答案放在此处,我只会重新编写其中的内容。试一试,如果您遇到困难,请在此处发布您的努力,如果需要,我可以帮助您解决问题

标签: android listview onclicklistener imagebutton onitemclicklistener


【解决方案1】:

您需要创建一个自定义适配器,该适配器接受可用于构建列表的对象列表。

您需要创建一个包含列表中所需信息的类。根据您所说的:

public class RowItem {

    private String _columnName;
    private Drawable _drawable;

    public RowItem(String columnName, Drawable drawable) {
         _columnName = columnName;
         _drawable = drawable;
    }

    public String getColumnName() {
        return _columnName;
    }

    public Drawable getDrawable() {
        return _drawable;
    }
}

然后从列表中您想要的项目创建这些对象

ArrayList<RowItem> rowItems = new ArrayList<>();

//Create a number of row items and add them to your list
RowItem myItem1 = new RowItem("String I want for column name", myDrawable);
rowItems.add(myItem1);

创建 RowItem 对象列表后,您可以像这样创建自定义适配器:

CustomListViewAdapter customAdapter = new CustomListViewAdapter(this, R.layout.todo_row, rowItems);

然后您可以通过它的构造器将您的 RowItem 对象列表传递到您的自定义适配器中(就像您之前尝试做的那样):

public class CustomListViewAdapter extends ArrayAdapter<RowItem> {

Context context;
ArrayList<RowItem> _rowItems;

public CustomListViewAdapter(Context context, int resourceId,
        ArrayList<RowItem> rowItems) {
    super(context, resourceId);
    this.context = context;
    _rowItems = rowItems;
    System.out.println("I am in the custom Adapter class "+ context);
}

@Override
public View getView(int position, View convertView, ViewGroup parent){
    System.out.println("This is the get view");
    View row = convertView;
    RowItem item = _rowItems.get(position);

    // you can now get your string and drawable from the item
    // which you can use however you want in your list
    String columnName = rowItem.getColumnName();
    Drawable drawable = rowItem.getDrawable();
    if (row == null) {
        LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
       row = mInflater.inflate(R.layout.todo_row, parent, false);

    }

    ImageButton chkDone = (ImageButton) row.findViewById(R.id.chkDone);
    chkDone.setOnClickListener(new View.OnClickListener() {              
          @Override
          public void onClick(View v) {
                View parentRow = (View) v.getParent();
                ListView listView = (ListView) parentRow.getParent();
                final int position =   listView.getPositionForView(parentRow);
                System.out.println("I am in position "+ position);
          }
     });

    return row;
}

【讨论】:

  • 根据我掌握的信息,这是我能想到的最佳答案。希望它能让你更清楚
  • 非常感谢,非常感谢您的帮助。我已将您的代码放入我的课程中。一切似乎都很好,除了 rowItems = rowItems; 行。它不喜欢。它说 _rowItems 无法解析为变量。我是否错过了导入以处理变量上的“”?
  • 非常欢迎您。听起来您好像错过了这一行:ArrayList&lt;RowItem&gt; _rowItems = new ArrayList&lt;&gt;(); 尽管我的回答中该行有错字,而且可能会更短一些。我现在将编辑我的答案
  • 我现在已经编辑了我的答案。确保您的CustomListViewAdapter 中有以下行:ArrayList&lt;RowItem&gt; _rowItems;
  • 好的,谢谢。但是,它抱怨以下行:'String columnName = rowItem.getColumnName(); '和下面的那个。我的另一个问题是如何从 Main Activity 调用 CustomListViewAdapter?我有:'CustomListViewAdapter customAdapter = new CustomListViewAdapter(this, R.layout.todo_row, List);'但它不喜欢它。它说令牌 > 上的语法错误,这是 myItem1 位...再次,非常感谢!
【解决方案2】:

试试这个

ImageButton chkDone = (ImageButton) findViewById(R.id.chkDone);
chkDone.setClickable(true);

可能对你有用

【讨论】:

  • 可能是问题在于..您正在 ListView Click 上注册 ImageButtonClick。这意味着您的 imagebutton 点击​​不会注册,直到您点击 listitem。所以尝试将图像按钮点击移动到列表项点击之外
【解决方案3】:

更改此行。您应该在您的AdapterView 中调用findViewById(),而不是在Activity

ImageButton chkDone = (ImageButton) arg0.findViewById(R.id.chkDone);

更新 没错,很抱歉。您应该在您需要创建的适配器类中覆盖方法getView()。应该是这样的:

@Override
public View getView(int position, View convertView, ViewGroup parent){
    View row = convertView;
    if (row == null) {
       LayoutInflater mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
       row = mInflater.inflate(R.layout.mylistlayout, parent, false);
    }

    ImageButton chkDone = (ImageButton) findViewById(R.id.chkDone);
    chkDone.setOnClickListener(new View.OnClickListener() {              
          @Override
          public void onClick(View v) {
                View parentRow = (View) v.getParent();
                ListView listView = (ListView) parentRow.getParent();
                final int position =   listView.getPositionForView(parentRow);
                System.out.println("I am in position "+ position);
          }
     });

    return row;
}

【讨论】:

  • 谢谢,我已经创建了一个自定义适配器类并将上面的代码放入其中。我正在为调用自定义适配器的代码行苦苦挣扎: ListAdapter customAdapter = new ListAdapter(this, R.layout.itemlistrow, List);不确定我应该为 放什么我正在使用矩阵光标来构建行的内容。
【解决方案4】:

查看您的 Java 代码,您似乎在 ListViewOnItemClickListener 中有 ImageButtonOnClickListener。因此,将它放在该方法之外,我相信它应该可以工作。

编辑:试试这个:

    public View getView(int position, View row, ViewGroup parent) {
            final ViewHolder holder;
            if (row == null) {
                LayoutInflater inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
                row = inflater.inflate(R.layout.items_layout, parent, false);
                holder = new ViewHolder();

                holder.chkDone = (ImageButton) row.findViewById(R.id.chkDone);

             row.setTag(holder);
            } else {
                holder = (ViewHolder)row.getTag();
            }

            // You add all your methods here...
            holder.chkDone.setOnClickListener(new View.OnClickListener() {              
               @Override
                  public void onClick(View v) {
                     // TODO Auto-generated method stub
                     View parentRow = (View) v.getParent();
                     ListView listView = (ListView) parentRow.getParent();
                     final int position = listView.getPositionForView(parentRow);
                     System.out.println("I am in position "+ position);
               }
             });

        }
        return(row);
    }

    class ViewHolder {
        ImageButton chkDone;
    }

【讨论】:

  • 它不起作用,因为包含ImageButton 的布局是在ListView 内部定义的
  • 为什么不在ListViewOnItemClickListener之外定义呢?我觉得应该没问题,试试吧。
  • 编辑了我的答案,所以试试吧。
  • @M-Y,我很乐意尝试,但是一个愚蠢的问题,我如何调用 getView?
  • @user3079872 如果您需要传入包含字符串和可绘制对象的内容,请创建一个包含这两项内容的类并将该类的列表传递给它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-28
  • 2019-02-23
  • 2021-09-28
  • 2016-05-04
  • 1970-01-01
  • 1970-01-01
  • 2015-12-19
相关资源
最近更新 更多