1

I am using BaseAdapter for filling the ListView

But it resets to the new item when it updates. How can i remain on its current position. i have searched and found few codes but it doesn't worked for me.

Here is my code:

public  void appendToMessageHistory(ArrayList username, ArrayList message) {
    if (username != null && message != null) {

        if(lv.getAdapter()==null){

            adapter = new ChatListAdapter(this, name, messages);
        lv.setAdapter(adapter);
        adapter.notifyDataSetChanged();}
        else{
            //int i=lv.getFirstVisiblePosition();
        adapter.updateData(this, name, messages);
        adapter.notifyDataSetChanged();

        //lv.smoothScrollToPosition(i);
        }

    }
}

and my BaseAdapter :

  public class ChatListAdapter extends BaseAdapter {
  private Context context;
private ArrayList<String> names;
private ArrayList<String> messages;


static class ViewHolder {
     public TextView name, message;
     public ImageView image;
}

public ChatListAdapter(Context context, ArrayList<String> names, ArrayList<String>   messages) {

     this.context = context;
    this.names = names;
     this.messages = messages;

}
public void updateData(Context context, ArrayList<String> names, ArrayList<String> messages){
    this.context = context;
    this.names = names;
    this.messages = messages;


}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View rowView = convertView;
    if (rowView == null) {
        LayoutInflater inflater = LayoutInflater.from(context);

            rowView = inflater.inflate(R.layout.layout,
                null);

        ViewHolder viewHolder = new ViewHolder();
        viewHolder.name = (TextView) rowView.findViewById(R.id.name);
        viewHolder.message=(TextView) rowView.findViewById(R.id.firstLine);
        rowView.setTag(viewHolder);
    }

    ViewHolder holder = (ViewHolder) rowView.getTag();
    String name = names.get(position);
    String message = messages.get(position);

           holder.message.setTextColor(context.getResources().getColor(this.getTextColorID()));



    return rowView;
}

@Override
public int getCount() {
    return names.size();
}

@Override
public Object getItem(int position) {
    return names.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}
@Override
public int getViewTypeCount() {
    // you have two different row types
    return 2;
}

@Override
public int getItemViewType(int position) {
    // You need to tell to adapter which row is needed at given position
    return names.get(position).equals(own) ? 0 : 1;
}

  }

I am also using stackFromBottom=true

I have used smoothScrollToPosition() but it scrolls back to the position after reset of listview i want to stick on the current position even when adapter updates.

Punit
  • 617
  • 1
  • 7
  • 17
  • You should have a look at http://stackoverflow.com/questions/8276128/retaining-position-in-listview-after-calling-notifydatasetchanged?rq=1 – k3v1n4ud3 Mar 18 '14 at 09:26
  • I've tried this too but not working it still resets! – Punit Mar 18 '14 at 09:35

2 Answers2

0

Have you tried the setSelectionFromTop method?

In the else block of your appendToMessageHistory method, try:

int index = lv.getFirstVisiblePosition();
View v = lv.getChildAt(0);
int top = (v == null) ? 0 : v.getTop();

adapter.updateData(this, name, messages);
adapter.notifyDataSetChanged();

lv.setSelectionFromTop(index, top);

An explanation of this is found here: Maintain/Save/Restore scroll position when returning to a ListView

Community
  • 1
  • 1
Dylan Watson
  • 2,103
  • 1
  • 17
  • 38
0

I resolved my bug.

It's very simple

It bounds the notifyDataSetChanged() function to specific condition

Here is my code:

 public  void appendToMessageHistory(ArrayList username, ArrayList message) {
    if (username != null && message != null) {

        if(lv.getAdapter()==null){

            adapter = new ChatListAdapter(this, name, messages);
        lv.setAdapter(adapter);
        adapter.notifyDataSetChanged();
  }
        else{
            int i = lv.getFirstVisiblePosition();
            int last = lv.getLastVisiblePosition();
            View v = lv.getChildAt(0);
            int top = (v == null) ? 0 : v.getTop();
            if (top < 0 && lv.getChildAt(1) != null) {
                    i++;
                    v = lv.getChildAt(1);
                    top = v.getTop();
            }



            adapter.updateData(this, name, messages);
            if(last==messages.size()-2)
                adapter.notifyDataSetChanged();
            lv.setSelection(i);
            lv.setSelectionFromTop(i, top);


        }

    }
}

Not it remains on current position if it is not showing last item and if it is showing last item then it will notify.

Punit
  • 617
  • 1
  • 7
  • 17