获取新数据后,保持列表视图的滚动位置

时间:2016-05-25 08:54:50

标签: android listview

我有一个listview,刷新后获取新数据。它位于列表视图的顶部,而不是我最后滚动到的位置。

我设置了一个计时器,在2秒后,它获取新数据并将其放入listview。

非常感谢任何帮助。提前致谢:D

这是Mainactivity

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    listView = (ListView) findViewById(R.id.listView);
    listView.setOnItemClickListener(this);

    getJSON();

    handler.postDelayed(runnable, 3500);
} 

 private Runnable runnable = new Runnable() {
    @Override
    public void run() {

        getJSON();

        handler.postDelayed(this, 2000);
    }
};

private void showEmployee(){
    JSONObject jsonObject = null;
    ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String, String>>();
    try {
        jsonObject = new JSONObject(JSON_STRING);
        JSONArray result = jsonObject.getJSONArray(Config.TAG_JSON_ARRAY);

        for(int i = 0; i<result.length(); i++){
            JSONObject jo = result.getJSONObject(i);
            String id = jo.getString(Config.TAG_ID);
            String name = jo.getString(Config.TAG_NAME);

            HashMap<String,String> employees = new HashMap<>();
            employees.put(Config.TAG_ID,id);
            employees.put(Config.TAG_NAME,name);
            list.add(employees);
        }

    } catch (JSONException e) {
        e.printStackTrace();
    }

    ListAdapter adapter = new SimpleAdapter(
            MainActivity.this, list, R.layout.list_item,
            new String[]{Config.TAG_ID,Config.TAG_NAME},
            new int[]{R.id.id, R.id.name});

    listView.setAdapter(adapter);

}

 private void getJSON(){
    class GetJSON extends AsyncTask<Void,Void,String> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            JSON_STRING = s;
            showEmployee();
        }
        @Override
        protected String doInBackground(Void... params) {
            RequestHandler rh = new RequestHandler();
            String s = rh.sendGetRequest(Config.URL_GET_ALL);
            return s;
        }
    }
    GetJSON gj = new GetJSON();
    gj.execute();
}

5 个答案:

答案 0 :(得分:1)

onCreate()中的

用空列表初始化你的适配器并用listView绑定。 使你的适配器和列表全局列出。

现在无论何时向适配器添加数据,只需调用adapter.notifyDataSetChanged()

这就是它在片段中的工作原理。

答案 1 :(得分:1)

ListView滚动到顶部,因为Adapter再次设置。您无需在每次收到新数据时设置Adapter,只需将新数据添加到现有的List /数据集中,然后在notifyDatasetChanged()&#上调用ListView即可39; s AdapterListView的位置不会改变。

答案 2 :(得分:0)

要恢复滚动位置,请使用此功能。

    Parcelable state;

     @Override
   public void onPause() {    
  // Save ListView state @ onPause
  Log.d(TAG, "saving listview state @ onPause");
   state = listView.onSaveInstanceState();
  super.onPause();
}

...

@Override
public void onViewCreated(final View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Set new items
 listView.setAdapter(adapter);
...
 // Restore previous state (including selected item index and scroll        position)
 if(state != null) {
    Log.d(TAG, "trying to restore listview state..");
    listView.onRestoreInstanceState(state);
}

}

答案 3 :(得分:0)

在listview的onScrollListner中尝试获取最后一个可见项的位置,当你加载更多数据时,设置listview的setSelection

int ScrollPos=0;

listview.setOnScrollListener(new OnScrollListener() {

        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
        // TODO Auto-generated method stub
            int threshold = 1;
            int count = listview.getCount();
            if (listViewList1.size() >= YOUR LOAD ELEMENTS SIZE(Everytime))
                if (scrollState == SCROLL_STATE_IDLE) {
                    if (listview.getLastVisiblePosition() >= count
                            - threshold) {
                        scrollPos = listViewList.size();
                        // Execute LoadMoreDataTask AsyncTask

                    }
                }
        }
        @Override
        public void onScroll(AbsListView view, int firstVisibleItem,
                int visibleItemCount, int totalItemCount) {
            // TODO Auto-generated method stub
        }
    });

同时再次获取更多数据只需调用Listview.setSelection(scrollPos) 并且第一次只是设法将你的回滚设置回0 希望这会对你有所帮助

答案 4 :(得分:0)

您必须将适配器和列表声明为实例变量,而不是在本地声明它们。每当数据发生任何变化时,您必须对列表进行重新更新操作,然后调用适配器的notifyDataSetChanged()方法来更新列表视图。

将您的代码更改为:

ArrayList<HashMap<String,String>> list;
ListAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

listView = (ListView) findViewById(R.id.listView);
list = new ArrayList<HashMap<String, String>>();//changed
adapter = new SimpleAdapter(
    MainActivity.this, list, R.layout.list_item,
    new String[]{Config.TAG_ID,Config.TAG_NAME},
    new int[]{R.id.id, R.id.name});//changed

listView.setAdapter(adapter);
listView.setOnItemClickListener(this);

getJSON();

handler.postDelayed(runnable, 3500);
} 

private Runnable runnable = new Runnable() {
@Override
public void run() {

    getJSON();

    handler.postDelayed(this, 2000);
}
};

private void showEmployee(){
JSONObject jsonObject = null;
ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String, String>>();
try {
    jsonObject = new JSONObject(JSON_STRING);
    JSONArray result = jsonObject.getJSONArray(Config.TAG_JSON_ARRAY);

    for(int i = 0; i<result.length(); i++){
        JSONObject jo = result.getJSONObject(i);
        String id = jo.getString(Config.TAG_ID);
        String name = jo.getString(Config.TAG_NAME);

        HashMap<String,String> employees = new HashMap<>();
        employees.put(Config.TAG_ID,id);
        employees.put(Config.TAG_NAME,name);
        list.add(employees);
    }

} catch (JSONException e) {
    e.printStackTrace();
}

adapter.notifyDataSetChanged();//changed

}

private void getJSON(){
class GetJSON extends AsyncTask<Void,Void,String> {
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        JSON_STRING = s;
        showEmployee();
    }
    @Override
    protected String doInBackground(Void... params) {
        RequestHandler rh = new RequestHandler();
        String s = rh.sendGetRequest(Config.URL_GET_ALL);
        return s;
    }
}
GetJSON gj = new GetJSON();
gj.execute();
}