Lets say you have a spinner widget, like the one we created in our 'colours' example, and you wanted to put a button on each row of your spinner for your users to click (everyone loves clicking buttons, right?).
You might have a layout a bit like this simple one below:
<LinearLayout android:id="@+id/LinearLayout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView android:text="this is a row"
android:id="@+id/tvViewRow"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
<Button android:text="Click me!"
android:id="@+id/BtnToClick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="myClickHandler">
</Button>
</LinearLayout>
.. Containing just a textView and a Button View.
A listView with textual, non-clickable views in it responds to Click events via the OnItemClickListener event.
But once you put a button in the ListView, this event no longer fires.
So how do you capture the button's click event, and find what row in your ListView a clicked button is located in?
You may have noticed this
android:onClick="myClickHandler">
in our layout above..What this does is tie every click of every instance of that button, in every row of our ListView to one single handler, located in the code of our ListActivity class below:
public void myClickHandler(View v)
{
//reset all the listView items background colours
//before we set the clicked one..
ListView lvItems = getListView();
for (int i=0; i < lvItems.getChildCount(); i++)
{
lvItems.getChildAt(i).setBackgroundColor(Color.BLUE);
}
//get the row the clicked button is in
LinearLayout vwParentRow = (LinearLayout)v.getParent();
TextView child = (TextView)vwParentRow.getChildAt(0);
Button btnChild = (Button)vwParentRow.getChildAt(1);
btnChild.setText(child.getText());
btnChild.setText("I've been clicked!");
int c = Color.CYAN;
vwParentRow.setBackgroundColor(c);
vwParentRow.refreshDrawableState();
}
In this case, the
View v
being passed in as a parameter is our button.We get the parent of our button, being careful to cast it as a LinearLayout (have another look at the xml if you're not sure why), and then simply set the background colour of our Layout Row.
Don't forget to call
.refreshDrawableState();
on your vwParentRow
or it will never redraw and you won't see your nice colour change... Tada!
Update: Hi everyone, thanks for all the interest, here's a link to the full project zipped.
Updated Update: Here's another link, and another, and another.
I've also updated the above myClickHandler to loop through the other items in the ListView and reset them to a default colour, in this case blue, to make it a bit more obvious what's going on. Hope that helps.
Please up full source code :D
ReplyDeleteThis help a lot Thanks
ReplyDeleteYes please provide source code. I'm having a problem with making a ListView with anything more than just a single TextView in it. I would like to make ListViews with multiple Views as you did.
ReplyDeleteI figured it out. First changed my ArrayAdapter constructor, then modified how you used getParent and getChildAt.
ReplyDeleteThanks for the reference.
How to I get the item data or position for the clicked view=button resp. its parent row?
ReplyDeleteBut this ll chage the colour of all items when clicked. if i click in one item, colour gets chaged and then i click on another that also ll get changed so how to implement selector colour using this
ReplyDeleteDude, Thanks. exactly what I was looking for.
ReplyDeleteIf you add onItemClickListener on the ListView, can you click either the row or the button ? In ,y case after I added button, the row was no longer clickable.
ReplyDeleteplease provide full source
ReplyDeleteThanks a lot for the nice concept!!
ReplyDeletebut the link that you provided doesn't work :-(
google doc says that the document isn't available anymore.
Thanks Aman, that's weird, works for me.
ReplyDeleteI'll upload it in a couple of other places for backup.
Thanks for letting me know.
I tried this and get an error
ReplyDeleteERROR No resource identifier found for attribute 'onClick' in package 'android' menu_item.xml
this is the simplest approach i have got on net..worked like a charm!! thanks buddy..
ReplyDeletehow can i find out the row number from top which has been selected??
ReplyDeleteThank u Very much ..looking for this topic..
ReplyDeleteIn the listView button click event, i want to switch over to different activity in the activity group.how to do that.Please help.
ReplyDeleteHi.Can somebody post link to source code, i have some problems with adapter.
ReplyDeleteBy the way,its better to post source code on google sites, and not on filetube or rapidshare. That way it wont be deleted after some time.
Thanks.
Hi Alex,
ReplyDelete.. Thanks for visiting. The first link is to google docs and should work for you. Here you go.
the link seems to be dead or something cannot find the link, can you re check please ?
ReplyDeleteHi guys,
ReplyDelete.. can you try again now?
I've made it public in google docs, and I've checked it from another computer where I haven't signed into google and it works fine for me.
It should take you to a page with a downloadable zip file of the project.
How can you capture the list item click AND the button click?
ReplyDeleteHi Ben,
ReplyDeleteDepending on who you ask, it may be either not really possible (as soon as you add a button you can no longer click on the row, and that's by design), or do-able with a bit of a hack.
See here:
http://groups.google.com/group/android-developers/browse_thread/thread/3d96af1530a7d62a/83deebc96c885b0b
Hope that helps.
Hi there, if anyone could help me out please here. I am facing a problem and can not find the solution for this … My code is the following and i cant seem to find the errors but its just when the splash screen is exited towards the main page, just top button works, others don’t … but when tapped that button and return from there then all the buttons work. I want them all to work
ReplyDeletepackage net.xuting;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class xutingMenu extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// button 1
Button btn_live_tv = (Button) findViewById(R.id.btnLiveTv);
btn_live_tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
startActivity(new Intent(“net.xuting.LIVETV”));
//button2
Button btn_Favorites = (Button) findViewById(R.id.btnFavorites);
btn_Favorites.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
startActivity(new Intent(“net.xuting.FAVORITES”));
}
});
//button 3
Button btn_Featured = (Button) findViewById(R.id.btnFeatured);
btn_Featured.setOnClickListener (new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
startActivity(new Intent(“net.xuting.FEATURED”));
}
});
//button 4
Button btn_Video_On_Demand = (Button) findViewById(R.id.btnVideoOnDemand);
btn_Video_On_Demand.setOnClickListener (new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
startActivity(new Intent(“net.xuting.VIDEO_ON_DEMAND”));
}
});
//button 5
Button btn_Search = (Button) findViewById(R.id.btnSearch);
btn_Search.setOnClickListener (new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
startActivity(new Intent(“net.xuting.SEARCH”));
}
});
//button 6
Button btn_Settings = (Button) findViewById(R.id.btnSettings);
btn_Settings.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
startActivity(new Intent(“net.xuting.SETTINGS”));
}
});
}
});
}
}
Hi Baiga,
ReplyDelete.. Have you tried debugging this and clicking the buttons to see what's going on?
You could also try replacing your startActivity calls with a simple Toast notification and see if that works, you can find some instruction on creating Toasts here.
If you're still not having any luck, please upload your project somewhere and I'd be happy to have a look at it for you.
Hi Glen,
ReplyDeleteThanks again for this nice post, but am having a problem with mine, My xml file also contains a RelativeLayout tag and within that i have the button tag in order for the buttons to be positions on the left, how do i get the button to respond to the click this time..
Thanks.
Hi Serge, can you post your code so I can have a look?
ReplyDeletethanks a lot
ReplyDeletehi
ReplyDeleteIt is a nice solution but can you please tell me how i implement it on listView
I have class which extends Activity instead of ListActivity and in that activity I am using custom list, how do I implement custom listener for buttons.
It is really urgent will appriciate your prompt reply.
Awesome... Was just searching for this only :D
ReplyDeleteHello, could you tell me, how can i find out the row number of ListView using "MyClickHandler".
ReplyDelete@Invis
Deletepublic void myClickHandler(View v) {
int position = getListView().getPositionForView(v);
...
}
nice one ,but if button is in inner linear layout
ReplyDeletethen how we get it.
Nice Code Dear thank.Nadir Pakistani
ReplyDelete