after refreshing listview it shows first position data - android

I have a long ListView that the user can scroll around. I am refreshing this listview after every 30 seconds, listview refresh succesfully. But there is one issue that I want the list to be scrolled to the same point that it was previously before refreshing. Because now if list refresh then it shows the first position.
I am updating list through AsynchronousTask as:
private class HttpTask extends AsyncTask<String, Boolean, String> {
#Override
protected String doInBackground(String... params) {
System.out.println("inside doInBackground>>!!>>> ");
getResponse();
return "Executed";
}
#Override
protected void onProgressUpdate(Boolean... progress) {
}
#Override
protected void onPostExecute(String result) {
// publishProgress(false);
System.out.println("post excute funt***********");
setListAdapter(new ListAdapter(getApplicationContext(),
R.layout.mylist, dataArr));
}
}
Any help will be appreciated.Thanks in advance

try to use setSelectionFromTop() to set the position to the previously visible state.

You would just have to do this :
listView.setSelection(position) // position is the item on the listView

I think when your listview is going to be refreshed the get the position of item which is first visible at that time then refresh your listview and set the position which you got before refreshing
int firstPosition = mEventListView.getFirstVisiblePosition();
EventLogAdapter eventLogAdapter = new EventLogAdapter(mContext, events);
mEventListView.setAdapter(eventLogAdapter);
mEventListView.setSelection(firstPosition);

Instead of set a new ListAdapter, do listAdapter.notifyDataSetChanged() this will refresh the contents of view instead of create new ones and the listview will not scroll up

What you are doing is you are assigning adapter to your list view when you call refresh
setListAdapter(new ListAdapter(getApplicationContext(),
R.layout.mylist, dataArr));
Which is wrong
You have to refresh your adapter
dataArr.notifyDataSetChanged();
Hope this will work

Related

How to reset recyclerView position item views to original state after refreshing adapter

I have a RecyclerView with rows that have views that when clicked will be disabled for that row position.
The problem is after I update the adapter like this:
adapterData.clear();
adapterData.addAll(refreshedAdapterData);
notifyDataSetChanged();
After refreshing the data, the disabled views at the previous recycler position still remain disabled even though the data is refreshed.
How can I reset the views to the original state after refreshing adapter data.
Use below code.
adapterData.clear();
adapterData.addAll(refreshedAdapterData);
adapter.notifyDataSetChanged();
OR
recyclerView.invalidate();
When you call notifyDataSetChanged(), the onBindViewHolder() method of every view is called. So you could add something like this in the onBindViewHolder() of your Adapter method:
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, final int position) {
if (refreshedAdapterData.get(position).isInDefaultState()) {
//set Default View Values
} else {
//the code you already have
}
}
I have resolved this by putting a conditional statement inside onBindViewHolder method instructing all positions to reset the disabled views if data meets the required conditions for a refreshed data.
#Christoph Mayr, thanks for your comments. It helped point me in the right direction.
I cleared the data then notify change but the selected checkbox doesn't reset but just moves up one position. Let say I selected item #1 , move out of the RecyclerView, came back and it will auto select item #0.
So, I created new adapter again at onResume(), i worked for me but i don't know if it's the right way to handle this situation.
#Override
public void onResume() {
super.onResume();
if(selectedItems != null && selectedItems.size() > 0){
selectedItems.clear(); // if no selected items before then no need to reset anything
if(adapter != null && recyclerView != null){
// to remove the checked box
adapter = null;
adapter = new MyAdapter(items, new MyAdapter.MyAdapterListener() {
#Override
public void onSelected(int pos) {
selectedItems.add(items.get(pos));
}
#Override
public void onUnSelected(int pos) {
selectedItems.remove(items.get(pos));
}
});
recyclerView.setAdapter(adapter);
}
}
}

Update a listview item row but on scroll the modifications don't remain

