I have an image inside my group_row
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="#8fbfff" >
<TextView
android:id="#+id/tv_category_name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="TextView"
android:layout_weight="1" />
<ImageView
android:id="#+id/img_add_category"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ico_add_item"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:layout_marginRight="10dp" />
</LinearLayout>
I want to detect when this image was clicked and the id of the Group, and then StartActivityForResult. I was able to do it inside my custom ExpandableListView_Adapter:
#Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
final Category category = arr_categories.get(groupPosition);
convertView = inflater.inflate(R.layout.row_category, parent, false);
((TextView)convertView.findViewById(R.id.tv_category_name)).setText(category.getCategory_name());
ImageView img_add = (ImageView) convertView.findViewById(R.id.img_add_category);
img_add.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "Add item to category: "+category.getCategory_id(), Toast.LENGTH_LONG).show();
// Declare on intent to use Add/Edit Note activity
Intent open_add_new_item = new Intent(context, Activity_Add_Edit_Base_Item.class);
// Pass the currently selected category ID to the Intent
open_add_new_item.putExtra("CURR_ITEM_CATEGORY", category.getCategory_id());
// Start the activity
((Activity) context).startActivityForResult(open_add_new_item, Constants.Request_Codes.REQUEST_CODE_CREATE_NEW_ITEM);
}
});
return convertView;
}
This works just fine. However, If there's a possibility to do so, I'd like to separate this image click detection from the Adapter and do it in my fragment (I think it'll be easier to implement OnActivityResult this way). I tried to do it by setting OnGroupClickListener for my ExpandableListView:
master_lv.setOnGroupClickListener(new OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView parent, View v,
int groupPosition, long id) {
final Category c = arr_all_categories.get(groupPosition);
ImageView img_add = (ImageView) v.findViewById(R.id.img_add_category);
img_add.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//Category c = arr_all_categories.get(groupPosition);
Toast.makeText(getActivity(), "group position: "+c.getCategory_id(), Toast.LENGTH_LONG).show();
// Declare on intent to use Add/Edit Note activity
Intent open_add_new_item = new Intent(getActivity(), Activity_Add_Edit_Base_Item.class);
// Pass the currently selected category ID to the Intent
open_add_new_item.putExtra("CURR_ITEM_CATEGORY", c.getCategory_id());
// Start the activity
startActivityForResult(open_add_new_item, Constants.Request_Codes.REQUEST_CODE_CREATE_NEW_ITEM);
}
});
return false;
}
});
However this didn't work at all: I'm not getting the Toast message and the Intent doesn't fire.
Is it possible to do so? If it is - how? Thanks!
The first one you need to do is set clickable=true to root layout of the custom cell xml.
After that, what we are going to do is Custom Event Raising. We will use interfaces.
Create a interface class
Example :
public interface OnImageClickListener {
public void onImageClicked();
}
Then create a instance in adapter
public OnImageClickListener mListener;
Also set OnClickListener to imageview in getView method of the adapter and add the following line in OnClick method.
mListener.OnImageClicked();
Lastly, in Activity;
mAdapter.mListener = new OnImageClickListener();
Magic will happen here :)
or you can implement this interface like
public MyActivity implements OnItemClickListener and let the implement methods.
Then you can
mAdapter.mListener = this;
Good luck there :)
Related
Is it possible to bind onClickListener for listView item buttons in activity? My listView item has name, delete and edit buttons. listView items are stored in List.
exercises_list_view_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="vertical"
android:paddingLeft="10dp"
android:paddingRight="10dp">
<Button
android:id="#+id/deleteExerciseBtn"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:background="#android:drawable/ic_delete" />
<Button
android:id="#+id/editExerciseBtn"
android:layout_width="26dp"
android:layout_height="26dp"
android:layout_marginRight="5dp"
android:layout_marginTop="7dp"
android:layout_toLeftOf="#id/deleteExerciseBtn"
android:background="#drawable/edit_btn" />
<TextView
android:id="#+id/exerciseName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginRight="8dp"
android:layout_toLeftOf="#id/editExerciseBtn"
android:ellipsize="end"
android:maxLines="1"
android:text="This is a Large text with fill width"
android:textColor="#000000"
android:textSize="18sp" />
</RelativeLayout>
code in activity :
#Override
public void onButtonClickListner(int position, String value) {
Toast.makeText(create_workout.this, "Button click " + value,
Toast.LENGTH_SHORT).show();
}
List<WorkoutExercise> workoutExercises = workout.getWorkoutExercises();
ListView exercisesList = (ListView) findViewById(R.id.exerciseListView);
WorkoutExerciseListAdapter listAdapter = new WorkoutExerciseListAdapter(this, R.layout.exercises_list_view_item, workoutExercises);
listAdapter.setCustomButtonListener(create_workout.this);
exercisesList.setAdapter(listAdapter);
Since WorkoutExerciseListAdapted has a lot of code I pasted it here : https://pastebin.com/FYNVVQnS
What I am trying to do is :
If user clicks edit button I need to pass Exercise object to another activity for editing.
If user clicks delete button I need to remove that item from List<> and update listView (with notifyDataSetChanged() ? )
I tried to look for answer through stackoverflow and google, but it either didn't work or my app started crashing.
Few of tried examples:
http://www.c-sharpcorner.com/UploadFile/9e8439/create-custom-listener-on-button-in-listitem-listview-in-a/
Adding an onclicklistener to listview (android)
and others..
I would appreciate any advice. Thank you for your time.
1. Update your customButtonListener interface as below:
public interface customButtonListener {
public void onEditButtonClickListner(int position, String value);
public void onDeleteButtonClickListner(int position);
}
2. In adapters getView() method set click listener to edit and delete buttons:
#NonNull
#Override
public View getView(final int position, #Nullable View convertView, #NonNull final ViewGroup parent) {
............
...................
// Edit
viewHolder.editBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (customListner != null) {
customListner.onEditButtonClickListner(position, getItem(position).getExerciseName());
}
}
});
// Delete
viewHolder.deleteBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (customListner != null) {
customListner.onDeleteButtonClickListner(position);
}
}
});
return convertView;
}
3. In your activity, add CustomButtonListener to your ListView:
A. Get item position from `onEditButtonClickListner()` and get `workoutExercise` object and pass it to another activity
B. Get item position from `onDeleteButtonClickListner()` and delete item and upadte ListView.
Add below codes in your Activity:
..........
.................
listAdapter.setCustomButtonListener(create_workout.this);
exercisesList.setAdapter(listAdapter);
exercisesList.setCustomButtonListener(new WorkoutExerciseListAdapter.customButtonListener() {
#Override
public void onEditButtonClickListner(int position, String value)
{
// Item
WorkoutExercise workoutExercise = workoutExercises.get(position);
// Do something with object workoutExercise
}
#Override
public void onDeleteButtonClickListner(int position)
{
// Delete
workoutExercises.remove(position);
// Update ListView
listAdapter.notifyDataSetChanged();
}
});
Hope this will help~
If you wan't to fire any events for every list-item on your list-view, Then you should implement it in your BaseAdapter class.
On your WorkoutExerciseListAdapter, Inside the getView() methord define your event listner.
If you need to get the click event on your Activity, Then implement and use an interface, If so then at the WorkoutExerciseListAdapter
MyNotifier listner;
public interface MyNotifier
{
void OnButtonClicked;
}
public void setMyNotificationListner(MyNotifier listner)
{
this.listner=listner;
}
Then when the button clicks
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
Button b=(Button)v.getViewByID(<id>);
b.setOnClickListner(new OnClickListner...
{
listner.OnButtonClicked()
}
}
At the MainActivity
WorkoutExerciseListAdapter listAdapter = new WorkoutExerciseListAdapter(this, R.layout.exercises_list_view_item, workoutExercises);
listAdapter.setMyNotificationListner(new MyNotifier {..//You get click calls here..};)
I have a ListView with multiple elements for each row as follows:
list_element.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/global_container"
android:descendantFocusability="blocksDescendants"
android:layout_width="match_parent"
android:layout_height="match_parent">
<HorizontalScrollView
android:id="#+id/scrollview"
android:clickable="true"
android:focusable="false"
android:focusableInTouchMode="false"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none">
Fragment1.java is inflating the layout that contains the listview which has the elements above.
I need to be able to capture click events for each item to change the color of an element when the item is clicked and when another item is clicked restore it to its original color as the new item changes the element color and so on.
This means that I tried to capture OnItemClickListener inside Fragment1.java:
if (rootView != null) {
myList = (ListView) rootView.findViewById(R.id.my_list);
}
ArrayList l = new ArrayList();
//Bogus list
for (int i=0; i<20; i++) {
l.add(new Object());
}
adapter = new MyListAdapter(l, getActivity());
myList.setAdapter(adapter);
final MyListAdapter ad = adapter;
myList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View arg1, int position, long id) {
ad.setClickedPosition(position);
ad.notifyDataSetChanged();
}
});
But (I assume) all the Touch events of HorizontalScrollView are capturing the click/touch... event and I get no response. As you can see I tried android:descendantFocusability="blocksDescendants" and changing focusability back and forth with no results.
I also tried capturing different events inside the list adapter:
vi = inflater.inflate(R.layout.list_element, null, true);
vi.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d("aaa", "aaa");
}
});
And/OR
horizontalScroll = vi.findViewById(R.id.scrollview);
horizontalScroll.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d("aaa", "aaa");
}
});
Both options without any results. How shall I then capture a click event for an item on the list and keeping to be able to work with the HorizontalScrollView ?
Ok, I solved the problem as follows:
To be able to click on a list item this two things needed to be done.
First:
android:descendantFocusability="blocksDescendants"
needs to be present on the top-most element of the row element layout.
Second:
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false"
these 3 properties need to be present on the HorizontalScrollView.
The problem with that solution is that HorizontalScrollView won't work per se, so you need to activate it once the click event is detected. I do it on the getView() method of the adapter.
When the element is clicked I pass the position to the adapter:
fragment.java
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View arg1, int position, long id) {
//Private method inside the adapter
ad.setClickedPosition(position);
ad.notifyDataSetChanged();
}
});
adapter.java
public void setClickedPosition(int clickedPosition) {
this.clickedPosition = clickedPosition;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (clickedPosition == position)
holder.scrollview.setScrollingEnabled(true);
else
holder.scrollview.setScrollingEnabled(false);
}
CustomHorizontalScrollview.java
public void setScrollingEnabled (boolean enabled) {
this.isScrollEnabled = enabled;
}
//...
#Override
public boolean onTouchEvent(MotionEvent ev) {
//...
if (isScrollEnabled) {
return super.onTouchEvent(ev);
}
//...
}
Something to be considered is that this solution works for me since the behaviour "first click then swipe" is what I was looking for, so be aware this might not be exactly what you want but should help you in your quest to make that work.
try to change your list_element.xml as below:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/global_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<HorizontalScrollView
android:id="#+id/scrollview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none" />
</RelativeLayout>
hope this helps you
I have a custom view for each row in a custom ListAdapter and I am trying to perform onClick action and get the row position in the list where the click came from.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:paddingLeft="10dip" android:id="#+id/itemRoot" android:clickable="false">
<TextView android:layout_width="wrap_content" android:text="TextView"
android:layout_height="wrap_content" android:id="#+id/itemTxt"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"></TextView>
<TextView android:layout_toRightOf="#+id/itemTxt" android:text="TextView"
android:layout_height="wrap_content" android:layout_alignBottom="#+id/itemTxt"
android:id="#+id/amountTxt" android:paddingLeft="6dip"
android:layout_centerVertical="true" android:layout_width="match_parent"></TextView>
<ImageView android:id="#+id/delBtn" android:layout_height="wrap_content"
android:src="#drawable/delete" android:layout_width="wrap_content"
android:layout_alignParentRight="true" android:paddingRight="10dip"
android:layout_centerVertical="true"></ImageView>
</RelativeLayout>
I want to figure out when TextView or ImageView is clicked, I also need to know what row in the list it came form. I have tried using OnItemClickListener and it works fine to get the row where the click comes from. However, once I register an OnClick listener for the views, the onItemClicked() method gets skipped and onClick() is executed straight away, but there is no way of getting the row position that the view is in(or at least not that I know if).
If I set clickable to false for the views, then onItemClicked get called and I tried manually calling performClick() on the given view. But this only works for the root element (RelativeLayout), and if click comes from TextView inside the layout the click doesn't propagate.
I can't really figure out how to get both position in the list and perform onClick action.
Any thoughts are welcome.
Alex
You could assign the proper OnClickListener to each ImageView and TextView from inside your ListAdapter's overridden getView method.
Inside that method you know the item's position, so you can pass it to the custom listener classes, and use it there as you want:
#Override
public View getView(final int position, View convertView, ViewGroup parent)
{
// TODO: instantiate the layout
// here I call a super method
final View view = super.getView(position, convertView, parent);
final TextView textView = (TextView)view.findViewById(R.id.itemTxt);
textView.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
Log.i("Click", "TextView clicked on row " + position);
}
});
final ImageView imageView = (ImageView)view.findViewById(R.id.delBtn);
imageView.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
Log.i("Click", "ImageView clicked on row " + position);
}
});
return view;
}
The other possible option to have the OnClickListener in the same class as the creating activity is to add to the activity implements OnItemClickListener.
public class DisplayListCustom extends Activity implements OnItemClickListener
Then set the custom list to listen
ListView list = (ListView)findViewById(R.id.custom_list);
list.setClickable(true);
list.setOnItemClickListener(this);
list.setAdapter(new CustomListAdapter(getApplicationContext(), listItems));
Finally in the onItemClick return, you can find the inner views by using resource ID
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
LinearLayout listItem = (LinearLayout) v;
TextView clickedItemView = (TextView) listItem.findViewById(R.id.name);
String clickedItemString = clickedItemView.getText().toString();
Log.i("DisplayListCustom", "Click detected " + clickedItemString + ", position " + Integer.toString(position));
This is the solution I went with. I used LinearLayout for my custom layout container, but I assume the same applies to RelativeLayout.
You need to extend your TextView etc, override the click method, do the appropriate actions and then the trick is to return false so it's then propagated to the listview.
I have an ExpandableListView which has a lot of children and for every child I would start an activity. Someone told me to create an unique class with all the activities of every children. Is it possible? How? In my project I have a Child.class, a Group.class, a MyExpandableListView.class, a XmlHandler.class and the main activity. I take the name for the ExpandableList from xml files that are in res/raw folder. I hope someone could help me. Thank you.
If your activities triggered by the ExpandableListView's child click event are similar (I mean only the data they display is different), it's enough for you to have a single activity, and make it's content dynamic based on the selected (clicked) child of the ExpandableListView.
Let's call your new activity Details.
If your main activity doesn't extend ExpandableListActivity, but you have inside a member of type MyExpandableListView myExpandableListView, you should set the `OnChildClickListener on that:
final ExpandableListView myExpandableListView = getExpandableListView();
myExpandableListView.setOnChildClickListener(new OnChildClickListener()
{
#Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id)
{
final Child selectedChild = groups.get(groupPosition)
.getChildren().get(childPosition);
final Intent intent = new Intent(testactivity.this, Details.class);
intent.putExtra("selectedChild", selectedChild);
startActivity(intent);
return true;
}
});
If your main activity extends ExpandableListActivity, to call the Detail activity, you need to override the onChildClick event of your ExpandableListActivity:
#Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id)
{
final Child selectedChild = groups.get(groupPosition)
.getChildren().get(childPosition);
final Intent intent = new Intent(this, Details.class);
intent.putExtra("selectedChild", selectedChild);
startActivity(intent);
return true;
}
You add the clicked child's value as an extra to the Details activity's intent by the putExtra method, and then just start the activity.
Inside the Details activity you can retrieve the passed Child (the clicked item on your exp.listactivity) from the activity's Intent using the getSerializableExtra method (for this to work, your Child class must implement java.io.Serializable!).
Details.java:
public class Details extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.details);
final Intent intent = getIntent();
if (intent.hasExtra("selectedChild"))
{
final Child selectedChild = (Child)intent.
getSerializableExtra("selectedChild");
if (selectedChild != null)
{
((TextView)findViewById(R.id.nameText)).
setText(selectedChild.getName());
((ImageView)findViewById(R.id.image)).setImageResource(getResources().
getIdentifier(selectedChild.getImage(), "drawable", "com.test.com"));
}
}
}
}
Your Details activity's layout should contain a text and an image
details.xml
<?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="100dip"
android:orientation="vertical">
<TextView android:id="#+id/nameText"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:paddingLeft="10dip" android:textColor="#android:color/white"
android:textSize="30dip" android:gravity="center_vertical|center_horizontal" />
<ImageView android:id="#+id/image"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:scaleType="fitCenter" android:layout_below="#id/nameText" />
</RelativeLayout>
By this you can achieve, that when you click on a child item of your ExpandableListActivity, you start a new activity (Details) where the selected Child's image and text are displayed.
If you put more information inside your Child class (or url from where to fetch more data), you can get it more complicated.
I've seen example com.example.android.apis.view.List11 from ApiDemos. In that example, each row takes the view android.R.simple_list_item_multiple_choice. Each such view has a TextView and a CheckBox.
Now I want each view to have 2 TextViews and 1 CheckBox, somewhat similar to the List3 example. I tried creating a custom layout file row.xml like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<CheckBox
android:id="#+id/checkbox"
android:layout_alignParentRight="true"
android:layout_width="wrap_content"
android:layout_height="fill_parent" />
<TextView
android:id="#+id/text_name"
android:textSize="13px"
android:textStyle="bold"
android:layout_toLeftOf="#id/checkbox"
android:layout_alignParentLeft="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/text_phone"
android:textSize="9px"
android:layout_toLeftOf="#id/checkbox"
android:layout_below="#id/text_name"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
Then in Activity's onCreate(), I do like this:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Query the contacts
mCursor = getContentResolver().query(Phones.CONTENT_URI, null, null, null, null);
startManagingCursor(mCursor);
ListAdapter adapter = new SimpleCursorAdapter(this,
R.layout.row,
mCursor,
new String[] { Phones.NAME, Phones.NUMBER},
new int[] { R.id.text_name, R.id.text_phone });
setListAdapter(adapter);
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
}
The result kind of looks like what I want, but it looks like the list doesn't know which item of it is selected. Also, I need to click exactly on the CheckBox. In the List11 example, I only need to click on the item row.
So what do I need to do to make a multiple choice list with my custom view for each row? Many thanks.
You have to make your own RelativeLayout that implements the Checkable interface and have a reference to the CheckBox or to the CheckedTextView (or a list if it's multiple choice mode).
Look at this post:
http://www.marvinlabs.com/2010/10/29/custom-listview-ability-check-items/
The answer of Rahul Garg is good for the first time the list is loaded, if you want some rows to be checked depending on the model data, but after that you have to handle the check/uncheck events by yourself.
You can override the onListItemCLick() of the ListActivity to check/uncheck the rows
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
ViewGroup row = (ViewGroup)v;
CheckBox check = (CheckBox) row.findViewById(R.id.checkbox);
check.toggle();
}
If you do so, do not set the ListView to CHOICE_MODE_MULTIPLE, because it makes strange things when calling the function.
To retrieve the list of checked rows, you have to implement a method yourself, calling getCheckItemIds() on the ListView does not work:
ListView l = getListView();
int count = l.getCount();
for(int i=0; i<count; ++i) {
ViewGroup row = (ViewGroup)l.getChildAt(i);
CheckBox check = (Checked) row.findViewById(R.id.ck1);
if( check.isChecked() ) {
// do something
}
}
Each such view has a TextView and a
CheckBox.
No, it doesn't. It has a CheckedTextView.
So what do I need to do to make a
multiple choice list with my custom
view for each row?
Try making the CheckBox android:id value be "#android:id/text1" and see if that helps. That is the ID used by Android for the CheckedTextView in simple_list_item_multiple_choice.
The solution is to create a custom View that implements the Clickable interface.
public class OneLineCheckableListItem extends LinearLayout implements Checkable {
public OneLineCheckableListItem(Context context, AttributeSet attrs) {
super(context, attrs);
}
private boolean checked;
#Override
public boolean isChecked() {
return checked;
}
#Override
public void setChecked(boolean checked) {
this.checked = checked;
ImageView iv = (ImageView) findViewById(R.id.SelectImageView);
iv.setImageResource(checked ? R.drawable.button_up : R.drawable.button_down);
}
#Override
public void toggle() {
this.checked = !this.checked;
}
}
And create a custom layout for the list items using the new widget.
<?xml version="1.0" encoding="utf-8"?>
<ax.wordster.OneLineCheckableListItem xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:background="#drawable/selector_listitem"
android:orientation="horizontal" >
<ImageView
android:id="#+id/SelectImageView"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="#drawable/button_friends_down" />
<TextView
android:id="#+id/ItemTextView"
android:layout_width="fill_parent"
android:layout_height="60dp"
android:gravity="center"
android:text="#string/___"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#color/text_item" />
</ax.wordster.OneLineCheckableListItem>
Then create a new custom Adapter using the layout above.
It is possible by some trick
in your ListActivtyClass in method
protected void onListItemClick(ListView l, View v, int position, long id) {
//just set
<your_model>.setSelected(true);
}
now in you custom Adapter
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(textViewResourceId, parent, false);
}
if (<your_model>.isSelected()) {
convertView.setBackgroundColor(Color.BLUE);
} else {
convertView.setBackgroundColor(Color.BLACK);
}
return convertView;
}
this way you can customize the view in adapter when the item is selected in the list.
Simple example how to get a custom layout to work as custom checkbox:
private class FriendsAdapter extends ArrayAdapter<WordsterUser> {
private Context context;
public FriendsAdapter(Context context) {
super(context, R.layout.listitem_oneline);
this.context = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final int pos = position;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rv = inflater.inflate(R.layout.listitem_oneline, parent, false);
rv.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
boolean checked = friendsListView.isItemChecked(pos);
friendsListView.setItemChecked(pos, !checked);
}
});
WordsterUser u = getItem(position);
TextView itw = (TextView) rv.findViewById(R.id.ItemTextView);
itw.setText(u.userName + " (" + u.loginName + ")");
ImageView iv = (ImageView) rv.findViewById(R.id.SelectButton);
if (friendsListView.isItemChecked(position)) {
iv.setImageResource(R.drawable.downbutton);
} else {
iv.setImageResource(R.drawable.upbutton);
}
return rv;
}
}
I found it very useful this little code: http://alvinalexander.com/java/jwarehouse/apps-for-android/RingsExtended/src/com/example/android/rings_extended/CheckableRelativeLayout.java.shtml
It is a great addition to #ferdy182 's http://www.marvinlabs.com/2010/10/29/custom-listview-ability-check-items/ content.
Got the solution ... You can get the clicks on the views (like checkboxes in custom layouts of row) by adding listener to each of them in the adapter itself while you return the converted view in getView(). You may possibly have to pass a reference of list object if you intent to get any list specific info. like row id.
I want to confirm that the Pritam's answer is correct. You need an onClickListener on each list's item (define it in the adapter's getView()).
You can create a new onClickListener() for each item, or have the adapter implement onClickListener() - in this case the items must be tagged for the listener to know, which item it is operating on.
Relying on the list onItemClickListener() - as someone advised in another thread - will not work as the CheckBox will intercept the click event so the list will not get it.
And finally #Rahul and JVitella:
The situation is that the CheckBox on a list item must be clickable and checkable independently from the list item itself. Therefore the solution is as I just described above.