Androidプログラミング日記 (仮)  

ListView&改造ListView

あなたは

人目のプログラマーだよ。

Androidプログラミング日記 (仮).

 

 

 

 

最大の難関

いやぁ参りました。画面変更からですが一つ作りたいアプリができて、無理やりでも作成しようとしたらつまづきまして・・・

そして画面変更から手をつけました。次が今回のListViewの改造です。色々なサイト様や書籍を見ても、ほとんど違う書き方&新しい分野なので理解もできず;;しかし何度も書き換えたり、試したりして一つのサイト様にいきつき、理解できました。

愚鈍人様マジ神デス。感謝!

てことで、基本のListViewと改造したListViewを紹介します。全然違うものなのできをつけましょう。

 

 

使用画像

Layoutというものがあります。これは画面に何かをどういうふうに配置させるかというものです。ゲームなどの場合はViewというものを使って画像を配置させたりしますね。しかしそういう指定がない場合、”R.layout.main.xml”という感じでActivityファイルの最後のほうに設定されて、main.xmlというファイル内容のレイアウトで配置されます。”○○View”と書かれているものが順番に配置されます。別にmain.xmlでなくても、自作もできます。内容も変えることができます。直接layoutを作成することができたりしますが、今回はmain.xmlなどのxmlファイルを使用してレイアウトする方法でいきます。

今回やりたいことはListViewの勉強で、まず基本のListViewを勉強してそれから改造されたListViewを勉強しました。

まずは基本から

ファイル名「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" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />
    <ListView
        android:id="@+id/listView1"
   		android:layout_height="wrap_content"
    	android:layout_width="fill_parent"
   		android:layout_weight="1"></ListView>

</LinearLayout>
						

ファイル名「ListViewTestActivity.java」

package and.roid.listviewtest;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class ListViewTestActivity extends Activity{
	//ListView使用準備
	private ListView listView;
	//リストビューに表示させるアイテム用変数
	private List<String> strs = new ArrayList<String>();
	//データをリストビューに表示させるための変数
	private ArrayAdapter<String> adapter;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        //メンドイので一気に同じ20アイテム登録
        for(int i=0;i<20;i++){
        	strs.add((i+1)+":"+"アンドロイドロボ");
        }

        //ListView使用
        listView = (ListView)findViewById(R.id.listView1);

        //アダプターに表示させたいアイテムを登録
        adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,strs);

        //ListViewにアダプターを渡し登録
        listView.setAdapter(adapter);
    }

}
 
 

まずmain.xmlにListVIewを使用するために設定しました。

ここでListViewの仕組みとして、ListViewにデータの固まりを渡すと画像のようになり、画面からはみでてもスクロールして観覧できるよう配置されます。ここで重要なのがデータの固まりを渡すとこですが、普通にわたすのではなく、”Adapter”というものを使用します。

Adapterは種類がいくつかありますが、上記のようなStringオブジェクト一つの固まりやInteger一つなど、一つだけならArrayAdapterがいい感じみたいです。

今回はString型のArrayAdapterを使用しましたので、String型のListを使用しStringを設定しました。そしてAdapterにそのListを設定し、出来上がったAdapterをListViewにいれこみます。

実行すると画像な感じに無事表示できました。

これが基本となるListViewのやり方とわたくしは納得して基本OKと判断し、次の段階にイクノデシタ・・・

 

 

ファイル名「main2.xml」

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="horizontal"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
>
<ImageView
  android:id="@+id/memo_view"
  android:layout_width="50px"
  android:layout_height="50px"
  android:layout_gravity="center_vertical"
/>
<TextView
  android:id="@+id/text_no"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_weight="1"
  android:textSize="20sp"
  android:padding="10dip"
/>
<TextView
  android:id="@+id/text_memo"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_weight="1"
  android:textSize="20sp"
  android:padding="10dip"
/>
</LinearLayout>

ファイル名「ListViewTest2Activity.java」

						package and.roid.listviewtest2;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;

public class ListViewTest2Activity extends Activity {

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

		ListView lv = new ListView(this);
		setContentView(lv);

		//ここでいつも画面にどんなものを表示させるかを決めています
		//今回は別クラスのListAdapterを指定しています
		lv.setAdapter(new ListAdapter(this));
	}
}

ファイル名「ListAdapter.java」

/*
 * このクラスはArrayAdapterでは一つのオブジェクト
 * しか登録できないので、BaseAdapterをextendsさせた
 * クラスで色々設定することでAdapterに複数のオブジェクト
 * を一つの固まりとして設定することができるようになっています
 */
