1

編集:

さらに詳しく調べてみると、問題は、FragmentActivityonCreate()メソッドでレイアウトを拡張すると、ViewPager内でさまざまなビューが拡張されることであるとほぼ確信しています。xml1.findViewById()だから私が別のビューを見ていることを使用してそれらにアクセスしようとすると。で使用されているビューにアクセスするにはどうすればよいViewPagerですか?私FragmentPagerAdapterを見ると、フラグメントは1回以上スワイプするたびに新しいオブジェクトとして作成されているように見えます。4つのビューすべてを一度に初期化する必要があります。その後、電話をかけるたびにupdateUI、4つのビューが一度に変更されます。したがって、新しく更新された4つのビューすべての間をスワイプできます。

を使用してみpagerAdapter.getItem(index).getView().findViewById( )ましたが、が返されますNullPointerException。例外が発生した後、クラスのgetView()メソッドをオーバーライドしてみました。Fragment私がメソッドに入れたのはreturn view;、ビューがメソッドで返されたビューの保存されたインスタンスであるということだけでしたonCreateView。これにより、ViewPagerに4つの空白の画面が表示されて間をスワイプできました。

FragmentPagerAdapter質問の最後に実装を追加しました。

編集終了

ViewPagerを使用して実装してみましたFragments。非常に奇妙な結果が出ています。

private TextView view1a, view1b;
private TextView view2a, view2b;
private TextView view3a, view3b;
private TextView view4a, view4b;
private Spinner spinner1, spinner2, spinner3, spinner4;
private Checkbox check1, check2, check3, check4;

private ViewPager mViewPager;
private View xml1, xml2, xml3, xml4;

public void onCreate( Bundle savedInstanceState ) {
    super.onCreate( savedInstanceState );
    setContentView( R.layout.main_page );

    mViewPager = (ViewPager) findViewById( R.id.pager );
    FragmentManager fm = getSupportFragmentManager();
    MoreParmsFragmentPagerAdapter pagerAdapter = new MoreParmsFragmentPagerAdapter(fm);

    xml1 = LayoutInflater.from( getBaseContext()).inflate( R.layout.xml1, null );
    xml2 = LayoutInflater.from( getBaseContext()).inflate( R.layout.xml2, null );
    xml3 = LayoutInflater.from( getBaseContext()).inflate( R.layout.xml3, null );
    xml4 = LayoutInflater.from( getBaseContext()).inflate( R.layout.xml4, null );
    populateSpinners();
    updateUI();
}


public void populateSpinners() {
    array1Adapter = new ArrayAdapter<String>( this, android.R.layout.simple_spinner_item, res.getStringArray( R.array.array1 )  );
    array1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner1 = (Spinner) xml1.findViewById(R.id.spinner1);
    spinner1.setAdapter(array1Adapter);

    array2Adapter = new ArrayAdapter<String>( this, android.R.layout.simple_spinner_item, res.getStringArray( R.array.array2 )  );
    array2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner2 = (Spinner) xml2.findViewById(R.id.spinner2);
    spinner2.setAdapter(array2Adapter);

    array3Adapter = new ArrayAdapter<String>( this, android.R.layout.simple_spinner_item, res.getStringArray( R.array.array3 )  );
    array3Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner3 = (Spinner) xml3.findViewById(R.id.spinner3);
    spinner3.setAdapter(array3Adapter);

    array4Adapter = new ArrayAdapter<String>( this, android.R.layout.simple_spinner_item, res.getStringArray( R.array.array4 )  );
    array4Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner4 = (Spinner) xml4.findViewById(R.id.spinner4);
    spinner4.setAdapter(array4Adapter);
}

