Androidプログラミングブログ

Androidプログラミングを勉強していく中でわかったことをメモする

【Androidプログラミング入門 #008】ListView(リストビュ)ーを最後まで表示したら追加読込する

はじめに

下記記事でListViewにデータを表示しました。 android.swift-studying.com

今回はListView(リストビュ)ーを最後まで表示したら追加読込します。
インターネットからデータを取ってくるときに全部のデータを
一度でまとめてとってきたら時間がかかってしまいます。

1. プロジェクト作成

SampleListViewUpdateという名前でプロジェクトを作成しました。

f:id:fjswkun:20151024165825p:plain

f:id:fjswkun:20151024165837p:plain

f:id:fjswkun:20151024165847p:plain

f:id:fjswkun:20151024165857p:plain

2. 画面レイアウトの作成

content_main.xmlを開き、プロジェクト作成時に
自動追加されるTextViewを削除し、ListViewを追加します。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto" 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"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:showIn="@layout/activity_main" tools:context=".MainActivity">

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

3. ListViewに簡単な文字列を表示

MainActivity.javaを開き、編集します。 まずはListViewに10個だけ行を表示します。

package com.swift_studying.samplelistviewupdate;

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class MainActivity extends AppCompatActivity {
    private static final int MAX_LIMIT = 50;
    private ArrayAdapter<String> adapter;
    private ListView listView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        listView = (ListView)findViewById(R.id.listView);
        adapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1);
        addAdapter();
        listView.setAdapter(adapter);
    }

    @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);
    }

    private void addAdapter(){
        for (int i=0; i<10; i++){
            adapter.add("item" + (adapter.getCount() + 1));
        }
        listView.invalidateViews();
    }
}

4. 追加読み込み処理の作成

ListViewの最後の行を表示したら、追加読込するようにします。

package com.swift_studying.samplelistviewupdate;

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.ProgressBar;
import android.widget.ListView;

public class MainActivity extends AppCompatActivity {
    private static final int MAX_LIMIT = 50;
    private ProgressBar progressBar;
    private ArrayAdapter<String> adapter;
    private ListView listView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        listView = (ListView)findViewById(R.id.listView);
        progressBar = new ProgressBar(this);
        adapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1);
        addAdapter();

        listView.addFooterView(progressBar);
        listView.setAdapter(adapter);

        listView.setOnScrollListener(new AbsListView.OnScrollListener() {
            boolean isLoading = false;
            boolean isAllLoaded = false;

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                // 処理の必要なし
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                if (isLoading){
                    return;
                }

                if (isAllLoaded){
                    return;
                }

                if ((totalItemCount  - visibleItemCount) == firstVisibleItem){
                    isLoading = true;

                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            try{
                                Thread.sleep(3000);
                            }
                            catch (InterruptedException exception){
                                // 処理なし
                            }

                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    addAdapter();
                                    if (adapter.getCount() >= MAX_LIMIT){
                                        listView.removeFooterView(progressBar);
                                        isAllLoaded = true;
                                    }
                                }
                            });
                            isLoading = false;
                        }
                    }).start();

                }
            }
        });
    }

    @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);
    }

    private void addAdapter(){
        for (int i=0; i<10; i++){
            adapter.add("item" + (adapter.getCount() + 1));
        }
        listView.invalidateViews();
    }
}

5. 実行

実行します。

f:id:fjswkun:20151024171536p:plain

f:id:fjswkun:20151024171544p:plain

f:id:fjswkun:20151024171551p:plain

うまく実行できなかった方はこちらからサンプルをダウンロード。
SampleListViewUpdate.zip - Google ドライブ

参考情報

humitomotti.hateblo.jp

Androidアプリ開発逆引きレシピ (PROGRAMMER’S RECiPE)

Androidアプリ開発逆引きレシピ (PROGRAMMER’S RECiPE)

開発用デバイス

Androidの勉強をはじめた人は知っているようにエミュレーターはちょー遅い。
開発用に安いAndroidを買えば、勉強がはかどります!
iPhoneと比較すると安いので買ったほうがいいと思います。

おすすめデバイス

勉強用に使うだけなので価格が高い最新デバイスは必要ないと思います。
最新のデバイスは一人前のAndroidプログラマーになったら購入を検討しましょう。

nexus5 16GBASUS Nexus7 ( 2013 ) TABLET

その他に探すなら↓から。
Android nexus5を勉強用に購入