问题
I have a listview with a custom Adapter. A custom row in the listView containts 2 imagebuttons that need to handle a something when I click on it. But it doesn't work well like I want, because when I start the app and click on the imagebutton then nothing happens, but if I first click on the row and then on the imageButton, then my click is being handled. I tried a few solutions that helped other users here SO, but nobody had the exact same problem as me that it gets handled after a row click.
FavoriteActivity
public class FavoriteActivity extends Activity {
private List<Favorite> favoriteItem = new ArrayList<Favorite>();
ViewHolder holder = new ViewHolder();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.favorite);
populateFavoriteList();
populateListview();
registerClickCallBack();
}
private void populateFavoriteList() {
favoriteItem.add(new Favorite(R.drawable.icon_camera, "item 1"));
favoriteItem.add(new Favorite(R.drawable.icon_camera, "item 2"));
favoriteItem.add(new Favorite(R.drawable.icon_camera, "item 3"));
favoriteItem.add(new Favorite(R.drawable.icon_camera, "item 4"));
favoriteItem.add(new Favorite(R.drawable.icon_camera, "item 5"));
favoriteItem.add(new Favorite(R.drawable.icon_camera, "item 6"));
favoriteItem.add(new Favorite(R.drawable.icon_camera, "item 7"));
favoriteItem.add(new Favorite(R.drawable.icon_camera, "item 8"));
}
private void populateListview() {
ArrayAdapter<Favorite> adapter = new MyListAdapter();
ListView list = (ListView) findViewById(R.id.favoriteList);
list.setAdapter(adapter);
}
private class MyListAdapter extends ArrayAdapter<Favorite> {
public MyListAdapter() {
super(FavoriteActivity.this, R.layout.favorite_row, favoriteItem);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// To be sure we have a view, because null is possible
View itemView = convertView;
if (itemView == null) {
itemView = getLayoutInflater().inflate(R.layout.favorite_row, parent, false);
}
// Find the item to work with
Favorite currentItem = favoriteItem.get(position);
// Filling the View
holder.thumbnail = (ImageButton) itemView.findViewById(R.id.favoriteThumbnail);
holder.thumbnail.setBackgroundResource(currentItem.getThumbnail());
holder.name = (TextView) itemView.findViewById(R.id.favoriteName);
holder.name.setText(currentItem.getName());
return itemView;
}
}
private void registerClickCallBack() {
ListView list = (ListView) findViewById(R.id.favoriteList);
list.setOnItemClickListener(new AdapterView.OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent, View viewClicked, int position, long id) {
final Favorite favoriteClicked = favoriteItem.get(position);
String msg = "Clicked position " + position + " which is " + favoriteClicked.getName();//Can I use my holder here to get the name back?? Because it wasn't working...
Toast.makeText(FavoriteActivity.this, msg, Toast.LENGTH_LONG).show();
ImageButton btnDirections = (ImageButton) viewClicked.findViewById(R.id.favoriteDirections);
ImageButton btnDelete = (ImageButton) viewClicked.findViewById(R.id.favoriteDelete);
btnDirections.setOnClickListener(new OnClickListener() {
String btnmsg = "getting directions for " + favoriteClicked.getName();
@Override
public void onClick(View v) {
Toast.makeText(FavoriteActivity.this, btnmsg, Toast.LENGTH_LONG).show();
}
});
btnDelete.setOnClickListener(new OnClickListener() {
String btnmsg = "getting delete for " + favoriteClicked.getName();
@Override
public void onClick(View v) {
Toast.makeText(FavoriteActivity.this, btnmsg, Toast.LENGTH_LONG).show();
}
});
}
});
}
static class ViewHolder {
ImageButton thumbnail;
TextView name;
}
}
FavoriteClass
public class Favorite {
private int favoriteThumbnail;
private String favoriteName;
public Favorite(int favoriteThumbnail, String favoriteName){
super();
this.favoriteThumbnail = favoriteThumbnail;
this.favoriteName = favoriteName;
}
public int getThumbnail(){
return favoriteThumbnail;
}
public String getName(){
return favoriteName;
}
}
favorite_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="4"
android:descendantFocusability="blocksDescendants">
<ImageButton
android:layout_width="75dp"
android:layout_height="65dp"
android:contentDescription="thumbnail"
android:src="@drawable/icon_camera"
android:layout_weight="2"
android:id="@+id/favoriteThumbnail"
android:scaleType="fitXY"
style="@style/favoriteRowItems"
android:focusable="false"/>
<TextView
android:id="@+id/favoriteName"
android:layout_weight="2"
android:layout_gravity="center_vertical"
android:text="Name"
android:textSize="30sp"
style="@style/favoriteRowItems"/>
<ImageButton
android:contentDescription="Direction"
android:layout_weight="0.5"
android:src="@drawable/icon_directions"
android:id="@+id/favoriteDirections"
style="@style/favoriteRowItems"
android:focusable="false"/>
<ImageButton
android:contentDescription="Delete from favorite"
android:layout_weight="0.5"
android:src="@drawable/icon_delete"
android:id="@+id/favoriteDelete"
style="@style/favoriteRowItems"
android:layout_marginRight="5dp"
android:focusable="false"/>
</LinearLayout>
回答1:
Add your two buttons to the getView
method, and include them in your handler, then on a pass through the getView
method you want to assign a click listener like this:
holder.btnDelete.setOnClickListener(new OnClickListener() {
String btnmsg = "getting delete for " + favoriteClicked.getName();
@Override
public void onClick(View v) {
Toast.makeText(FavoriteActivity.this, btnmsg, Toast.LENGTH_LONG).show();
}
});
So your ViewHolder
class will look like this:
static class ViewHolder {
ImageButton thumbnail;
TextView name;
ImageButton btnDelete;
ImageButton btnDirections;
}
and you set up the buttons in the getView()
method as per the other Views
holder.btnDirections=(ImageButton)itemView.findViewById(R.id.favoriteDirections);
holder.btnDelete=(ImageButton)itemView.findViewById(R.id.favoriteDelete);
回答2:
Well, you're initializing the click listeners of the buttons in the ListView's onItemClickListener()
, of course it's only going to work after you click the row.
You need to set these up in the getView()
method. Note, however, that it's not really standard practice to provide clickable items inside a ListView item.
来源:https://stackoverflow.com/questions/16460368/handling-imagebutton-clicks-inside-a-custom-listview