2015年8月29日土曜日

Android開発 Glideを使ってURLから取得した画像をリサイズ表示

https://github.com/bumptech/glide
Androidの画像変換ライブラリのGlideを使って、URLから画像を取得・リサイズして表示します。

画像の非同期ダウンロード、メモリ管理、キャッシュ管理などを裏側でやってくれるので、利用者側がアプリに画像処理を実装するときには、ほとんど手間取らないで済む。という便利なライブラリです。
同じような画像変換ライブラリとしてPicassoというものが有りました(ライブラリ名はこちらの方が格好いい)が、GlideのほうがGoogle寄り、ということでこちらを使ってみました。
(GitHubのREADMEのいちばん下にThis is not an official Google product.という但し書きがありますが。なぜか、プルリクエストをするときにはGoogleのライセンスを承諾する感じです。

こんな感じで使うことができます。

元画像

アプリでURLを読み込んだ画像


実装するにあたって以下の資料が参考になりました。
Android - PicassoとGlideのどちらを使うべきか? - Qiita
http://qiita.com/rejasupotaro/items/ead90beaeaa2a6eace35
Introduction to Glide, Image Loader Library for Android, recommended by Google :: The Cheese Factory
http://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en
When placeholder is replaced by image it keeps with the size of placeholder when using .override(size, size) · Issue #542 · bumptech/glide
https://github.com/bumptech/glide/issues/542

以下、サンプルコードです。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/my_image_view" />
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="test.page.facebook.glidetest" >
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "test.page.facebook.glidetest"
minSdkVersion 15
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
repositories {
mavenCentral()
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.0'
compile 'com.github.bumptech.glide:glide:3.6.0'
}
view raw build.gradle hosted with ❤ by GitHub
package test.page.facebook.glidetest;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ビューを取得
ImageView imageView = (ImageView) findViewById(R.id.my_image_view);
// Glideを設定
Glide.with(this)
// 画像URL
.load("https://40.media.tumblr.com/f49e56a443aecd533fb53d55a1cf1408/tumblr_nsc4fht5ol1u3hv5ko1_1280.jpg")
// リスナー(エラーハンドリングをする)
.listener(new RequestListener<String, GlideDrawable>() {
@Override
public boolean onException(Exception e, String s, Target<GlideDrawable> glideDrawableTarget, boolean b) {
Log.d("Glide", "Error in Glide listener");
if (e != null) {
e.printStackTrace();
}
return false;
}
@Override
public boolean onResourceReady(GlideDrawable glideDrawable, String s, Target<GlideDrawable> glideDrawableTarget, boolean b, boolean b2) {
return false;
}
})
// リサイズ(縦横の最大サイズを指定して、収める)
.override(600, 600)
// ローディング画像
.placeholder(android.R.drawable.ic_menu_call)
// エラー画像
.error(android.R.drawable.ic_delete)
// placeholderを設定した場合に必要 これを書かないとplaceholder画像と同じ大きさにリサイズされる
.dontAnimate()
// imageViewに投入
.into(imageView);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}

2015年8月22日土曜日

Android開発 Facebookページを開く

AndroidからFacebookページを開くようにします。
Facebookアプリが入っているときは、アプリを立ち上げてFacebookページを開き、Facebookアプリがないときにはブラウザで開きます。
いろいろ調べたのですが、古いFacebookアプリの場合のやり方が多く出てきて、そのやり方だと実装できないことがわかりました。そこで、Stack Overflowを見たところ、最近の実装方法を書いている人がいたので参考になりました。

Open facebook page from android app (in facebook version > v11) - Stack Overflow
http://stackoverflow.com/questions/24526882/open-facebook-page-from-android-app-in-facebook-version-v11

以下コードサンプルです。
アクションバーのSettingsをタップすると、Facebookページを開くようにしてみました。
package facebook.page.test;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
OpenFacebookPage();
return true;
}
return super.onOptionsItemSelected(item);
}
protected void OpenFacebookPage(){
// FacebookページのID
String facebookPageID = "dempagumi.inc";
// URL
String facebookUrl = "https://www.facebook.com/" + facebookPageID;
// URLスキーム
String facebookUrlScheme = "fb://page/" + facebookPageID;
try {
// Facebookアプリのバージョンを取得
int versionCode = getPackageManager().getPackageInfo("com.facebook.katana", 0).versionCode;
if (versionCode >= 3002850) {
// Facebook アプリのバージョン 11.0.0.11.23 (3002850) 以上の場合
Uri uri = Uri.parse("fb://facewebmodal/f?href=" + facebookUrl);
startActivity(new Intent(Intent.ACTION_VIEW, uri));
} else {
// Facebook アプリが古い場合
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(facebookUrlScheme)));
}
} catch (PackageManager.NameNotFoundException e) {
// Facebookアプリがインストールされていない場合は、ブラウザで開く
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(facebookUrl)));
}
}
}

