ViewPagerの使用

ViewPager を使って, スクロールして複数のViewを見るような。 android-support-v4.jar というjar に, ViewPager といった拡張クラスが入っています。これを使います。 使い方は,かなりListに似ています。Adapter(UIの構築などのコードつき), そのAdapterの操作でデータを管理, AdapterをViewPagerにセットすることでデータ表示させます。

さてこれを作るための手順です。

方法一:

  • 全体のレイアウト(xml)
  • 各ページのレイアウト(xml)
  • Main のActivity
  • Adapter

  • 全体のレイアウト(main.xml)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<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>
  1. 各ページのレイアウト(xml) ページに使うレイアウトを作りました。 card.xml という名前を付けました。画像とテキストが入っています。 ページのレイアウトを取り込みます。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<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/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="100dp" >
    </ImageView>

    <TextView
        android:id="@+id/textViewName"
        android:layout_width="fill_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:textAlignment="center"
        android:textSize="30sp" />

</LinearLayout>
  1. Main のActivity (MainActivity.java) 本体Activity のコードです。 ポイントは, ViewPager を取り出して, Adapterを設定しているところです。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        List<PersonData> list = PersonDataGenerator.createPersonData();
        ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);
        ViewPagerAdapter pagerAdapter = new ViewPagerAdapter(this, list);
        viewPager.setAdapter(pagerAdapter);
    }
}
  1. Adapter (ViewPagerAdapter.java)

Adapter とは, 各ページのデータを設定したり, ページのリソースの処理をしたりするものです。ListView のAdapter とだいたい同じ 感じですが, PagerAdapter を extends する必要があります。 その実装例です。 @Override しているメソッドは必須です。 destroyItem は, Eclipse のQuickFix では登場しませんが, ないと, ページをめくった時に落ちますw。(Viewのメモリ管理をしているっぽい)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class ViewPagerAdapter extends PagerAdapter {
    LayoutInflater inflater = null;
    List<PersonData> list;

    public ViewPagerAdapter(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);
        TextView nameView = (TextView) layout.findViewById(R.id.textViewName);
        nameView.setText(list.get(position).getName());
        ImageView charView = (ImageView) layout.findViewById(R.id.imageView);
        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)

ア:PersonData.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class PersonData implements Parcelable {
    private String name;
    private int res;

    public PersonData() {
    }

    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;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(getName());
        dest.writeInt(getRes());
    }
}

イ:PersonDataGenerator.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
public class PersonDataGenerator {
    public static List<PersonData> createPersonData() {
        List<PersonData> res = new ArrayList<PersonData>();
        res.add(new PersonData("Sara Rukawa", R.drawable.test1));
        res.add(new PersonData("Aoi Hinomoto", R.drawable.test2));
        res.add(new PersonData("Himeno Katsuragi", R.drawable.test3));
        res.add(new PersonData("Sharuru Yoshino", R.drawable.test4));
        res.add(new PersonData("Rikka Morizono", R.drawable.test5));
        res.add(new PersonData("Lily", R.drawable.test6));
        res.add(new PersonData("Lucy", R.drawable.test7));
        return res;
    }
}

方法二:

  • 全体のレイアウト(xml)
  • 各ページのレイアウト(xml)
  • Main のActivity
  • Adapter
  • Fragment

  • 全体のレイアウト(main.xml) (方法一と同じ)

  • 各ページのレイアウト(xml) (方法一と同じ)

  • Main のActivity (MainActivity.java) 本体Activity のコードです。 ポイントは, ViewPager を取り出して, Adapterを設定しているところです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
public class MainActivity extends FragmentActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);
        // 这里因为是3.0一下版本,所以需继承FragmentActivity,通过getSupportFragmentManager()获取FragmentManager
        // 3.0及其以上版本,只需继承Activity,通过getFragmentManager获取事物
        FragmentManager fm = getSupportFragmentManager();
        // 初始化自定义适配器
        ViewFragmentPageAdapter adapter = new ViewFragmentPageAdapter(fm);
        // 绑定自定义适配器
        viewPager.setAdapter(adapter);
    }
}
  1. Adapter (ViewFragmentPageAdapter.java) Adapter とは, 各ページのデータを設定したり, ページのリソースの処理をしたりするものです。 FragmentPagerAdapter を extends する必要があります。

その実装例です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
public class ViewFragmentPageAdapter extends FragmentPagerAdapter {
    private List<PersonData> list;

    public ViewFragmentPageAdapter(FragmentManager fm) {
        super(fm);
        this.list = PersonDataGenerator.createPersonData();
    }

    @Override
    public Fragment getItem(int position) {
        return ViewFragment.newInstance(position, list);
    }

    @Override
    public int getCount() {
        return list.size();
    }
}

5.Fragment (ViewFragment.java)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class ViewFragment extends Fragment {
    private PersonData personData = new PersonData();

    public static ViewFragment newInstance(int num, List<PersonData> list) {
        ViewFragment fragment = new ViewFragment();
        Bundle bundle = new Bundle();
        bundle.putParcelable("PERSONDATA", list.get(num));
        fragment.setArguments(bundle);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        personData = getArguments().getParcelable("PERSONDATA");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.card, null);
        ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
        imageView.setBackgroundResource(personData.getRes());
        TextView textViewName = (TextView) view.findViewById(R.id.textViewName);
        textViewName.setText(personData.getName());
        return view;
    }
}

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