すべての要素が同じなら普通に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 件のコメント:
コメントを投稿