0

My problem is the following:

I have a list of news which is updated every few minutes as follows:

Always new messages appear before old ones (Prepend list)

// Step 1 -  Prepend array list
arraylist.add(0, map);

// Step 2 - Notify
adapter.notifyDataSetChanged();

When you call "notifyDataSetChanged" scroll position are kept but .. I want to stay at the current position ... to be somewhat lower.

eg (Facebook > prepend list after X minutes)

when the user runs at the top to see the new results.

Test Code:

public class testActivity extends Activity {
    // Declare Variables
    private JSONArray jr;

    private ListView listview;

    private testAdapter adapter;
    private ArrayList<HashMap<String, String>> arraylist;

    private EditText message;
    private ImageButton post;

    private static final String TAG = "test.activity";

    /* Create */

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);

        listview = (ListView) findViewById(R.id.listview);

        arraylist = new ArrayList<HashMap<String, String>>();
        adapter = new testAdapter(this, arraylist);

        listview.setAdapter(adapter);

        message = (EditText) findViewById(R.id.message);
        post = (ImageButton) findViewById(R.id.post);

        post.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                postMessage();
            }
        });

    }

    /* Post Message */

    public void postMessage() {
        new MyRequest(this, "user", "post",
                MyRequest.setParam
                        (
                                "message", message.getText().toString().trim()
                        )
        ) {
            @Override
            public void Done(String resp, JSONObject data) {
                HashMap<String, String> map = new HashMap<String, String>();

                try {

                    map.put("date", data.getString("date"));
                    map.put("message", data.getString("message"));

                    arraylist.add(0, map);

                    Parcelable state = listview.onSaveInstanceState();

                    listview.setAdapter(adapter);
                    listview.onRestoreInstanceState(state);
                }
                catch (JSONException e) {
                    Log.e(TAG, "Error JSON Fetch!");
                }
            }
        };
    }
}

TestAdapter:

public class testAdapter extends BaseAdapter {
    Context context;
    LayoutInflater inflater;
    ArrayList<HashMap<String, String>> data;
    HashMap<String, String> resultp = new HashMap<String, String>();

    public testAdapter(Context context,
                       ArrayList<HashMap<String, String>> arraylist) {
        this.context = context;
        data = arraylist;
    }

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

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

    @Override
    public long getItemId(int position) {
        return position;
    }

    public View getView(final int position, View convertView, ViewGroup parent) {
        View itemView = convertView; //trying to reuse a recycled view

        ViewHolder holder = null;

        if (itemView == null) //The view is not a recycled one .. we have to inflate
        {
            inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            itemView = inflater.inflate(R.layout.listview_item, parent, false);

            holder = new ViewHolder();

            holder.date = (TextView) itemView.findViewById(R.id.message);
            holder.message = (TextView) itemView.findViewById(R.id.date);

            itemView.setTag(holder);
        }
        else // View recycled
            holder = (ViewHolder) itemView.getTag();

        resultp = data.get(position);

        holder.message.setText(resultp.get("message"));
        holder.date.setText(resultp.get("date"));

        return itemView;
    }

    /* View Holder */
    static class ViewHolder {
        TextView message;
        TextView date;
    }
} // End Class
beresfordt
  • 4,713
  • 7
  • 32
  • 41
Valy Dvweb
  • 37
  • 8

1 Answers1

0

In order to maintain the position the scroller had before you updated the data, you have to first get the first item's position in your adapter by:

int position = listView.getFirstVisiblePosition();

and then:

listView.setSelection(position);

to set the scroller to be on the specified position on entering the ListView activity.

Edit: After a quick search I came across this question. You can find multiple ways to implement what you want and different opinions but the above way is the most simple one from what I can see.

Edit 02: Since you mention that your ListView is updated top-down you can do the following:

Parcelable state = listView.onSaveInstanceState();
listView.setAdapter(adapter);
listView.onRestoreInstanceState(state);

The first line gets the listview's exact state. The second line sets your adapter. The third line re-applies the (previously saved) state.

Community
  • 1
  • 1
George Daramouskas
  • 3,470
  • 3
  • 18
  • 48
  • yes ... I tried this ... but my list is updated at the top (prepend mode). This means that the current position does not correspond. – Valy Dvweb Feb 26 '15 at 15:37
  • Could you please post some code (listview's and adapter) in order for us to figure this out? – George Daramouskas Feb 26 '15 at 16:26
  • Simplify how much test code and if you fail back with a post. – Valy Dvweb Feb 26 '15 at 17:04
  • I attached a test code that simulates this situation – Valy Dvweb Feb 26 '15 at 18:19
  • Please override the `onCreate()` method of your `ListView` and put the `listView.onRestoreInstanceState(state);` method there. Then override the `onPause()` method and and put the `state = listView.onSaveInstanceState();` there. Declare the `Parcelable state;` as a `static` variable in your class. Try this and tell me if your problem is resolved. – George Daramouskas Feb 26 '15 at 19:03