android - 如何在底部滑动后继续阅读ListView中的内容?

标签 android listview android-listview swipe swiperefreshlayout

我使用了 here 中的 SwipyRefreshLayout| ,因为我需要在 ListView 结束时更新数据并在下载后继续阅读内容。但我有一些问题 - 在应用程序的底部滑动焦点转到 ListView 顶部之后。我在 ListView 中有无穷无尽的帖子,所以我需要下载后继续阅读。我应该为此改变什么?你能帮帮我吗?

这是应用程序的代码

    public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, SwipyRefreshLayout.OnRefreshListener {

    private static final String TAG = "MainActivity";
    private static final int LAYOUT = R.layout.activity_main;
    private static final String URL = "http://killpls.me";
    private static final String URL_MODERATION = "http://killpls.me/moderation/";

    private Toolbar toolbar;
    private DrawerLayout drawerLayout;
    private NavigationView navigationView;
    private ActionBarDrawerToggle toggle;
    private FloatingActionButton fab;
    private ProgressDialog progressDialog;
    private SwipyRefreshLayout mSwipyRefreshLayout;

    private NewPostsAsyncTask newPostsAsyncTask;
    private ModerationAsyncTask moderationAsyncTask;

    public Elements content;
    public ArrayList<String> titleList = new ArrayList<String>();
    private ArrayAdapter<String> adapter;
    private ListView listView;

    private int navigationDrawerItemId;
    private boolean isRefreshed = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(LAYOUT);

        initToolbar();
        initNavigationView();
        initActionBarDrawerToggle(); // Добавляет возможность открыть NavigationDrawer через значок
        initFloatingActionButton();
        initSwipeRefreshLayout();

        listView = (ListView) findViewById(R.id.listView);
    }

    private void initToolbar() {
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                return false;
            }
        });
    }

    private void initNavigationView() {
        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);
    }

    private void initActionBarDrawerToggle() {
        toggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawerLayout.setDrawerListener(toggle);
        toggle.syncState();
    }

    private void initFloatingActionButton() {
        fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

    private void initSwipeRefreshLayout() {
        mSwipyRefreshLayout = (SwipyRefreshLayout) findViewById(R.id.swipyrefreshlayout);
        mSwipyRefreshLayout.setOnRefreshListener(this);
        mSwipyRefreshLayout.setColorSchemeResources(android.R.color.holo_blue_bright,
                android.R.color.holo_green_light,
                android.R.color.holo_orange_light,
                android.R.color.holo_red_light);
    }

    @Override
    public void onBackPressed() {
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        navigationDrawerItemId = item.getItemId();

        if (navigationDrawerItemId == R.id.new_posts) {
            Log.i(TAG, "Выбрано раздел \"Новые\" в Navigation Drawer");
            adapter = new ArrayAdapter<String>(this, R.layout.list_item, R.id.item, titleList);
            isRefreshed = false;
            newPostsAsyncTask = new NewPostsAsyncTask();
            newPostsAsyncTask.execute();
            if (!adapter.isEmpty()) adapter.clear();
        } else if (navigationDrawerItemId == R.id.moderation) {
            Log.i(TAG, "Выбрано раздел \"Модерация\" в Navigation Drawer");
            adapter = new ArrayAdapter<String>(this, R.layout.list_item, R.id.item, titleList);
            isRefreshed = false;
            moderationAsyncTask = new ModerationAsyncTask();
            moderationAsyncTask.execute();
            if (!adapter.isEmpty()) adapter.clear();
        } else if (navigationDrawerItemId == R.id.tell_story) {
            Log.i(TAG, "Выбрано раздел \"Рассказать историю\" в Navigation Drawer");
            adapter = new ArrayAdapter<String>(this, R.layout.list_item, R.id.item, titleList);
            if (!adapter.isEmpty()) adapter.clear();
        } else if (navigationDrawerItemId == R.id.most_terrible_stories) {
            Log.i(TAG, "Выбрано раздел \"Самые страшные\" в Navigation Drawer");
            adapter = new ArrayAdapter<String>(this, R.layout.list_item, R.id.item, titleList);
            if (!adapter.isEmpty()) adapter.clear();
        } else if (navigationDrawerItemId == R.id.random_story) {
            Log.i(TAG, "Выбрано раздел \"Случайная\" в Navigation Drawer");
            adapter = new ArrayAdapter<String>(this, R.layout.list_item, R.id.item, titleList);
            if (!adapter.isEmpty()) adapter.clear();
        } else if (navigationDrawerItemId == R.id.happy_end) {
            Log.i(TAG, "Выбрано раздел \"Happy end\" в Navigation Drawer");
            adapter = new ArrayAdapter<String>(this, R.layout.list_item, R.id.item, titleList);
            if (!adapter.isEmpty()) adapter.clear();
        } else if (navigationDrawerItemId == R.id.about_project) {
            Log.i(TAG, "Выбрано раздел \"О проекте\" в Navigation Drawer");
            adapter = new ArrayAdapter<String>(this, R.layout.list_item, R.id.item, titleList);
            if (!adapter.isEmpty()) adapter.clear();
        } else if (navigationDrawerItemId == R.id.help_all) {
            Log.i(TAG, "Выбрано раздел \"Хочу помочь всем\" в Navigation Drawer");
            adapter = new ArrayAdapter<String>(this, R.layout.list_item, R.id.item, titleList);
            if (!adapter.isEmpty()) adapter.clear();
        }

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }

    @Override
    public void onRefresh(SwipyRefreshLayoutDirection direction) {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                if (navigationDrawerItemId == R.id.new_posts) {
                    Log.i(TAG, "Обновленно раздел \"Новые\" в Navigation Drawer");
                    isRefreshed = true;
                    newPostsAsyncTask = new NewPostsAsyncTask();
                    newPostsAsyncTask.execute();
                } else if (navigationDrawerItemId == R.id.moderation) {
                    Log.i(TAG, "Обновленно раздел \"Модерация\" в Navigation Drawer");
                    isRefreshed = true;
                    moderationAsyncTask = new ModerationAsyncTask();
                    moderationAsyncTask.execute();
                } else if (navigationDrawerItemId == R.id.tell_story) {
                    Log.i(TAG, "Обновленно раздел \"Рассказать историю\" в Navigation Drawer");
                } else if (navigationDrawerItemId == R.id.most_terrible_stories) {
                    Log.i(TAG, "Обновленно раздел \"Самые страшные\" в Navigation Drawer");
                } else if (navigationDrawerItemId == R.id.random_story) {
                    Log.i(TAG, "Обновленно раздел \"Случайная\" в Navigation Drawer");
                } else if (navigationDrawerItemId == R.id.happy_end) {
                    Log.i(TAG, "Обновленно раздел \"Happy end\" в Navigation Drawer");
                } else if (navigationDrawerItemId == R.id.about_project) {
                    Log.i(TAG, "Обновленно раздел \"О проекте\" в Navigation Drawer");
                } else if (navigationDrawerItemId == R.id.help_all) {
                    Log.i(TAG, "Обновленно раздел \"Хочу помочь всем\" в Navigation Drawer");
                } else {
                    Log.i(TAG, "Попытка обновить главную страницу");
                }

                // Когда обновление закончено, вызываем метод setRefreshing(boolean) и передаем ему false.
                mSwipyRefreshLayout.setRefreshing(false);
            }
        }, 4000);
    }

    class NewPostsAsyncTask extends AsyncTask<String, Void, String> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            if (!isRefreshed) {
                progressDialog = new ProgressDialog(MainActivity.this);
                progressDialog.setTitle("Новые");
                progressDialog.setMessage("Загрузка...");
                progressDialog.setIndeterminate(false);
                progressDialog.show();
            }
        }

        @Override
        protected String doInBackground(String... params) {
            Document doc;
            try {
                doc = Jsoup.connect(URL).get(); // Считываем заголовок страницы

                // Получение номера страницы селектором и преобразование его в число
                Elements pageSpan = doc.select("div.paginator > span:first-child");
                int pageCount = Integer.parseInt(pageSpan.first().text());
                // Стоит еще проверить, что элементы нашлись, вызовом !pageSpan.isEmpty(),
                // first() для пустого списка возвращает null.

                for (int i = pageCount; i > 0; i--) {
                    String pageCountString = Integer.toString(i);
                    doc = Jsoup.connect("http://killpls.me/page/" + pageCountString).get();
                    parseDocument(doc);
                    if (i == 1697) {
                        break; // Ограничение до 1697 страницы, чтобы не лагало. Надо исправить.
                    }
                }

            } catch (IOException e) {
                e.printStackTrace(); // Если не получилось считать
            }
            return null;
        }

        public void parseDocument(Document doc) {

            // Парсит посты на странице
            content = doc.select("[style=margin:0.5em 0;line-height:1.785em]");

            for (Element contents : content) {
                if (!contents.text().contains("18+")) {
                    // Выводит только посты без ссылки на 18+
                    titleList.add(contents.text());
                }
            }
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            listView.setAdapter(adapter);
            if (navigationDrawerItemId == R.id.new_posts) progressDialog.dismiss();
        }
    }

    class ModerationAsyncTask extends AsyncTask<String, Void, String> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            if (!isRefreshed) {
                progressDialog = new ProgressDialog(MainActivity.this);
                progressDialog.setTitle("Модерация");
                progressDialog.setMessage("Загрузка...");
                progressDialog.setIndeterminate(false);
                progressDialog.show();
            }
        }

        @Override
        protected String doInBackground(String... params) {
            Document doc;
            try {
                doc = Jsoup.connect(URL_MODERATION).get();
                parseDocument(doc);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        public void parseDocument(Document doc) {

            // Парсит посты на странице
            content = doc.select("[style=margin:0.5em 0;line-height:1.785em]");

            for (Element contents : content) {
                titleList.add(contents.text());
            }
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            listView.setAdapter(adapter);
            if (navigationDrawerItemId == R.id.moderation) progressDialog.dismiss();
        }
    }
}

