0

У меня есть эта иерархия в моем андроид приложениеФрагмент перезагружается при изменении ориентации

активность содержит фрагмент FragmentGame, который содержит FragmentTypeOfGame;

активность >> FragmentGame >> FragmentTypeOfGame

Внутри FragmentGame, я получил таймер и другие метки, поэтому, когда я изменить ориентацию экрана, моя игра кажется перезапуском, но я могу проверить таймер продолжает работать (потому что это еще один поток, я думаю).

Итак, мой вопрос: как мне удастся сохранить весь экран без перезагрузки.

У меня уже были эти ссылки, но я не могу узнать, как его решить?

Why not use always android:configChanges="keyboardHidden|orientation"?

Forcing Android to not redraw activity on orientation change

Вот идет мой манифест:

<application 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:theme="@style/AppTheme" 
    > 
    <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/> 
    <activity 
     android:name=".MainActivity" 
     android:label="@string/app_name" 
     android:configChanges="orientation" 
     > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 

    <activity android:name="com.facebook.FacebookActivity" 
     android:configChanges= 
      "keyboard|keyboardHidden|screenLayout|screenSize|orientation" 
     android:theme="@android:style/Theme.Translucent.NoTitleBar" 
     android:label="@string/app_name" /> 

    <provider android:authorities="com.facebook.app.FacebookContentProviderXXXXXXXXX" 
     android:name="com.facebook.FacebookContentProvider" 
     android:exported="true" /> 
</application> 

Вот мой GameFragment OnCreateView:

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 

    //Default components start 
    defaultComponentsStarting(inflater, container); 

    FourBlocksGameStyle f = new FourBlocksGameStyle(); 
    frgManager.beginTransaction().replace(R.id.rl_root, f, "4blocks").addToBackStack(null).commit(); 

    if (savedInstanceState != null) { 
     // Restore last state 
     actualGameTime = savedInstanceState.getDouble("actualGameTime"); 
    } 

    handler = new Handler(Looper.getMainLooper()); 
    mainRunnable = new Runnable() { 
     @Override 
     public void run() { 
      // Do something and reschedule ourself 

      if(GAMETIME <= actualGameTime){ 
       cancelTimer(); 

       setLabel(txtTimer, 0, GAMETIME/1000); 
       int countSum = Integer.parseInt(txtHits.getText().toString()); 

       //Devolve pra main cuidar da finalização 
       Intent i = new Intent(ctx, MainActivity.class); 
       i.putExtra("CountSum", countSum); 
       startActivity(i); 
      } 
      else { 
       actualGameTime += GAMEDELAY; 
       double floatingTime = actualGameTime/1000; 

       setLabel(txtTimer, 0, floatingTime); 
       handler.postDelayed(this, GAMEDELAY); 
      } 
     } 
    }; 
    return view; 
} 

и здесь моя MainActivity onCreate?

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    FacebookSdk.sdkInitialize(getApplicationContext()); 
    setContentView(R.layout.activity_main); 

    this.setVolumeControlStream(AudioManager.STREAM_MUSIC); 

    final SharedPreferences prefs = getSharedPreferences("hitColor", MODE_PRIVATE); 
    int startHighscore = prefs.getInt("highScore", 0); 

    gameOver = new GameOverFragment(); 
    highScoreGameOver = new HighScoreFragment(); 
    game = new GameFragment(); 

    Intent i = getIntent(); 
    int countSum = i.getIntExtra("CountSum", -1); 

    if(countSum == -1) { 
     //Log.d("GSS", "Primeira entrada"); 
     if(savedInstanceState == null) { 
      Log.d("GSS", "savedInstace null"); 
      getFragmentManager() 
        .beginTransaction() 
        .replace(R.id.layout_root_view, game) 
        .addToBackStack(null) 
        .commit(); 
     } 
    } 
    else { 
     Log.d("GSS", "COUNT: " + String.valueOf(countSum)); 
     Log.d("GSS", "HIGH: " + String.valueOf(startHighscore)); 

     finishGame(countSum, startHighscore, prefs); 
    } 
} 
+0

Пожалуйста, проверьте этот вопрос. Он должен помочь вам: http://stackoverflow.com/questions/10126845/handle-screen-rotation-without-losing-data-android – aviundefined

ответ

1

С текущей конфигурации для деятельности configChanges-х, Ваш фрагмент воссоздаст UI при изменении ориентации. Поскольку это будет совершенно новый макет, это имеет смысл.

Но ваш фрагмент не будет звонить onCreate еще раз. Он начнется с onCreateView после звонка и onStop, чтобы уничтожить интерфейс фрагмента.

Таким образом, когда ориентация изменяется, то есть, когда фрагмент переходит в , вы должны сохранить данные пользовательского интерфейса в Bundle объекта (определить его как глобальную переменную внутри фрагмента) в . Поскольку Фрагмент начнется с onCreateView, вы сможете восстановить данные своего пользовательского интерфейса после раздувания вашего макета в методе onCreateView.

Bundle savedInstanceState будет null. Он не будет хранить ваши данные при изменении конфигурации, поэтому вы не можете полагаться на это.

+1

Мне нравится ваш комментарий о сохранении данных, когда onPause(). –

0

вот пример, как вы можете получить данные из Фрагмента вручную ..

public class RetainedFragment extends Fragment { 

// data object we want to retain 
private MyDataObject data; 

// this method is only called once for this fragment 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    // retain this fragment 
    setRetainInstance(true); 
} 

public void setData(MyDataObject data) { 
    this.data = data; 
} 

public MyDataObject getData() { 
    return data; 
} 
public Bitmap getBitmap() { return bitmap; } 
public void setBitmap(Bitmap bmp) { bitmap = bmp; } 
} 

затем в вашем MainActivity, вы получите данные, когда фрагмент перезагружается,

public class MyActivity extends Activity { 

private RetainedFragment dataFragment; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    // find the retained fragment on activity restarts 
    FragmentManager fm = getFragmentManager(); 
    dataFragment = (DataFragment) fm.findFragmentByTag(“data”); 

    // create the fragment and data the first time 
    if (dataFragment == null) { 
     // add the fragment 
     dataFragment = new DataFragment(); 
     fm.beginTransaction().add(dataFragment, “data”).commit(); 
     // load the data from the web 
     dataFragment.setData(loadMyData()); 
    } 

    // the data is available in dataFragment.getData() 
    ... 
} 

@Override 
public void onDestroy() { 
    super.onDestroy(); 
    // store the data in the fragment 
    dataFragment.setData(collectMyLoadedData()); 
} 
} 

еще, вы можете восстановить объект, но вы никогда не должны передавать объект, который привязан к деятельности, таких как Drawable, Adapter, View или любой другой объект, связанный с контекстом. надеюсь, что это помогает ..

Кроме того, вы можете установить восстановление следующим способом,

@Override 
public void onConfigurationChanged(Configuration newConfig) { 
super.onConfigurationChanged(newConfig); 

// Checks the orientation of the screen 
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { 
    Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show(); 
    // code for landscape configurtion // load the previous data. 
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){ 
    Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show(); 
    // code for landscape configurtion // load the previous data. 
} 
} 
Смежные вопросы