Android PullToRefresh

2013-04-16T00:00:00+00:00 Android Java

※以下の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を指定すると上部の引っ張ってリロードするビューが消えて作用しなくなる模様。ソース追えて無くて、これでやるのが正解なのかは謎ですけど...

ActionBarCompat