How to refresh Listview within BaseAdapter? [duplicate] - android

This question already has answers here:
how to refresh custom listview using baseadapter in android
(5 answers)
Closed 8 years ago.
I have application this application contain listview , Listview retrieve data from local database sqlite , by using adapter this is my Adapter class code :
public class CommandsListAdapter extends BaseAdapter {
public static String ID = null;
private List<String> data;
ArrayList<HashMap<String, String>> commandList = new ArrayList<HashMap<String, String>>();
private ArrayAdapter<String> listAdapter;
Context context;
public CommandsListAdapter(Context con,
ArrayList<HashMap<String, String>> list) {
commandList = list;
context = con;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return commandList.size();
}
#Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return commandList.get(arg0);
}
#Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return arg0;
}
#Override
public View getView(final int index, View convertView, ViewGroup arg2) {
// TODO Auto-generated method stub
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.people_list, null);
}
TextView tvTime = (TextView) convertView.findViewById(R.id.timeOfBlock);
TextView tvName = (TextView) convertView.findViewById(R.id.name);
tvName.setText(commandList.get(index).get(MyDatabase.Number_Block));
tvTime.setText(commandList.get(index).get(MyDatabase.Time_Of_Block));
Typeface tf = Typeface.createFromAsset(context.getAssets(),
"segoeuil.ttf");
tvTime.setTypeface(tf);
tvName.setTypeface(tf);
convertView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// Message.message(context,
// commandList.get(index).get(MyDatabase.Block_Table_Id));
Intent i = new Intent(context, MessageDetail.class);
i.putExtra(ID,
commandList.get(index).get(MyDatabase.Block_Table_Id)
.toString());
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// context.startActivity(i);
}
});
convertView.setOnLongClickListener(new OnLongClickListener() {
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
ID=commandList.get(index).get(MyDatabase.Block_Table_Id);
removeListItem(v, index);
return false;
}
});
return convertView;
}
protected void removeListItem(View rowView, final int positon) {
final Animation animation = AnimationUtils.loadAnimation(
context, android.R.anim.slide_out_right);
rowView.startAnimation(animation);
Handler handle = new Handler();
handle.postDelayed(new Runnable() {
#Override
public void run() {
commandList.remove(positon);
MyDatabase db=new MyDatabase(context);
db.open();
// db.deleteBlock(ID);
db.close();
Message.message(context, ID);
}
}, 1000);
}
}
and this is my Activity Class code :
public class ListOfBlock extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list_of_block);
ActionBar actionBar = getActionBar();
// for color
actionBar.setBackgroundDrawable(new ColorDrawable(Color
.parseColor("#a20000")));
if (actionBar != null) {
actionBar.setTitle(getResources().getString(
R.string.title_activity_list_of_block));
actionBar.setDisplayHomeAsUpEnabled(true);
// actionBar.setIcon(R.drawable.ic_launcher);
}
ListView lvCommands = (ListView) findViewById(R.id.ListOfBlockerListView);
lvCommands.setAdapter(new CommandsListAdapter(getApplicationContext(),
new MyDatabase(getApplicationContext()).getBlockers()));
}
}
now I want to refresh the listview within getview method , I don't know how to do this , and I found some answer but really this is not helped me , thanks for any help .

YourActivity.this.recreate();
This will recreate your list. Keep a variable say n=false in the actvity where you perfom those operations. Then when you call back the activity with list, just pass this as true.
In the activiy where you perfom those operations,
Intent i = new Intent(Operations.this,ListActivity.class);
ListActivity.n=true;
startActivity(i);
In onCreate of ListActivity create a class variable boolean n=false;
if(n){
ListActivity.this.recreate();
}
Hope it helps. Cheers!

I hope this is help you , within the class adapter do this :-
ArrayList<HashMap<String, String>> commandList = new ArrayList<HashMap<String, String>>();
private ArrayList<HashMap<String, String>> searchArrayList;
public CommandsListAdapter(Context con,
ArrayList<HashMap<String, String>> list) {
commandList = list;
context = con;
searchArrayList=list;
}
and create a function for update your listview like this , also within Adapter Class :-
public void updateResults(ArrayList<HashMap<String, String>> results) {
searchArrayList = results;
//Triggers the list update
notifyDataSetChanged();
}
and any where you want to update your listview call this function , and I did this for you Sister , like this :-
updateResults(commandList);
one thing for sure these codes above this is all your code but I made some modify , and the parameter of updateResults function commandList this is your ArrayAdapter you defined already .
I hope this is work

