在准备ListView时保持滚动位置



我的问题如下:

我有一个新闻列表,每隔几分钟更新一次,如下所示:

总是新消息出现在旧消息之前(准备列表)

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

当您调用"notifyDataSetChanged"时,滚动位置保持不变,但。。我想留在现在的位置。。。稍微低一点。

例如(Facebook>X分钟后准备列表)

当用户在顶部运行以查看新结果时。

测试代码:

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!");
                }
            }
        };
    }
}

测试适配器:

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

为了保持滚动条在更新数据之前的位置,您必须首先通过以下方式获取适配器中第一个项目的位置:

int position = listView.getFirstVisiblePosition();

然后:

listView.setSelection(position);

以在进入ListView活动时将滚动条设置在指定位置。

编辑:经过快速搜索,我发现了这个问题。你可以找到多种方法来实现你想要的和不同的意见,但据我所见,上面的方法是最简单的。

编辑02:由于您提到您的ListView是自上而下更新的,因此您可以执行以下操作:

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

第一行获取列表视图的确切状态。第二行设置适配器。第三行重新应用(以前保存的)状态。

最新更新