end0tknr's kipple - 新web写経開発

http://d.hatena.ne.jp/end0tknr/ から移転します

ListViewのカスタマイズと要素(行)の追加・削除

ポイントは、

  • レイアウトxmlによる独自レイアウト
  • BaseAdapter継承のアダプタクラス
  • android:onClick="〜" によるイベント登録

かな?

activity_main.xml

<?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" >
    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" >
    </ListView>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >
        <Button
            android:id="@+id/btn_add"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onClickAddItemBtn"
            android:text="ADD ITEM" />
        <Button
            android:id="@+id/btn_del"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onClickDelItemBtn"
            android:text="DEL ITEM" />
    </LinearLayout>

</LinearLayout>

list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/list_item"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

<TextView
    android:id="@+id/text_view1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />
<TextView
    android:id="@+id/text_view2"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>
</LinearLayout>

MainActivity.java

package com.example.listview;

import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

    ListView listView;
    BookAdapter adapter;
    static List<Book> dataList = new ArrayList<Book>();    
        
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        adapter = new BookAdapter();
        listView = (ListView)findViewById(R.id.listView1);
        listView.setAdapter(adapter);
        
        listView.setOnItemClickListener( new OnListItemClick() );
    }
    
    public void onClickAddItemBtn(View v) {
        dataList.add(
            new Book("TEXT_1111","TEXT_2222"));
        adapter.notifyDataSetChanged(); //このmethodにより再描画
    }
    public void onClickDelItemBtn(View v) {
        int delPos = dataList.size()-1;
        if (delPos < 0) return;
        dataList.remove(delPos);
        adapter.notifyDataSetChanged(); //このmethodにより再描画
    }

    // http://android.keicode.com/basics/ui-listview-customize.php
    private class BookAdapter extends BaseAdapter {
        // ??? なぜ、classなのに、コンスタントラクタが不要なの?
        public int getCount() {    return dataList.size();    }
        public Object getItem(int position) { return dataList.get(position);}
        public long getItemId(int position) { return position; }
        
        public View getView(int position, View convertView,ViewGroup parent) {
            
            TextView textView1;
            TextView textView2;
            View v = convertView;
            
            if(v==null){
                LayoutInflater inflater = 
                        (LayoutInflater)
                        getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                v = inflater.inflate(R.layout.list_item, null);
            }
            Book book = (Book)getItem(position);
            if(book != null){
                textView1 = (TextView) v.findViewById(R.id.text_view1);
                textView2 = (TextView) v.findViewById(R.id.text_view2);
                textView1.setText(book.text1);
                textView2.setText(book.text2);
            }
            return v;
        }
    }
    
    class Book {
        String text1;
        String text2;
        
        Book(String a_text1, String a_text2){
            text1 = a_text1;
            text2 = a_text2;
        }
        public String getText1() { return text1; }
        public String getText2() { return text2; }
    }
    
    // イベントクラスの定義
    // http://d.hatena.ne.jp/jitsu102/20091124/1259032137
    // http://ichitcltk.hustle.ne.jp/gudon/modules/pico_rd/index.php?content_id=69
    class OnListItemClick implements OnItemClickListener {

        public void onItemClick(
                AdapterView<?> parent,
                View view,  //ListView
                int pos,
                long id) {
            Book item = (Book) listView.getItemAtPosition(pos);
            
            String[] msgStrs = 
                {"NO."+ pos + " was clicked.", item.getText1()};
            
            Toast.makeText(getApplicationContext(),
                    joinStrs("\n",msgStrs),
                    Toast.LENGTH_SHORT).show();
        }
    }
    //文字列連結 javascriptのjoin()の代替
    String joinStrs(String delimiter, String[] orgStrs){
        String retStr = "";
        
        if(orgStrs.length == 0) return retStr;
        
        retStr = orgStrs[0];
        for (int i=1; i<orgStrs.length; i++){
            retStr += (delimiter+orgStrs[i]);
        }
        return retStr;
    }
    
}