Simply calling notifyDataSetChanged() of BaseAdapter class refresh the list view items. Call it appropriately based upon your requirement.
Cheers.

Related

adapter.notifyDataSetChanged() not working when I update ArrayList

I have seen a lot of post about this case but I don't find a solution for me. I use SwipeRefreshLayout.OnRefreshListener and this is my code in onRefresh() method. This doesn't work.
new Handler().postDelayed(new Runnable() {
#Override public void run() {
Aviso aviso = new Aviso();
aviso.setTitle("MMMMMMMMMMMMMMMMMMMMMM");
aviso.setDescription("Deskribapena");
aviso.setPubDate("Wed, 19 Mar 2016 12:40:00 GMT");
aviso.setDcDate("2016-03-19T12:40:00Z");
avisosList.add(aviso);
swipeRefresh.setRefreshing(false);
adapter.notifyDataSetChanged();
}
}, 2000);
But if I create new adapter and set in the ListView the result is good
new Handler().postDelayed(new Runnable() {
#Override public void run() {
Aviso aviso = new Aviso();
aviso.setTitle("MMMMMMMMMMMMMMMMMMMMMM");
aviso.setDescription("Deskribapena");
aviso.setPubDate("Wed, 19 Mar 2016 12:40:00 GMT");
aviso.setDcDate("2016-03-19T12:40:00Z");
avisosList.add(aviso);
adapter = new AvisosEnListaAdapter(getActivity(), avisosList);
lv.setAdapter(adapter);
swipeRefresh.setRefreshing(false);
}
}, 2000);
Adapter code:
public class AvisosEnListaAdapter extends BaseAdapter{
protected Activity activity;
protected ArrayList<Aviso> items;
//Constructor
public AvisosEnListaAdapter (Activity activity, ArrayList<Aviso> items){
this.activity = activity;
this.items = items;
}
public AvisosEnListaAdapter(ArrayList<Aviso> items) {
this.items = items; // TODO Auto-generated constructor stub
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return items.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return items.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return items.get(position).get_Id();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View v = convertView;
if(convertView == null){
LayoutInflater inf = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inf.inflate(R.layout.custom_avisosenlista, null);
}
//Create Aviso object
Aviso aviso = items.get(position);
//write title
TextView title = (TextView) v.findViewById(R.id.custom_avisosenlista_tv_title_aviso);
//Fuente
Typeface fontTitulo = Typeface.createFromAsset(activity.getAssets(), "fonts/OpenSans-Regular.ttf");
//Setter fuente
title.setTypeface(fontTitulo);
title.setText(aviso.getTitle());
//write data
TextView tvData = (TextView) v.findViewById(R.id.custom_avisosenlista_tv_data_aviso);
Typeface fontData = Typeface.createFromAsset(activity.getAssets(), "fonts/OpenSans-LightItalic.ttf");
//Setter fuente
tvData.setTypeface(fontData);
tvData.setText(aviso.getFechaParaPublicar());
return v;
}
}
Where is the problem?
Well, exist a little problem that the element appear in the last position and I want to appear in the first position.
I have one way
Create refresh method in your Adapter like
public void refresh(ArrayList<Aviso> itemsw) {
this.items = itemsw;
notifyDataSetChanged();
}
Now you just called this method from your Activity
Aviso aviso = new Aviso();
aviso.setTitle("MMMMMMMMMMMMMMMMMMMMMM");
aviso.setDescription("Deskribapena");
aviso.setPubDate("Wed, 19 Mar 2016 12:40:00 GMT");
aviso.setDcDate("2016-03-19T12:40:00Z");
avisosList.add(aviso);
adapter.refresh(avisosList);
EDIT:
To add the element at a particular location, use a different overload method for arraylist
instead of
avisosList.add(aviso);
use
avisosList.add(index, aviso); //Indes is the position where you want your item to appear
Any time in your Activity/Fragment do you do any avisosList = new ArrayList(); or something like that to re-add the new items? If so, you must know that a new object is being created, so it doesn't link to the adapter list object, so that's why it is failing to update.
You can only do the "new ArrayList()" only once when managing the adapter, and then to change the content of the List everytime you want to change the adapter, and then, of course, to call to notifyDataSetChanged();
Reload the list elements into you adapter.
Eg:
adapter.setListItems(avisosList);
adapter.notifyDataSetChanged();
You need to implement the addition of the element in the adapter instead of adding an element to the list from which the adapter is created
public class AvisosEnListaAdapter extends BaseAdapter{
protected Activity activity;
protected ArrayList<Aviso> items;
........
public void addItem(Aviso item){
items.add(item);
}
}
then
adapter.addItem(aviso);
adapter.notifyDataSetChanged();

