Q&A
前提・実現したいこと
Android Studioおよびjavaを扱うのは初めてで、
webで調べながら見よう見まねで作成しているような状況ですが、
あるFragmentから別のFragmentに値を渡す方法がわからず苦戦しております。
理解が足りていないことは重々承知で、お見苦しいかとは思いますが
ご教示いただけますと幸いです。
FragmentとViewPagerでTabLayoutを作っています。
各Tabの表示内容を別々のFragmentで表示します。
処理の流れは、
・Fragment2(=Tab2)に配置したspinnerで入力内容を選択し
・Fragment2のボタンを押すと、選択したspinnerの内容が
Fragment1(=Tab1)に配置したTableLayoutに書き込まれる。
Fragment2で入力、Fragment1で表示というイメージです。
※本来はfragment1でもう一段回処理して、最終的な履歴をFragment3(Tab3)に
書き込む予定なのですが、今回は割愛します。
フラグメントマネージャーにはFragmentが3つありますが気にしないでください。
発生している問題・エラーメッセージ
自分で調べた範囲では、bundleを介して値を渡せるということは分かったのですが、
実際にやってみるとnullになってしまいます。
該当のソースコード
【MainActivity.java】 package com.example.MyApp; import android.support.design.widget.TabLayout; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // スライド用の部品 ViewPager viewPager = findViewById(R.id.viewpager); viewPager.setAdapter(new SampleFragmentPagerAdapter(getSupportFragmentManager(), MainActivity.this)); // 上部にタブをセットする TabLayout tabLayout = findViewById(R.id.tabs); tabLayout.setupWithViewPager(viewPager); } }
【SampleFragmentPagerAdapter.java】 package com.example.MyApp; import android.content.Context; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; public class SampleFragmentPagerAdapter extends FragmentPagerAdapter { final int PAGE_COUNT = 3; // Tabのタイトルテキスト。サイズやカラーはstyles.xmlで設定する。 private String tabTitles[] = new String[]{"現在の状況", "予約フォーム"}; private Context context; public SampleFragmentPagerAdapter(FragmentManager fm, Context context) { super(fm); this.context = context; } @Override public int getCount() { return PAGE_COUNT; } @Override public Fragment getItem(int position) { // fragmentを切り替える switch(position){ case 0: return new PageFragment(); case 1: return new PageFragment2(); case 2: return new PageFragment3(); } return null; } @Override public CharSequence getPageTitle(int position) { // Generate title based on item position return tabTitles[position]; }
【PageFragment2.java】 // 入力フォームを表示するTab2 package com.example.MyApp; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.Spinner; import android.widget.Button; //Fragmentクラスを継承します public class PageFragment2 extends Fragment { // Fragmentで表示するViewを作成 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); // 画面回転時にFragmentの再生成を禁止 setRetainInstance(true); // fragment_page2.xmlのレイアウトをViewとして作成します。 // fragment_page2.xmlにはspinnerがいくつか並んでいて、 // 最下部にボタンが配置されている。 return inflater.inflate(R.layout.fragment_page2, container, false); } // Viewが生成し終わった時に呼ばれるメソッド @Override public void onViewCreated(View view, Bundle saveInstanceState){ super.onViewCreated(view, saveInstanceState); // 名前選択用のspinner設定 final Spinner spinnerName = view.findViewById(R.id.spinner_name); // spinnerの文字サイズなど変更できるように ArrayAdapter<String> adapterName = new ArrayAdapter<>(getContext(), R.layout.spinner_item, getResources().getStringArray(R.array.spinner_names)); // ドロップダウンメニューにするため adapterName.setDropDownViewResource(R.layout.spinner_dropdown_item); // spinner に adapterをセット spinnerName.setAdapter(adapterName); // (中略。上記のようなspinnerを複数設定) //ボタンを押したときのリスナーを設定 Button button01 = view.findViewById(R.id.button01); button01.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View view){ // spinnerの選択内容をフラグメント1に渡すためにBundleにセット FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); PageFragment fragment = new PageFragment(); Bundle args = new Bundle(); args.putString("name_spinner", (String) spinnerName.getSelectedItem()); fragment.setArguments(args); fragmentTransaction.commit(); // spinnerを初期化 spinnerName.setSelection(0); // (中略。他のspinnerについても同様に設定) } }); } }
【PageFragment.java】 // 入力結果を表示するためのTab1 package com.example.MyApp; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.TextView; import android.os.Bundle; //Fragmentクラスを継承します public class PageFragment extends Fragment { //Fragmentで表示するViewを作成 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); // 画面回転時にFragmentの再生成を禁止 setRetainInstance(true); //fragment_page.xmlのレイアウトをViewとして作成します。 // fragment_page.xmlにはTableLayoutとボタンが配置されています。 return inflater.inflate(R.layout.fragment_page, container, false); } // Viewが生成し終わった時に呼ばれるメソッド @Override public void onViewCreated(View view, Bundle saveInstanceState) { super.onViewCreated(view, saveInstanceState); final TextView name = view.findViewById(R.id.reserve_2c); // R.id.reserve_2c は Tbaleのセルのidです。 // ボタンを押したらBundleから値を受け取り、セルに書き込む。 // ※ 本当は、PageFragment2.javaでボタンを押した時点でセルへの書き込みまで // おこなうとか、ページがTab2からTab1に切り替わったことを検出して // セルに書き込む、とかにしたかったが、よく理解できなかったので // まずはボタンのOnClickListenerで動かしてみる。 Button button = view.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // nullチェック Bundle bundle = getArguments(); if (bundle == null) { name.setText("null"); } else { // nullでなければspinnerで選択した内容をセルに書き込む name.setText(bundle.getString("name_spinner")); } // (中略。その他のspinnerについても同様に値を受け取りセルに書き込みたい) } }); } }
【PageFragment.java】でBundleから値を受け取れたかどうかをnullチェックすると、
nullが返って来て上手く値を受け渡しできずに困っています。
試したこと
Bundleにセットする時点で問題があるのかを確認するため、
【PageFragment2.java】にて、
final TextView testText = view.findViewById(R.id.test_text); testText.setText(args.getString("name_spinner"));
を加えてみると、spinnerNameで選択した内容がTextViewで表示されました。
しかし、同じ【PageFragment2.java】でも、
final TextView testText = view.findViewById(R.id.test_text); Bundle bundle = getArguments(); testText.setText(bundle.getString("name_spinner"));
とするとnullになります。
(これはbundleへのセットは行えているがゲットが上手く
できていないということでしょうか?)
補足情報(FW/ツールのバージョンなど)
Android Studio 3.0
以上、よろしくお願いいたします。
回答2件
下記のような回答は推奨されていません。
このような回答には修正を依頼しましょう。
2018/02/22 22:47 編集
2018/02/23 00:47
2018/02/26 15:02