ListViewsetOnItemClickListener 无法通过添加按钮工作

我有一个列表视图,每行都有文本和按钮,列表视图 setOnItemClickListener ()不工作。是否可能以不同的方式处理项目单击和按钮单击事件(项目单击应调用 ActivityA,按钮单击应调用 ActivityB)。有人有办法吗

    private ArrayList<String> userIDArr = null;
private ArrayList<String> userNameArr = null;
private DatabaseHelper dbHelper = null;
private ListView userListView=null;




public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.list_view);
dbHelper = new DatabaseHelper(this.getApplicationContext());
Map<String,ArrayList<String>> displayMap = dbHelper.getUserListToDisplay();
userIDArr = displayMap.get("UserID");
userNameArr = displayMap.get("FirstName1");




userListView = (ListView) findViewById(R.id.listView2);
userListView.setAdapter(new UserListAdapter(this,userIDArr));




userListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {


Toast.makeText(usersListActivity.this,
"Item in position " + position + " clicked", Toast.LENGTH_LONG).show();
}
});
}




public class UserListAdapter extends ArrayAdapter<String>
{
Activity context;
public UserListAdapter(Activity context, ArrayList<String> names) {
super(context, R.layout.list_item, names);
this.context = context;
}
private class ViewHolder {
public TextView UserNameAndID;
public TextView Description;
public Button  UploadBtn;
}


@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
View rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = context.getLayoutInflater();
rowView = inflater.inflate(R.layout.list_item, null, true);
holder = new ViewHolder();
holder.UserNameAndID = (TextView) rowView.findViewById(R.id.User_detailsTxt);
holder.Description = (TextView) rowView.findViewById(R.id.User_status);
holder.UploadBtn = (Button) rowView.findViewById(R.id.uploadbutton);
holder.UploadBtn.setOnClickListener(new View.OnClickListener() {


public void onClick(View v) {
Toast.makeText(usersListActivity.this," Button clicked",Toast.LENGTH_SHORT).show();
}
});
rowView.setTag(holder);
} else {
holder = (ViewHolder) rowView.getTag();
}
String s = userNameArr.get(position)+","+userIDArr.get(position);
holder.UserNameAndID.setText(s);
holder.Description.setText("U r in middle");
return rowView;
}
}
}`
92621 次浏览

Batter thing is to add both Listener to the whole of the rowView and to the Button inside Adapter. Something like this.

public class MyAdapter extends BaseAdapter implements View.OnClickListener{


@Override
public View getView(int position, View convertView, ViewGroup parent)
{
View rowView = convertView;
if(rowView == null)
{
//intialize rowView, and set onclick listener only once.
rowView = someIntilizationMehhodOrInflatorMethod();
//add listener to the button also and also to the row view
rowView.setOnClickListener(this);
}
//all your inflation and setting values goes here and at the end,
//set position as tag to get the correct position, rather buggy one.
rowView.setTag(String.valueOf(position));




return rowView;
}
public void onClick(View v)
{
//now get the tag of View v and convert it to integer.
int pos = Integer.parseInt(v.getTag().toString());
Toast.makeText(context,"Item in position " + pos + " clicked",Toast.LENGTH_LONG).show();
}
}

Try setting your buttons (or any other views you want to handle click inside a list item) like this:

android:focusable="false"
android:focusableInTouchMode="false"

If you have an active view/focusable view in your list view then it will disable onItemClickListener... you can try to make it unfocusable by adding: android:focusable="false" to any view that is usually focusable.

Sometimes the List will still not be able to make the Click Listener to pass. And at this case you might have to add one more attribute.

android:descendantFocusability="blocksDescendants"

And this attribute has to be added to the top most layout of your XML where you have provided the ListView elements.

Instead of adding button add ImageView and provide setOnItemClcik listener which would work fine.

public View getView(final int position, View convertView, ViewGroup parent) {
MyViewHolder mViewHolder;
if(convertView == null) {
convertView = inflater.inflate(R.layout.youtubesearchrow, null);
mViewHolder = new MyViewHolder();
mViewHolder.alarm = (ImageView)convertView.findViewById(R.id.alarm);
convertView.setTag(mViewHolder);
} else {
mViewHolder = (MyViewHolder) convertView.getTag();
}


mViewHolder.tvTitle = detail(convertView, R.id.tvTitle,
// mViewHolder.tvDesc  = detail(convertView, R.id.tvDesc,
mViewHolder.ivIcon  = detail_image(convertView, R.id.ivIcon,


mViewHolder.alarm.setOnClickListener(new OnClickListener() {


@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});


return convertView;
}

I don't know exactly why, but sometimes when you set the adapter, the listeners are cleared. Then, you must call setOnClickListener after setAdapter or setListAdapter.

I'm also getting the same error. If in the list layout you have any button to replace it with TextView i.e ImageButton with ImageView. For Reference their is my code:

private Activity activity;
private LayoutInflater inflater;


private List<ItemList> itemListsItems;


private Bookmark_SharedPref pref;


ImageLoader imageLoader = AppController.getInstance().getImageLoader();


public CustomListAdapter_Item(Activity activity,List<ItemList> itemListsItems){
this.activity=activity;
this.itemListsItems=itemListsItems;
pref = new Bookmark_SharedPref(activity);
}




@Override
public int getCount() {
return itemListsItems.size();
}


@Override
public Object getItem(int position) {
return itemListsItems.get(position);
}


@Override
public long getItemId(int position) {
return position;
}


@Override
public View getView(final int position, View convertView, ViewGroup parent) {


View v = convertView;
ViewHolder holder;


if(inflater == null){
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
if(convertView == null){
convertView = inflater.inflate(R.layout.item_layout,null);


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




if(imageLoader == null){
imageLoader = AppController.getInstance().getImageLoader();
}








holder.img = (NetworkImageView)convertView.findViewById(R.id.item_image);
holder.Title = (TextView)convertView.findViewById(R.id.item_title);
holder.Cat = (TextView)convertView.findViewById(R.id.item_category);


holder.id = (TextView)convertView.findViewById(R.id.itemid);


holder.Desc = (TextView)convertView.findViewById(R.id.item_description);


holder.book = (ImageView)convertView.findViewById(R.id.bookmark_star);






// getting blog data or the row
ItemList il = itemListsItems.get(position);


//setting image
holder.img.setImageUrl(il.getImageUrl(), imageLoader);


// setting title
holder.Title.setText(il.getTitle());


//setting category
holder.Cat.setText(il.getCategory());




//setting blog id
holder.id.setText(il.getId());


//setting description
holder.Desc.setText(il.getDescription());


//bookmarking the post
holder.book.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {


itemListsItems.get(position).isFav = !itemListsItems.get(position).isFav;
((ImageView)v.findViewById(R.id.bookmark_star)).setImageResource(itemListsItems.get(position).isFav ? R.mipmap.active_star : R.mipmap.inactive_star);


if(itemListsItems.get(position).isFav){
String data = Integer.toString(itemListsItems.get(position).id);
Toast.makeText(v.getContext(),"fav hai "+data,Toast.LENGTH_SHORT).show();
pref.addPref(data);
} else {
String data = Integer.toString(itemListsItems.get(position).id);
Toast.makeText(v.getContext(),"not fav"+ data,Toast.LENGTH_SHORT).show();
pref.removePref(data);
}
//notifyDataSetChanged();
}
});


((ImageView)convertView.findViewById(R.id.bookmark_star)).setImageResource(itemListsItems.get(position).isFav ? R.mipmap.active_star : R.mipmap.inactive_star);


/*
if(itemListsItems.get(position).isFav){
String data = Integer.toString(itemListsItems.get(position).id);
Toast.makeText(convertView.getContext(),"fav hai "+data,Toast.LENGTH_SHORT).show();
pref.addPref(data);
} else {
String data = Integer.toString(itemListsItems.get(position).id);
//Toast.makeText(convertView.getContext(),"not fav"+ data,Toast.LENGTH_SHORT).show();
pref.removePref(data);
}
*/
return convertView;
}


private static class ViewHolder {
public TextView Title, Desc,Cat,id;
ImageView book;
NetworkImageView img;
}

Also keep in mind to make list layout as android:focussable="true" and for that button/text parameter use android:focussable="false".

Try set setClickable(false) for each Button, ImageButton, etc and View like this:

view.setClickable(false);
button.setClickable(false);
imagebutton.setClickable(false);

Also you have to add

android:descendantFocusability="blocksDescendants"

to main(first level) layout

Remove android:clickable="true" from the internal custome view from the ListView.

Make the parent clickable attribute to false like this android:clickable="false".

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:orientation="vertical">

Again facing problem, then for all the child views add this clickable false.

Add android:focusable="false" attribute to button and to parent view add android:descendantFocusability="blocksDescendants" attribute like this.

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants">


<ImageButton
android:id="@+id/sell_button"
android:layout_width="wrap_content"
android:focusable="false"
android:layout_height="wrap_content"
android:src="@drawable/ic_sell" />
</RelativeLayout>

It's amazing to noticed that how XML changed causes the setonitemclicked in java Worked for me..

android:descendantFocusability="blocksDescendants"
android:focusable="false"
android:focusableInTouchMode="false"