ListView android 行中的 ImageButton 不工作
ImageButton within row of ListView android not working
我有一个 ListView,其中一行有一个 ImageButton。
我可以单击特定的行并且这有效:新的预期 activity 开始。
但是,如果我单击 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>
非常感谢!
编辑
根据建议,我创建了一个自定义适配器 Class 来显示该行。所以我更改了代码如下: Main activity 现在有以下代码行:
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也是一样
它编译了,但它什么也没做,现在甚至不显示该行...
如果您需要我 post 构建 matrixCursor 的代码,请告诉我。
非常感谢,非常感谢。
试试这个
ImageButton chkDone = (ImageButton) findViewById(R.id.chkDone);
chkDone.setClickable(true);
对你有用吗
更改此行。您应该在 AdapterView
中调用 findViewById()
,而不是在 Activity
中调用 findViewById()
。
ImageButton chkDone = (ImageButton) arg0.findViewById(R.id.chkDone);
更新
没错,非常抱歉。您应该在需要创建的适配器 class 中覆盖方法 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;
}
查看您的 Java 代码,您似乎在 ListView
的 OnItemClickListener
中包含了 ImageButton
的 OnClickListener
。因此,把它放在那个方法之外,我相信它应该可以工作。
编辑:试试这个:
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;
}
您需要创建一个自定义适配器,它接受可用于构建列表的对象列表。
您需要创建一个 class 来保存列表中所需的信息。从你所说的话来看:
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;
}
我有一个 ListView,其中一行有一个 ImageButton。 我可以单击特定的行并且这有效:新的预期 activity 开始。 但是,如果我单击 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>
非常感谢!
编辑
根据建议,我创建了一个自定义适配器 Class 来显示该行。所以我更改了代码如下: Main activity 现在有以下代码行:
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也是一样
它编译了,但它什么也没做,现在甚至不显示该行... 如果您需要我 post 构建 matrixCursor 的代码,请告诉我。
非常感谢,非常感谢。
试试这个
ImageButton chkDone = (ImageButton) findViewById(R.id.chkDone);
chkDone.setClickable(true);
对你有用吗
更改此行。您应该在 AdapterView
中调用 findViewById()
,而不是在 Activity
中调用 findViewById()
。
ImageButton chkDone = (ImageButton) arg0.findViewById(R.id.chkDone);
更新
没错,非常抱歉。您应该在需要创建的适配器 class 中覆盖方法 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;
}
查看您的 Java 代码,您似乎在 ListView
的 OnItemClickListener
中包含了 ImageButton
的 OnClickListener
。因此,把它放在那个方法之外,我相信它应该可以工作。
编辑:试试这个:
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;
}
您需要创建一个自定义适配器,它接受可用于构建列表的对象列表。
您需要创建一个 class 来保存列表中所需的信息。从你所说的话来看:
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;
}