フラグメントを埋め込む主なアクティビティがあります:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
vd = VirtualDatabaseTableProvider.getInstance(getApplicationContext());
fm = getSupportFragmentManager();
fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
//Create Layout and add fragments
setContentView(R.layout.main_window);
ListFragment ListFragment= new ListFragment();
android.support.v4.app.FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragment_pane, ListFragment, "List");
//ft.replace(R.id.fragment_pane, ListFragment);
ft.addToBackStack(null);
ft.commit();
//Initialising buttons
imgBtnFontInc = (ImageButton) findViewById(R.id.ImgBtnUpFont);
imgBtnFontInc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(textViewAttached){
try{
//Some text Resize
}
}catch (NullPointerException npe){
Log.e(TAG, "Error on calling Text resize");
Log.e(TAG, npe.getMessage());
Log.e(TAG, npe.getStackTrace().toString());
}
}
}
}
);
/* More Buttons code..... */
imgBtnFontDec.setVisibility(View.GONE);
imgBtnFontInc.setVisibility(View.GONE);
/* Some Saved State handling to recover detailed text Screen*/
if(savedInstanceState != null){
if (savedInstanceState.containsKey("UUID")){
try{
String uuid = savedInstanceState.getString("UUID");
if (uuid != null){
iniTextScreen(uuid);
}
}catch (Exception e){
Log.e(TAG, "Unable To return text");
}
}
}
テキストは関数で初期化されます:
private void initTextScreen(String StringID){
Bundle Data = new Bundle();
Data.putString("UUID", StringID);
TextScreenFragment TextFragment = new TextScreenFragment();
TextFragment.setArg1ments(Data);
if(fm == null){
fm = getSupportFragmentManager();
}
android.support.v4.app.FragmentTransaction ft = fm.beginTransaction();
ft.setCustomAnimations( R.anim.animation_enter, R.anim.animation_exit);
ft.replace(R.id.fragment_pane, TextFragment, "TextFragment");
ft.addToBackStack(null);
ft.commit();
}
TextScreenFragment からの単純なコールバックを使用して、メイン アクティビティでのボタンの可視性を処理しました。メイン アクティビティでのコールバック:
public void onTextViewAttached() {
textViewAttached = true;
MainActivity.this.imgBtnFontDec.setVisibility(View.VISIBLE);
MainActivity.this.imgBtnFontInc.setVisibility(View.VISIBLE);
}
TextScreenFragment で呼び出されるコールバック:
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (!(activity instanceof Callbacks)) {
throw new IllegalStateException(
"Activity must implement fragment's callbacks.");
} else {
listener = (Callbacks) activity;
listener.onTextViewAttached();
}
}
public interface Callbacks {
/**
* Callback for when an item has been selected.
*/
public void onTextViewAttached();
}
それは機能しますが、私がアンドロイド携帯電話を置くと、ポートレート/ランドスケープモードが切り替わります.フラグメントの onAttached は、メインのアクティビティとボタンオブジェクトの onCreate の前に呼び出されます。メインアクティビティでonCreateが呼び出される前に、メインアクティビティにフラグメントをアタッチするにはどうすればよいですか?
ボタンが既に初期化された後、onCreate メソッドの最後に特定のフラグメントをアタッチしましたが、onCreate でボタン オブジェクトが初期化されていないため、フラグメントをアタッチして null 例外を取得する前に、フラグメントの onAttach が呼び出されるのはなぜですか? それはどのように可能ですか?
コメントアウトすると:
`// MainActivity.this.imgBtnFontDec.setVisibility(View.VISIBLE);
//MainActivity.this.imgBtnFontInc.setVisibility(View.VISIBLE);`
コールバック関数public void onTextViewAttached()
では、クラッシュはもうありませんが、メイン アクティビティが作成される前に onAttach が呼び出され、2 回呼び出されることに気付きました。地獄からの初期化されていないアクティビティで 1 回は (メイン アクティビティのすべての要素が null であるか、デフォルト値を持っている)、2 番目です。フラグメントがメイン アクティビティ onCreate から適切にアタッチされる時間。
私は、オリエンテーション スイッチのフラグメントが初期化されていないアクティビティにアタッチされるという結論に達しました。レイアウトからボタンを取得するには、メイン アクティビティで onCreate の前に他の関数を呼び出す必要がありますか?
それは、私が気付いていないフラグメント自動アタッチ動作の一種であり、利用できるのでしょうか?
メインアクティビティが作成される前に onAttach がフラグメントで呼び出されるため、フラグメントがアタッチされたアクティビティのライフサイクルは直感に反するように見えます。