2014年3月17日月曜日

ListView -02 (リストの追加、スクロールの一番下を検知、スクロールが一番下になったら追加,行の高さの固定)

もっと自由にListViewを使う

わりと使うことが多いリストビュー。

わりと小さい機能だけど、たまに欲しくなる機能をまとめてみました。

ListViewはじめての方はこちらのページを確認してね。
http://androidgamepark.blogspot.jp/2013/09/listview-baseadapter.html


今日紹介するのはこちら、

1.リストの区切りの線を入れる。線の色を変える
2.リストの削除
3.一番下まで、スクロールしたら、リストに追加する
4.行の高さを固定したい

この3つの機能を紹介します。

1.の線の色に関しては、

ListView oListView   = new ListView( getApplicationContext() );
//行間の線色を指定
oListView.setDivider( new ColorDrawable( Color.RED ) );
//線の太さ
oListView.setDividerHeight( 2 );

setDividerを使えばOKです。色の指定はColorDrawableを使用して下さい。
また、線の太さを指定しないと線が出てないので、注意!!

2.のリストの削除に関しては、
ListAdapterの中身を削除して、
notifyDataSetChanged();
を呼べば大丈夫です。

3.も
ListAdapterの中身を追加して、
notifyDataSetChanged();
を呼べば大丈夫です。

ただ、一番下まで、スクロールしたかを拾うのに

ListView.setOnScrollListener( this );

をimplementsする必要があります。

4.はリストの高さを指定するだけです。

詳しくはサンプルソースを見てください。

サンプルソースは3ファイルから、構成されます。
MainActivity
ListAdapter
Adapterの中身クラス
の3ファイルです。

◇サンプルソース
■MainWebView

package com.example.ListView;

import android.app.Activity;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;


public class MainActivity extends Activity implements OnItemClickListener, OnScrollListener, OnItemLongClickListener{

    //レイアウトパラメータ
    private final int MP = ViewGroup.LayoutParams.MATCH_PARENT;
    //リスト情報を格納した配列
    private ListAdapter oAdp;
    //行の挿入が可能かのフラグ
    private boolean bChk = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //レイアウトの生成
        LinearLayout oLayout = new LinearLayout( this );
        //レイアウトを画面に反映
        setContentView(oLayout);

        //リストビューの生成
        ListView oListView   = new ListView( this );
        //レイアウトパラムの設定
        oListView.setLayoutParams( new LayoutParams( MP,MP ) );
        //行間の線色を指定
        oListView.setDivider( new ColorDrawable( Color.RED ) );
        //線の太さ
        oListView.setDividerHeight( 2 );
        //リストをクリックした時の処理を設定
        oListView.setOnItemClickListener( this );
        //リストをスクロールした時の処理を設定
        oListView.setOnScrollListener( this );
        //リストを長押しした時の処理を設定
        oListView.setOnItemLongClickListener( this );

        //リストビューに入れるアイテムAdapterを生成
        oAdp = new ListAdapter( getApplicationContext() );
        //Adapterにアイテムを追加
        Add_DataList();
        //Adapteの中身を更新
        oAdp.notifyDataSetChanged();

        //リストビューにアイテムadapterを設定
        oListView.setAdapter( oAdp );
        //リストをレイアウトに追加
        oLayout.addView( oListView );
    }

    //アダプターにアイテムを追加
    private void Add_DataList(){
        for (int i = 0; i < 13; i ++){
            //配列にタイトルと画像を格納
            if ( i == 12 ){
           oAdp.Set_Datalist(new ListItem(String.valueOf("番号:" + i), "むかしむかしあるところにおじいさんとおばあさんがいました。おばあさんはかわにせんたくにおじいさんはやまにしばかりにいってました。FINISH!!", R.drawable.ic_launcher));
            }else{
           oAdp.Set_Datalist(new ListItem(String.valueOf("番号:" + i), "Hello, Goodbye, Hello Goodbye", R.drawable.ic_launcher));
            }
        }
    }

    @Override
    public void onItemClick(AdapterView parent, View view, int position, long id) {
        //クリックされた項目を取得
        ListItem oList = oAdp.getItem(position);
        //押された時のパラメーターを表示
        Toast.makeText(getApplicationContext(), "押下されたのは:" + oList.Get_Title(), Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onScroll(AbsListView view, int iTop, int iVisible, int iTotal) {
        boolean bLast = iTotal == iTop + iVisible;
        //最終行であるかの確認
        if (bLast && bChk) {
            Add_DataList();
            oAdp.notifyDataSetChanged();
        }
    }


    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        // スクロールの状態を検知する
        switch (scrollState) {
           // スクロールしていない
    case OnScrollListener.SCROLL_STATE_IDLE:
              // スクロール中であることを示すフラグをfalseに
              bChk = false;
              break;
    // スクロール中
          case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
              bChk = true;
            break;
          // はじいたとき
          case OnScrollListener.SCROLL_STATE_FLING:
              break;
        }
    }

    @Override
    public boolean onItemLongClick(AdapterView parent, View view, int positon, long id) {
        //データリストを削除
        oAdp.Del_Datalist(positon);
        //Adapteの中身を更新
        oAdp.notifyDataSetChanged();
        return false;
    }
}