Android - How to get checkbox to work with sqlite database

I am trying to create a listview with checkbox, and user can check the options to select which customer to pay the particular expense. I created the listview with checkbox, the problem is how to access database from my custom adapter class? It seems like i can't declare my sqlite database in that class. But i would like to add the expense to checked customer by referring to the customerId. How can i do that? I stuck in onCheckChanged method in my custom adapter class. Sorry for my bad english. Thanks
This is my AddExpense class:
public class AddExpense extends ListActivity implements OnClickListener {
EditText expenseName;
Spinner expenseType;
EditText expensePrice;
EditText expenseQuantity;
EventController controller = new EventController(this);
Button btnadd;
ListView lv;
#SuppressWarnings("unchecked")
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.addexpense);
expenseName = (EditText) findViewById(R.id.expenseName);
expenseType = (Spinner) findViewById(R.id.expenseType);
// Create an ArrayAdapter using the string array and a default spinner
// layout
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
this, R.array.type, android.R.layout.simple_spinner_item);
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
expenseType.setAdapter(adapter);
expensePrice = (EditText) findViewById(R.id.expensePrice);
expenseQuantity = (EditText) findViewById(R.id.expenseQuantity);
btnadd = (Button) findViewById(R.id.btnaddexp);
btnadd.setOnClickListener(this);
#SuppressWarnings("rawtypes")
ArrayList person = new ArrayList();
person.clear();
Intent objIntent = getIntent();
String eventId = objIntent.getStringExtra("eventId");
String query = "SELECT * FROM friends WHERE friendEvent = " + eventId;
Cursor c1 = controller.selectQuery(query);
if (c1 != null & c1.getCount() != 0) {
if (c1.moveToFirst()) {
do {
getParticipant person1 = new getParticipant();
person1.setfriendId(c1.getString(c1
.getColumnIndex("friendId")));
person1.setfriendName(c1.getString(c1.getColumnIndex("friendName")));
person.add(person1);
} while (c1.moveToNext());
}
}
c1.close();
ListAdapter listadapter = new ListAdapter(AddExpense.this,person);
adapter.notifyDataSetChanged();
setListAdapter(listadapter);
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
HashMap<String, String> queryValues = new HashMap<String, String>();
Intent objIntent = getIntent();
String eventId = objIntent.getStringExtra("eventId");
queryValues.put("eventId", eventId);
queryValues.put("expenseName", expenseName.getText().toString());
queryValues
.put("expenseType", expenseType.getSelectedItem().toString());
queryValues.put("expensePrice", expensePrice.getText().toString());
queryValues
.put("expenseQuantity", expenseQuantity.getText().toString());
controller.insertExpense(queryValues);
this.callHomeActivity(v);
finish();
}
public void callHomeActivity(View view) {
super.onResume();
}
This is my custom adapter code:
public class ListAdapter extends BaseAdapter implements OnCheckedChangeListener{
Context ctx;
LayoutInflater lInflater;
ArrayList<getParticipant> objects;
ListAdapter(Context context, ArrayList<getParticipant> friendList) {
ctx = context;
objects = friendList;
lInflater = (LayoutInflater) ctx
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return objects.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return objects.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
getParticipant person = objects.get(position);
View view = convertView;
if (view == null) {
view = lInflater.inflate(R.layout.view_expenses_participant_entry, parent, false);
}
TextView friendId = (TextView)view.findViewById(R.id.friendId);
friendId.setText(person.getfriendId());
TextView friendName = (TextView)view.findViewById(R.id.friendName);
friendName.setText(person.getfriendName());
CheckBox cbperson = (CheckBox)view.findViewById(R.id.list_checkbox);
cbperson.setOnCheckedChangeListener(this);
return view;
}
#Override
public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
// TODO Auto-generated method stub
}
why can't you access your database here, You have Context of your activity in ctx variable, you can access db in OnCheckedChanged() method, See below
#Override
public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
// TODO Auto-generated method stub
YOURSQLITEdatabase db = new YOURSQLITEdatabse(ctx);
db.performYourOperationsHere();
db.close();
}
Cursor Adapter should simplify things for you or you can add the id as tag in the check box view, take a look at setTag and then get the tag in your onCheckedChanged and
do operations in onCheckedChanged OR
keep storing it in an array or removing it depending on weather it's checked or unchecked and use this array of ids to perform db operations when adding expense on click of submit button, if you have something like that on your screen as doing db operation on every click will slow things for the user
Am not sure if you are doing this the correct way, Better would be if you study cursor adapters first.