public void updateUI() {
    view1a = (TextView) xml1.findViewById( R.id.view_one_a );
    view1b = (TextView) xml1.findViewById( R.id.view_one_b );
    view2a = (TextView) xml2.findViewById( R.id.view_two_a );
    view2b = (TextView) xml2.findViewById( R.id.view_two_b );
    view3a = (TextView) xml3.findViewById( R.id.view_three_a );
    view3b = (TextView) xml3.findViewById( R.id.view_three_b );
    view4a = (TextView) xml4.findViewById( R.id.view_four_a );
    view4b = (TextView) xml4.findViewById( R.id.view_four_b );
    // There is work done here to determine what to set
    // the different TextViews' text to.
    //
    // `view**.setText()` is called for all views above with their respective values.

    spinner1 = (Spinner) xml1.findViewById( R.id.spinner1 );
    spinner2 = (Spinner) xml2.findViewById( R.id.spinner2 );
    spinner3 = (Spinner) xml3.findViewById( R.id.spinner3 );
    spinner4 = (Spinner) xml4.findViewById( R.id.spinner4 );
    // There is work done here to determine what index the Spinners
    // should have selected.
    //
    // `Spinner.setSelection( index ) is called on all spinners.

    check1 = (CheckBox) xml1.findViewById( R.id.check1 );
    check2 = (CheckBox) xml2.findViewById( R.id.check2 );
    check3 = (CheckBox) xml3.findViewById( R.id.check3 );
    check4 = (CheckBox) xml4.findViewById( R.id.check4 );
    // There is work done here to determine whether or not
    // to check the CheckBoxes.
    //
    // CheckBox.setChecked() is called for all checkboxes.
}
}

これは私のFragmentクラスの例です:

public class xmlOneFragment extends Fragment {
    int mCurrentPage;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        /** Getting the arguments to the Bundle object */
        Bundle data = getArguments();

        /** Getting integer data of the key current_page from the bundle */
        mCurrentPage = data.getInt("current_page", 0);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
       View v = inflater.inflate(R.layout.xml1, container,false);
       return v;
    }
}

最初の問題は、Spinnersが対応する配列で満たされることがないことです。私のメソッド全体に、私が期待するものを示すLogCat呼び出しがありますが、それ自体は入力されていません。populateSpinners()Spinners

2番目の問題はupdateUI()メソッドで発生します。すべての呼び出しの下のコメントは、findViewById()特定の計算を行って、に入れるテキスト、TextViews設定するインデックスSpinners、およびをチェックするかどうかを決定する場所CheckBoxesです。見つかった値をLogCat示す呼び出しがありますが、それらはすべて期待されるものです。メソッドが呼び出されたとき、.setText(), .setSelection(), and .setChecked()エラーは表示されませんが、どの項目もまったく設定されていません。すべてが空白のままです。

3番目の問題は私を最も混乱させているものです。現在TextViews、すべてが一意のIDを持っています。これを最初に実装しようとしたとき、呼び出しのプレフィックスなしViewPagerupdateUI()メソッドにTextViewsを処理させました。xml*.findViewById()

view1a = (TextView) findViewById( R.id.view_one_a );
view1b = (TextView) findViewById( R.id.view_one_b );
view2a = (TextView) findViewById( R.id.view_two_a );
view2b = (TextView) findViewById( R.id.view_two_b );
view3a = (TextView) findViewById( R.id.view_three_a );
view3b = (TextView) findViewById( R.id.view_three_b );
view4a = (TextView) findViewById( R.id.view_four_a );
view4b = (TextView) findViewById( R.id.view_four_b );
// There is work done here to determine what to set
// the different TextViews' text to.
view**.setText( whatever );

このメソッドの結果は、でしたが、3番目と4番目のページでを呼び出したNullPointerException場合のみです。最初の2ページは例外をスローしませんでした。そこで、3ページ目と4ページ目をコメントアウトしました。プログラムが実行され、最初の2ページに正しいTextViewに正しい値が表示されました。次に、メソッドに追加しようとしましたが、例外はスローされませんが、ビューはまったく更新されません。.setText()TextViewsxml*.findViewById()

