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

More than 1 year has passed since last update.

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

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

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

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にまとまった情報がなかったので
いずれ訳に立つ人がでてくるかな〜と思って
投稿してみました。
これから初心者脱却に向けて頑張りますー

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

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