最佳答案

这里的代码:

ModerationAsyncTask

protected void onPostExecute(String s) {
    super.onPostExecute(s);
    listView.setAdapter(adapter);
    if (navigationDrawerItemId == R.id.new_posts)
    progressDialog.dismiss();
}

AsyncTask 执行后,您重置 listView 的适配器,这将使 listView 的所有日期都无效。这对于 listView 来说完全是一个新的数据集,无论它真正包含什么。由于适配器更改,项目的所有信息(如位置)都丢失了。

当适配器的日期更改时考虑使用 ArraryAdater.notifyDataSetChanged()。

关于android - 如何在底部滑动后继续阅读ListView中的内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34624360/

相关文章:

.net - 有没有一种简单的方法可以通过 DataTable 填充 ListView?

java - 如何在 Android 中使用 Jackson 从 JSONArray url 获取 java 对象

java - Android:添加到列表中的最后一个对象会覆盖所有其他对象

java - Android 自定义适配器和 asyncTask 不更新 listView

android - 如何在android中设计类似布局

android - 如何使用 Picasso 设置 @BindingAdapter?

android - 尽管有 ViewHolder、LazyLoader 和简单的布局,Listview 仍然卡顿

java - 按钮点击无 react

Java Goose 不在 Android 上提取内容

android - Kivy:从主应用程序停止 android 服务