Getting AsyncTask result data from Fragment

I have AsyncTask class called LoadXMLData, and as you can see I parse XML data in doInBackground() method.
public class LoadXMLData extends AsyncTask<String, RSSFeed, RSSFeed>{
public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
private ProgressDialog mProgressDialog;
private Context context;
RSSFeed feed;
public LoadXMLData(Context context) {
this.context = context;
mProgressDialog = new ProgressDialog(context);
mProgressDialog.setMessage("Molimo Vas, sačekajte. Podaci se učitavaju.");
}
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog.show();
Log.d("OVDE SAM:", "onPreExecute()");
}
#Override
protected RSSFeed doInBackground(String... urls) {
// Obtain feed
DOMParser myParser = new DOMParser();
feed = myParser.parseXml(urls[0]);
Log.d("OVDE SAM:", "PARSIRAM XML");
return feed;
}
#Override
protected void onPostExecute(RSSFeed result) {
mProgressDialog.dismiss();
super.onPostExecute(result);
}
}
And I have few fragments, where I need to get data from that AsyncTask. How I could do that?
Here is the code of an fragment called NajnovijeFragment.
public class NajnovijeFragment extends Fragment{
GridView lv;
RSSFeed feed;
CustomListAdapter adapter;
private String RSSFEEDURL = "http://balkanandroid.com/feed/";
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_najnovije, container,
false);
lv = (GridView) view.findViewById(R.id.GridView1);
// Set an Adapter to the ListView
adapter = new CustomListAdapter();
lv.setAdapter(adapter);
// Set on item click listener to the ListView
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// actions to be performed when a list item clicked
int pos = arg2;
Bundle bundle = new Bundle();
bundle.putSerializable("feed", feed);
Intent intent = new Intent(getActivity(), DetailsActivity.class);
intent.putExtras(bundle);
intent.putExtra("pos", pos);
startActivity(intent);
}
});
return view;
}
#Override
public void onDestroy() {
super.onDestroy();
adapter.imageLoader.clearCache();
adapter.notifyDataSetChanged();
}
class CustomListAdapter extends BaseAdapter {
private LayoutInflater layoutInflater;
public ImageLoader imageLoader;
public CustomListAdapter() {
layoutInflater = (LayoutInflater) getActivity().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
imageLoader = new ImageLoader(getActivity().getApplicationContext());
}
public int getCount() {
// TODO Auto-generated method stub
// Set the total list item count
return feed.getItemCount();
}
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
public View getView(int position, View convertView, ViewGroup parent) {
// Inflate the item layout and set the views
View listItem = convertView;
int pos = position;
if (listItem == null) {
listItem = layoutInflater.inflate(R.layout.list_item, null);
}
// Initialize the views in the layout
ImageView iv = (ImageView) listItem.findViewById(R.id.thumb);
TextView tvTitle = (TextView) listItem.findViewById(R.id.title);
TextView tvDate = (TextView) listItem.findViewById(R.id.tvDate);
// Set the views in the layout
imageLoader.DisplayImage(feed.getItem(pos).getImage(), iv);
tvTitle.setText(feed.getItem(pos).getTitle());
tvDate.setText(feed.getItem(pos).getDate());
return listItem;
}
}
}
The easiest way to get data from an ASyncTask is by implementing a callback.
Create an Interface:
public interface OnXMLLoadFinishedListener {
public void onXMLDataReady(RSSFeed results);
}
In you LoadXMLData:
private OnXMLLoadFinishedListener listener;
public void setOnXMLLoadFinishedListener(OnXMLLoadFinishedListener listener){
this.listener = listener;
}
#Override
protected void onPostExecute(RSSFeed result) {
super.onPostExecute(result);
listener.onXMLDataReady(RSSFeed results);
}
In your Fragment:
public class NajnovijeFragment extends Fragment implements OnXMLLoadFinishedListener{
and override onXMLDataReady:
#override
public void onXMLDataReady(RSSFeed results){
//display your data.
}
Make sure that when you create your AsyncTask instance you set the listener otherwise this will not work:
LoadXMLData xmlLoader = new LoadXMLData();
xmlLoader.setOnXMLLoadFinishedListener(this);
Your AsyncTask already knows context, so you could call back into your activity (called ActivityMain for illustrative purposes) in onPostExecute. e.g.
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
((ActivityMain) context).loadCompleteHandler(param1,param2,...)
}
It's then up to you how you want to implement loadCompleteHandler in your activity. Now your activity might not exist, so you must be careful to cancel the AsyncTask when the activity is removed. Fragments belonging to an activity can also access the activity.
AsyncTask is a Class that is very related to the UI, if you need to update the UI with this XML parsing you should take this consideration:
Make the asynctask an inner class in your fragment or
Pass the fragment to your asynctask
Update the fragment's view in onPostExecute()
In any case you should check if your activity is null, if so... avoid updating views, something like that:
onPostExecute(Object xml) {
if(getActivity != null) {
// update Views like...
textViewLabel.setText(parsedXml.getTitle);
}
}
I would suggest you to use SafeAsyncTask, which is a java class from the Roboguice Project, only one file, and it is related to java.util.concurrent.Callable, just copy and paste the source:
SafeAsyncTask.java
How to use it!