最後の注意:ViewPager機能は正しく、適切なレイアウト間を非常にうまくスワイプできます。ビューを必要な値で更新しようとすると、問題が発生します。問題は、レイアウトをどのように膨らませているか、または何度もそれを行う方法に関係していると思います。3番目の問題は本当に私を困惑させます。1ページ目/2ページ目と3ページ目/4ページ目で違いはわかりませんが、明らかに動作が異なります。また、示されている最初のコードブロックは、として表されActivity、2番目のコードブロックはに切り替えましたFragmentActivity

編集してFragmentPagerAdapterを追加します

public class MoreParmsFragmentPagerAdapter extends FragmentPagerAdapter {
    final int PAGE_COUNT = 4;

    public MoreParmsFragmentPagerAdapter( FragmentManager fm ) {
        super(fm);
    }

    public Fragment getItem( int arg0 ) {
        if( arg0 == 0 ) {
            xmlOneFragment xml1Frag = new xmlOneFragment();
            Bundle data = new Bundle();
            data.putInt( "current_page", arg0 );
            xmlOneFrag.setArguments( data );
            return xmlOneFrag;
        } else if( arg0 == 1 ) {
            xmlTwoFragment xml2Frag = new xmlTwoFragment();
            Bundle data = new Bundle();
            data.putInt( "current_page", arg0 );
            xmlTwoFrag.setArguments( data );
            return xmlTwoFrag;
        } else if( arg0 == 2 ) {
            xmlThreeFragment xml3Frag = new xmlThreeFragment();
            Bundle data = new Bundle();
            data.putInt( "current_page", arg0 );
            xmlThreeFrag.setArguments( data );
            return xmlThreeFrag;
        } else {
            xmlFourFragment xml4Frag = new xmlFourFragment();
            Bundle data = new Bundle();
            data.putInt( "current_page",  arg0 );
            xmlFourFrag.setArguments( data );
            return xmlFourFrag;
        }
    }

    @Override
    public CharSequence getPageTitle(int position) {
        if( position == 0 ) {
            return "xml1";
        } else if( position == 1 ){
            return "xml2";
        } else if( position == 2 ) {
            return "xml3";
        } else {
            return "xml4";
        }
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return PAGE_COUNT;
}
}

編集2:

private ViewPager mViewPager;
private MoreParmsFragmentPagerAdapter pagerAdapter;
private FragmentManager fm;
private AntiPumpFragment apFrag;
private RelaxedCloseFragment relFrag;
private MiscParmsFragment miscFrag;
private DNP3Fragment dnpFrag;

