web-dev-qa-db-ja.com

Androidフラグメントにビューを再構築させる

2つのフラグメントがある単純なアプリがあり、横向きモードでは両方のフラグメントが並べて表示され、縦向きではフラグメントAが表示されます。オプションを選択した場合は、フラグメントBを表示するアクティビティを開始します。問題はポートレートモードでフラグメントBを表示していますが、ユーザーがメニューオプションを選択した場合、フラグメントBに関連付けられているビューを更新または再描画したいのですが、これを機能させる方法がわかりません。 getViewメソッドとgetLayoutInflaterメソッドを試しましたが、新しいビューを作成していると思うので、画面が変わりません。また、フラグメントAへの参照を取得しようとしましたが、ルーチンを呼び出して新しいフラグメントを作成し、フラグメントBを置き換えることができると考えましたが、表示されていないため、フラグメントAへの参照を取得できません。私が本当にする必要があるのは、新しいビューを膨らませるためにonCreateViewメソッドを再度呼び出すように強制することですが、これを試みるためにいくつかのメソッドを試しましたが、onCreateViewを再度呼び出すことができません。これを行う方法について何か考えはありますか?

14
Chris

FragmentTransactionを実行し、replace()メソッドを使用する必要があります

これはそれほど難しいことではありませんが、答えはメニューがどこにあるかによって異なります(つまり、onOptionsItemSelected()が親アクティビティ内にコールバックするのか、それともフラグメントA/Bにあるのか)。

簡単にするために、メニューの実装とonOptionsItemSelected()が親アクティビティにあり、menu_option1が選択された場合にフラグメントの形状を変更するとします。次のようになります。

_@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
//...
switch (item.getItemId()) {
case R.id.menu_option1:
    //do something
    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    Fragment newFragment = new YourFragmentClass();
    FragmentTransaction transaction = getFragmentManager().beginTransaction();
    transaction.replace(R.id.your_fragment_id, newFragment);
    transaction.addToBackStack(null);
    transaction.commit();
    return true;
case R.id.menu_option2:
    //do something else;
    return true;
default:
    return super.onOptionsItemSelected(item);
}
}
_

または、メニューがフラグメントの1つの子である場合(再利用可能なコードのために必要です)、1つの方法は、ホストアクティビティにフラグメントで定義されたインターフェイスを実装するように要求することです。コールバック。また、フラグメントクラス内のonOptionsItemSelected()コールバックでは、このコールバックメソッドを呼び出すだけです。

一口に聞こえますが、実際に必要なことはいくつかあります。これがフラグメントクラスであると偽ってください

_public static class FragmentA extends ListFragment {
OnSelectedListener mListener;
// Container Activity must implement this interface
public interface OnSelectedListener {
    public void onSelected();
}
...
@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    //This is to ensure that the Activity has implemented the interface we set up above
    try {
        mListener = (OnSelectedListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString() + " must implement OnSelectedListener");
    }
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
//...
switch (item.getItemId()) {
case R.id.menu_option1:
    //do something
    getActivity().onSelected();
    return true;
case R.id.menu_option2:
    //do something else;
    return true;
default:
    return super.onOptionsItemSelected(item);
}
}
...
}
_

次に、アクティビティで、次のようなものが表示されます。

_public class MainActivity extends Activity implements FragmentA.onSelectedListener{
...
public void onSelected(){
    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    Fragment newFragment = new YourFragmentClass();
    FragmentTransaction transaction = getFragmentManager().beginTransaction();
    transaction.replace(R.id.your_fragment_id, newFragment);
    transaction.addToBackStack(null);
    transaction.commit();
}
}
_
9
BMo

ユーザーがメニューオプションを選択した場合、フラグメントBに関連付けられているビューを更新または再描画したいのですが、これを機能させる方法がわかりません。

onOptionsItemSelected()で、アクティビティにフラグメントのメソッドを呼び出して、ウィジェットを新しいコンテンツで更新させます。または、アクティビティにFragmentTransactionを実行させて、フラグメントを置き換えます(フラグメントが元々FragmentTransactionを介して設定された場合)。

1
CommonsWare