Listview swaps text inside of EditText when kaypad is invisible or visible

Problem : in Listview swaps text inside of EditText. it happen when keyboard invisible or visible. as shown in below images.
Code : ListView Activity Class :
public class DayPlannerFormActivity extends Activity {
private TextView txtHeader;
private Context mContext;
private ListView lvDayplannerFrom;
private FormDayPlannerAdapter adapter;
private Activity activity;
final Handler mHandler = new Handler();
private Vector<DayPlannerForm> list = new Vector<DayPlannerForm>();
final Runnable mUpdateResults = new Runnable() {
public void run() {
updateResultsInUi();
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dayplanner);
mContext = this;
activity = this;
txtHeader = (TextView) findViewById(R.id.txtHeader);
txtHeader.setText(R.string.haivlate);
lvDayplannerFrom = (ListView) findViewById(R.id.lvDayplanner);
startfetchOperation();
}
private void updateResultsInUi() {
adapter= new FormDayPlannerAdapter(activity,list);
lvDayplannerFrom.setAdapter(adapter);
}
protected void startfetchOperation() {
Thread t = new Thread() {
#Override
public void run() {
getData();
}
};
t.start();
}
private void getData() {
try{
list.clear();
DayPlannerForm dpf = new DayPlannerForm("Task Name 1","","");
list.add(dpf);
dpf =new DayPlannerForm("Task Name 2","","");
list.add(dpf);
mHandler.post(mUpdateResults);
} catch (Exception e){
mHandler.post(mUpdateResults);
}
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
try{
if(lvDayplannerFrom != null)
lvDayplannerFrom.setAdapter(null);
} catch (Exception e){}
}
}
Code : List View Adapter Class
public class FormDayPlannerAdapter extends BaseAdapter {
private Activity mActivity;
private static Vector<DayPlannerForm> list;
private static LayoutInflater inflater;
private Context mContext;
public FormDayPlannerAdapter ( Activity _activity,Vector<DayPlannerForm> _list) {
mActivity = _activity;
mContext = _activity;
list = _list;
inflater = (LayoutInflater)mActivity.getSystemService(mActivity.LAYOUT_INFLATER_SERVICE);
}
public static class ViewHolder{
public TextView txtTaskName;
public CheckBox chbAction;
public EditText edtDecription;
}
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View vi=convertView;
ViewHolder holder;
if(convertView==null){
vi = inflater.inflate(R.layout.dayplanner_listitem_form, null);
holder=new ViewHolder();
holder.txtTaskName=(TextView)vi.findViewById(R.id.txtTaskName);
holder.chbAction = (CheckBox) vi.findViewById(R.id.chbAction);
holder.edtDecription = (EditText) vi.findViewById(R.id.edtDecription);
vi.setTag(holder);
}
else
holder=(ViewHolder)vi.getTag();
holder.txtTaskName.setText(list.get(position).getTaskName());
return vi;
}
}
How to resolve this problem
Problem solve bye Adding android:windowSoftInputMode="adjustPan" this attribute in activity tag in the manifest.xml
On first look i think that problem occurring by the the following code:-
DayPlannerForm dpf = new DayPlannerForm("Task Name 1","","");
list.add(dpf);
dpf =new DayPlannerForm("Task Name 2","","");
list.add(dpf);
You should take different objects of DayPlannerForm Class for each Task Name.
DayPlannerForm dpf1,dpf2;
dpf1 = new DayPlannerForm("Task Name 1","","");
list.add(dpf1);
dpf2 =new DayPlannerForm("Task Name 2","","");
list.add(dpf2);
I think this might solve your problem.