public void onCreate( Bundle savedInstanceState ) {
    super.onCreate( savedInstanceState );
    mViewPager = (ViewPager) findViewById( R.id.pager );
    fm = getSupportFragmentManager();
    pagerAdapter = new MoreParmsFragmentPagerAdapter(fm);
    mViewPager.setAdapter( pagerAdapter );

    apFrag = (AntiPumpFragment) fm.findFragmentByTag( "android:switcher:" + R.id.pager + ":0" );
    relFrag = (RelaxedCloseFragment) fm.findFragmentByTag( "android:switcher:" + R.id.pager + ":1" );
    miscFrag = (MiscParmsFragment) fm.findFragmentByTag( "android:switcher:" + R.id.pager + ":2" );
    dnpFrag = (DNP3Fragment) fm.findFragmentByTag( "android:switcher:" + R.id.pager + ":3" );

私のコードのどこでも、これらのフラグメントはすべてnullを返します。ViewPager画面に正しく表示され、4つのビューすべてをきれいにスワイプできます。ただし、私のif( apFrag != null )ステートメントはすべてスキップされます。

4

1 に答える 1

1

最初の問題は、スピナーが対応する配列で満たされないことです。populateSpinners() メソッド全体に LogCat 呼び出しがあり、予想どおりの結果が表示されますが、Spinners 自体には値が設定されていません。

Spinnersの から来るビューに接続する代わりに、 を使用して で使用されるレイアウト ファイルから新しいビューをインフレートするだけなので、後で理解したように、初期化FragmentsされViewPager表示されません。この新しいビューの子を初期化しても、 の UI に存在しない/表示されないため、視覚的な結果は表示されません。 にアタッチするのを待って「フローティング」しているため、どのビューがあるかを表示できます。LayoutInflaterFragmentsActivityViewGroupActivity

2 つ目の問題は updateUI() メソッドで発生します。すべての findViewById() 呼び出しの下にあるコメントは、特定の計算を行って、TextView に入れるテキスト、Spinner を設定するインデックス、および CheckBox をチェックするかどうかを決定する場所です。見つかった値を示す LogCat 呼び出しがあり、それらはすべて期待どおりです。.setText()、.setSelection()、および .setChecked() メソッドが呼び出されると、エラーは表示されませんが、項目はまったく設定されません。すべてが空白のままです。

View表示されているビューを初期化せず、接続されていない階層を更新しているのと同じ点です。

3番目の問題は、私を最も混乱させているものです。TextView はすべて一意の ID を持つようになりました。この ViewPager を最初に実装しようとしたとき、updateUI() メソッドで xml* を使用せずに TextView を処理しました。[...]このメソッドは NullPointerException を引き起こしましたが、3 ページ目と 4 ページ目の TextView で .setText() を呼び出した場合のみでした。最初の 2 ページは例外をスローしませんでした

たぶんこれで問題が解決するでしょう: はViewPager、左右にスワイプできるようにするだけでなく、(アダプターを介して) できるだけ少ないビューを使用できるように設計されています (ListViewたとえば、表示されている行のみを膨張させる)。このために、特定の数のページのみを構築します。このページ数はデフォルトで 3 (表示される 1 ページ + 両側に 1 ページあるため、スワイプがスムーズになります) であり、ViewPager前後にスワイプすると他のページの読み込みが開始されます。を開始するViewPagerと、最初のページ (表示されているページ) + 次のページ (右側) が読み込まれるため、ユーザーはすぐにスワイプできます。他の 2 つのページは効率のためにロードされず、それらからウィジェットにアクセスしようとすると、NullPointerException見つからないからです。そして、最終的に、ユーザーがそれらのページをまったく表示しない可能性がある場合は、不必要な作業を行うべきではありません。ViewPagerこれで、 が作成してメモリに保持するページの数を変更することができます ( を使用setOffscreenPageLimit()して数値を指定します) が、これはメモリ内のすべてのウィジェットを一度にロードするため (場合、これはおそらくそれほど悪くはありませんが、あなたが何をしたいのかわかりません)。

pagerAdapter.getItem(index).getView().findViewById( ) を使用してみましたが、NullPointerException が返されます。例外が発生した後、Fragment クラスで getView() メソッドをオーバーライドしようとしました。メソッドに入力したのは return view; だけで、view は onCreateView メソッドで返された View の保存されたインスタンスです。これにより、ViewPager に 4 つの空白の画面が表示され、その間をスワイプすることができました。

で現在使用されている のインスタンスが返されず、インスタンス化されたばかりのnewが返されるgeItem()ため、アダプタのメソッドを使用することはできません。インスタンス化されただけで にアタッチされていないため、そのメソッドはビューを返しません。FragmentViewPager FragmentActivitygetView()

ViewPager で使用されているビューにアクセスするにはどうすればよいですか?

いつアクセスするかによって異なります。アダプタを に設定した時点でデータが利用可能になる場合は、またはメソッドでViewPager初期化を移動するだけです。FragmentsonCreateViewonActivityCreated

Fragment後でからにアクセスしたい場合は、 が (今のところ)にの形式の特別なタグを追加するViewPagerことを知っているので、小さなハックを使用できます。たとえば、最初の にアクセスするには:ViewPagerFragmentsFragmentManagerandroid:switcher:theIdOfTheViewPager:thePositionInTheViewPagerFragmentViewPager

xmlOneFragment first = (xmlOneFragment)getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":0");
// if the fragment is found and its view is available do stuff
if (first != null && first.getView() != null) {
     // do stuff   
}

最適な解決策ではありませんが、ViewPager.

于 2013-01-10T08:50:38.627 に答える