2015年8月15日土曜日

Android開発 フリックイベントを取得する


Androidでフリックイベントを取得してみます。

http://developer.android.com/intl/ja/reference/android/view/GestureDetector.html
GestureDetector クラスを使うことで詳細なタッチイベントを処理できるようになります。
そのなかの onFling メソッド(タップしてから移動して指が離れるまでの情報を扱う)を利用します。
public abstract boolean onFling (MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
パラメータは以下のようになります。
e1 The first down motion event that started the fling.
e2 The move motion event that triggered the current onFling.
velocityX The velocity of this fling measured in pixels per second along the x axis.
velocityY The velocity of this fling measured in pixels per second along the y axis.

実装するにあたって、下記の資料が参考になりました。
スワイプのイベントを取得する - ほげほげ(仮)
http://starzero.hatenablog.com/entry/20110414/1302759479
【Android】onFlingでフリック時の移動距離を取得する|俺メモ Web時々アプリ | OREMEMO
http://www.ore-memo.com/564.html
タッチパネルのダブルタップや長押しを検出する « Tech Booster
http://techbooster.jpn.org/andriod/device/3936/#more-3936

以下、サンプルコードです。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
package flick.input.test;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.widget.TextView;
public class MainActivity extends ActionBarActivity {
// テキストビュー
private TextView textView1;
private TextView textView2;
// X軸最低スワイプ距離
private static final int SWIPE_MIN_DISTANCE = 50;
// X軸最低スワイプスピード
private static final int SWIPE_THRESHOLD_VELOCITY = 200;
// Y軸の移動距離 これ以上なら横移動を判定しない
private static final int SWIPE_MAX_OFF_PATH = 250;
// タッチイベントを処理するためのインタフェース
private GestureDetector mGestureDetector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGestureDetector = new GestureDetector(this, mOnGestureListener);
textView1 = (TextView)findViewById(R.id.textView1);
textView2 = (TextView)findViewById(R.id.textView2);
}
// タッチイベント
@Override
public boolean onTouchEvent(MotionEvent event) {
return mGestureDetector.onTouchEvent(event);
}
// タッチイベントのリスナー
private final GestureDetector.SimpleOnGestureListener mOnGestureListener = new GestureDetector.SimpleOnGestureListener() {
// フリックイベント
@Override
public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) {
try {
// 移動距離・スピードを出力
float distance_x = Math.abs((event1.getX() - event2.getX()));
float velocity_x = Math.abs(velocityX);
textView1.setText("横の移動距離:" + distance_x + " 横の移動スピード:" + velocity_x);
// Y軸の移動距離が大きすぎる場合
if (Math.abs(event1.getY() - event2.getY()) > SWIPE_MAX_OFF_PATH) {
textView2.setText("縦の移動距離が大きすぎ");
}
// 開始位置から終了位置の移動距離が指定値より大きい
// X軸の移動速度が指定値より大きい
else if (event1.getX() - event2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
textView2.setText("右から左");
}
// 終了位置から開始位置の移動距離が指定値より大きい
// X軸の移動速度が指定値より大きい
else if (event2.getX() - event1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
textView2.setText("左から右");
}
} catch (Exception e) {
// TODO
}
return false;
}
};
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}

2015年8月8日土曜日

Android開発 Fragment上にYouTube APIを使って動画を再生する

Android開発 FragmentでYouTube APIを使って動画を再生する
YouTube Android Player API | YouTube Android API | Google Developers
https://developers.google.com/youtube/android/player/

YouTubeはWebViewでも再生できるといえば再生はできるのですが、動作がのろかったり画像が荒かったりしたので、調べてみたところ、AndroidアプリにはYouTube APIというものが使えるということがわかりました。
このYouTube APIを使って、YouTubeの動画を再生してみました。
普通にアクティビティでYouTube APIを使うだけならば、他のサイトでもやり方を紹介されているので、より実用性が高いだろうと考えてフラグメント上でYouTubeを再生できるようにしてみます。

アプリをGoogle Developers Consoleに登録して、APIキーを取得

