how to clear my listview in android - android

I have included my ListAdapter in my EMPLOYEE class.And list1 contains the values of Empname,
Eno,Salary fetched from webservices.Now after displaying the 5 records in the employee
screen...when I click on Depatrment Activity and come back to Employee ... the initial
5 records are appended to the list and now 10 records are present and so on .... the process is going on like this...
Please help me so as no duplicates are appended and it has to refresh the list.
Note : clear() or notifydatasetchanged(), invalidate() are not working.
ListAdapter adapter = new SimpleAdapter(this, list1,
R.layout.employee, new String[] { "EmpName","Eno", "Salary" }, new int[]
{R.id.ename, R.id.eno,R.id.sal});
setListAdapter(adapter);
Listview lv = getListView();
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
pos = position;
registerForContextMenu(getListView());
}
});
TextView tvdept = (TextView) findViewById(R.id.Department);
tvdept.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startActivity(new Intent(Employee.this, Department.class));
}
});

Without seeing more code, it's difficult to be sure, but I'll hazard a guess...
When you leave an activity and come back, the framework tries to restore you to where you were using the savedInstanceState bundle. It uses this to re-create where you last were in that activity. It sounds like you have set up the list in the onCreate method and haven't checked for a savedInstanceState bundle, so when you come back to the activity the framework is restoring your list and then proceeds into your code and re-creates the list (in this case adding the same data again).
Try wrapping your list creation code in an if that checks for the existence of the savedInstanceState bundle.
Like this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
// do your list setup here
}
}
Using that, if you come back to the activity and the framework saved your state, it will simply restore it and not run through your list creation code.
I know this doesn't answer the actual question, but it should solve the root issue (duplicating list data on return to activity).

Related

Android programming: I cant get data to reload into arrayadapter

I am still stuck with this issue, can anyone help. It seems that my problem is that I cant update the data list. I have tried every solution that I've searched for on google etc.. but half the time i'm not even sure that I'm doing the correct thing.
I've used the onResume() to call notifyDataSetChanged, it didn't work. I've tried putting a refresh method into the adapter which i then called in OnResume(). Again it didn't work. Some people suggest clearing the adpater (adapter.clear();) in onResume and then using the addAll() function to relist the data but nothing works.
There has to be a simple solution to this. I have literally been stuck on this for 2 days now. very frustrated.
Here's my Fragment code again...
enter code here
public class SavedAppFragment extends ListFragment {
private static final String TAG = "AppClicked"; //DEBUGGER
private ArrayList<App> mSavedApps;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Populate the ArrayList
mSavedApps = SavedAppData.get(getActivity()).getApps();
AppAdapter adapter = new AppAdapter(mSavedApps);
setListAdapter(adapter);
}
//LIST ITEM CLICKED: /*Control what happens when list item is clicked: I.E. Load up a quiz while putting an EXTRA key containg the package name of the App to be launhced should the user get the question correct */ #Override public void onListItemClick(ListView l, View v, int position,long id) { //Return the crime for the list item that was clicked App c = ((AppAdapter) getListAdapter()).getItem(position); Log.d(TAG, "was clicked");
//Start the Activity that will list the detail of the app
Intent i = new Intent(getActivity(), Quiz_Activity.class);
String name = c.getPackage();
i.putExtra("packagename", name);
startActivity(i);
}
private class AppAdapter extends ArrayAdapter {
private ArrayList<App> mSavedApps;
public AppAdapter(ArrayList<App> apps) {
super(getActivity(), 0, apps);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//If we weren't given a view, inflate one
if (null == convertView) {
convertView = getActivity().getLayoutInflater().inflate(R.layout.list_item_app, null);
//((AppAdapter) getListAdapter()).notifyDataSetChanged();
}
((AppAdapter) getListAdapter()).notifyDataSetChanged();
//Configure the view for this crime
App c = getItem(position);
TextView nameTextView = (TextView) convertView.findViewById(R.id.app_name);
nameTextView.setText(c.getName());
// nameTextView.setText(applicationInfo.loadLabel(packageManager));
TextView packageTextView = (TextView) convertView.findViewById(R.id.app_package);
packageTextView.setText(c.getPackage());
CheckBox appCheckBox = (CheckBox) convertView.findViewById(R.id.app_checked);
appCheckBox.setChecked(c.isChecked());
//Return the view object to the ListView
return convertView;
}
}
}
THANKS!!!
When you return to Activity B, the previous Activity B hasn't been destroyed. Thus, it skips the onCreate. Move all of the stuff you want to make sure happens every time into the onResume. I think you want to make your Adapter a class variable (I'll call it mAdapter) in onCreate, and add code that will get data from the list directly. If you need to do something, put a "refresh" function in the adapter. I'm assuming you have a custom Adapter, because I've never heard of AppAdapter. If you don't, then extend AppAdapter and add that functionality. Thus, your onCreate should look like this:
mAdapter = new AppAdapter(mSavedApps);
setListAdapter(mAdapter);
Your onRefresh could update the data contained in the adapter by some new update function, like so:
mAdapter.update(SavedAppData.get(getActivity()).getApps());