ListView Added Duplicate item in list when screen orientation changes

I trying to create List View i face some problem when orientation changes.
Problem is: when i changes orientation of screen list-view add duplicate list item in list. how to restrict this data change
Code Is:
public class DayPlannerActivity extends Activity {
private TextView txtHeader;
private Context mContext;
private ListView lvDayplanner;
private DayPlannerAdapter adapter;
private Activity activity;
private static Vector<DayPlanner> list = new Vector<DayPlanner>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dayplanner);
mContext = this;
activity = this;
txtHeader = (TextView) findViewById(R.id.txtHeader);
txtHeader.setText(R.string.haivlate);
String[] Checks = {"select","Check1","Check2"};
DayPlanner dp = new DayPlanner("11:00 PM", Checks);
list.add(dp);
dp = new DayPlanner("12:00 PM", Checks);
list.add(dp);
lvDayplanner = (ListView) findViewById(R.id.lvDayplanner);
adapter= new DayPlannerAdapter(activity,list);
lvDayplanner.setAdapter(adapter);
}
}
List Adapter :
public class DayPlannerAdapter extends BaseAdapter {
private Activity mActivity;
private static Vector<DayPlanner> list;
private static LayoutInflater inflater;
public DayPlannerAdapter ( Activity _activity,Vector<DayPlanner> _list) {
mActivity = _activity;
list = _list;
inflater = (LayoutInflater)mActivity.getSystemService(mActivity.LAYOUT_INFLATER_SERVICE);
}
public static class ViewHolder{
public TextView txtScheduledTime;
public Spinner spnrChecks;
public Button btnGo;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View vi=convertView;
ViewHolder holder;
if(convertView==null){
vi = inflater.inflate(R.layout.dayplanner_listitem, null);
holder=new ViewHolder();
holder.txtScheduledTime=(TextView)vi.findViewById(R.id.txtScheduledTime);
holder.spnrChecks = (Spinner) vi.findViewById(R.id.spnrChecks);
holder.btnGo = (Button) vi.findViewById(R.id.btnGo);
vi.setTag(holder);
}
else
holder=(ViewHolder)vi.getTag();
holder.txtScheduledTime.setText(list.get(position).getScheduledTime());
ArrayAdapter<String> spnrAdapter=new ArrayAdapter<String>(mActivity,
android.R.layout.simple_spinner_item, list.get(position).getChecks());
spnrAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
holder.spnrChecks.setAdapter(spnrAdapter);
holder.btnGo.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent i = new Intent();
i.setClass(mActivity,DayPlannerFormActivity.class);
mActivity.startActivity(i);
}
});
return vi;
}
}
Since Android automatically saves Views states when the orientation changes, you need a way to know if it's not the first call to onCreate. Luckily, it's easy: Override onSaveInstanceState, and store even 1 value to make the bundle your get in onCreate not-null.
#Override
public void onSaveInstanceState(Bundle outInstanceState) {
outInstanceState.putInt("value", 1);
}
Then, when the activity is recreated, the parameter savedInstanceState in onCreate will not be null. So just do the test:
if(savedInstanceState != null)
Before you add data to your views.
its because your list of dayplanner objects is static, so when you change the orientation of the view it recreates the activity but since in java a static object is not recreated, but saved for that type, it makes the list have two of the same.
Way too late the party here,will still answer as it might be useful to someone else. I was also having the same issue it was resolved by PROPERLY implementing the view holder design pattern.

Categories

Resources