Registering your application | YouTube Android Player API | Google Developers
https://developers.google.com/youtube/android/player/register

YouTube APIを使うためには、Google Developers Consoleにアプリを登録して、APIキーを取得する必要があります。

1)KeyStoreを作成

こちらの資料が参考になりました。
Android Studioでアプリ公開用KeyStoreを作成して本番ビルドする
http://qiita.com/konifar/items/6c6b73deae9085a69666

Key store pathと、Aliasは以下のようにしました。
Key store path: /Users/username/StudioProjects/FragmentDeYoutube/my.keystore
Alias: FragmentDeYoutube

2)SHA1フィンガープリントを出力

ターミナルを開いてコマンドを入力します。
$ keytool -exportcert -alias FragmentDeYoutube -keystore /Users/username/StudioProjects/FragmentDeYoutube/my.keystore -list -v
Enter keystore password:
Alias name: FragmentDeYoutube
〜〜〜
  SHA1: XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
  SHA256: XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:
  Signature algorithm name: SHA1withRSA
  Version: 3
〜〜〜
SHA1の値を使います。

3)Google Developers ConsoleでAPIキーを取得

Registering your application | YouTube Android Player API | Google Developers
https://developers.google.com/youtube/android/player/register?hl=ja

Google Developers Console(https://console.developers.google.com/)は、ちょっとわかりずらいですが、以下の遷移でAPIキー作成できます。
プロジェクトを作成 -> APIと認証 -> API -> YouTube Data API -> APIを有効にする -> 認証情報 -> 公開 API へのアクセス 新しいキーを作成 -> Androidキー
フォームが表示されるので以下のように入力します。
リクエストを受け入れる Android アプリの証明書フィンガープリントとパッケージ名 (省略可)
SHA1 証明書フィンガープリントとパッケージ名(セミコロンで区切る)を 1 行に 1 組ずつ入力してください。 例: 45:B5:E4:6F:36:AD:0A:98:94:B4:02:66:2B:12:17:F2:56:26:A0:E0;com.example
入力が完了すると、APIキーが確認できるようになります。

YouTube Android Player APIライブラリを組み込む

YouTube Android Player API - Download | YouTube Android Player API | Google Developers
https://developers.google.com/youtube/android/player/downloads/?hl=ja

上記ページからファイルをダウンロードして、プロジェクトにライブラリを組み込みます。
YouTubeAndroidPlayerApi-1.2.1.zipを使います。
ダウンロードして、解凍後、libs/YouTubeAndroidPlayerApi.jarをプロジェクトの app/libs/ ディレクトリにコピーします。
$ cp /Users/username/Desktop/YouTubeAndroidPlayerApi-1.2.1/libs/YouTubeAndroidPlayerApi.jar /Users/username/StudioProjects/FragmentDeYoutube/app/libs/
build.gradleを編集。compile files('libs/YouTubeAndroidPlayerApi.jar')を追記します。
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.2.0'
    compile files('libs/YouTubeAndroidPlayerApi.jar')
}
これで、YouTube APIを使ってアプリを作る準備が出来ました。

サンプルコード

YouTubePlayerSupportFragment | YouTube Android API | Google Developers
https://developers.google.com/youtube/android/player/reference/com/google/android/youtube/player/YouTubePlayerSupportFragment?hl=ja

