问题
I have a ListView with a row that has an ImageButton. I can click on a particular row and this works: the new expected activity starts. But if I click on the ImageButton, and this is an item within the row, nothing happens. The imageButton gets highlighted but the print out within the onClick of the ImageButton is not executed. Can anyone tell me how I can resolve this? Here is my code:
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);
}
});
}
});
Here is the XML for the Row where the ImageButton is:
<?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>
Thanks very much!
EDIT
Following suggestions I have created a Custom Adapter Class to show the row. So I have changed the code as follows: The Main activity now has the following lines of code:
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);
And the CustomListViewAdapter Looks like:
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;
}
}
The XML is the same.
It compiles, but it doesn't do anything and it does not even show the row now... Let me know if you need me to post the code that builds up the matrixCursor.
Thanks very much, much appreciated.
回答1:
You need to create a custom adapter which accepts a list of objects that you can use to build your list.
You need to create a class which holds the information needed in your list. From what you've said something like this:
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;
}
}
Then create these objects from the items you want in your list
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);
After creating your list of RowItem objects you create your custom adapter like this:
CustomListViewAdapter customAdapter = new CustomListViewAdapter(this, R.layout.todo_row, rowItems);
Then you can pass your list of RowItem objects into your custom adapter via it's contructor (like you were trying to do previously):
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;
}
回答2:
try this
ImageButton chkDone = (ImageButton) findViewById(R.id.chkDone);
chkDone.setClickable(true);
may it works for you
回答3:
Change this line. You should call findViewById()
in your AdapterView
, not in Activity
.
ImageButton chkDone = (ImageButton) arg0.findViewById(R.id.chkDone);
UPDATE
That's right, so sorry. You should Override method getView()
in your adapter class which you need to create. It must be like this:
@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;
}
回答4:
Looking at your Java code, it seems that you have the ImageButton
's OnClickListener
inside the ListView
's OnItemClickListener
.. Therefore, put it outside of that method and it should work I believe.
EDIT: Try this:
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;
}
来源:https://stackoverflow.com/questions/29819256/imagebutton-within-row-of-listview-android-not-working