はじめに
Android Studio で Javaを用いたモバイルアプリの開発を学んでいます。
layoutファイルについてはあまり力を入れて記述していません(ざっくりです)。画面切り替えの動作等にフォーカスしているため、stringファイルは使用しませんでした。
学んだ内容
-
FragmentManager
FragmentTransaction
を用いた表示フラグメントの切り替え(画面遷移) -
addToBackStack
popBackStack
を用いたアクションバー戻るボタンクリックで戻る動作
学習のために作成したサンプルアプリの概要
1つのアクティビティにメインとなるフラグメントを用意し、そこからボタンを押すことによって2つのフラグメントに行き来ができるだけの簡単なアプリ。
アクティビティ:1つ
フラグメント:3つ(メイン1つ、サブ2つ)
この①、②ボタンでサブフラグメント1、サブフラグメント2にそれぞれ遷移する
メイン画面(MainFragment) |
---|
![]() |
サブ1画面(SubFragment1) |
---|
![]() |
サブ2画面(SubFragment2) |
---|
![]() |
ディレクトリ構成

各javaファイルの処理内容
-
MainActivity.java
- MainFragmentの表示
- SubFragmentのアクションバーに戻るボタン「←」を表示するメソッドを定義
-
MainFragment.java
- Fragmentの表示を切り替えるメソッドを定義
- 設置したボタンのクリックリスナとFragmentを切り替えるメソッドの呼び出し
-
SubFragment(1, 2).java
- アクションバーに戻るボタンの表示
- 戻るボタンをクリックしたときに戻る処理を記述
ファイルのコードと解説
それぞれ、ファイルのコードを記載
layoutファイル
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activityMain"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
</FrameLayout>
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragmentMain"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainFragment">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="25dp"
android:text="メインフラグメントだよ"/>
<Button
android:id="@+id/bt1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="250dp"
android:layout_marginLeft="70dp"
android:textSize="25dp"
android:text="①"/>
<Button
android:id="@+id/bt2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="250dp"
android:layout_marginLeft="250dp"
android:textSize="25dp"
android:text="②"/>
</FrameLayout>
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/SubFragment1"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SubFragment1">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="25dp"
android:text="サブフラグメント1だよ"/>
</FrameLayout>
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/SubFragment2"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SubFragment2">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="25dp"
android:text="サブフラグメント2だよ" />
</FrameLayout>
javaファイル
※package, import 文は記載していません。
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// メソッドを呼び出し、デフォルトでMainFragmentを表示
addFragment(new MainFragment());
}
// Fragmentを表示させるメソッドを定義(表示したいFragmentを引数として渡す)
private void addFragment(Fragment fragment) {
// フラグメントマネージャーの取得
FragmentManager manager = getSupportFragmentManager();
// フラグメントトランザクションの開始
FragmentTransaction transaction = manager.beginTransaction();
// MainFragmentを追加
transaction.add(R.id.activityMain, fragment);
// フラグメントトランザクションのコミット。コミットすることでFragmentの状態が反映される
transaction.commit();
}
// 戻るボタン「←」をアクションバー(上部バー)にセットするメソッドを定義
public void setupBackButton(boolean enableBackButton) {
// アクションバーを取得
ActionBar actionBar = getSupportActionBar();
// アクションバーに戻るボタン「←」をセット(引数が true: 表示、false: 非表示)
actionBar.setDisplayHomeAsUpEnabled(enableBackButton);
}
}
画面表示に指定したフラグメントを表示したいので transaction.add
をする
引数はこのような値をいれる
transaction.add(追加先のレイアウト画面部品のR値, 追加する(表示したい)Fragmentオブジェクト);
MainFragment.java
public class MainFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// フラグメントで表示する画面をlayoutファイルからインフレートする
View view = inflater.inflate(R.layout.fragment_main, container, false);
// 所属している親アクティビティを取得
MainActivity activity = (MainActivity) getActivity();
// アクションバーにタイトルをセット
activity.setTitle("メインフラグメント");
// 戻るボタンは非表示にする(MainFragmentでは戻るボタン不要)
// ここをfalseにしておかないとサブフラグメントから戻ってきた際に戻るボタンが表示されたままになってしまう
activity.setupBackButton(false);
// ボタン要素を取得
Button bt1 = view.findViewById(R.id.bt1);
Button bt2 = view.findViewById(R.id.bt2);
// ①ボタンをクリックした時の処理
bt1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// SubFragment1に遷移させる
replaceFragment(new SubFragment1());
}
});
// ②ボタンをクリックした時の処理
bt2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// SubFragment2に遷移させる
replaceFragment(new SubFragment2());
}
});
return view;
}
// 表示させるFragmentを切り替えるメソッドを定義(表示したいFragmentを引数として渡す)
private void replaceFragment(Fragment fragment) {
// フラグメントマネージャーの取得
FragmentManager manager = getFragmentManager(); // アクティビティではgetSupportFragmentManager()?
// フラグメントトランザクションの開始
FragmentTransaction transaction = manager.beginTransaction();
// レイアウトをfragmentに置き換え(追加)
transaction.replace(R.id.activityMain, fragment);
// 置き換えのトランザクションをバックスタックに保存する
transaction.addToBackStack(null);
// フラグメントトランザクションをコミット
transaction.commit();
}
}
すでにメインフラグメントを表示しており、ボタンクリックで表示を切り替えたいので transaction.replace
を使用
引数は add
の処理と同じイメージ
transaction.replace(表示先のレイアウト画面部品のR値, 置き換える(表示したい)Fragmentオブジェクト);
メインフラグメントから遷移したサブフラグメントではアクションバーの戻るボタン「←」でメインフラグメントに戻れるようにしたいため
transaction.addToBackStack(null);
を記述することにより、遷移前に表示していたフラグメントを保存している。
この記述により遷移先のフラグメントで
getFragmentManager().popBackStack();
を呼び出すことで、戻るボタン「←」をクリックしたときに戻る処理ができるようになる
SubFragment1.java / SubFragment2.java
public class SubFragment1 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// フラグメントで表示する画面をlayoutファイルからインフレートする
View view = inflater.inflate(R.layout.fragment_sub1, container, false);
// 所属親アクティビティを取得
MainActivity activity = (MainActivity) getActivity();
// アクションバーにタイトルをセット
activity.setTitle("サブフラグメント1");
// 戻るボタンを表示する
activity.setupBackButton(true);
// この記述でフラグメントでアクションバーメニューが使えるようになる
setHasOptionsMenu(true);
return view;
}
// アクションバーボタンを押した時の処理
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// android.R.id.homeで戻るボタン「←」を押した時の動作を検知
case android.R.id.home:
// 遷移前に表示していたFragmentに戻る処理を実行
getFragmentManager().popBackStack();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
public class SubFragment2 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// フラグメントで表示する画面をlayoutファイルからインフレートする
View view = inflater.inflate(R.layout.fragment_sub2, container, false);
// 所属親アクティビティを取得
MainActivity activity = (MainActivity) getActivity();
// アクションバーにタイトルをセット
activity.setTitle("サブフラグメント2");
// 戻るボタンを表示する
activity.setupBackButton(true);
// この記述でフラグメントでアクションバーメニューが使えるようになる
setHasOptionsMenu(true);
// View viewのが良い?
return view;
}
// アクションバーのボタンを押した時の処理
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// 戻るボタン「←」を押した時android.R.id.homeに値が入る
case android.R.id.home:
// 遷移前に表示していたFragmentに戻る処理を実行
getFragmentManager().popBackStack();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
getFragmentManager().popBackStack();
この記述で一つ前のフラグメントに戻る。
最後に
今回は内容に含みませんでしたが、今後フラグメント間のデータの受け渡しについても書けたら良いと思っています。
Java / Android を学び始めて1ヶ月弱程度の初心者です。ご指摘等ありましたらコメントください。
参考にさせていただいた資料
- https://developer.android.com/training/basics/fragments/fragment-ui?hl=ja
- https://qiita.com/tagfa/items/a1e2b7302ad36aa99dab
- https://akira-watson.com/android/fragment-code.html
非常にわかりやすく助かりました!ありがとうございました!