Android開発におけるViewPagerとFragmentの活用

ViewPagerの実装

ViewPagerを使用して複数のビューをスライド表示する機能を実装します。

レイアウトファイルの作成

  • layout1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffff0000"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="画面1"
        android:textSize="30sp" />

</LinearLayout>
  • activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

アダプターの実装

public class CustomPagerAdapter extends PagerAdapter {
    private List<View> viewList;

    public CustomPagerAdapter(List<View> views) {
        this.viewList = views;
    }

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

    @Override
    public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
        return view == object;
    }

    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        container.addView(viewList.get(position));
        return viewList.get(position);
    }

    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        container.removeView(viewList.get(position));
    }
}

アクティビティの実装

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        LayoutInflater inflater = getLayoutInflater();
        View screen1 = inflater.inflate(R.layout.layout1, null);
        View screen2 = inflater.inflate(R.layout.layout2, null);
        View screen3 = inflater.inflate(R.layout.layout3, null);

        List<View> viewList = new ArrayList<>();
        viewList.add(screen1);
        viewList.add(screen2);
        viewList.add(screen3);

        ViewPager viewPager = findViewById(R.id.viewPager);
        CustomPagerAdapter adapter = new CustomPagerAdapter(viewList);
        viewPager.setAdapter(adapter);
    }
}

Fragmentの基本操作

静的Fragmentの実装

public class SampleFragment extends Fragment {
    private View rootView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if (rootView == null) {
            rootView = inflater.inflate(R.layout.fragment_sample, container, false);
        }
        return rootView;
    }
}
  • fragment_sample.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="サンプルテキスト"
        android:gravity="center_horizontal"
        android:textSize="24sp" />

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="クリック" />

</LinearLayout>

動的Fragmentの操作

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.btnFragment1).setOnClickListener(this);
        findViewById(R.id.btnFragment2).setOnClickListener(this);

        replaceFragment(new FragmentA());
    }

    private void replaceFragment(Fragment fragment) {
        getSupportFragmentManager().beginTransaction()
            .replace(R.id.container, fragment)
            .addToBackStack(null)
            .commit();
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.btnFragment1) {
            replaceFragment(new FragmentA());
        } else if (v.getId() == R.id.btnFragment2) {
            replaceFragment(new FragmentB());
        }
    }
}

Fragment間通信の実装

Activity経由の通信

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        getSupportFragmentManager().beginTransaction()
            .add(R.id.fragment1, new FragmentX())
            .add(R.id.fragment2, new FragmentY())
            .commit();
    }
}

public class FragmentX extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_x, container, false);
        
        view.findViewById(R.id.button).setOnClickListener(v -> {
            FragmentY fragmentY = (FragmentY) getActivity().getSupportFragmentManager()
                .findFragmentById(R.id.fragment2);
            if (fragmentY != null) {
                fragmentY.updateText("新しいメッセージ");
            }
        });
        
        return view;
    }
}

public class FragmentY extends Fragment {
    private TextView textView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_y, container, false);
        textView = view.findViewById(R.id.textView);
        return view;
    }

    public void updateText(String message) {
        textView.setText(message);
    }
}

Fragmentのライフサイクル

FragmentのライフサイクルはActivityと連携しています。

Activity状態Fragmentコールバック
作成onAttach()
作成onCreate()
作成onCreateView()
作成onActivityCreated()
開始onStart()
実行onResume()
一時停止onPause()
停止onStop()
破棄onDestroyView()
破棄onDestroy()
破棄onDetach()

ViewPager2とFragmentの連携

基本的な実装

public class ViewPagerAdapter extends RecyclerView.Adapter<ViewPagerAdapter.PagerViewHolder> {
    private String[] titles = {"項目1", "項目2", "項目3"};
    private int[] colors = {R.color.red, R.color.green, R.color.blue};

    @NonNull
    @Override
    public PagerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new PagerViewHolder(LayoutInflater.from(parent.getContext())
            .inflate(R.layout.item_pager, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull PagerViewHolder holder, int position) {
        holder.container.setBackgroundResource(colors[position]);
        holder.title.setText(titles[position]);
    }

    @Override
    public int getItemCount() {
        return titles.length;
    }

    static class PagerViewHolder extends RecyclerView.ViewHolder {
        TextView title;
        LinearLayout container;

        PagerViewHolder(@NonNull View itemView) {
            super(itemView);
            container = itemView.findViewById(R.id.container);
            title = itemView.findViewById(R.id.titleText);
        }
    }
}

タブ付きViewPagerの実装

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ViewPager2 viewPager = findViewById(R.id.viewPager);
        List<Fragment> fragments = Arrays.asList(
            new FragmentA(),
            new FragmentB(),
            new FragmentC()
        );

        FragmentStateAdapter adapter = new FragmentStateAdapter(this, getLifecycle(), fragments);
        viewPager.setAdapter(adapter);

        viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
            @Override
            public void onPageSelected(int position) {
                updateTab(position);
            }
        });
    }

    private void updateTab(int position) {
        // タブUIの更新処理
    }
}

class FragmentStateAdapter extends FragmentStateAdapter {
    private List<Fragment> fragments;

    public FragmentStateAdapter(@NonNull FragmentManager fragmentManager, 
                              @NonNull Lifecycle lifecycle, List<Fragment> fragments) {
        super(fragmentManager, lifecycle);
        this.fragments = fragments;
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        return fragments.get(position);
    }

    @Override
    public int getItemCount() {
        return fragments.size();
    }
}

タグ: Android Fragment ViewPager ViewPager2 UIコンポーネント

6月5日 18:28 投稿