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とかと似たようなテクニックですね。
次回はデータの数を変更します。


