LoginSignup
14
15

More than 5 years have passed since last update.

[Android][初心者向け?]非同期でDBからデータ取得しつつ末尾での自動読み込み+最適な位置への自動スクロール

Last updated at Posted at 2015-07-26

初心者趣味プログラマーなのでツッコミどころ満載だと思うので
容赦ないツッコミよろしくお願いします

わかりにくい。
ここは良くない等の指摘は大歓迎です。
ガンガンコメントください。

※わかりにくいと思うので説明しておきます
最適な位置への自動スクロールとは、
末尾での自動読み込み処理後、一番上まで戻ってしまうとユーザービリティを損ねるので
自動読み込みで追加した要素の少し上(今まで見ていたところ)まで
自動でスクロールするということです。

OnScrollListenerをimplementsしてグローバル変数を設定

public class List extends AppCompatActivity implements AbsListView.OnScrollListener {
//ここでグローバル変数の設定します
    myListView = (ListView) findViewById(R.id.myListView);
    int position;
    int y;
    private AsyncTask<Void, Void, String> mTask;

最後までスクロールされたかどうかの判定

AbsListView.OnScrollListenerのonScrollを利用
・表示されている先頭のインデックス(firstVisibleItem)、
・表示されているリストの数(visibleItemCount)
・リストのトータル数(totalItemCount)
が引数として渡ってくるので、
firstVisibleItem + visibleItemCount = totalItemCount
になる時、最後までスクロールされたと判定出来る。

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
                         int visibleItemCount, int totalItemCount) {
    // 最後までスクロールされたかどうかの判定  
        if (totalItemCount == firstVisibleItem + visibleItemCount) {
    // ここに次の数件を取得して表示する処理を書けばいい  
    //ListView.getFirstVisiblePosition()を実行すると、現在表示しているリストビューの一番上にあるアイテムのポジションを取得できます。
            position = myListView.getFirstVisiblePosition();
            y = myListView.getChildAt(0).getTop();
            additionalReading();
        }
    }

書かないとエラーになるonScrollStateChanged

onScrollStateChangedメソッドはスクロールの状態を検知するためのメソッドです。
使う必要がないと思ったため省きたかったのですが、Overrideが必須だったようなので、
つけくわえました。

これを使えばもっとスマートに自動読み込み、自動スクロール実装できるんでしょうか?
というよりもっと気になるのは空でいいものなのか...

    @Override
    public void onScrollStateChanged(AbsListView arg0, int arg1) {
    }

既に読み込み処理が開始していないのかのチェック

"最後までスクロールされたかどうかの判定" で呼び出した関数です。


    private void additionalReading() {
    // 既に読み込み中ならスキップ
    /*
        AsyncTaskがexecute(実行)していない
            そして
        AsyncTaskのステータスがRUNNINGでない。
        ときスキップする         
    */
    if (mTask != null && mTask.getStatus() == AsyncTask.Status.RUNNING) {
            return;
        }
        mTask = new MyAsyncTask().execute();
    }

非同期で取得し、ようやくViewにセット...



        public class MyAsyncTask extends AsyncTask<Void, Void, String> {
            public MyAsyncTask() {

            }

            @Override
            protected String doInBackground(Void... params) {
            //doInBackgaroudのreturnはonPostExecuetの引数に渡ります。
            //ここで僕は通信して外部サーバーから情報を取得し、resultにViewにセットしたい値を代入しておきます。
            //確か、Viewの操作はdoInBackgroundからではできません。         
            return result;
            }

            @Override
            protected void onPostExecute(String result) {
            //表示位置の指定はListView.setSelection()メソッドで位置を指定するだけで可能です。
            //指定した位置までスクロールします。
            //position は先頭に表示したい行のインデックス。            
             //y は指定したピクセル分、下にずらします。
                myListView.setSelectionFromTop(position, y);
            }
     }


※大した内容でなくすいません
ただWebにまとまった情報がなかったので
いずれ訳に立つ人がでてくるかな〜と思って
投稿してみました。
これから初心者脱却に向けて頑張りますー

少しでもここは直すべきと思うことあれば...

もし時間あって気が向いた時にでも
コメントで指摘してもらえたら嬉しいです。

14
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
15