可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
in my app i use image button in list view. i write action for each image button. but i get java.lang.NoSuchMethodException: onClick exception. i do not know the reason for error please help me. how to write action for the image buttons . thanks in advance.
public class InventoryListActivity extends ListActivity { private InventoryAdapter adapter; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.inventory_list); adapter = new InventoryAdapter(this); setListAdapter(adapter); } }
in InventoryAdapter activity:
public class InventoryAdapter extends BaseAdapter implements Observer,OnClickListener { public InventoryAdapter(Context ctx) { context = ctx; inventory = IAPManager.shared().getInventory(); inventory.addObserver(this); inventory.load(); } public void update(Observable o, Object arg) { switch ( ((Inventory)arg).getStatus() ) { case LOADED: this.notifyDataSetChanged(); break; default: break; } } @Override public int getCount() { return inventory.size(Inventory.FilterType.ALL); } @Override public Object getItem(int position) { return inventory.getProducts(Inventory.FilterType.ALL).get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { Product product = (Product) getItem(position); View view; if(convertView == null) { LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflater.inflate(R.layout.inventory_list_item, null); } else { view = convertView; } play = (ImageButton)findViewById(R.id.imageButton2); detail = (ImageButton)findViewById(R.id.imageButton3); buy = (ImageButton)findViewById(R.id.imageButton2); play.setTag(position); detail.setTag(position); buy.setTag(position); titleView = (TextView) view.findViewById(R.id.product_title); titleView.setText(product.getTitle()); iconView = (ImageView) view.findViewById(R.id.product_icon); String iconURL = product.getIconURLString(); if(AsyncImageLoader.contains(iconURL)) { iconView.setImageDrawable(AsyncImageLoader.get(iconURL)); } else { iconView.setImageDrawable(null); new AsyncImageLoader(product.getIconURLString(), new AsyncImageLoader.Delegate(){ public void imageLoaded(String urlString, Drawable imageDrawable) { notifyDataSetChanged(); } }); } descriptionView = (TextView) view.findViewById(R.id.product_description); descriptionView.setText(product.getDescription()); return view; } private ImageButton findViewById(int imagebutton2) { // TODO Auto-generated method stub return null; } @Override public void onClick(View v) { Log.e("onclick","onclick"); Integer position = (Integer) v.getTag(); switch(v.getId()){ case R.id.imageButton1: Log.e("Buy","buy position"+position); break; case R.id.imageButton2: Log.e("play","play position"+position); break; case R.id.imageButton3: Log.e("detail","detail position"+position); break; } }
}
in xml:
<ImageButton android:background="@drawable/play_btn" android:focusable="false" android:onClick="onClick" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/imageButton2" android:layout_weight="0.5" />
回答1:
I think the problem is, that you're trying to wire up the onClick listener via xml but implement it in your adapter. I think android simply doesn't recognize the onClick listener or doesn't know that is should be used for the ImageButton. Try to implement and add the OnClickListener dynamically in the getView() method.
UPDATE
Check the first if statement of the getView() method. There the OnClickListener will be set for the 3 buttons. As your adapter implements the OnClickListener interface you pass the adpater to the method. You also have to remove the android:onClick="onClick"
attribute from your ImageButtons in the layout xml file.
@Override public View getView(int position, View convertView, ViewGroup parent) { Product product = (Product) getItem(position); View view; if(convertView == null) { LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflater.inflate(R.layout.inventory_list_item, null); play = (ImageButton)findViewById(R.id.imageButton2); detail = (ImageButton)findViewById(R.id.imageButton3); buy = (ImageButton)findViewById(R.id.imageButton2); // Set the OnClickListener for the 3 image buttons. play.setOnClickListener(this); detail.setOnClickListener(this); buy.setOnClickListener(this); } else { view = convertView; } play = (ImageButton)findViewById(R.id.imageButton2); detail = (ImageButton)findViewById(R.id.imageButton3); buy = (ImageButton)findViewById(R.id.imageButton2); play.setTag(position); detail.setTag(position); buy.setTag(position); titleView = (TextView) view.findViewById(R.id.product_title); titleView.setText(product.getTitle()); iconView = (ImageView) view.findViewById(R.id.product_icon); String iconURL = product.getIconURLString(); if(AsyncImageLoader.contains(iconURL)) { iconView.setImageDrawable(AsyncImageLoader.get(iconURL)); } else { iconView.setImageDrawable(null); new AsyncImageLoader(product.getIconURLString(), new AsyncImageLoader.Delegate(){ public void imageLoaded(String urlString, Drawable imageDrawable) { notifyDataSetChanged(); } }); } descriptionView = (TextView) view.findViewById(R.id.product_description); descriptionView.setText(product.getDescription()); return view; }
回答2:
For those of us who are stubborn and don't want to make the OnClickListener, here is an example:
http://developer.android.com/reference/android/widget/Button.html
NOTE: to hook the XMLs android:onClick field up to your activity's method, you will need to have the correct signature, namely:
void YourMethod(View v);
回答3:
You need to remove the android:onClick="onClick" from your XML, because the ImageButton doesn't know what that means. That's why you're getting a NoSuchMethodException at runtime.
You also should remove the findViewById method that returns null -- that's going to cause nothing but problems.
Don't implement OnClickListener, that's not what you want for this. And then, get rid of your onClick method. Instead, you should define a new OnClickListener for each ImageButton. Like so:
play.setOnClickListener(new View.OnClickListener() { public void onClick(View arg0) { Log.i("play","play button clicked"); } });
Do that for each of the "play", "detail", and "buy" ImageButtons. Note that you can use any variable in there that's defined as final.
final Product product = (Product)getItem(position); detail.setOnClickListener(new View.OnClickListener() { public void onClick(View arg0) { Log.i("detail", "clicked for product " + product.toString()); } }
I hope that points you in the right direction.
回答4:
I have done a similar thing but in the main activity (where the listview is declared) i've added this:
listView.setOnItemClickListener(new OnItemClickListener(){ public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { switch(view.getId()){ case R.id.imageButton1: Log.e("Buy","buy position"+position); break; case R.id.imageButton2: Log.e("play","play position"+position); break; case R.id.imageButton3: Log.e("detail","detail position"+position); break; } });
回答5:
If your layout is inflated in a Fragment
in which you want to catch the onClick
as specified by the XML, it might be directed to your main Activity
.
I have a ViewPager
that is showing a number of fragments. Each fragment has a clickable ImageView
which should call changePicture
when clicked, but the fragment code is not called, it is the main Activity
which gets the call.
So the way I solved it is to define that onClickListener
as many has mentioned.