ViewPager UIの変更
前回の引き続きまして, ViewPagerを見ていきます。 English
前回は, Android でページをスクロールするUIをつくる という題で, スワイプして移動するViewをViewPagerを使って実装しました。
さて, ここから何かしらのイベントを取って, ViewPager内のUIを変更するにはどうするか, ちょっとした工夫が必要になります。
変更に関しては, 2つの変更があります。
1. UIもしくはデータの変更
2. データの追加・削除]
今回は1を扱います。次回2を扱います。
1.ですが, ちょっとした工夫が必要になります。
今回は, このページの画像をタップすると, 名前の部分を”Favorites!” と変更するイベントを追加しましょう。
手順です。
1. Adapter に, イベントのコードを追加(引数として渡したいものは, final で定義して保存しておきましょう)
2. イベント内にListenerを作成(interface), イベントメソッドを入れておく
3. Activity側に2で作成したリスナを実装する
4. タグをもとに, UIを取り出して変更する + データそのものも変更しておく(destroyで再作成されるので)
なんだか言葉で書くとややこしいですが, コードを見ていきましょう。
Adapter
public class CardPagerAdapter extends PagerAdapter { LayoutInflater _inflater = null; List<PersonData> list; private TextView nameView; private ImageView charView; // listener private ClickPagerImgListerner listener; public CardPagerAdapter( Context context, List<PersonData> list ) { super(); _inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); this.list = list; } @Override public Object instantiateItem(ViewGroup container, int position) { LinearLayout layout = (LinearLayout)_inflater.inflate(R.layout.card, null); nameView = (TextView)layout.findViewById(R.id.word); String name = list.get(position).getName(); nameView.setText(list.get(position).getName()); nameView.setTag(name); // Add tag charView = (ImageView)layout.findViewById(R.id.img); charView.setImageResource(list.get(position).getRes()); charView.setClickable(true); final int index = position; charView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //Log.d("", index); if ( listener != null ) { listener.change(index); } } }); container.addView(layout); return layout; } @Override public void destroyItem(ViewGroup container, int position, Object object) { ((ViewPager) container).removeView((View) object); } @Override public int getCount() { return list.size(); } @Override public boolean isViewFromObject(View view, Object obj) { return view.equals(obj); } public void setListener( ClickPagerImgListerner listener ) { this.listener = listener; } }
前回の部分と違うのは, listenerが入っていること, 画像にClickイベントを追加し, リスナーのメソッドを呼び出していること。
TextViewにタグをつけているところです。タグは後で, Activityから, Viewを取得するのに使っています。
そのリスナーです
Listener
public interface ClickPagerImgListerner { public void change( int position ); }
ただのインターフェイスです。これをActivityに実装することで, AdapterとActivityをinterface でゆるくつなぎます。
Activity
public class ViewPagerActivity extends Activity implements ClickPagerImgListerner { private ViewPager viewPager; List<PersonData> list; int currentIndex; CardPagerAdapter pagerAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.viewport); this.list = PersonDataGenerator.createPersonData(); viewPager = (ViewPager) findViewById(R.id.viewpager); pagerAdapter = new CardPagerAdapter(this, list); pagerAdapter.setListener(this); viewPager.setOnPageChangeListener(new PageChangeListener()); viewPager.setAdapter(pagerAdapter); currentIndex = 0; } class PageChangeListener extends SimpleOnPageChangeListener { @Override public void onPageSelected(int position) { // Page change Operation! super.onPageSelected(position); currentIndex = position; } } @Override public void change(int position) { TextView nameView = (TextView)viewPager.findViewWithTag(list.get(position).getName()); nameView.setText("Favorites!"); list.get(position).setName("Favorites"); } }
さて, ここがメインです。リスナーで拾ったイベントがここに帰ってきます。 changeというやつです。
UIをタグを使って引っ張り出し, テキストを変更します。 そしてAdapterにセットしたデータも変更します(destroyされたときに, データをもとにUIを作り直すので)
notifyDataSetChangedは呼ばなくても大丈夫。データの数が変わらない時は効果ありません。
イベントを拾って動的にViewPager内のデータの変更ができます。
AWTとか, Swingとかと似たようなテクニックですね。
次回はデータの数を変更します。