すべての要素が同じなら普通にListAdapterをセットすればいいんだけど、間になにか要素を挟みたいときとかなかなか苦労する。ListViewの要素を再利用するためにViewHolderとか使ってるとレイアウトが固定されてしまうので。
今回はViewHolderを使いつつある箇所でListViewの要素のレイアウトを切り替えることができたのでメモ。
ビューの切り替え自体はViewFlipperを使う。
リストビューの1つの要素のXMLはこんな感じ(object.xml)
<?xml version="1.0" encoding="utf-8"?>
<ViewFlipper xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/flipper"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<!-- ViewFlipperの初期画面(1ページ目) -->
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:id="@+id/text_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
<!-- ViewFlipperの2ページ目 -->
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<Button
android:id="@+id/button"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
</ViewFlipper>
テスト用のアクティビティのXML(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/listview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</ListView>
</LinearLayout>
そしてサンプルコードはこんな感じ(MainActivity.java)
package com.andcreate.sample.viewflipperlistview;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.ViewFlipper;
public class MainActivity extends Activity{
@Override
public void onCreate(Bundle bundle){
super.onCreate(bundle);
setContentView(R.layout.main);
ListView listView = (ListView)findViewById(R.id.listview);
List<ObjectData> objects = new ArrayList<ObjectData>();
for(int i = 0; i < 50; i++){
if(i % 5 == 0){
objects.add(new ObjectData("text:" + i, "button:" + i, false));
}
else{
objects.add(new ObjectData("text:" + i, "button:" + i, true));
}
}
listView.setAdapter(new SampleAdapter(this, objects));
}
}
class ObjectData{
String textStr;
String buttonStr;
boolean isBtn; //ボタンを表示するかどうか
public ObjectData(String textStr, String buttonStr, boolean isBtn){
this.textStr = textStr;
this.buttonStr = buttonStr;
this.isBtn = isBtn;
}
}
class ViewHolder{
ViewFlipper flipper;
TextView textView;
Button button;
}
class SampleAdapter extends ArrayAdapter<ObjectData>{
private LayoutInflater inflater;
public SampleAdapter(Context context, List<ObjectData> objects){
super(context, 0, objects);
this.inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public View getView(int position, View convertView, ViewGroup parent){
ViewHolder holder;
if(convertView == null){
convertView = inflater.inflate(R.layout.object, parent, false);
holder = new ViewHolder();
holder.flipper = (ViewFlipper)convertView.findViewById(R.id.flipper);
holder.textView = (TextView)convertView.findViewById(R.id.text_view);
holder.button = (Button)convertView.findViewById(R.id.button);
convertView.setTag(holder);
}else{
holder = (ViewHolder)convertView.getTag();
}
ObjectData data = getItem(position);
if(data.isBtn){
//ボタンなら
holder.button.setText(data.buttonStr);
holder.flipper.setDisplayedChild(1); //2ページ目を表示
}else{
//テキストビューなら
holder.textView.setText(data.textStr);
holder.flipper.setDisplayedChild(0); //1ページ目を表示
}
return convertView;
}
}
ViewHolderの切り替え自体はViewHolder#showNext()やViewHolder#showPrevious()でやることが多いけど、今回の場合それでやると表示がうまくいかなかったのでViewHolder#setDisplayChild()を使った。
今回の場合、ViewFlipperなので、動的に要素の高さを変更することはできない。できたらなかなかすごいけど何かいい方法があるのかな?

0 件のコメント:
コメントを投稿