I am trying to implement a "favorite item" feature on my listview.
When user touches the "favorite" imageview of any row, if item was not a favorite, it becomes a favorite, and if item was a favorite, it becomes a non favorite AND the row disappears from the view. (There is a separate view in my app where user can set back the favorite to true if he wants to)
For each list item I am using Sharedpreferences to store if it is a favorite or not.
I am handling the clicklistener in my listadapter, not in my list activity.
Code of my ListAdapter:
public class ListItemsAdapter extends ArrayAdapter<ListItems> {
int resource;
String response;
Context context;
//Initialize adapter
public ListItemsAdapter(Context context, int resource, List<ListItems> items) {
super(context, resource, items);
this.resource=resource;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
LinearLayout ll;
//Get the current alert object
final ListItems i = getItem(position);
//Inflate the view
if(convertView==null)
{
ll = new LinearLayout(getContext());
String inflater = Context.LAYOUT_INFLATER_SERVICE;
LayoutInflater li;
li = (LayoutInflater)getContext().getSystemService(inflater);
li.inflate(resource, ll, true);
}
else
{
ll = (LinearLayout) convertView;
}
// to display favorite icon on each row
ImageView favo = (ImageView)ll.findViewById(R.id.favView);
SharedPreferences sPrefs = PreferenceManager.getDefaultSharedPreferences(getContext());
if (sPrefs.getBoolean("fav"+i.id, false)==false)
favo.setBackgroundResource(R.drawable.icon_favoriteno);
if (sPrefs.getBoolean("fav"+i.id, false)==true)
favo.setBackgroundResource(R.drawable.icon_favoriteyes);
// listener of the imageview to handle the user's touch
final ImageView fav = (ImageView)ll.findViewById(R.id.favView);
fav.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
SharedPreferences sPrefs = PreferenceManager.getDefaultSharedPreferences(getContext());
if (sPrefs.getBoolean("fav"+i.id, false)==false) {
Toast.makeText(getContext(), R.string.addedToFavorite, Toast.LENGTH_SHORT).show();
fav.setBackgroundResource(R.drawable.icon_favoriteyes);
SharedPreferences.Editor editor = sPrefs.edit();
editor.putBoolean("fav"+i.id, true);
editor.commit();
}
else if (sPrefs.getBoolean("fav"+i.id, false)==true) {
Toast.makeText(getContext(), R.string.removedFromFavorite, Toast.LENGTH_SHORT).show();
fav.setBackgroundResource(R.drawable.icon_favoriteno);
SharedPreferences.Editor editor = sPrefs.edit();
editor.putBoolean("fav"+i.id, false);
editor.commit();
}
}
});
return ll;
}
The display of the icon wether it is set as a favorite or not works well. What I don't manage to do is to make the row disappear as soon as the user sets the favorite icon as no.
I have tried to add notifyDataSetChanged(); in the onclicklistener but it does nothing.
It is possible that I don't get what I want because I am trying to do this in my ListAdapter class and not my Activity class.
The problem is that each row has several icons each with an onclicklistener, so I think I can't use the activity class to handle the click, but maybe I am wrong
Do you actually remove it from the data set of the adapter?
Because I can't see the remove call to your ArrayAdapter in your code of the OnClickListener.
The adapter itself cares only about it's data set - not how you paint the view (which is what you do with your favorites.
According to your question, just to remove a row from list view,
As you are assigning ListItems in ListItemsAdapter's constructor,
You just need to remove the item from ListItems, and reassign the adapter to listview or call notifyDataSetChanged for the adapter,code is as below,
items.remove(location);
adapter = new ListItemsAdapter(this,1, items);//not sure about integer parameter so I just put 1
list.setAdapter(adapter);
or
items.remove(location);
adapter.notifyDataSetChanged();
either of above two options should work.
Related
Overview:
I have a ListView with a custom adapter/layout, every time a user adds a new row (which contains a number), I check if that number is the smallest in the list. If so, an image within that row must be set as visible while setting all other row's images as invisible.
Problem:
My ListView does not set any row's image as visible, even though I have the index of the smallest element.
How I'm doing it:
//In MainActivity
private void addProduct(float price) { //User adds product
priceList.add(price); //Add to Float list
adapter.notifyDataSetChanged();
updateView(findMinIndex(priceList)); //Find smallest val indx
}
private void updateView(int index){
View v = listView.getChildAt(index -
listView.getFirstVisiblePosition());
if(v == null)
return;
ImageView checkMark = (ImageView) v.findViewById(R.id.check_mark);
checkMark.setVisibility(View.VISIBLE); //Initially set Invisible
}
Edit, CustomAdapter:
public CustomList(Activity context,
ArrayList<Float> priceList) {
super(context, R.layout.list_single, priceList);
this.context = context;
priceList = priceList;
}
#Override
public View getView(int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView = inflater.inflate(R.layout.list_single, null, true);
TextView price = (TextView) rowView.findViewById(R.id.new_price);
ImageView cheapest = (ImageView) rowView.findViewById(R.id.check_mark);
price.setText(priceList.get(position) + "");
return rowView;
}
Thank you
It is your priceList binded with the adapter?
First of all i would put a breakpoint to see if you are getting the right view in the updateView method.
try this way;
Create a Pojo class with imageview and it's state(Visibility) initially set all to invisible
Add your items to the ArrayList of Pojo Class type.
when user enters a new row based on your requirement set visibility state to true or false(visible or invisible) and call notifyDataSetChanged() to the adapter.
Doing this way you can have a easy track of the items.
I got it working :).
Problem is that adapter.notifyDataSetChanged(); is async, so while it's doing that, updateView(findMinIndex(priceList)); runs but doesn't find the new row as it should. Therefore, I add a runnable to the ListView object as so:
adapter.notifyDataSetChanged();
listView.post( new Runnable() {
#Override
public void run() {
updateView(findMinIdx(priceList));
}
});
Now it works perfectly!
I am using a Custom List Adapter with ViewHolder pattern to inflate views into my List that shows an image (width = match_parent), some text on the left (below the image) and a button on the right(also below the image).
Here is the code for the adapter class -
public class DishItemListAdapter extends ArrayAdapter<DishItem> {
//declare fonts - BOLD and LIGHT
final Typeface tf_light = Typeface.createFromAsset(getContext().getAssets(),
"fonts/Roboto-Thin.ttf");
final Typeface tf_bold = Typeface.createFromAsset(getContext().getAssets(),
"fonts/Roboto-Regular.ttf");
//get item count
CartItemCount cartItemCount;
//count for dish at particular position
ArrayList<Integer> dishCountList = new ArrayList<>();
//for matching key string in SharedPrefs
String existingKeyString;
Typeface font_light, font_bold;
/* List of DishItem Objects shown on the Dashboard */
private List<DishItem> DishItemList = new ArrayList<DishItem>();
public DishItemListAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
this.font_bold = tf_bold;
this.font_light = tf_light;
}
/* Add a New DishItem Item (object) to the list of DishItems on the Dashboard i.e. DishItemList */
#Override
public void add(DishItem object) {
DishItemList.add(object);
super.add(object);
}
#Override
public int getCount() {
return this.DishItemList.size();
}
#Override
public DishItem getItem(int index) {
return this.DishItemList.get(index);
}
#Override
public View getView(final int position, final View convertView, ViewGroup parent) {
Log.e("getView() at " + position, "");
View row = convertView;
final DishItemViewHolder viewHolder;
// A ViewHolder keeps references to children views to
// avoid unnecessary (and expensive) calls to findViewById() on each row.
if (row == null) {
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.list_item_dish, parent, false);
//instantiate DishItem View Holder
viewHolder = new DishItemViewHolder();
//get BUTTON for Adding Dish to Cart
viewHolder.addToCart = (Button) row.findViewById(R.id.add_to_cart_button);
//BUTTONS for + and - (adding and removing items from cart)
viewHolder.addItemButton = (Button) row.findViewById(R.id.increase_item_count);
viewHolder.removeItemButton = (Button) row.findViewById(R.id.decrease_item_count);
//DISH NAME, CHEF NAME, DISH PRICE and DISH IMAGE
viewHolder.dishName = (TextView) row.findViewById(R.id.dish_name_textview);
viewHolder.chefName = (TextView) row.findViewById(R.id.chef_name_textview);
viewHolder.dishPrice = (TextView) row.findViewById(R.id.dish_price_textview);
viewHolder.dishImage = (ImageView) row.findViewById(R.id.dish_imageview);
//image absolute path
viewHolder.imageStorePath = new String();
//image for depicting whether image is VEG or NON VEG
viewHolder.veg_nonveg_indicator = (ImageView) row.findViewById(R.id.veg_nonveg_indicator);
//viewSwitcher for switching between BUTTON and - + button
viewHolder.viewSwitcher = (ViewSwitcher) row.findViewById(R.id.viewswitcher);
//indicator for item added to Cart
viewHolder.addedToCartIndicator = (TextView) row.findViewById(R.id.added_to_cart_text_indicator);
viewHolder.addedToCartIndicator.setVisibility(View.INVISIBLE);
//counter for number of items selected for a particular dish
viewHolder.dishQuantity = (TextView) row.findViewById(R.id.dish_quantity);
//set tag for the ViewHolder
row.setTag(viewHolder);
} else {
/* Get the ViewHolder back to get fast access to the DishItem UI widgets (views) */
viewHolder = (DishItemViewHolder) row.getTag();
}
//create object of Item Count Class
cartItemCount = new CartItemCount();
/* fetch DishItem View at current position (="position") */
final DishItem dishItem = getItem(position);
row.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.e("clicked"+position,"");
viewHolder.dishName.setText("CLICKED");
}
});
return row;
}
static class DishItemViewHolder {
TextView dishName;
TextView chefName;
TextView dishPrice;
TextView dishQuantity;
String imageStorePath;
boolean isDishItemSelected;
Button addToCart, addItemButton, removeItemButton;
ImageView veg_nonveg_indicator;
ImageView dishImage;
ViewSwitcher viewSwitcher;
TextView addedToCartIndicator;
}
}
PROBLEM
Suppose I add 6 DishItem beans (model) to the list. Then, when I perform onClick on the 1st item in the list, the 1st item's text changes to CLICKED as it should. Also, in the Log, in says clicked:0 (as 1st list item's index is 0).
But the text for 4th list item also changes to CLICKED, which it shouldn't.
Now I read this post explaining the recycling mechanism of ListView.
However, I DO NOT want it to work that way since I want to update only those items I click.
What am I doing wrong here?
Is there any workaround this recycling mechanism to update only the particular item that I click?
UPDATE
Problem solved. I followed BlackBelt's approach and have thus accepted his answer, but I'd like to thank all of you for your inputs !! :)
Here is the updated getView() method.
/**
*
* #param position The position of the item within the adapter's data set of the item whose view we want.
* #param convertView The old view to reuse, if possible.
* Note: You should check that this view is non-null and of an appropriate type before using.
* If it is not possible to convert this view to display the correct data, this method
* can create a new view. Heterogeneous lists can specify their number of view types,
* so that this View is always of the right type (see getViewTypeCount() and getItemViewType(int)).
* #param parent The parent that this view will eventually be attached to
* #return A View corresponding to the data at the specified position.
*/
#Override
public View getView(final int position, final View convertView, ViewGroup parent) {
View row = convertView;
final DishItemViewHolder viewHolder;
// A ViewHolder keeps references to children views to
// avoid unnecessary (and expensive) calls to findViewById() on each row.
if (row == null) {
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.list_item_dish, parent, false);
//instantiate DishItem View Holder
viewHolder = new DishItemViewHolder();
//get BUTTON for Adding Dish to Cart
//viewHolder.addToCart = (Button) row.findViewById(R.id.add_to_cart_button);
viewHolder.addItemButton = (Button) row.findViewById(R.id.add_to_cart_secondary_button);
viewHolder.removeItemButton = (Button) row.findViewById(R.id.remove_from_cart_button);
//DISH NAME, CHEF NAME, DISH PRICE and DISH IMAGE
viewHolder.dishName = (TextView) row.findViewById(R.id.dish_name_textview);
viewHolder.chefName = (TextView) row.findViewById(R.id.chef_name_textview);
viewHolder.dishPrice = (TextView) row.findViewById(R.id.dish_price_textview);
viewHolder.dishImage = (ImageView) row.findViewById(R.id.dish_imageview);
//image absolute path
viewHolder.imageStorePath = new String();
//image for depicting whether image is VEG or NON VEG
viewHolder.veg_nonveg_indicator = (ImageView) row.findViewById(R.id.veg_nonveg_indicator);
//indicator for item added to Cart
viewHolder.addedToCartIndicator = (TextView) row.findViewById(R.id.added_to_cart_text_indicator);
viewHolder.addedToCartIndicator.setVisibility(View.INVISIBLE);
//set tag for the ViewHolder
row.setTag(viewHolder);
} else {
/* Get the ViewHolder back to get fast access to the DishItem UI widgets (views) */
viewHolder = (DishItemViewHolder) row.getTag();
}
//get object for CART ITEM COUNT class
final CartItemCount cartItemCount = new CartItemCount();
//get current dish item (MODEL from Bean class)
final DishItem dishItem = getItem(position);
//disable any highlighting unless dish is selected (verified from SharedPreferences)
viewHolder.dishImage.setColorFilter(null);
//hide ITEM COUNT indicator over the image unless dish is selected (again, verified from SharedPreferences)
viewHolder.addedToCartIndicator.setVisibility(View.INVISIBLE);
//show the + and - buttons on the right and left (respectively) side on the Dish ImageView
viewHolder.addItemButton.setVisibility(View.VISIBLE);
viewHolder.removeItemButton.setVisibility(View.VISIBLE);
//get data from Preferences (to see which dish is selected)
SharedPreferences pref = getContext().getSharedPreferences("DishDetails", Context.MODE_PRIVATE);
Map<String, ?> allEntries = pref.getAll();
for (Map.Entry<String, ?> entry : allEntries.entrySet()) {
Log.d("KEY = " + entry.getKey(), " VALUE = " + entry.getValue().toString());
}
//get Count for each dish in the list and set Quantity in the Model (DishItem.java)
if (pref != null) {
int currentDishCount = pref.getInt("dishCount" + position, 0);
Log.e("Current DishCount", String.valueOf(currentDishCount));
if (currentDishCount > 0) {
getItem(position).setisDishItemSelected(true);
dishItem.setDishQuantity(currentDishCount);
Log.d("dish item" + position," selected");
}
}
//update Views for selected DishItems
if (dishItem.isDishItemSelected()) {
viewHolder.dishImage.setColorFilter(Color.parseColor("#80E0E0E0"));
viewHolder.addedToCartIndicator.setVisibility(View.VISIBLE);
viewHolder.addedToCartIndicator.setText(dishItem.getDishQuantity() + " items in cart");
}
viewHolder.addItemButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dishItem.setisDishItemSelected(true);
dishItem.setDishQuantity(dishItem.getDishQuantity() + 1);
//save data to preferences
SharedPreferences pref = getContext().getSharedPreferences("DishDetails", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.putInt("dishCount" + position, dishItem.getDishQuantity());
editor.commit();
//increment Total Number of Items in Cart
int itemCount = cartItemCount.getitemCount();
cartItemCount.setitemCount(itemCount + 1);
Log.d("itemCount =", String.valueOf(itemCount));
//broadcast the value of itemCount to MainMenuActivity
Intent intent = new Intent("NEW_CART_ITEM");
intent.putExtra("value", cartItemCount.getitemCount());
getContext().sendBroadcast(intent);
Log.d("broadcast", "sent");
//notify adapter of change in underlying data (i.e. update View to show Changes in Model)
notifyDataSetChanged();
}
});
viewHolder.removeItemButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("Old Dish Qty. ", String.valueOf(dishItem.getDishQuantity()));
//if dishCount has reached ZERO, set Dish as NOT SELECTED for buying
if (dishItem.getDishQuantity() == 0) {
dishItem.setisDishItemSelected(false);
} else {
dishItem.setisDishItemSelected(true);
dishItem.setDishQuantity(dishItem.getDishQuantity() - 1);
Log.d("New Dish Qty.", String.valueOf(dishItem.getDishQuantity()));
//decrement TOTAL number of items in Cart
int itemCount = cartItemCount.getitemCount();
cartItemCount.setitemCount(itemCount - 1);
Log.d("itemCount =", String.valueOf(itemCount));
//broadcast the value of itemCount to MainMenuActivity
Intent intent = new Intent("NEW_CART_ITEM");
intent.putExtra("value", cartItemCount.getitemCount());
getContext().sendBroadcast(intent);
Log.d("broadcast", "sent");
//recheck -> if dish Count has reached ZERO, set Dish as NOT SELECTED for buying
if (dishItem.getDishQuantity() == 0) {
dishItem.setisDishItemSelected(false);
}
}
//save Current Quantity of Dish Selected to SharedPreferences
SharedPreferences pref = getContext().getSharedPreferences("DishDetails", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.putInt("dishCount" + position, dishItem.getDishQuantity());
editor.commit();
//notify adapter of change in underlying data (i.e. update View to show Changes in Model)
notifyDataSetChanged();
}
});
return row;
}
The idea was simple (I didn't know it before) -
In the onClick Listener for the buttons, change the Model i.e. Data i.e. DishItem using the setters and getters defined in the bean class.
call
notifyDataSetChanged()
to tell the adapter about changes in data so that Views can be adjusted accordingly.
In the getView() method, set views bases on those data values.
Is there any workaround this recycling mechanism to update only the
particular item that I click?
No workaround here. You have to change the dataset (at position - the item you clicked), and ask the Adapter to redraw the ListView's children. I would strongly suggest you to use the OnItemClickListener too.
To change something, you must know the position of your item:
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Code here
}
});
this will give you the correct position you've touch it. Other way, inside your getView (in the Adapter):
DishItemList = dishCountList.get(position);
That way you'll have the position of your item. To touch only the one you want:
row.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// here you can DishItemList.get("and get the key you need");
}
});
You should reset the view's state to the default one in the getView and apply the item's data after this. It works like this:
Get the row's view (either the convertView or inflate a new one)
Create and attach a view holder
Get the current item's data and state
Apply ALL the state params and data (so write "Clicked" if the current item is clicked or clear the TextView's text otherwise - do not assume that it contains the correct text already)
You'd need to store the item's state somewhere - currently you use the TextView's text to do this and it breaks due to the recycling behaviour. The correct way is to add a field to the DishItem or just create a new class to contain the state of each item (selected, focused and so on - all the states you'd like to support). In the onClickListener change the state's value and then change the views' contents or just call notifyDataSetChanged on the adapter.
I have a list of checkboxes (created via custom list adapter), some of which start checked based on stored data. When the user presses another button, I'd like to check which boxes are checked. Right now it starts with two boxes, one of which is clicked. When I click the checkboxes the UI changes appropriately, but when I do the "gather checked" function, it reports the original configuration, not the changed one.
The XML for the row:
CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Default"
android:id="#+id/cause_checkbox"
xmlns:android="http://schemas.android.com/apk/res/android"
The List adapter:
private class CauseEntryAdapter extends ArrayAdapter {
List selectedCauseKeys;
List availableCauseKeys;
public CauseEntryAdapter(Context context, List<String> causeLabels, List<String> availableCauseKeys, List<String> selectedCauseKeys) {
super(context, 0, causeLabels);
if (selectedCauseKeys != null)
this.selectedCauseKeys = selectedCauseKeys;
else
this.selectedCauseKeys = new LinkedList<>();
this.availableCauseKeys = availableCauseKeys;
}
public View getView(int position, View convertView, ViewGroup parent) {
String cause = (String) getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.cause_list_item, parent, false);
}
CheckBox checkbox = (CheckBox) convertView.findViewById(R.id.cause_checkbox);
checkbox.setText(cause);
checkbox.setChecked(selectedCauseKeys.contains(availableCauseKeys.get(position)));
return convertView;
}
}
The code to collect checked boxes:
public List<String> getCheckedCauses() {
List<String> ret = new LinkedList<String>();
for(int i = 0; i< mAdapter.getCount(); i++) {
CheckBox checkBox = (CheckBox) mAdapter.getView(i, null, null).findViewById(R.id.cause_checkbox);
if (checkBox.isChecked()) {
ret.add((String) mAdapter.getItem(i));
}
//TODO why is this picking up preferences not the list?
}
return ret;
}
The list lives in a fragment, I invoke it with:
CauseListFragment causeListFragment = (CauseListFragment) fragmentManager.getFragments().get(0);
return causeListFragment.getCheckedCauses();
That is because your getCheckedCauses method asks the adapter to tell him the state of checkboxed by calling the getView method, which relies on the original state you passed to the adapter.
One solution may be, in your adapter, to set a listener on the checkboxes and update the availableCauseKey list each time a check box is clicked.
EDIT: Or simpler, have a isBoxChecked() method in your adapter like this:
public boolean isBoxChecked(int viewId){
View convertView = LayoutInflater.from(getContext()).inflate(R.layout.cause_list_item, parent, false);
CheckBox checkbox = (CheckBox) convertView.findViewById(R.id.cause_checkbox);
return checkBox.isChecked();
}
I have a ListView where each row item has EditText and CheckBox elements. You can see the sample image below.
What I intend to do is
I want to implement both OnItemClickListener (for ListView) and OnClickListener (for EditText and CheckBox) i.e. I want Task A to be done on clicking the ListView items (outside EditText and CheckBox) and I also want to do individual tasks on clicking EditText and CheckBox respectively.
My Problem
If no attribute is set on ListView, EditText or CheckBox to control the focus, then the default behaviour is that ListView row items won't listen to item click, but EditText and CheckBox are getting the focus
On playing around with these attributes and there values (eg - )
// to ListView
android:descendantFocusability="blocksDescendants"
// to EditText and CheckBox
android:focusable="false"
android:focusableInTouchMode="true"
Listeners are working either for ListView or for the EditText. CheckBox click listener seems to work in all cases (strange). I am new to this and any kind of help would be appreciated. I cannot post the source right now, for that please bear with me. Any solution, suggestion or explanation would do a great help.
I am glad that I happen to solve this problem. What I wanted to do was (let me clear it out again) I wanted the EditText to be focusable and additionally I should be able to click on each row of the ListView to perform some specific task. Well we won't be needing these attributes:
android:focusable=""
android:focusableInTouchMode=""
android:descendantFocusability=""
What simple needed to be done is
In you custom ListAdapter class implement OnClickListener for each items (say EditText, CheckBox, etc.) and implement OnClickListener of rootView (i.e. for ListView row item) too.
For Example:
public class CustomListAdapter extends ArrayAdapter<YOUR_OBJECT> {
Context context;
ArrayList<YOUR_OBJECT> itemlist = new ArrayList<YOUR_OBJECT>();
Integer resourceID;
ViewHolder holder;
public ServicesListAdapter(Context context, int resourceId, ArrayList<YOUR_OBJECT> itemlist) {
super(context, resourceId, itemlist);
this.itemlist.addAll(itemlist);
this.context = context;
this.resourceID = resourceId;
}
public class ViewHolder {
TextView name;
EditText editText;
CheckBox checkBox;
}
public View getView(final int position, View rootView, ViewGroup parent) {
LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (rootView == null) {
rootView = mInflater.inflate(resourceID, null);
holder = new ViewHolder();
holder.name = (TextView) rootView.findViewById(R.id.name);
holder.editText = (EditText) rootView.findViewById(R.id.port);
holder.checkBox = (CheckBox) rootView.findViewById(R.id.check_box);
// Add Listeners for EditText and CheckBox here
rootView.setTag(holder);
} else {
holder = (ViewHolder) rootView.getTag();
}
// Click Listener for the ListView row item
rootView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context, "Clicked" + position, Toast.LENGTH_SHORT).show();
}
});
// Do what rest you need to do with your ViewHolder
}
}
I'm trying to display high scores for a game I'm creating, with two columns, one for their name, and the other for the amount of moves it took them to complete the game.
Currently it is all stored in a SQLiteDatabase and presented in a list view, where it appears as one column in the format
name,moves
But I'd like to get the moves on the opposite of the screen, would this require multiple list views or would it require editing of the one list view, or its adapter?
The code currently used is:
datasource = new HighScoreDataSource(this);
datasource.open(); //Open the connection
List<HighScore> values = datasource.getAllHighScores(); //Retrieve all the data
//Using a simple cursor adapted to show the elements
ArrayAdapter<HighScore> adapter = new ArrayAdapter<HighScore>(this, android.R.layout.simple_list_item_1, values);
setListAdapter(adapter);
Make a row layout with two TextViews placed the way you want and implement a simple custom ArrayAdapter:
public class CustomAdapter extends ArrayAdapter<HighScore> {
private LayoutInflater inflater;
public CustomAdapter(Context context, int textViewResourceId,
List<HighScore> objects) {
super(context, textViewResourceId, objects);
inflater = LayoutInflater.from(context);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.new_row_layout, parent, false);
}
HighScore item = getItem(position);
TextView name = (TextView) findViewById(R.id.name_id_textview);
name.setText(/*get the name from the item HighScore object*/);
TextView moves = (TextView) findViewById(R.id.moves_id_textview);
moves.setText(/*get the moves from the item HighScore object*/);
return convertView;
}
}
Another option is to break your List<HighScore> values in a List of HashMaps(containing two entries, one for name and one for moves) and use a SimpleAdapter(with the row layout above).