SwipeRefreshLayout

2014-03-30T00:00:00+00:00 Android Java

参考: [Android] Support Library に追加された SwipeRefreshLayout - @adakoda

上記参考によるとAndorid Support v4 packageにSwipeRefreshLayoutっていうのが追加された模様。んまぁ見る限りだとAndroid PullToRefreshとActionBar PullToRefreshを組み合わせたのっぽいような感じもするんですが

という事で使ってみた。ちなみに/path/to/android_sdk/extras/android/support/samples/Support4Demosにサンプルが入ってる

プロジェクトを作る

んまぁ今時ならAndroid Studio(+gradle-android-toolkit)辺りを使うのが結構モダンなのではっていう所なので、それ向けな構造を作るだけ

├── app
│   ├── build.gradle
│   ├── libs
│   │   └── android-support-v4.jar
│   └── src
│       └── main
│           ├── AndroidManifest.xml (ただのActivity参照だけなので省略する)
│           ├── java
│           │   └── sample
│           │       └── test
│           │           ├── MainActivity.java
│           │           └── MainListFragment.java
│           └── res
│               ├── drawable系は省略
│               ├── layout
│               │   ├── activity_main.xml
│               │   └── list_fragment.xml
│               └── values
│                   ├── colors.xml
│                   └── strings.xml (app_nameしかないので省略)
├── build.gradle (特に特記する事無いので省略)
└── settings.gradle (include ":app"だけ)

gradleとかならandroid-support-v4.jarは"com.google.android:support-v4"な参照をcompileスコープに突っ込めば良いんだけど、これ更新されてない模様なのでそれでやるとSwipeRefreshLayoutが参照できない。なのでlibsディレクトリに突っ込んどいてapp/build.gradleでクラスパス参照を追加しておく

んまぁ一つづつファイルを書いてく

app/build.gradle

apply plugin: "android"

dependencies {
    compile "com.actionbarsherlock:actionbarsherlock:4.4.0@aar"
    compile files("libs/android-support-v4.jar")
}

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.3"
}

先で書いたようにandroid-support-v4.jarな参照は別途ディレクトリに突っ込んであるのを使う。多分、actionbarsherlockも使ってるのでこれでcom.google.androidなやつも参照されるんじゃねーかって思うけどそこはexcludeとかしておいた方がいいのかなと(やらなくても一応ビルド上問題はない模様)

app/src/main/res/values/colors.xml

ActionBar PullToRefreshのようなプログレスな所の色をカスタマイズしているのでこれを使う

<?xml version="1.0" ?>
<resource>
    <color name="color1">#ff0f9d58</color>
    <color name="color2">#ffdb4437</color>
    <color name="color3">#ff4285f4</color>
    <color name="color4">#fff4b400</color>
</resource>

んまぁ公式なやつのサンプルからコピペで

app/src/main/res/layout/activity_main.xml

上記参考な所ではActivityでやっている模様だけど、今回ListFragment関係上でそういう所をやる。なので<fragment>を書くだけ

<?xml version="1.0" ?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <fragment
        android:name="sample.test.MainListFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</FrameLayout>

app/src/main/res/layout/list_fragment.xml

ListFragmentから使うレイアウトでSwipeRefreshLayoutを使うようにしなきゃならんので

<?xml version="1.0" ?>
<android.support.v4.widget.SwipeRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/swipe_refresh_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:id="@+id/android:list"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</android.support.v4.widget.SwipeRefreshLayout>

app/src/main/java/sample/test/MainActivity.java

package sample.test;

import android.os.Bundle;

import com.actionbarsherlock.app.SherlockFragmentActivity;

public class MainActivity extends SherlockFragmentActivity {
    @Override
    protected void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        setContentView(R.layout.activity_main);
    }
}

app/src/main/java/sample/test/MainListFragment.java

package sample.test;

import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.widget.SwipeRefreshLayout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;

import com.actionbarsherlock.app.SherlockListFragment;

public class MainListFragment extends SherlockListFragment implements SwipeRefreshLayout.OnRefreshListener{


    SwipeRefreshLayout mRefreshLayout;
    ArrayAdapter<String> mAdapter;
    int counter = 0;

    final Handler mHandler = new Handler();
    final Runnable onRefreshCompleteRunnable = new Runnable() {
        @Override
        public void run() {
            mAdapter.add("hoge" + ++counter);
            mRefreshLayout.setRefreshing(false);
        }
    };

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.list_fragment, container, false);

        mRefreshLayout = (SwipeRefreshLayout)view.findViewById(R.id.swipe_refresh_layout);
        mRefreshLayout.setColorScheme(
            R.color.color1,
            R.color.color2,
            R.color.color3,
            R.color.color4
        );
        mRefreshLayout.setOnRefreshListener(this);

        mAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1);
        mAdapter.add("hoge" + ++counter);

        setListAdapter(mAdapter);

        return view;
    }

    @Override
    public void onRefresh() {
        mHandler.removeCallbacks(onRefreshCompleteRunnable);
        mHandler.postDelayed(onRefreshCompleteRunnable, 3000);
    }
}

上記参考なやつをちょいと変えただけなので詳しいことはそちらを参照。んまぁOnRefreshListenerなonRefreshがListViewを上から下に引っ張る際にイベントとして発生するようになる。んでsetRefreshing(false)にすることでプログレス終了な通知を出す。上記参考によるとsetRefreshing(true)を呼び出す事でonRefreshを発生させられる模様

以上、という事で動作画面をキャプチャしてYouTubeにうpしました

{% youtube 6Ee0n6mITyU %}

angular.jsをやってみる (14) - $scope.$apply - angular.jsをやってみる (13) - $sceとngSanitize -