2013年6月14日金曜日

Android でページをスクロールするUIをつくる(ViewPager)

こんにちは。Android も昔と比べると, いろいろなUIを標準でサポートするようになりました。

This is English version here

今回は, ViewPager を使って, スクロールして複数のViewを見るような

iOS ですと, ScrollView と, UIView のコンビネーションで作れたりするやつです。

Android では, android-support-v4.jar というjar に, ViewPager といった拡張クラスが入っています。

これは,  Android Support Library と呼ばれるやつで, 標準では入ってなかったりします
(すみません忘れました)

Android SDK Manager を開いて確認してみましょう。


Install されていない場合は, インストールです。

今回の成果物はこんな感じです。





これらの複数のページをぺらぺらとめくれるように作ります。

こちらにUI変更のコードを書きました, ちょっと難易度高めです(ViewPager UIの変更)

こちらにデータの追加のコードを書きました。上のやつの知識が前提です。(ViewPager データの追加)


1. レイアウト
本体のレイアウトです。 Main となるActivity です。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_weight="1" />

</LinearLayout>

ViewPager を配置しました。

2. 各ページのレイアウト
ページに使うレイアウトを作りました。 card.xml という名前を付けました。画像とテキストを入れました

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <ImageView  android:id="@+id/img"
        android:contentDescription="@string/cardimg"
     android:layout_width="fill_parent"
     android:layout_marginTop="100dp"
     android:layout_height="wrap_content"
     android:layout_gravity="center"
    ></ImageView>
    
    
 <TextView android:id="@+id/word"
     android:layout_width="fill_parent"
     android:layout_height="match_parent"
     android:textSize="30sp"
     android:textAlignment="center"
     android:gravity="center"
     />
</LinearLayout>

3.  コード
初めは, 本体Activity のコードです。

ポイントは, ViewPager を取り出して, Adapter と, PageChangeListener を設定しているところです。

public class ViewPagerActivity extends Activity 
{
 private ViewPager viewPager;
 
 List<Persondata> list;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) 
 {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.viewport);
  
  this.list = PersonDataGenerator.createPersonData();
  
  viewPager = (ViewPager) findViewById(R.id.viewpager);
  PagerAdapter pagerAdapter = new CardPagerAdapter(this, list);
  viewPager.setOnPageChangeListener(new PageChangeListener());
  viewPager.setAdapter(pagerAdapter);
 }
 
 class PageChangeListener extends SimpleOnPageChangeListener
 {
  @Override
  public void onPageSelected(int position) 
  {
   // Page change Operation!
  }
 }
}

Adapter とは, 各ページのデータを設定したり, ページのリソースの処理をしたりするものです。ListView のAdapter とだいたい同じ 感じですが, PagerAdapter を extends する必要があります。

その実装例です。

@Override しているメソッドは必須です。 destroyItem は, Eclipse のQuickFix では登場しませんが, ないと, ページをめくった時に落ちますw。(Viewのメモリ管理をしているっぽい)

public class CardPagerAdapter extends PagerAdapter 
{
 LayoutInflater _inflater = null;
 
 List<Persondata> list;
 
 private TextView nameView;
 
 private ImageView charView;
 
 
 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);
  nameView.setText(list.get(position).getName());
  
  charView = (ImageView)layout.findViewById(R.id.img);
  charView.setImageResource(list.get(position).getRes());
  
  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);
 }
}

各ページのデータを外から注入して, 画像とテキストを設定します。
レイアウトは, XML から読み込んでいます(card.xml)


最後にデータクラスを
public class PersonData 
{
 private String name;
 
 private int res;
 
 public PersonData( String name, int res )
 {
  this.name = name;
  this.res = res;
 }

 public String getName() 
 {
  return name;
 }

 public void setName(String name) 
 {
  this.name = name;
 }

 public int getRes() 
 {
  return res;
 }

 public void setRes(int res) 
 {
  this.res = res;
 }
}

public class PersonDataGenerator 
{
 public static List<Persondata> createPersonData()
 {
  List<Persondata> res = new ArrayList<Persondata>();
  
  res.add(new PersonData("Sara Rukawa", R.drawable.tw_sar_eco));
  res.add(new PersonData("Aoi Hinomoto", R.drawable.tw_aoi_eco));
  res.add(new PersonData("Himeno Katsuragi", R.drawable.tw_him_eco));
  res.add(new PersonData("Sharuru Yoshino", R.drawable.tw_shr_eco));
  res.add(new PersonData("Rikka Morizono", R.drawable.tw_rik_eco));
  
  return res;
 }
}

画像のリソースと名前を定義しているだけですけどね。
これで, ページをスクロールして表示していくようなUIの出来上がりです。標準のライブラリだけできるのは, 素敵です。









0 件のコメント:

コメントを投稿