【问题标题】:Listview jump to top when adding new item添加新项目时列表视图跳转到顶部
【发布时间】:2016-11-28 12:01:39
【问题描述】:

我正在制作具有从多个 URL 添加数据的滚动侦听器的应用程序 但是当我滚动列表跳转到第一个位置并加载 URL 时,我知道每次我加载新的 URL 任务时,我的同步任务中的适配器都会在我加载新项目时执行,但我不知道如何修复它

public class jsontask extends AsyncTask<String, String, List<newsmodel>> {


    @Override
    protected List<newsmodel> doInBackground(String... params) {
        BufferedReader reader = null;
        HttpURLConnection connection = null;
        try {
            URL url = new URL(params[0]);

            connection = (HttpURLConnection) url.openConnection();
            if (connectiondetector.isConnected()) {
                connection.addRequestProperty("Cache-Control", "max-age=0");
            } else {
                moviemodelList.addAll((List<newsmodel>) cacheThis.readObject(
                       technology.this, fileName));

            }
            connection.connect();
            InputStream stream = connection.getInputStream();
            reader = new BufferedReader(new InputStreamReader(stream));
            StringBuffer buffer = new StringBuffer();
            String line = "";
            while ((line = reader.readLine()) != null) {
                buffer.append(line);

            }


            String finaljson = buffer.toString();
            JSONObject parentobject = new JSONObject(finaljson);


            JSONArray parentarray = parentobject.getJSONArray("articles");

            for (int i = 0; i < parentarray.length(); i++) {
                JSONObject finalobject = parentarray.getJSONObject(i);
                newsmodel newsmodel = new newsmodel();
                newsmodel.setAuthor(finalobject.getString("author"));
                if (finalobject.isNull("author")) {

                }
                newsmodel.setDescription(finalobject.getString("description"));
                newsmodel.setTitle(finalobject.getString("title"));
                newsmodel.setImage(finalobject.getString("urlToImage"));
                newsmodel.setUrl(finalobject.getString("url"));

                newsmodel.setPublishedAt(finalobject.getString("publishedAt"));
                cacheThis.writeObject(technology.this, fileName, moviemodelList);
                moviemodelList.add(newsmodel);

            }


            return moviemodelList;

        } catch (MalformedURLException e) {
            e.printStackTrace();
            return moviemodelList;
        } catch (IOException e) {
            e.printStackTrace();
            return moviemodelList;
        } catch (JSONException e) {

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {


            }
            try {
                if (reader != null) {
                    reader.read();

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

        }


        return moviemodelList;
    }


    @Override
    protected void onPostExecute(List<newsmodel> result) {


        super.onPostExecute(result);
        newsadapter adapter = new newsadapter(getApplicationContext(), R.layout.row, result);
        lvnews.setAdapter(adapter);
    }

}


public class newsadapter extends ArrayAdapter {
    private List<newsmodel> moviemodelList;
    private int resource;
    private LayoutInflater inflater;

    public newsadapter(Context context, int resource, List<newsmodel> objects) {
        super(context, resource, objects);
        moviemodelList = objects;
        this.resource = resource;
        inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);


    }`

这就是我执行同步任务的方式

 protected void onStart() {
    super.onStart();
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    moviemodelList.clear();
    new jsontask().execute("https://newsapi.org/v1/articles?source=engadget&sortBy=top&apiKey=ade8f00a634b4825a028837ec107afae");
    lvnews.setOnScrollListener(new EndlessScrollListener() {
        @Override
        public boolean onLoadMore(int page, int totalItemsCount) {

            new jsontask().execute("url1");
            new jsontask().execute("url2");
            new jsontask().execute("url3");
            new jsontask().execute("url4");
            new jsontask().execute("url5");
            new jsontask().execute("url6");
            return false;
        }
    });

}

【问题讨论】:

    标签: java android arrays listview android-asynctask


    【解决方案1】:

    从 onPostExecute 中删除这些行

    newsadapter adapter = new newsadapter(getApplicationContext(), R.layout.row, result);
    lvnews.setAdapter(adapter);
    

    您在执行 doInBackground 后设置适配器eveytime。你只需要做一次。你可以在 onCreate 中做到这一点

    android AsyncTask 类中使用的基本方法定义如下

    doInBackground() : 该方法包含需要在后台执行的代码。在这种方法中,我们可以发送多个结果 通过 publishProgress() 方法到 UI 线程的次数。通知该 后台处理已经完成我们只需要使用 返回语句

    onPreExecute() :此方法包含在后台处理开始之前执行的代码

    onPostExecute() : 该方法在doInBackground 方法完成处理后被调用。 doInBackground 的结果被传递给 这个方法

    onProgressUpdate() : 该方法从 doInBackground 方法接收进度更新,通过 publishProgress 方法发布, 而且这个方法可以使用这个进度更新来更新UI线程

    请参考此link 了解异步任务的原理

    【讨论】:

    • 谢谢它的工作,但我必须去另一个活动,而不是回到主要活动,让它显示新闻我该如何解决这个问题
    • 添加 adapter.notifyItemChanged(moviemodelList.size());在moviemodelList.add(newsmodel)之后;在doInBackground
    【解决方案2】:

    在获得第一个 url 响应后调用第二个 new jsontask().execute("url2"); 然后调用第三个、第四个等等。

    制作一个通用代码以一次又一次地重用它。

    试试这个链接:http://www.devexchanges.info/2015/03/android-listview-dynamically-load-more.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-23
      相关资源
      最近更新 更多