質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Q&A

解決済

1回答

3643閲覧

ViewPagerからFragmentのインスタンスを得る方法

ken0625

総合スコア40

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

0グッド

0クリップ

投稿2016/05/21 18:13

編集2016/05/22 09:26

###前提・実現したいこと
viewPagerをつかってEditTextを含むFragmentを操作するコードを書いていて、ボタンを押したらviewPagerに含まれるすべてのFragmentにあるEditTextからgetData()したいのですが、fragmentのインスタンスをどのように取るのかで困っています。
instantiateItemを使うという解決策はキャストの問題でfragment自分で作ったfragmentのメソッドを読み込めません。

そしてviewPagerを動的に追加するために
http://qiita.com/takaaki7/items/9f135eb9e52625eb206e
この方が作ったライブラリを使っています。

どのようにviewPagerもしくはadapterからfragmentのインスタンスを取得すればよいのでしょうか。

###該当のソースコード

これが取得したいfragmentです。

public class ProductFragment extends Fragment { private View view; public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) { view = inflater.inflate(R.layout.layout_product_fragment, container, false); return view; } public HashMap<String,String> getData(){ HashMap<String,String> data = new HashMap<>(); data.put("name",((EditText)(view.findViewById(R.id.name))).getText().toString()); data.put("price",((EditText)(view.findViewById(R.id.price))).getText().toString()); data.put("comment",((EditText)(view.findViewById(R.id.comment))).getText().toString()); return data; } public static ProductFragment newInstance(int number){ Bundle bundle =new Bundle(); bundle.putInt("number", number); ProductFragment fragment = new ProductFragment(); fragment.setArguments(bundle); Log.d("message", "picture"); return fragment; } public boolean isDataNull(){ if(TextUtils.isEmpty(this.getData().get("name"))&&TextUtils.isEmpty(this.getData().get("price"))&&TextUtils.isEmpty(this.getData().get("comment"))){ return true; }else{ return false; } } }

これがadapterのコードです。先ほどのサイトで公開されているクラスを継承しています。

public class ProductFragmentAdapter extends ArrayFragmentStatePagerAdapter<Integer>{ public ProductFragmentAdapter(FragmentManager fm,int i){ super(fm,i); } @Override public Fragment getFragment(Integer number , int position) { ProductFragment fragment = ProductFragment.newInstance(number); return fragment; } @Override public void remove(int position){ super.remove(position); } @Override public CharSequence getPageTitle(int position) { return String.valueOf(position+1) + "個目の商品登録"; } public ProductFragment getProductFragment(ViewGroup container,int position){ Fragment fragment = (Fragment)instantiateItem(container,position); return (ProductFragment) fragment; } }

adapterが継承してるメソッドです