package and.roid.listviewtest2;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class ListAdapter extends BaseAdapter{
	private Context context;
	private List<Memo> list;//memoクラス用
	private String[] str = {"ろぼだす","ロボだよ","ろぼかな","ロボダス","ろぼだった",
			"ロボだったり","ロボなのです","ロボバイ","ロボさ","ロボロボ",
			"ロヴォロヴォ","ロボだよん","ろぼかも"};

	public ListAdapter(Context context) {
		super();
		this.context = context;

		//ここでmemoクラスの内容を設定
		Resources resources = context.getResources();
		Bitmap bimg = BitmapFactory.decodeResource(resources,R.drawable.robos);
		list = new ArrayList<Memo>();
		for(int i=0;i<13;i++){
			Drawable dimg = new BitmapDrawable(
					Bitmap.createBitmap(bimg,i*bimg.getWidth()/13,0,
							bimg.getWidth()/13,bimg.getHeight()));
		list.add(new Memo(dimg,str[i],i+1));

		}
	}

	/*
	 * ここからのメソッドはBaseAdapterをextendsさせると
	 * 自動的に配置されるメソッドです
	 * 内容はサッパリ!なので今後使用するときは
	 * このまま使用しそうです
	 */
	public int getCount() {
		return list.size();
	}

	public Memo getItem(int position) {

		return list.get(position);
	}

	public long getItemId(int position) {
		return position;
	}

	public View getView(int position, View convertView, ViewGroup parent) {
		/*
		 * ここがほぼメインな感じの所ですね
		 * ViewHolderクラスをわざわざ使用しているのは、
		 * リソースの無駄遣い回避のためぽいです。
		 * 愚鈍人さんマジ神
		 * やっている事は、どのレイアウト(main2.xml)を使用して
		 * main2で設定されてるレイアウトにそれぞれmemoクラスの
		 * メンバを設定しています
		 */
		ViewHolder holder;
		Memo memo = (Memo) getItem(position);

		if (convertView == null) {
			LayoutInflater inflater = LayoutInflater.from(context);
			convertView = inflater.inflate(R.layout.main2, null);

			holder = new ViewHolder();
			//main2のレイアウト内容の使用準備
			holder.iv = (ImageView) convertView.findViewById(R.id.memo_view);
			holder.tv1 = (TextView) convertView.findViewById(R.id.text_no);
			holder.tv2 = (TextView) convertView.findViewById(R.id.text_memo);

			convertView.setTag(holder);
		} else {
			holder = (ViewHolder) convertView.getTag();
		}
		//main2にmemo内容設定
		holder.tv1.setText(String.format("%d",memo.getNo()));
		holder.tv2.setText(memo.getMemo());
		holder.iv.setImageDrawable(memo.getImgs());

		return convertView;
	}
}

ファイル名「Memo.java」

package and.roid.listviewtest2;

import android.graphics.drawable.Drawable;

public class Memo {
	private String memo;
	private int no;
	private Drawable img;

	public Memo(Drawable imgs,String memo, int no) {
		img = imgs;
		this.memo = memo;
		this.no = no;
	}

	public Drawable getImgs(){return img;}
	public String getMemo() {return memo;}
	public int getNo() {return no;}
}

ファイル名「ViewHolder.java」

package and.roid.listviewtest2;

import android.widget.ImageView;
import android.widget.TextView;

public class ViewHolder {
	TextView tv1;
	TextView tv2;
	ImageView iv;

}
 
 

改造完了!といいたいとこですが、わたしはコードの半分くらいしか理解できていません;;

上記でやりたかったことは、画像+数字+String値をListViewに並べて表示、しかも画像は縮小。これがやりたかったんです。

たったこれだけのことになん十時間費やしたことか・・・しかし!無事できました。

このコードのキモは何といってもBaseAdapterと独自設定のmain2.xmlです。今回ListViewはxmlファイルで設定はしておらず、BaseAdapterをextendsしたクラスを呼び出すことでその中で直接ListViewを設定しています。改造したListViewに必要なものは、ListView、ListViewの1行に表示させたいレイアウト(今回はmain2.xml)そしてBaseAdapterです。

BaseAdapterをextendsさせたクラス内で複数の違う種類のViewレイアウトを設定してmain2.xmlのそれぞれの内容を設定しています。

なんていうか、出来なかったことが出来るようになった喜びはものすごい充実感を得ることができますよね。

みんなもがんばっ!

 

 

 

Androidプログラミング日記 (仮) | サイトマップ | 個人情報保護方針 | 応援メールテヘペロ | ©2012 Japan  相互リンク大募集中です