Change Specific TextView Color in Listview

i Have Two Database
first one Contain All The Items, and the ListView Display it
and the second db contain the the Favorite item , [selected from the first database]
what i want is that when the listview display all the items
check if the item is already exist in Favoritelist then make that textview background RED for this item
i have this code that work fine
public static void ChangeMyFavoritesBG(){
for (int i = 0; i < Items.size(); i++) {
if(db.verification(Items.get(i).toString())){
try {
TextView favtextview = (TextView) listview.getChildAt(i-listview.getFirstVisiblePosition()).findViewById(R.id.item_name);
favtextview.setBackgroundResource(R.drawable.redcolor);
}catch (NullPointerException e) {
}}}}
db.verification check if item exist in favorites database
if true . then it should change the background of this item to red
this code work fine but only if i put it in button click
i need to make the code work automatically
but if i made it start automatically when the activity is loaded i get NullPointer Error
i guess because the function ChangeMyFavoritesBG(); work before the listview display items
any idea guys? and sorry for my bad english
Do this control inside the getView(int position, View convertView, ViewGroup parent) method of the Adapter used by the listView.
If your favorite is not currently visible in the ListView then getChildAt() will return null.
You are looping over all items in the list view and my guess is that it holds more items than can fit on the screen. When your favorite item is one of them then this fragment of your code
listview.getChildAt(i-listview.getFirstVisiblePosition())
will return null. And that will cause the NullPointerException when you call findViewById(R.id.item_name) on it.
Just add a check for null on the result of getChildAt(). If it is null then do nothing, if it is non-null then call the second part. This will protect against the exception when your favorite item is not on the screen, and will allow it to be colored red when your favorite is visible on the screen.
update
My apologies, I read to quickly and misunderstood your problem to be about the NullPointerException but you say that your code works fine when you call it from a button click handler but not when you call it automatically at start-up.
You are right, the ListView does not yet have any items loaded when you are still in onCreate(). You can add a delay before running you code. The following works for me:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
// initialize the ListView with data for the list items. (I'm using a string array in this
// example. You are loading it from a database table, but that is the same in principle.)
ListAdapter adapter = new ArrayAdapter<String>(this, R.layout.item_list, R.id.item_name, Items);
ListView listview = (ListView) findViewById(R.id.listview);
listview.setAdapter(adapter);
// ask the system to wait before setting the background color of the favorite item so that
// the ListView has time to load the items.
final int DELAY_IN_MILLISECONDS = 100;
listview.postDelayed(new Runnable() {
#Override
public void run() {
ChangeMyFavoritesBG();
}
}, DELAY_IN_MILLISECONDS);
}
As you can see in the above example, after initializing the ListView, you ask the system to wait 100 milliseconds before calling ChangeMyFavoritesBG(). Hopefully that is enough time to load the items from the database into the ListView. If it is not enough time then you can, of course, use a longer delay.
The alternative
The above should work, but to be honest I would not write it this way. The above code is very brittle because it depends on the timing of how long it takes to load the items. I recommend that you put your background coloring into a customized adapter.
Because you want the items displayed in a customized way -- you want them to have a red background when it is the favorite one -- you should use a customized adapter. Override the bindView() function to make the background red when it is the favorite one or give it a normal background when it is not the favorite.
I don't know how you currently get the items from the database into your ListView, but inheriting from SimpleCursorAdaptor would work pretty well.
public class FavoritesItemAdapter extends SimpleCursorAdapter {
public FavoritesItemAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) {
super(context, layout, c, from, to, flags);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
super.bindView(view, context, cursor);
// read the name from the database
int nameColumnIndex = cursor.getColumnIndexOrThrow("name");
String name = cursor.getString(nameColumnIndex);
// write the name to the TextView
TextView nameText = (TextView) view.findViewById(R.id.item_name);
nameText.setText(name);
// set the background to normal or to red, depending on if it is the favorite one or not
boolean isFavorite = db_verification(name);
if (isFavorite) {
nameText.setBackgroundResource(R.drawable.redcolor);
} else {
nameText.setBackgroundResource(android.R.color.transparent);
}
}
public boolean db_verification(String name) {
// this is a stub. You must use your own code here
return name.equals("the favorite one");
}
}
You can then throw away ChangeMyFavoritesBG() and initialize your ListView with the adapter in onCreate() like this.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
Cursor cursor = readItemsFromDatabase();
String[] from = new String[] { "name_column" }; // mapping from database column name ...
int[] to = new int[] { R.id.item_name }; // ... to View ID in the item's layout.
FavoritesItemAdapter adapter = new FavoritesItemAdapter(this, R.layout.item_list, cursor, from, to, 0);
ListView listview = (ListView) findViewById(R.id.listview);
listview.setAdapter(adapter);
}
Good luck!