I have a ListView in an Android Activity and a custom adapter for that listview.
I want to be able to edit a row item and update that row instantly. This works, the modifications of the row is seen But, on scroll i loose all data.
This is my Asynk task from where i get the data and update the list row item:
/**
*
*/
public class EditNewsFeedPostAsyncTask extends AsyncTask<Void, Void, Boolean> {
public Activity context;
public String content;
public int rowPosition;
public ListView listView;
public TextView decriptionTxt;
#Override
protected Boolean doInBackground(Void... params) {
try {
token = Utils.getToken(context);
if (token != null) {
....
// {"status":"true"}
if (result != null) {
....
}
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
#Override
protected void onPostExecute(final Boolean success) {
if (success) {
updateListView(rowPosition, content);
}
}
public boolean updateListView(int position, String content) {
int first = listView.getFirstVisiblePosition();
int last = listView.getLastVisiblePosition();
if (position < first || position > last) {
return false;
} else {
View convertView = listView.getChildAt(position - first);
decriptionTxt.setText(content);
listView.invalidateViews();
return true;
}
}
private void updateView(int index, TextView decriptionTxt) {
View v = listView.getChildAt(index - listView.getFirstVisiblePosition());
if (v == null)
return;
decriptionTxt.setText(content);
listView.invalidateViews();
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onCancelled() {
}
}
What am i missing? shouldn't the data be persistent?
Thx
You must update the object in your listView adapter, not only the views!
after scrolling, the getView method inside your list's adapter will call and you will return the default view for that.
if you want to change that item permanent, you should update your data set and call notifyDataSetChanged on your adapter.
Make sure you're updating the data, not just the view.
When you modify the row, are you changing the underlying data or just the view? If just the view...
You're probably running into ListView recycling issues. This answer has a great explanation. Basically, ListViews are about efficiency in displaying views based on data, but are not good for holding new data on screen. Every time a ListView item is scrolled out of view, its View is recycled to be used for the item that just scrolled into view. Therefore, if you put "hi" in an EditText and then scroll it off screen, you can say goodbye to that string.
I solved this in my app by ditching ListView altogether and using an array of LinearLayouts (probably a clunky approach, but I had a known list size and it works great now). If you want to continue using a ListView, you'll have to approach it from a "data first" perspective. Like I said, ListViews are great at showing info from underlying data. If you put "hi" in an EditText and simultaneously put that string in the underlying data, it would be there regardless of any scrolling you do. Updating onTextChanged might be cumbersome, so you could also let each row open a dialog in which the user enters their data which then updates the underlying dataset when the dialog closes.
These are just some ideas, based on some assumptions, but editing views in a ListView is, in general, not very in line with how ListViews work.

Clear all items in a ListFragment

I am using a ListFragment and display a dynamic list from a database, I want to update the view and change the order of the list by running the ASYNCTASK again. At them moment when this is done the new data just gets put on the bottom of the current list.
asynctask in fragment:
creates the list adapter and displays it
protected void onPostExecute(String file_url) {
// // dismiss the dialog once done
pDialog.dismiss();
fragment_module.this.getListView().invalidateViews(); //does nothing
adapter = new SimpleAdapter(getActivity(),
questionsList, R.layout.questionlistitem, new String[] {
TAG_QUESTIONVOTE, TAG_QUESTIONTEXT,
TAG_QUESTIONANSWER, CONCATINATED_SUBMISSION,
TAG_QUESTIONID }, new int[] { R.id.upvoteText,
R.id.questionText, R.id.questionAnswer,
R.id.submission, R.id.qid });
// updating listview
setListAdapter(adapter);
}
The view is to change after an onclick event is just want the list to be cleared so it can update.
update
Code called to update view and re-run asynctask
fragment_module.this.getListView().invalidateViews();
getQuestionList obj2 = new getQuestionList();
obj2.execute();
you can use something like
collection.clear();
listview.getAdapter().notifyDataSetChanged();

Refresh listview onpost execute asynctask

i know this question has been posted multiple times and i browsed almost all of them but there is not result, i am performing a deleting an item from mysql database but it is not refreshing, here is the code of the onclicklistener and the button:
onClick listener:
holder.void_button.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
adapter = new CustomListViewVoidAdapter(context,R.layout.mytemp, items);
item_selected= items.get(position);
new DeleteOrder().execute();
}});
vi.setTag(holder);
}
OnPostExecute from AsyncTask:
protected void onPostExecute(String unused){
adapter.remove(item_selected);
adapter.notifyDataSetChanged();
}
the adapter is instatiated globally, can you please check where the problem might be?
it is not returning any error, just deleting the item and not refreshing.
Regards
Ralph
Throwing it out there, but, have you tried adapter.notifyDataSetInvalidated();? That forces an update.
Also, put the code in the asynctask!
Like such:
protected void onPostExecute() {
adapter.notifyDataSetChanged();
adapter.notifyDataSetInvalidated();
}
You better set the adapter again to the list view in onPostExecute with the new values. And you don't need to call notifyDataSetChangedin this case. Also don't re-intialize the adapter in onClick, this is not neccessary.
Add below line in postExecute.
if(adapter != null) {
adapter = new CustomListViewVoidAdapter(context,R.layout.mytemp, items);
YourListviewObject.setAdapter(adapter);
}

ListView.getChildAt(validPosition) returns null

When user clicks on item of ListView I show Edit button at this item of list. lastSelectedPosition has the position of the list item that was clicked last.
code:
public class MainActivity extends Activity {
private ListView listView;
private MyAdapter adapter;
// static - If the activity is re-created, the data
// about list items remain.
private static List<String> items = loadItems();
private MyItemClickListener listener = new MyItemClickListener();
private int lastSelectedPosition = ListView.INVALID_POSITION;
#Override
protected void onCreate(Bundle savedInstanceState) {
listView = (ListView) findViewById(R.id.myListView);
adapter = new MyAdapter(R.layout.my_item, items);
listView.setAdapter(adapter);
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
listView.setOnItemClickListener(listener);
if (savedInstanceState != null) {
// Is recreating the activity because
// of the change screen orientation.
lastSelectedPosition = savedInstanceState.getInt("lastSelectedPos");
if (lastSelectedPosition != ListView.INVALID_POSITION) {
// !!! getChildAt() always returns null !!!
View listItem = listView.getChildAt(lastSelectedPosition);
View editButton = listItem.findViewById(R.id.editButton);
// Only selected list item has visible EditButton,
// other list items have not
editButton.setVisibility(View.VISIBLE);
}
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
// Is destroying the activity because
// of the change screen orientation.
outState.putInt("lastSelectedPos", lastSelectedPosition);
}
// Other methods
}
I think that getChildAt() always returns null in Activity.onCreate(), because at that moment the list is not yet fully developed. How I can get View of list item to show Edit button on it?
And sorry for my English.
Thanks
Your adapter needs to know about this selected position so it can be rendered properly in getView(). Just modify the constructor for your adapter to take the int, and update that int value whenever the onclick is called. In general, you should always have all the information you need to recreate the state of your list items within your adapter.
I think it is because you didn't change your lastSelectedPosition's value when user click on item in your listview. Just implement your onItemClickListener like the following code snippet. And change your lastSelectedPosition's value on this. And remove your
private MyItemClickListener listener = new MyItemClickListener();
line.
I think the value of lastSelectedPosition is couldn't changed until you define your listener variable. And also I didn't know where you define your listener variable.
lv1.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
lastSelectedPosition = arg2
}
});
I hope this will help you.

Categories

Resources