■ListItem
package com.example.ListView;

public class ListItem {


    private String sTitleText;
    private String sDetailText;
    private int    iResource;

    public ListItem(String sTitle, String sDetail, int iRes){
        //文字列を取得
    sTitleText     = sTitle;
        //画像のResIDを取得
        iResource      = iRes;
        //リスト内の詳細について
        sDetailText    = sDetail;
    }

    public String Get_Title(){

        //文字列を返す
        return sTitleText;
    }

    public String Get_Detail(){

        //文字列を返す
        return sDetailText;
    }

    public int Get_Resource(){

        //画像のResIDを返す
        return iResource;
    }
}


■ListAdapter

package com.example.ListView;

import java.util.ArrayList;

import java.util.List;

import android.content.Context;

import android.graphics.Color;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class ListAdapter extends BaseAdapter{

    //コンテキストを取得
    private Context mContext;
    //リスト情報を格納している配列
    private List<ListItem> dataList = new ArrayList<ListItem>();
    //レイアウトパラムの定数
    private final int MP = ViewGroup.LayoutParams.MATCH_PARENT;

    //コンストラクターで生成時に呼ばれる

    public ListAdapter(Context context){
        //生成時のコンストラクターでコンテクストを取得
        mContext = context;
    }

    @Override

    public int getCount() {
        //リストの行数
        return dataList.size();
    }

    @Override

    public ListItem getItem(int posion) {
        //配列の中身を返す
        return dataList.get(posion);
    }

    @Override

    public long getItemId(int posion) {
        //現在の配列の場所
        return posion;
    }

    @Override

    public View getView(int position, View view, ViewGroup parent) {

        View v = view;

        if( v == null ){
            //グリットビューの1マス内のレイアウトを作成
            LinearLayout oListLayout = new LinearLayout(mContext);
            //左から右にアイテムを追加
            oListLayout.setOrientation(LinearLayout.HORIZONTAL);

            LinearLayout oTextLayout = new LinearLayout(mContext);

            oTextLayout.setOrientation(LinearLayout.VERTICAL);

            //イメージビューを生成

            ImageView oImage = new ImageView(mContext);
            //テキストビューを生成
            TextView oTitle  = new TextView(mContext);
            TextView oDetail = new TextView(mContext);

            //文字大きさの指定

            oTitle.setTextSize(20);
            oDetail.setTextSize(15);

            //文字の色も指定

            oTitle.setTextColor(Color.BLACK);

            //判別用にタグをつける

            oImage.setTag("CellImage");
            oTitle.setTag("CellTitle");
            oDetail.setTag("CellDetail");

            //テキストレイアウトにビューを追加

            oTextLayout.addView(oTitle);
            oTextLayout.addView(oDetail);
            oTextLayout.setLayoutParams(new LayoutParams(MP, 120));
         
            //グリットビュー用のレイアウトに追加
            oListLayout.addView(oImage);
            oListLayout.addView(oTextLayout);
            v = oListLayout;
        }

        //配列から、アイテムを取得

        ListItem oList = getItem(position);
        if( dataList != null){
            //タグからテキストビューを取得
            TextView title = (TextView) v.findViewWithTag("CellTitle");
            //取得したテキストビューに文字列を設定
            title.setText(oList.Get_Title());

            //タグからテキストビューを取得

            TextView detail = (TextView) v.findViewWithTag("CellDetail");
            //取得したテキストビューに文字列を設定
  detail.setText(oList.Get_Detail());
       
  //タグからイメージビューを取得
            ImageView imag = (ImageView) v.findViewWithTag("CellImage");
            //イメージビューに画像を設定
            imag.setBackgroundResource( oList.Get_Resource() );
        }

        return v;

    }

    //データリストの追加

    public void Set_Datalist(ListItem oList){
        dataList.add(oList);
    }
 
    //データリストの削除
    public void Del_Datalist(int iPos){
        dataList.remove(iPos);
    }
}

■実行結果






こんな感じになります。

一番下までスクロールしたら、12行追加される。
行を長押ししたら、その行が削除される。

タッチイベントを拾って、数字がずれていないことを確認OK

注意点としては

implements OnItemClickListener, OnScrollListener, OnItemLongClickListener

implementsが複数あることを注意して下さい。