ListView items not getting populated when activity is launched

Here is my scenario:
I have a MainActivity and a CustomListViewActivity. In my MainActivity, I have 1 button and 1 spinner. On click of the button, I pass the selected spinner value to the CustomListViewActivity via Bundle and using Intents.
Now, in my CustomListViewActivity, I have a ListView that uses ArrayAdapter for populating it. I send a ArrayList from MainActivity, say for example
items = [abc]
In my CustomListViewActivity, I receive the same and use it to populate my ListView. The first time I do this, my value gets populated. The second time I do the same, the value existing is now replaced with the new one and the ListView shows one item instead of showing two.
So basically the problem is that the ListView is not updating and not showing both the items. Instead it shows me a single item always.
Here are snippets of my code
MainActivity.java
//code inside button click
..
{
items.add(spinner1.getSelectedItem().toString());
Bundle bundle =new Bundle();
bundle.putStringArrayList("data",items);
Intent i = new Intent(MainActivity.this,MyListViewActivity.class);
i.putExtras(bundle);
startActivity(i);
finish();
}
protected void onSaveInstanceState(Bundle icicle) {
super.onSaveInstanceState(icicle);
Log.i("App","onSave");
icicle.putStringArrayList("data",items);
}
#Override
protected void onRestoreInstanceState(Bundle icicle2) {
// TODO Auto-generated method stub
super.onRestoreInstanceState(icicle2);
Log.i("App","onRestore");
icicle2.putStringArrayList("data",items);
}
MyListViewActivity.java
private ArrayList<String> myItems;
private static String[] titles;
CustomListViewAdapter adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list_main);
listView = (ListView) findViewById(R.id.list1);
rowItems = new ArrayList<RowItem>();
adapter = new CustomListViewAdapter(this,R.layout.list_item, rowItems);
listView.setAdapter(adapter);
b=getIntent().getExtras();
if(b!=null)
{
myItems=b.getStringArrayList("data");
titles= new String[myItems.size()];
titles = myItems.toArray(myItems);
}
...
int i=0;
while(i<titles.length) {
item = new RowItem(titles[i]);
//rowItems.add(item);
Log.i("ROW", ""+rowItems.size());
i++;
adapter.add(item);
listView.setAdapter(adapter);
}
adapter.setNotifyOnChange(true);
adapter.notifyDataSetChanged();
}
}
How to make the ListView maintain the current data as well reflect the added data?
Thanks in advance
EDIT : Forgot to mention one more thing. In my MyListViewActivity class I have a button above the ListView that on clicked takes me to my MainActivity so that I can add a new Item again. So when I go back to MainActivity and try and add a new Item , it's the new Item that get displayed rather than showing both the previous and the new one
You need to persist and restore your items list in MainActivity's onSaveInstanceState and onRestoreInstanceState methods.
You also probably don't need to close the MainActivity by calling finish() every time you start the ListView activity but that depends on your application.
Basically, the problem you are having is that items is being recreated with each new instance of MainActivity. Since you finish MainActivity, a new instance is used every time you access that activity (and I assume you thought that items would just keep getting items added to it).