上記のように、YouTubePlayerSupportFragment が class android.support.v4.app.Fragment を継承しているので、v4ライブラリの Fragment の作法にのっとって実装していきます。
以下、サンプルコードです。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:id="@+id/main"
tools:context=".MainActivity">
<TextView android:text="@string/hello_world" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="xxxx.xxxx.xxxx.fragmentdeyoutube" >
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "xxxx.xxxx.xxxx.fragmentdeyoutube"
minSdkVersion 15
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.0'
compile files('libs/YouTubeAndroidPlayerApi.jar')
}
view raw build.gradle hosted with ❤ by GitHub
package xxxx.xxxx.xxxx.fragmentdeyoutube;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// フラグメント起動 (v4の作法で)
YoutubeFragment fragment = new YoutubeFragment();
FragmentManager manager = getSupportFragmentManager();
manager.beginTransaction()
.replace(R.id.main, fragment)
.addToBackStack(null)
.commit();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="@+id/youtube_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:visibility="visible" />
</RelativeLayout>
package xxxx.xxxx.xxxx.fragmentdeyoutube;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.google.android.youtube.player.YouTubeInitializationResult;
import com.google.android.youtube.player.YouTubePlayer;
import com.google.android.youtube.player.YouTubePlayer.OnInitializedListener;
import com.google.android.youtube.player.YouTubePlayer.Provider;
import com.google.android.youtube.player.YouTubePlayerSupportFragment;
public class YoutubeFragment extends Fragment {
// API キー
private static final String API_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
// YouTubeのビデオID
private static String VIDEO_ID = "EGy39OMyHzw";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.you_tube_api, container, false);
// YouTubeフラグメントインスタンスを取得
YouTubePlayerSupportFragment youTubePlayerFragment = YouTubePlayerSupportFragment.newInstance();
// レイアウトにYouTubeフラグメントを追加
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.youtube_layout, youTubePlayerFragment).commit();
// YouTubeフラグメントのプレーヤーを初期化する
youTubePlayerFragment.initialize(API_KEY, new OnInitializedListener() {
// YouTubeプレーヤーの初期化成功
@Override
public void onInitializationSuccess(Provider provider, YouTubePlayer player, boolean wasRestored) {
if (!wasRestored) {
player.setPlayerStyle(YouTubePlayer.PlayerStyle.DEFAULT);
player.loadVideo(VIDEO_ID);
player.play();
}
}
// YouTubeプレーヤーの初期化失敗
@Override
public void onInitializationFailure(Provider provider, YouTubeInitializationResult error) {
// YouTube error
String errorMessage = error.toString();
Toast.makeText(getActivity(), errorMessage, Toast.LENGTH_LONG).show();
Log.d("errorMessage:", errorMessage);
}
});
return rootView;
}
}

2015年8月1日土曜日

Android開発 ListViewでオートロードを実装する


リストビューを下までスクロールしたときに、追加でリストを読み込みをする処理をAndroidで実装します。
Webで言うところの、オートページローディングに似た感じです。Infinite ScrollやjQuery.autopagerで実装する、あのクルクルです。
下記の記事が参考になりました。

visible true: ListViewで最後尾までスクロールしたら自動的に要素を追加読み込みするサンプル
http://visible-true.blogspot.jp/2010/12/listview.html
φ(.. )メモシテオコウ AndroidのListViewで最下部までスクロールしたらデータの更新する場合のめも - φ(・・*)ゞ ウーン カーネルとか弄ったりのメモ
http://kernhack.hatenablog.com/entry/2013/10/25/211637

注意:このサンプルプログラムでは、リストを選択したときの処理を入れていません。もし選択処理を入れるときには以下の記事を参考にしてください。
Android開発 LayoutInflaterを利用してListViewをカスタマイズする
http://takeshiyako.blogspot.com/2015/07/android-layoutinflater-listview.html

以下、サンプルプログラムです。
activity_main.xml
ListViewを追加します。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/listView"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
listview_footer.xml
ListViewのフッターのクルクルです。
MainActivity.java
リストのアダプターを準備して、リストビューに渡すことろまでは普通です。
そのあと、フッターを追加後、スクロールのリスナーの部分を書いています。
package app.sample.listautoscroll;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class MainActivity extends ActionBarActivity {
// 1ページ辺りの項目数
Integer per_page = 20;
// フッターのプログレスバー(クルクル)
View mFooter;
// 予報表示用リストビューのアダプター
ArrayAdapter<String> adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// リスト用のアダプターを準備
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
// アダプターにアイテムを追加します
for (int i = 0; i < per_page; i++) {
adapter.add("リストビュー:" + i);
}
// リストビューへ紐付け
ListView listview = (ListView)findViewById(R.id.listView);
// リストビューにアダプターを設定します
listview.setAdapter(adapter);
// リストビューにフッターを追加
listview.addFooterView(getFooter());
// スクロールのリスナー
listview.setOnScrollListener(new AbsListView.OnScrollListener() {
// スクロール中の処理
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
// 最初とスクロール完了したとき
if ((totalItemCount - visibleItemCount) == firstVisibleItem) {
// アイテムの数 フッター分の1を引く
Integer ItemCount = totalItemCount - 1;
// アダプターにアイテムを追加します
for (int i = ItemCount; i < (ItemCount + per_page); i++) {
adapter.add("リストビュー:" + i);
}
}
}
// ListViewがスクロール中かどうか状態を返すメソッドです
@Override
public void onScrollStateChanged(AbsListView arg0, int arg1) {
}
});
}
private View getFooter() {
if (mFooter == null) {
mFooter = getLayoutInflater().inflate(R.layout.listview_footer, null);
}
return mFooter;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}