public abstract class ArrayFragmentStatePagerAdapter<T> extends ArrayPagerAdapter<T> { private static final String TAG = "StatePagerAdapter"; private static final boolean DEBUG = false; private final FragmentManager mFragmentManager; private FragmentTransaction mCurTransaction = null; private ItemsStateHandler mItemsStateHandler; private ArrayList<Fragment.SavedState> mSavedState = new ArrayList<>(); private ArrayList<Fragment> mFragments = new ArrayList<>(); private Fragment mCurrentPrimaryItem = null; @SuppressLint("CommitTransaction") @Override public Object instantiateItem(ViewGroup container, int position) { // If we already have this item instantiated, there is nothing // to do. This can happen when we are restoring the entire pager // from its saved state, where the fragment manager has already // taken care of restoring the fragments we previously had instantiated. if (mFragments.size() > position) { Fragment f = mFragments.get(position); if (f != null) { return super.instantiateItem(container, position); } } if (mCurTransaction == null) { mCurTransaction = mFragmentManager.beginTransaction(); } Fragment fragment = getFragment(getItem(position), position); if (DEBUG) Log.d(TAG, "Adding item #" + position + ": f=" + fragment); if (mSavedState.size() > position) { Fragment.SavedState fss = mSavedState.get(position); if (fss != null) { fragment.setInitialSavedState(fss); } } while (mFragments.size() <= position) { mFragments.add(null); } fragment.setMenuVisibility(false); fragment.setUserVisibleHint(false); mFragments.set(position, fragment); mCurTransaction.add(container.getId(), fragment); return super.instantiateItem(container, position); } }

これが上のスーパーメソッドです

public abstract class ArrayPagerAdapter<T> extends PagerAdapter { @Override public Object instantiateItem(ViewGroup container, int position) { return items.get(position); } /** * Adds the specified item at the end of the array. * * @param item The item to add at the end of the array. */ public void add(T item) { synchronized (lock) { items.add(identifiedItemFactory.create(item)); } itemPositionChangeChecked = new SparseBooleanArray(this.items.size()); notifyDataSetChanged(); } /** * Adds the specified items at the end of the array. * * @param items The items to add at the end of the array. */ }

うえで使われているクラスです

static class IdentifiedItemFactory<T> { private long lastId; IdentifiedItemFactory(long firstId) { lastId = firstId; } IdentifiedItem<T> create(T item) { return new IdentifiedItem(lastId++, item); } ArrayList<IdentifiedItem<T>> createList(List<T> items) { ArrayList<IdentifiedItem<T>> list = new ArrayList(); for (T item : items) { list.add(create(item)); } return list; } @SafeVarargs final ArrayList createList(T... items) { return createList(new ArrayList<>(Arrays.asList(items))); } } static class IdentifiedItem<T> { long id; T item; public IdentifiedItem(long id, T item) { this.id = id; this.item = item; } @Override public String toString() { return "IdentifiedItem{" + "id=" + id + ", item=" + item + '}'; } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ProductFragmentAdapter#getProductFragmentを使うとProductFragmentでインスタンスが取得できそうですが、できない理由がありますか?

投稿2016/05/22 05:15

yona

総合スコア18155

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ken0625

2016/05/22 08:25

なんか追記したのですがこのライブラリがinstantiateItemを継承していて、その結果fragmentを返さないでidentificateItemというクラスを返すようになっているみたいでキャストできないとエラーがでます...
yona

2016/05/22 09:13

コードの繋がりがよくわからないので、一番簡単そうな方法をコメントします。 1-ProductFragmentAdapterにフィールド変数、HashMap<Inreger,ProductFragment>を宣言する。 2-ProductFragmentAdapter#getFragmentでProductFragmentをreturnする前に1で宣言したHashMapに追加する。 3-全てのFrgmentにアクセスするときは1のHashMapにアクセスする。 また、ライブラリ側で何か方法が用意されているかもしれないので、ライブラリ作成者に聞いてみた方が早いかもしれないです。
ken0625

2016/05/22 09:25

ごめんなさいソースの書き方が悪いですね直します。 それも試したのですが...どうやらこのgetFragmentは単にaddした時だけに呼び出されるものではないので何回か追加と削除をしていると実際の中身とずれてきてしまうようなのです... とりあえず現在のフラグメントのインスタンスを手に入れる変数はあったので、viewPagerの中のフラグメントが遷移したタイミングでedittextの中身をゲットしてModelとしておいたクラスに入れたり更新することで一応出来たのですが...このadapterなどをおいてるfragment側でaddされたら追加して、削除されたらModelも削除してっていちいち記述するのでとても良い解決法とは思えません...
yona

2016/05/22 09:38

ソースコードまであるならmFragmentsへのアクセッサメソッドを追加するのはどうですか? あと、「adapterが継承しているメソッドです」の意味がわからないです。 このコードはどこから来たんですか? あなたが書いたコードはどれで、ライブラリのコードがどれか教えてください。
ken0625

2016/05/22 13:35

すいません説明がうまくなくて... ProductFragmentAdapterというのが僕が書いたコードで、これはArrayFragmentStatePagerAdapter<T>というクラスを継承しています。そしてこのArrayFragmentStatePagerAdapter<T>というのはArrayPagerAdapter<T>を継承していましてArrayPagerAdapter<T>がPagerAdapterを継承している形です... ライブラリはArrayFragmentStatePagerAdapter<T>とArrayPagerAdapter<T>の部分です。PagerAdapterは元からあるクラスです。
yona

2016/05/22 14:15

なるほど。 1-ProductFragmentAdapterにフィールド変数、HashMap<Inreger,ProductFragment>を宣言する。 2-ProductFragmentAdapter#getFragmentでProductFragmentをreturnする前に1で宣言したHashMapに追加する。 3-全てのFrgmentにアクセスするときは1のHashMapにアクセスする。 上記をやって不整合が発生するらしいですが、removeで削除する処理は追加しましたか? また、ArrayFragmentStatePagerAdapterのmFragmentsにアクセスするメソッドを追加するといいと思いますが。
ken0625

2016/05/22 14:58

はい。removeの時に消すのはやったのですが...なんかmfragmentsのアクセスがダメな理由と同じなのですが、ArrayFragmentStatePagerAdapterのremoveをするとき除去場所の変数をpositionで指定するのですが、なぜかpositionがmfragmentsのサイズより大きい時はmfragmentsにnullを入れて順番を調節をしてるみたいで、hashmapのremove(position)をやるとズレが生じるみたいです。 また同じことが原因でmFragmentsにはnullが入ることがあるので取得してもしょうがないみたいです... もともとPagerAdapterには全フラグメントのインスタンスを手に入れるというメソッドはないんですかね...やっぱり切替時にデータを取得する方法が前提なんでしょうか...
yona

2016/05/23 01:12

動的に変わるので、都度取得した方が確実ですね。 あとは、mFragmentsを取得するメソッドを追加してしまうかのどちらかでしょうね。
ken0625

2016/05/23 04:18

やはりそうなんですね...mfragmentsはnullがいろいろはいったりfragmentが追加されなかったり挙動が不明なので取得しても使えないので諦めます...
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問