How do I read the string from a Spinner selected event

I have a simple app where the user selects one of the US states and the state selected is to be used to list all of the counties in that state. In onCreate, I built an arrayadapter called Stateadapter, and set it to the spinner object "spinState". I then initialized a listener class StateOnItemSelectedListener. Outside of onCreate, I have the StateOnItemSelectedListener class that will read which State was selected in the spinner, and then perform the rest of the app's tasks.
I have two problems: when single stepping thru the code in debug mode, the "parent.getItemAtPosition(pos).toString" does not return the string value of the selected state (though numerous web examples suggest this should work).
Second, when running, the app fires the listener when going thru onCreate and all appears well until the user selects the spinner on the ui, and the app then does a force close.
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
spinState = (Spinner)this.findViewById(R.id.spinState);
ArrayAdapter<String> Stateadapter = new ArrayAdapter<String> (this,android.R.layout.simple_spinner_item, array_spinState);
Stateadapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinState.setAdapter(Stateadapter);
spinState.setOnItemSelectedListener(new StateOnItemSelectedListener());
}
public class StateOnItemSelectedListener implements OnItemSelectedListener
{
public void onItemSelected(AdapterView<?> parent, View itemSelected, int pos, long id)
{ State = spinState.getItemAtPosition(pos).toString();
//Do Stuff base on State;
}
public void onNothingSelected(AdapterView<?> parent)
{ //Do nothing here
}
}
Try doing what they do in the Spinner Tutorial, they create the adapter in a different way, but eventually they use the same code to access to selected item and it works.
What is the error in log cat from the force close, and what getItemAtPosition does return?

Stuck... need help.. Listview w/ Array Adapter

Ok, so I have this application that takes a adress strings (from values/xml) and parses it your current position) retuning a name, address and distance away. This is then picked up by an arrayadapter and put up on a listview. I cannot for the life of me get the list view to accept an onitemclick to start another activity, where I can launch a different view. I did have it where I was getting the row, name and address to show through to an alert dialog, but in my efforts to get it to launch an activity, I lost that.
So does anyone have any thoughts? I am using the following call to make my list and and arrays. This is stripped down, so assume I have all the imports and proper formatting. I know I am just missing something simple here...
public class Wf extends ListActivity {
private ArrayList<String> DistanceList;
private ArrayAdapter<String> aa;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
// Bind the ListView to an ArrayList of strings.
DistanceList = new ArrayList<String>();
ListView lv = (ListView)findViewById(R.id.ListView01);
aa = new ArrayAdapter<String>(getApplicationContext(),
R.layout.listbox_layout,
DistanceList);
lv.setAdapter(aa);
//Call to get distance... here
}
public void onListItemClick(ListView parent, View v,int position, long id) {
ListView lv = (ListView)findViewById(R.id.ListView01);
Toast.makeText(this, "You clicked", Toast.LENGTH_LONG).show();
}
From the ListActivity docs:
ListActivity has a default layout that
consists of a single, full-screen list
in the center of the screen. However,
if you desire, you can customize the
screen layout by setting your own view
layout with setContentView() in
onCreate(). To do this, your own view
MUST contain a ListView object with
the id "#android:id/list" (or list if
it's in code)
Your ListView does not have the correct ID. Your code is incomplete but I suspect the listener is not being registered with the ListView.

Categories

Resources