This is a follow on from an earlier question: ImageButton within row of ListView android not working
But after suggestions from SO gurus it has been suggested I post a new question.
The issue is that I have a custom adapter that is not showing any data. I have looked into other questions, but it didn't provide a solution.
In my Main Activity I have a couple of buttons, one of them: ToDo, should create a row that displays data from a SQLite database, and depending on some factors (dates mainly), it shows a type of traffic light that is stored as a drawable.
Part of the Items in this Row is an Image Button that I want the user to be able to click and the image should change. The user should be able also to click on the actual row and a new activity starts.
The issue I have is that NO DATA is being displayed.
So, here is my code:
public class MainActivity extends Activity {
// definitions etc ...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// definitions etc ...
}
public void ToDo(View v){ // the user has clicked in the ToDo button
IgroDatabaseHelper helper = new IgroDatabaseHelper(getBaseContext()); // create instance of SQLIte database
numRows = helper.NumEntries("ToDo"); // Get the number of rows in table
int i = 1;
ArrayList<RowItem> rowItems = new ArrayList<>();
RowItem myItem1;
while (i <= numRows){
// get items from database
// depending on value select different drawable
// put data into List Array of RowItem
myItem1 = new RowItem(TheWhat, R.drawable.teamworka, R.drawable.redtrafficlight, R.drawable.checkbox, TheWhenBy);
rowItems.add(myItem1);
//
i = i+ 1;
}
ListView yourListView = (ListView) findViewById(R.id.list);
CustomListViewAdapter customAdapter = new CustomListViewAdapter(this, R.layout.todo_row, rowItems);
yourListView.setAdapter(customAdapter);
}
The CustomListViewAdapter looks like this:
public class CustomListViewAdapter extends ArrayAdapter<RowItem> {
Context context;
ArrayList<RowItem> _rowItems;
public CustomListViewAdapter(Context context, int resourceId,
ArrayList<RowItem> rowItems) {
super(context, resourceId);
this.context = context;
_rowItems = rowItems;
System.out.println("I am in the custom Adapter class "+ _rowItems);
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
System.out.println("This is the get view");
View row = convertView;
RowItem item = _rowItems.get(position);
// you can now get your string and drawable from the item
// which you can use however you want in your list
String columnName = item.getColumnName();
int drawable = item.getDrawable();
if (row == null) {
LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = mInflater.inflate(R.layout.todo_row, parent, false);
}
ImageButton chkDone = (ImageButton) row.findViewById(R.id.chkDone);
chkDone.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
View parentRow = (View) v.getParent();
ListView listView = (ListView) parentRow.getParent();
final int position = listView.getPositionForView(parentRow);
System.out.println("I am in position "+ position);
}
});
return row;
}
}
The RowItem Class looks like:
public class RowItem {
private String _heading;
private int _icon;
private int _lights;
private int _chkdone;
private String _date;
public RowItem(String heading, int icon, int lights, int chkDone, String date) {
_heading = heading;
_icon = icon;
_lights = lights;
_chkdone = chkDone;
_date = date;
System.out.println("adding stuff to my rows");
System.out.println("my column Name is " + heading);
System.out.println("My drawable int is "+ icon);
}
public String getColumnName() {
System.out.println("column Names is "+ _heading);
return _heading;
}
public int getDrawable() {
return _icon;
}
public int getLights(){
return _lights;
}
public int getchkDone(){
return _chkdone;
}
public String getDate(){
return _date;
}
}
I am obviously missing something, as I mentioned earlier, no data gets shown. I know that there are 2 row items that get passed to the CustomListViewAdapter. But I also know that the View getView inside the CustomListViewAdapter does not actually get called.
I hope I have put enough information/code, but if you feel I need to explain something further, please say.
Thanking all very much in advance!
I don't see a getCount() method. You should be overriding it like this:
#Override
public int getCount() {
return _rowItems.getCount();
}
Alternatively, calling super(context, resourceId, rowItems); should also fix it.
Your ListView thinks there are no items to display. If you are using your own array, you must override the getCount() method to indicate the number of items you want to display.
Related
I am new to android..and my question is:
I am making one android Application in which I have one RadioGroup with two Radiobutton
btnA and btnB along with some other Parameters.
if btnA is Checked than value in database is 1 and if btnB is selected then Value in Database is 0.
I am retrieving Data from database while showing My Listview.
Now My Question is I want to display Listview with listItem like :
imgA if Value From Database is 1 .
imgB if Value from Database is 0.
How to do it???
I tried this
private Integer[] Images = {R.drawable.imgA,R.drawable.imgB};
Cursor cur = dop.getData();
if(cur!= null && cur.getCount()>0)
{
if(cur.moveToFirst()){
do {Integer btnType= cur.getInt(cur.getColumnIndex(databaseName.TableName.ColumnName));
if(btnType== 1){ImageId = Images[0];}
else if(btnType== 0){ImageId= Images[1];}}
//other Params
}while (cur.moveToNext());
}
Adapter myAdp = new Adapter(Activity.this,ImageId,para);
myList.setAdapter(myAdp);
My Adapter is Like
public class Adapter extends BaseAdapter {
public Context context;
public ArrayList<String>Param1;
public int ImageId;
public Adapter(Context context,int ImageId,ArrayList<String>Param1)
{
this.context = context;
this.ImageId = ImageId;
this.Param1= Param1;
}
public int getCount(){return param1.size();}
public Object getItem(int Position){return null;}
public long getItemId(int Position){return 0;}
public class viewHolder{
TextView tvParam1;
ImageView imgType;
}
#Override
public View getView(int Position,View Child,ViewGroup Parent)
{
viewHolder vHolder;
LayoutInflater inflator;
if(Child == null)
{
inflator = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
Child = inflator.inflate(R.layout.list_row,null);
vHolder = new viewHolder();
vHolder.tvparam1 = (TextView)Child.findViewById(R.id.txtParam1);
vHolder.imgType = (ImageView)Child.findViewById(R.id.imgType);
Child.setTag(vHolder);
}
else {vHolder = (viewHolder)Child.getTag();}
vHolder.tvParam1.setText(Param1.get(Position));
vHolder.imgType.setImageResource(ImageId);
return Child;
}
}
my Problem is I am getting same image for all list items.
but I want ImgA for btnA and imgB for btnB.
How to resolve this???
I got solution for this issue
what i done is: I took Integer Arraylist for storing my Images
In my Main Activity:
public int[] Images = {R.drawable.imgA,R.drawable.imgB};
public ArrayList<Integer>ImageId = new ArrayList<Integer>();
int i = 0;
if(cur.moveToFirst()){
if(btnType == 1)
{
ImageId.add(Images[0]);
}
else if(btnType == 0)
{
ImageId.add(Images[1]);
}
} while(cur.moveToNext());
also in myAdapter: I jst changed Integer Array to Integer Arraylist for Image
this solve my Problem
Take an array of ImageId and save the id in that array in specific positions.
int i = 0;
if(cur.moveToFirst()){
do {Integer btnType= cur.getInt(cur.getColumnIndex(databaseName.TableName.ColumnName));
if(btnType== 1){ImageId[i] = Images[0];}
else if(btnType== 0){ImageId[i] = Images[1];}}
i++;
} while(cur.moveToNext());
Now inside your adapter load the images like this
vHolder.imgType.setImageResource(ImageId[Position]);
You've logical error in your code.
I'm working on an Android application of booking medicine offline. I have used ListView for Cart, but whenever I add a new item in cart, my previous item get replaced.
L1 = imageacidity
L2 = imagecough
if(msg.toString().equals("L1")) {
adapter = new ContactImageAdapter(this, R.layout.list, imageacidity);
ListView dataList = (ListView) findViewById(R.id.list);
dataList.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
if(msg.toString().equals("L2"))
{
adapter = new ContactImageAdapter(this, R.layout.list, imagecough);
ListView dataList = (ListView) findViewById(R.id.list);
dataList.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
Here I have 5 elements in imageacidity and Imagecough Array. Whenever I select 1 item, it gets added in cart, but when I try to select another item it get replaced with new one.
You have to Add the element inside your adapter.
I will post a custom Adapter and show you how to add elements properly.
Adapter:
public class YourAdapter extends BaseAdapter {
List<String> itens;
private Context mContext;
private static LayoutInflater inflater = null;
public YourAdapter(Context context, List<String> itens){
this.itens = itens;
mContext = context;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return itens.size();
}
public String getItem(int position) {
return itens.get(position);
}
public long getItemId(int position) {
return 0;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
if (convertView == null)
vi = inflater.inflate(R.layout.list_row, parent, false);
String msg = itens.get(position);
TextView tx = vi.findViewById(R.id.your_id);
tx.setText(msg);
return vi;
}
public void addItem(String item){
itens.add(item);
}
public void addItens(List<String> itens){
this.itens.addAll(itens);
}
}
ListView:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
adapter = new CustomAdapter(this,yourListOfItens);
listView = (ListView) findViewById(R.id.list_view);
listView.setAdapter(adapter);
}
You can set initial data on constructor of adapter, or use methods addItem and addAll on a click button for example.
The problem you are describing of the data being removed is happening because making a new ContactImageAdapter and calling setAdapter, which will completely remove the data that was already in the ListView.
If you want to properly implement the code in the question, you need something like this.
String msg = ""; // TODO: get this String value
ListView dataList = (ListView) findViewById(R.id.list);
// TODO: Define a single List to store the data and use that in *one* adapter
List<Contact> contacts = new ArrayList<Contact>();
adapter = new ContactImageAdapter(this, R.layout.list, contacts);
dataList.setAdapter(adapter);
// TODO: Replace this with the object to add to the adapter
Contact contact = null;
if(msg.equals("L1")) {
// TODO: Use whatever values you want for "L1"
int img = R.drawable.bati_acidity_1;
String name = "Amlapitta";
String price = "price 170";
contact = new Contact(img, name, price);
}
else if(msg.equals("L2")) {
// TODO: Use whatever values you want for "L2"
int img = R.drawable.bati_acidity_2;
String name = "Amlapitta2";
String price = "price 270";
contact = new Contact(img, name, price);
}
if (contact != null) {
contacts.add(contact);
adapter.notifyDataSetChanged();
}
Another problem is that you are calling notifyDataSetChanged without actually changing the datasets of imageacidity or imagecough.
You can use an algorithm (logic) on the InputListAdapter checking and verifying if there is a MedicineVO (Value Object Pattern) item on old list before the calling notyChange(..) method. In addition, you can wrapping the logic in other class such as MedicineLogic to improve the adapter readability.
See the sample code below:
public class MedicineInputListAdapter extends ArrayAdapter<MedicineVo> {
public static final int[] COLORS = new int[] { Color.WHITE, Color.BLUE };
private Context mContext;
private List<MedicineVo> medicineVos;
private MedicineVo medicineVoActual;
public BasePreOSPreventivaCorretivaInputListAdapter(Context context, int resource, List<MedicineVo> medicineVos) {
super(context, resource, medicineVos);
this.medicineVoActual = new MedicineVo();
this.medicineVos = new ArrayList<MedicineVo>();
this.medicineVos.addAll(medicineVos);
this.mContext = context;
}
private static class ViewHolder {
TextView mMedicineTextView;
//------------------------------------------------------
// others Android view components
//------------------------------------------------------
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder;
if (convertView == null) {
//------------------------------------------------------
// mapper from xml to view and add itens to holder
//------------------------------------------------------
//------------------------------------------------------
// add event action to the mMedicineTextView
//------------------------------------------------------
viewHolder.mMedicineTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
TextView textView = (TextView) view;
MedicineVo medicineVo = (MedicineVo) textView.getTag();
boolean selected = medicineVo.getSelected();
if (selected) {
/*do it*/
}
refreshPreOSMaterialWhenUpdate(preOSMaterialVo);
}
});
convertView.setTag(viewHolder);
}
else {
viewHolder = (ViewHolder) convertView.getTag();
}
//------------------------------------------------------
// get item and adjust color
//------------------------------------------------------
MedicineVo item = getItem(position);
/*do it*/
return convertView;
}
public void refreshMedicineListWhenUpdate(MedicineVo medicineVo){
List<MedicineVo> newMedicineVos = new ArrayList<MedicineVo>();
for (MedicineVo medicineVoOnList : medicineVos) {
if( StringUtils.isNull(medicineVoOnList.getId()) )
continue;
if( MedicineLogic.existsOnList(medicineVos, medicineVoOnList) )
continue;
/* others checks if necessary */
newMedicineVos.add(medicineVoOnList);
}
medicineVos.addAll(newMedicineVos);
}
}
If you can't select more but only one item of your ListView, this might help.As others have commented on the question, changing the adapter of a ListView can clear the selection too, but as I supposed the code you've posted is inside onCreate (or other kind of initialization) so setting the adapter there won't affect the selection (since there can't be selection without items... :) )
After a tremendous amount of time searching in here, and everywhere else I am hopeless to find a solution.
So here is my problem.
I have created a list-view and on top of that I added a search-bar.
When I use the search-bar, to filter the results... when I click on item 7, instead of opening the specific clicked activity i.e. 7, it always starts from the first one.
I am looking forward to your help guys; because I need it!
public class Group extends ListActivity {
// ArrayList thats going to hold the search results
ArrayList<HashMap<String, Object>> searchResults;
// ArrayList that will hold the original Data
ArrayList<HashMap<String, Object>> originalValues;
LayoutInflater inflater;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.grouplist);
final EditText searchBox = (EditText) findViewById(R.id.searchBox);
ListView playersListView = (ListView) findViewById(android.R.id.list);
inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final EditText searchBox = (EditText) findViewById(R.id.searchBox);
ListView playersListView = (ListView) findViewById(android.R.id.list);
inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// these arrays are just the data that
// I'll be using to populate the ArrayList
String names[] = {/*list of names*/ };
String teams[] = {/*list of teams*/};
Integer[] photos = {R.drawable.... /*list of drawables*/};
Integer[] id ={/*Position*/};
originalValues = new ArrayList<HashMap<String, Object>>();
// temporary HashMap for populating the Items in the ListView
HashMap<String, Object> temp;
// total number of rows in the ListView
int noOfPlayers = names.length;
// now populate the ArrayList players
for (int i = 0; i < noOfPlayers; i++) {
temp = new HashMap<String, Object>();
temp.put("name", names[i]);
temp.put("team", teams[i]);
temp.put("photo", photos[i]);
temp.put("id", id[i]);
// add the row to the ArrayList
originalValues.add(temp);
}
// searchResults=OriginalValues initially
searchResults = new ArrayList<HashMap<String, Object>>(originalValues);
final CustomAdapter adapter = new CustomAdapter(this, R.layout.players, searchResults);
// finally,set the adapter to the default ListView
playersListView.setAdapter(adapter);
searchBox.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before, int count) {
// get the text in the EditText
String searchString = searchBox.getText().toString();
int textLength = searchString.length();
// clear the initial data set
searchResults.clear();
for (int i = 0; i < originalValues.size(); i++) {
String playerName = originalValues.get(i).get("name").toString();
if (textLength <= playerName.length()) {
// compare the String in EditText with Names in the
// ArrayList
if (searchString.equalsIgnoreCase(playerName.substring(0, textLength)))
searchResults.add(originalValues.get(i));
}
}
adapter.notifyDataSetChanged();
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void afterTextChanged(Editable s) {
}
});
// listening to single list item on click
playersListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
int pos=Integer.ParseInt(searchResults.get(position).get("id").toString());
switch (pos) {
case 0:
Intent newActivity = new Intent(TeamsList.this, Barca.class);
startActivity(newActivity);
break;
case 1:
etc...
}
}
}
});
}
Custom adapter Class:
private class CustomAdapter extends ArrayAdapter<HashMap<String, Object>> {
public CustomAdapter(Context context, int textViewResourceId, ArrayList<HashMap<String, Object>> Strings) {
// let android do the initializing :)
super(context, textViewResourceId, Strings);
}
// class for caching the views in a row
private class ViewHolder {
ImageView photo;
TextView name, team;
}
ViewHolder viewHolder;
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.players, null);
viewHolder = new ViewHolder();
// cache the views
viewHolder.photo = (ImageView) convertView.findViewById(R.id.photo);
viewHolder.name = (TextView) convertView.findViewById(R.id.name);
viewHolder.team = (TextView) convertView.findViewById(R.id.team);
//Take one textview in listview design named id
viewHolder.id = (TextView) convertView.findViewById(R.id.id);
// link the cached views to the convert view
convertView.setTag(viewHolder);
} else
viewHolder = (ViewHolder) convertView.getTag();
int photoId = (Integer) searchResults.get(position).get("photo");
// set the data to be displayed
viewHolder.photo.setImageDrawable(getResources().getDrawable(photoId));
viewHolder.name.setText(searchResults.get(position).get("name").toString());
viewHolder.team.setText(searchResults.get(position).get("team").toString());
viewHolder.id.setText(searchResults.get(position).get("id").toString());
// return the view to be displayed
return convertView;
}
}
}
I think you cant find correct position on listview item click. so u can use one textview with visibility="Gone" and insert the position in that textview in every row. now u can easily access position while clicking on item with the value of textview which shows perfect position. Hope it works. Thanx
The problem is that Adapter is populated once but with search results it gets overViewed by the searched items so on clicking it refers to the original items of list instead of the filtered list once , so we have to use the filtered lists' positions instead of the original one, i also faced this problem, try this:
In your listView.setOnItemClickListener
playersListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
//Object objFilteredItem = parent.getItemAtPosition(position);
//String a = searchResults.get(position);
switch (Integer.parseInt((String) adapter.getItem(position))) {
case 0:..
Intent newActivity = new Intent(TeamsList.this,Barca.class);
startActivity(newActivity);
break;
case 1:
etc...
break;
}
}
});
As from my previously answered question here, you have to override the getItem(position) method in your CustomAdapter. You are setting the onItemClick somewhat correctly but the list adapter doesn't know what exactly it's getting from getItem(position).
EDIT (details): You need to add something like this in your custom adapter -
#Override
public Object getItem(int position) {
return list.get(position);
}
You should already have the list in your custom adapter. If not, you can add a list reference to your CustomAdapter:
private ArrayList<HashMap<String, Object>> list;
Then setting it using a setter in your Group activity:
customAdapter.setList(searchResults);
I have implemented a custom adapter and listItemView. The adapter sets an onlclick listener to a button that is on the listItemView. The onclick listener simply calls a private method I have in the adapter and passes it the position of the item to be removed. I know the position is correct because the database removes the proper item. I have found similar questions but have not been able to adapt the answers to work for me. Ideas and thoughts are greatly appreciated. Thanks.
Here is the full adapter class
public class FoodListAdapter extends ArrayAdapter<FoodListItem> {
//private
private int type;
public FoodListAdapter(Context context, ArrayList<FoodListItem> _objects) {
super(context, 0, _objects);
type = 0;
}
public FoodListAdapter(Context context, ArrayList<FoodListItem> _objects, int _type) {
super(context, 0, _objects);
type = _type;
}
#Override
public View getView(int position, View reusableView, ViewGroup parent)
{
//Cast the reusable view to a listAdpaterItemView
FoodListItemView listItemView = (FoodListItemView) reusableView;
//Check if the listAdapterItem is null
if(listItemView == null)
{
//If it is null, then create a view.
listItemView = FoodListItemView.inflate(parent, this, type);
}
if (type == 2)
{
Button deleteButton = (Button) listItemView.findViewById(R.id.listItemViewDeleteBTN);
deleteButton.setTag(new Integer(position));
}
//Now we need to set the view to display the data.
listItemView.setData(getItem(position));
return listItemView;
}
}
Here is a portion of my code used in fragment. Note that I have a private variable decalred in the class for listAdapter, though I don't think I need that.
private void displayListForDate(Calendar _date)
{
//get the list view
ListView listView = (ListView) getView().findViewById(1);
//Clear the listview by removing the listadapter and setting it to null.
//listView.setAdapter(null);
//First we must get the items.
Global global = (Global) getActivity().getApplicationContext();
DietSQLiteHelper database = global.getDatabase();
//Create a list to hold the items we ate. This list will then be added to the listView.
final ArrayList<FoodListItem> consumedList;
//Add the items to the array.
consumedList = database.getConsumed(_date.getTimeInMillis());
//Create an adapter to be used by the listView
listAdapter = new FoodListAdapter(getActivity().getBaseContext(), consumedList, 2);
//Add the adapter to the listView.
listView.setAdapter(listAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
consumedList.remove(position);
listAdapter.notifyDataSetChanged();
}
});
}
If you didn't implement "equals" method of FoodListItem, try to implements it.
I would suggest,
that you just update the underlying data, in your case its ArrayList<FoodItems>.
In your Adapter make this simple method and change :
private List<FoodListItem> myList = new ArrayList<FoodListItem>();
public FoodListAdapter(Context context, List<FoodListItem> myList) {
super(context, 0, myList);
type = 0;
this.myList = myList;
}
public FoodListAdapter(Context context, List<FoodListItem> myList, int _type) {
super(context, 0, myList);
type = _type;
this.myList = myList;
}
// Also update your getView() method to use myList!
#Override
public View getView(int position, View reusableView, ViewGroup parent)
{
...
listItemView.setData(myList.get(position));
public void removeItem(int positio){
if(myList != null){
myList.remove(position);
}
}
And then in class, you are creating the adapter (Activity/Fragment), just call the method.
// Update the underlying ArrayAdapter
adapter.removeItem(position);
// Notify the adapter, the data has changed
adapter.notifyDataSetChanged();
Also, you shouldnt open connection to your SQLiteDatabase on UI thread, because you are blocking it. You never know, how fast is the reading from disk going to be. If it takes too long, user can think, that your application froze and therefore, he leaves, which you dont want. I would suggest to use AsyncTask, you will find a lot of examples.
I went through and cleaned up my code and it now works, here is the working code. I really don't know exactly the difference other than I updated the IDs that I was using to assign and get views. If anyone can explain the cause for the issue I was having I would appreciate it.
Here is the snippet from my fragment where I create the list view and assign an adapter.
private void displayListForDate(Calendar _date)
{
//get the list view
ListView listView = (ListView) getView().findViewById(R.id.listView);
//Clear the listview by removing the listadapter and setting it to null.
//listView.setAdapter(null);
//First we must get the items.
Global global = (Global) getActivity().getApplicationContext();
DietSQLiteHelper database = global.getDatabase();
//Create a list to hold the items we ate. This list will then be added to the listView.
ArrayList<FoodListItem> consumedList;
//Add the items to the array.
consumedList = database.getConsumed(_date.getTimeInMillis());
//Create an adapter to be used by the listView
listAdapter = new FoodListAdapter(getActivity().getBaseContext(), consumedList, 2);
//Add the adapter to the listView.
listView.setAdapter(listAdapter);
}
and here is my adapter class.
public class FoodListAdapter extends ArrayAdapter<FoodListItem>
{
//private
private int type;
public FoodListAdapter(Context context, ArrayList<FoodListItem> _objects) {
super(context, 0, _objects);
type = 0;
}
public FoodListAdapter(Context context, ArrayList<FoodListItem> _objects, int _type) {
super(context, 0, _objects);
type = _type;
}
#Override
public View getView(int position, View reusableView, ViewGroup parent)
{
//Cast the reusable view to a listAdpaterItemView
FoodListItemView listItemView = (FoodListItemView) reusableView;
//Check if the listAdapterItem is null
if(listItemView == null)
{
//If it is null, then create a view.
listItemView = FoodListItemView.inflate(parent, type);
}
if (type == 2)
{
Button deleteButton = (Button) listItemView.findViewById(R.id.listItemViewDeleteBTN);
deleteButton.setTag(new Integer(position));
deleteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Integer tag = (Integer) view.getTag();
deleteItem(tag.intValue());
}
});
}
//Now we need to set the view to display the data.
listItemView.setData(getItem(position));
return listItemView;
}
private void deleteItem(int position)
{
FoodListItem item = getItem(position);
Global global = (Global) getContext().getApplicationContext();
DietSQLiteHelper database = global.getDatabase();
database.removeConsumed(item.getID());
remove(getItem(position));
}
}
Here is my method:
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
DataBaseHandler handler = new DataBaseHandler(getApplicationContext());
//set the spinner for measurement type
Spinner measurementTypeSpinner = (Spinner) findViewById(R.id.MeasurementTypes);
ArrayAdapter adapter = (ArrayAdapter) measurementTypeSpinner.getAdapter();
int typePos = adapter.getPosition(savedInstanceState.getString("measurementtype"));
measurementTypeSpinner.setSelection(typePos);
//set the spinner for the measurement unit
Spinner measurementUnitSpinner = (Spinner) findViewById(R.id.MeasurementSubValues);
ArrayAdapter arrayAdapter = (ArrayAdapter) measurementUnitSpinner.getAdapter();
int unitPos = arrayAdapter.getPosition(savedInstanceState.getString("measurementunit"));
measurementUnitSpinner.setSelection(unitPos);
//set the value
EditText value = (EditText) findViewById(R.id.unit_value);
value.setText(savedInstanceState.getString("value"));
/**
* The list view stuff
*/
ListView unitsList = (ListView) findViewById(R.id.units_list);
unitsList.setItemsCanFocus(true);
MeasurementType mType = handler.getMeasurementType(savedInstanceState.getString("measurementtype"));
//create the converter
Converter converter = new Converter(MeasurementType.getMeasurementType(savedInstanceState.getString("measurementtype")), savedInstanceState.getString("measurementunit"), savedInstanceState.getString("value"));
//convert the values
ArrayList<Unit> convertedValues = converter.convert();
//set the adapter for the list view
unitAdapter = new UnitListAdapter(this, convertedValues, mType);
unitsList.setAdapter(unitAdapter);
}
Basically, there is another activity with a list of items and when the user checks one, it updates the database setting an int property to 1, so that when the ArrayAdapter goes through an arraylist it picks up the property as 1 and displays it, instead of 0 in which case it doesn't display it.
Now on pressing the back button, both the spinners are populated with the values I stored, the value for the EditText is restored, but the ListView is not updated, yet when I leave the app and come back in, the value that was checked is there in the list...
This says to me that I might need to do something with onStop() and onRestart() could someone please advice me. The comment saying 'the list view stuff' is where I am trying to update the list view, it just isn't working and when I debug it won't go into the restore method at all, which is confusing.
EDIT
public class UnitListAdapter extends ArrayAdapter<Unit> {
private Context context;
private ArrayList<Unit> units;
private MeasurementType type;
public UnitListAdapter(Context context, ArrayList<Unit> units, MeasurementType type) {
super(context, R.layout.unit, R.id.unit_name, units);
this.context = context;
this.units = units;
this.type = type;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.unit, parent, false);
final TextView unitName = (TextView) rowView.findViewById(R.id.unit_name);
final EditText unitValue = (EditText) rowView.findViewById(R.id.unit_value);
if(units.get(position) != null) {
if(units.get(position).getView() == 1) {
unitName.setText(units.get(position).getUnitName());
unitValue.setText(units.get(position).getValue().toString());
} else {
unitName.setVisibility(View.GONE);
unitValue.setVisibility(View.GONE);
}
}
return rowView;
}
#Override
public void add(Unit u) {
units.add(u);
notifyDataSetChanged();
}
#Override
public void clear() {
units.clear();
notifyDataSetChanged();
}
#Override
public int getCount() {
return units.size();
}
}
As asked for. Sorry about confusion whilst editing.
onRestoreInstanceState() is not called when the user presses the back button. Most likely you need to move your logic to onResume(). I suggest that you read about the Activity lifecycle to get a better understanding about when each of the onXxx() methods are called.
After updating the list you need to call notifyDataSetChanged() to repopulate the listview.
http://developer.android.com/reference/android/widget/ArrayAdapter.html#notifyDataSetChanged()