Android PullToRefresh
※以下のAndroid-PullToRefreshは現時点でも既にdeprecatedになっており、 https://github.com/chrisbanes/ActionBar-PullToRefresh を使うべきだそうです。既に補足済み
シリーズネタになるかどうかは現状微妙ですが...
PullToRefreshっていう引っ張ってリロードしたりだとか、画面中でデータが末尾に達した場合に次のページなデータを読み込むかだとか、んまぁそういうのを実現したい時に便利なのが https://github.com/chrisbanes/Android-PullToRefresh っていうのがある訳なんですが、まだ使ってみたりとかした事が無いし、ちょっと要件としてそういうのが出てきたので使ってみた
インストール
上記のgithubなAndroid-PullToRefreshプロジェクトからcloneして取ってくる。んでlibraryなディレクトリをEclipseとかでインポートする。で使用するアプリでこのAndroid-PullToRefreshプロジェクトをライブラリとして利用するように設定する
まぁこんだけでオッケー。githubプロジェクトにも書いてるけど、ListViewだとかViewPagerだとかListFragmentにも対応しているらしい。今回はListViewだけ使います
使い方は簡単でcom.handmark.pulltorefresh.library.PullToRefreshListViewをレイアウトにぶち込むかインスタンスを作る(+setContentView)だけ
MainActivity.java
package sample.test;
import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshListView;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class MainActivity extends Activity {
    private PullToRefreshListView mListView;
    private ArrayAdapter<String> mAdapter;
    private int mCount = 0;
    private Handler mHandler = new Handler();
    @Override
    public void onCreate(Bundle saveInstanceState) {
        super.onCreate(saveInstanceState);
        mListView = new PullToRefreshListView(this);
        mListView.setOnRefreshListener(
            new PullToRefreshBase.OnRefreshListener<ListView>() {
                @Override
                public void onRefresh(PullToRefreshBase<ListView> refreshView) {
                    refreshView.getLoadingLayoutProxy().setLastUpdatedLabel("OK");
                    mHandler.postDelayed(
                        new Thread() {
                            @Override
                            public void run() {
                                mAdapter.clear();
                                bindListView();
                                mAdapter.notifyDataSetChanged();
                                mListView.onRefreshComplete();
                            }
                        },
                        1000
                    );
                }
            }
        );
        mListView.setOnLastItemVisibleListener(
            new PullToRefreshBase.OnLastItemVisibleListener() {
                @Override
                public void onLastItemVisible() {
                    ProgressDialog dialog = new ProgressDialog(MainActivity.this);
                    dialog.setMessage("Now loading...");
                    dialog.setOnShowListener(new DialogInterface.OnShowListener() {
                        @Override
                        public void onShow(final DialogInterface dialog) {
                            mHandler.postDelayed(
                                new Thread() {
                                    @Override
                                    public void run() {
                                        bindListView();
                                        dialog.dismiss();
                                    }
                                },
                                2000
                            );
                        }
                    });
                    dialog.show();
                }
            }
        );
        mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
        mListView.setAdapter(mAdapter);
        setContentView(mListView);
    }
    @Override
    public void onStart() {
        super.onStart();
        bindListView();
    }
    private void bindListView() {
        for (int i = 0; i < 10; i++) {
            mCount++;
            mAdapter.add("hoge(" + mCount + ")");
        }
    }
}
bindListViewを呼ぶごとに10件のデータを適当に作ってバインドしちゃうだけ。で
- 引っ張ってリロードするのはsetOnRefreshListener
- 末尾に達した際にロードするのはsetOnLastItemVisibleListener
なリスナーを利用する事で実現する感じ。スクショ的には

っていうような感じで上部を引っ張る事でリロードをする事が出来る。又、末尾に達した際には次のデータを読み込む処理が行われる
余談
引っ張ってロードするやつは要らね、末尾に達した際にロードするやつだけ使いたいって場合は
package sample.test;
import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshListView;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ArrayAdapter;
public class MainActivity extends Activity {
    private PullToRefreshListView mListView;
    private ArrayAdapter<String> mAdapter;
    private int mCount = 0;
    private Handler mHandler = new Handler();
    @Override
    public void onCreate(Bundle saveInstanceState) {
        super.onCreate(saveInstanceState);
        mListView = new PullToRefreshListView(this);
        mListView.setMode(PullToRefreshBase.Mode.MANUAL_REFRESH_ONLY);
        mListView.setOnLastItemVisibleListener(
            new PullToRefreshBase.OnLastItemVisibleListener() {
                @Override
                public void onLastItemVisible() {
                    ProgressDialog dialog = new ProgressDialog(MainActivity.this);
                    dialog.setMessage("Now loading...");
                    dialog.setOnShowListener(new DialogInterface.OnShowListener() {
                        @Override
                        public void onShow(final DialogInterface dialog) {
                            mHandler.postDelayed(
                                new Thread() {
                                    @Override
                                    public void run() {
                                        bindListView();
                                        dialog.dismiss();
                                    }
                                },
                                2000
                            );
                        }
                    });
                    dialog.show();
                }
            }
        );
        mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
        mListView.setAdapter(mAdapter);
        setContentView(mListView);
    }
    @Override
    public void onStart() {
        super.onStart();
        bindListView();
    }
    private void bindListView() {
        for (int i = 0; i < 10; i++) {
            mCount++;
            mAdapter.add("hoge(" + mCount + ")");
        }
    }
}
んな感じでsetModeでMANUAL_REFRESH_ONLYを指定すると上部の引っ張ってリロードするビューが消えて作用しなくなる模様。ソース追えて無くて、これでやるのが正解なのかは謎ですけど...