Switching between activities -> infinitie loop - android

I'm new to android and have a "little" problem.
I'm starting the main activity which extend the base class.
The base class starts my "Navigation" class... and in the navigation class i have an switch argument to choose, wich activity should be created - well, at this moment i had an infinitie loop and i have noe idea why..
It works fine when i'm using fragments but i'm want to use activities... Hope someone can help me :)
Here is my code.
public class MainActivity extends Base {
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.v("boot", "MainActivity-onCreate");
super.onCreate(savedInstanceState);
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, new MainFragment())
.commit();
}
Base
public class Base extends ActionBarActivity implements
NavigationDrawer.NavigationDrawerCallback {
public NavigationDrawer mNavigationDrawer;
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.v("boot", "Base-onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set up the drawer
mNavigationDrawer = (NavigationDrawer)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
mNavigationDrawer.setUp((DrawerLayout)findViewById(R.id.drawer_layout),
R.id.navigation_drawer);
}
Navigation
public class NavigationDrawer extends Fragment {
private ActionBarDrawerToggle mDrawerToggle;
private NavigationDrawerCallback mCallbacks;
private DrawerLayout mDrawerLayout;
private ListView mDrawerListView;
private View mFragmentContainer;
private boolean mUserLearnedNavigation;
private static final String PREF_USER_LEARNED_NAVI = "navigation_learned";
private static final String STATE_SELECTED_POSITION = "selected_position";
private int mCurrentSelectedPosition;
private boolean mFromSavedInstanceState;
#Override
public void onCreate(Bundle savedInstanceState) {
Log.v("boot", "Nav - onCreate");
super.onCreate(savedInstanceState);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
mUserLearnedNavigation = sp.getBoolean(PREF_USER_LEARNED_NAVI, false);
if (savedInstanceState != null) {
mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
mFromSavedInstanceState = true;
}
selectItem(mCurrentSelectedPosition);
} ...
private void selectItem(int position) {
Log.v("boot", "Nav - selectitem");
mCurrentSelectedPosition = position;
if (mDrawerListView != null) {
mDrawerListView.setItemChecked(position, true);
}
if (mDrawerLayout != null) {
mDrawerLayout.closeDrawer(mFragmentContainer);
}
if (mCallbacks != null) {
mCallbacks.onNavigationDrawerItemClicked(position);
}
switch (position) {
case 0:
startActivity(new Intent(getActivity(), MainActivity.class));
break;
case 1:
startActivity(new Intent(getActivity(), ExpensesActivity.class));
break;
default:
startActivity(new Intent(getActivity(), MainActivity.class));
break;
}
}

Each time you start an activity, your menu get recreated and thus the switch case get executed. You shouldn't call selectItem in the onCreate of your menu. If you want to keep the user navigation, you'll have to start the proper activity in MainActivity.
You can add a check to see if getActivity is an instance of the activity you want to start before calling startActivity so you don't run in infinite loop again.

Related

Fragment is restored but then recreated on screen orientation

I have an Activity (MainActivity) with a DrawerLayout using a NavigationDrawerFragment as a navigation menu. In this NavigationDrawerFragment, on navigation item click, startActivity(intent to MainActivity with extra) is called to send an intent, received in onNewIntent, to MainActivity ; android:launchMode="singleTop" in the manifest ; to display the corresponding fragment. In onCreate, if saveInstanceState is not null, no fragment transaction is made because the current fragment will be automatically restored.
The problem is : for one fragment (not the others) : DashboardFragment, the one launched by default, on screen orientation, the fragment is restored but then recreated.
I can see that using the debugger : the regular process is called : Activity recreated, fragment restored correctly, then fragment recreated.
I can also see it in the FragmentManager logs (comparing behavior with another fragment) : the fragment is restored correctly but then, I can see a commit replacing the fragment with a new instance of DashboardFragment. In the code, I can't see where this commit would come from (I've put breakpoints in all the commits int the code and none is called).
Do you have any idea why this is happening ?
I can put code on request, this is a complex app, not open source, and I'm not sure which part to put here.
Simplified MainActivity :
public class MainActivity extends MeerkatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MeerkatApplication.get(this).getAppComponent().inject(this);
setContentView(R.layout.base_activity_layout_withdrawer);
setSupportActionBar(toolbar);
navigationDrawerFragment = (NavigationDrawerFragment) getSupportFragmentManager().findFragmentById(R.id.navigationMenu);
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout,
toolbar,
R.string.open_drawer,
R.string.close_drawer);
drawerLayout.addDrawerListener(drawerToggle);
drawerLayout.setStatusBarBackground(R.color.primaryDarkColor);
drawerToggle.syncState();
final ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowTitleEnabled(true);
}
//first calling before onNewIntent :
if (savedInstanceState == null) {
openFirstOpenableSection();
}
if (paneContainer != null) {
// Enable animation
LayoutTransition transition = new LayoutTransition();
transition.enableTransitionType(LayoutTransition.CHANGING);
paneContainer.setLayoutTransition(transition);
}
}
private void openFirstOpenableSection() {
int dc_id = -1;
if(getIntent() != null){
dc_id = getIntent().getIntExtra(EXTRA_DATACENTER_ID,-1);
}
int sectionToOpen = findFirstOpenableSection(sessionInformations
.getOrganizationInformations());
eventBus.post(new NavigationChangedEvent(sectionToOpen));
switch (sectionToOpen) {
case R.id.dashboard:
if(dc_id != -1){
IntentStarter.showDashAfterRequest(this,dc_id);
}else{
IntentStarter.showDashboard(this);
}
break;
...
default:
IntentStarter.showNoSectionAvailable(this);
}
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
Bundle extras = intent.getExtras();
if (extras != null) {
String showAction = intent.getStringExtra(EXTRA_SHOW_ACTION);
if (rightPane != null) {
rightPane.setVisibility(View.GONE);
}
switch (extras.getInt(EXTRA_MENU_ITEM, -1)) {
case EXTRA_MENU_ITEM_DASHBOARD:
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, DashboardFragmentBuilder
.newDashboardFragment(sessionInformations.getUser().getId(),
getResources().getString(R.string.dashboard_personalDashboard),
"pda"), "DASHBOARD")
.commit();
}
drawerLayout.closeDrawer(GravityCompat.START);
break;
...
case EXTRA_MENU_ITEM_LOGOUT:
logout();
break;
default:
break;
}
}
}
IntentStarter :
public final class IntentStarter {
public static void showDashboard(Context context) {
Intent intent = new Intent(context, MainActivity.class);
intent.putExtra(MainActivity.EXTRA_MENU_ITEM, MainActivity.EXTRA_MENU_ITEM_DASHBOARD);
context.startActivity(intent);
}
}
NavigationDrawerFragment :
public class NavigationDrawerFragment extends MeerkatFragment {
#OnClick({R.id.dashboard, ... R.id.logout})
public void onMenuItemSelected(View view) {
switch (view.getId()) {
case R.id.dashboard:
desactivateAllViews();
IntentStarter.showDashboard(getActivity());
view.setActivated(true);
break;
case R.id.logout:
IntentStarter.logout(getActivity());
view.setActivated(true);
break;
...
}
}
}

A resource was acquired at attached stack trace but never released after start splash screen using jeremyfeinstein

currently I need to create an application of wallpaper. I need to start a splash screen before enter into main screen. my main screen is developed using reference from slidingmenu. However, after start splash screen, I have got error below: Please advise and help. Thank you !!
Error after start a fragment activity after run splash screen
E/StrictMode: A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.
java.lang.Throwable: Explicit termination method 'end' not called
at dalvik.system.CloseGuard.open(CloseGuard.java:184)
at java.util.zip.Inflater.<init>(Inflater.java:82)
at com.android.okio.GzipSource.<init>(GzipSource.java:57)
Splash Screen activity
public class SplashScreen extends SherlockActivity {
// Splash screen timer
private static int SPLASH_TIME_OUT = 2000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
new Handler().postDelayed(new Runnable() {
/*
* Showing splash screen with a timer. This will be useful when you
* want to show case your app logo / company
*/
#Override
public void run() {
// This method will be executed once the timer is over
// Start your app main activity
Intent i = new Intent(SplashScreen.this, FragmentChangeActivity.class);
startActivity(i);
// close this activity
finish();
}
}, SPLASH_TIME_OUT);
}
}
Fragment Activity
public class FragmentChangeActivity extends MainActivity {
private Fragment mContent;
public FragmentChangeActivity() {
super(R.string.changing_fragments);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// set the Above View
if (savedInstanceState != null)
mContent = getSupportFragmentManager().getFragment(savedInstanceState, "mContent");
if (mContent == null)
mContent = new ColorFragment(R.color.red);
// set the Above View
setContentView(R.layout.content_frame);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content_frame, mContent)
.commit();
// set the Behind View
setBehindContentView(R.layout.menu_frame);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.menu_frame, new ColorMenuFragment())
.commit();
// customize the SlidingMenu
getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
getSupportFragmentManager().putFragment(outState, "mContent", mContent);
}
public void switchContent(Fragment fragment) {
mContent = fragment;
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content_frame, fragment)
.commit();
getSlidingMenu().showContent();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.share:
new AlertDialog.Builder(this)
.setTitle(R.string.share)
.setMessage(Html.fromHtml(getString(R.string.apache_license)))
.show();
break;
case R.id.info:
new AlertDialog.Builder(this)
.setTitle(R.string.info)
.setMessage(Html.fromHtml(getString(R.string.about_msg)))
.show();
break;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.example_list, menu);
return true;
}
}
Remove the
public MainActivity(int titleRes) {
mTitleRes = titleRes;
}
Activity classes are instantiated with the no-arg constructor and your activity does not have it. Declaring an explicit constructor prevents the implicit no-arg constructor from being generated.
To pass parameters to activities, use the extras Bundle with the Intent. Start an Activity with a parameter
I am able to display the splash screen now. Here is the code:
public class SplashScreen extends SherlockFragmentActivity {
// Splash screen timer
private static int SPLASH_TIME_OUT = 2000;
private PictureFragment mainFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Add the fragment on initial activity setup
if (savedInstanceState == null) {
// Add the fragment on initial activity setup
mainFragment = new PictureFragment();
getSupportFragmentManager()
.beginTransaction()
.add(android.R.id.content, mainFragment)
.commit();
} else {
// Or set the fragment from restored state info
mainFragment = (PictureFragment) getSupportFragmentManager()
.findFragmentById(android.R.id.content);
}
}
}
Here is the code to display splash screen image
public class PictureFragment extends SherlockFragment {
// Splash screen timer
private static int SPLASH_TIME_OUT = 2000;
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_splash, container, false);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent i = new Intent(getActivity(), FragmentChangeActivity.class);
startActivity(i);
getActivity().finish();
}
}, SPLASH_TIME_OUT);
return view;
}
}

Navigation Drawer AsyncTask

I would like to expose my problem and I want to know how I could solve it.
In my application I'm using an activity, making a simple login, launching a asyncTask. At the end of this task, the user is redirected to another activity, which is the home activity of application. The latter has the task of managing a navigation drawer and its fragments. The contents of each fragment must be populated with data retrieved from a server and the navigation drawer set the default fragment F1, which is displayed after the user has logged on.
Now the problem is:
How can I recover the data necessary to populate the listView contained in fragment1?
I know how to implement an adapter for the listView, but I don't understand how to communicate the home activity with the fragment F1. My intention would be to retrieve a circular dialog (content in F1) and run it as long as the data required for the adapter have not been recovered.
Here some code:
public class LoginActivity extends ActionBarActivity {
private Button loginButton;
private ProgressDialog progressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
loginButton = (Button) findViewById(R.id.login_button);
loginButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new Login().execute();
}
};
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private class Login extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(LoginActivity.this);
progressDialog.setMessage("Login");
progressDialog.setCancelable(false);
progressDialog.show();
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if (progessDialog.isShowing()) {
progressDialog.dismiss();
}
Intent intent = new Intent(getApplicationContext(), HomeActivity.class);
Bundle bundle = new Bundle();
intent.putExtras(bundle);
startActivity(intent);
}
#Override
protected Void doInBackground(String... params) {
// code to retrieve data.
}
}
}
public class HomeActivity extends ActionBarActivity implements FragmentDrawer.FragmentDrawerListener {
private Toolbar toolbar;
private FragmentDrawer fragmentDrawer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowHomeEnabled(false);
fragmentDrawer = (FragmentDrawer) getSupportFragmentManager().findFragmentById(R.id.fragment_navigation_drawer);
fragmentDrawer.setUp(R.id.fragment_navigation_drawer, (DrawerLayout) findViewById(R.id.drawer_layout), toolbar);
fragmentDrawer.setDrawerListener(this);
// Here the problem!!!
displayView(0);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_home, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private void displayView(int position) {
switch (position) {
case 0:
Fragment fragmentOne = new FragmentOne();
move(matchFragment);
break;
case 1:
Fragment fragmentTwo = new FragmentTwo();
move(teamFragment);
break;
case 2:
Fragment fragmentThree = new FragmentThree();
move(myTeamFragment);
break;
case 3:
//other fragment....
default:
break;
}
}
public void move (Fragment fragment) {
if (fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container_body, fragment, fragment.getClass().getSimpleName());
fragmentTransaction.commit();
}
}
#Override
public void onDrawerItemSelected(View view, int position) {
displayView(position);
}
}
public class FragmentOne extends Fragment {
private ListView listView;
private ArrayList<Info> infos;
private InfoAdapter infoAdapter;
public FragmentOne() {}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_match, container, false);
listView = (ListView) rootView.findViewById(R.id.match_list_view);
return rootView;
}
}
Now, where do I implement the AsyncTask to retrieve data for adapter? In fragment or the Activity?
If it were the Activity, how can I recover the elements of view of fragment?
Thanks in advance and sorry for bad english.
for your first quesiton:
I don't understand how to communicate the home activity with the
fragment F1
You can pass information from HomeActivity to the Fragment through parameters passed to the Fragment's constructors. So instead of Fragment fragmentOne = new FragmentOne();, you can call Fragment fragmentOne = new FragmentOne(A a); where a is data you want to pass to the fragment. Of course, you need to add in the constructor with parameters to the Fragment class.
For the 2nd point:
Now, where do I implement the AsyncTask to retrieve data for adapter?
In fragment or the Activity? If it were the Activity, how can I
recover the elements of view of fragment?
You can put AsynchTask call inside onCreate() to load data for the listView...etc. Another option which I prefer is to use Loaders. Please see this documentation on Loaders here http://developer.android.com/guide/components/loaders.html. It also has an example.
For explanation and sample, you can follow these 4-part tutorials:
http://www.androiddesignpatterns.com/2012/07/loaders-and-loadermanager-background.html.

How to Call Navigation Drawer Fragment from Activity?

I have a Navigation Drawer which is created by Android studio. I Called a Activity from the Navigation Drawer.In that Activity, the navigation drawer is not showing up ?
How can i Call the Navigation Drawer from the below Activity ?
PlayerActivity
import com.google.android.youtube.player.YouTubeInitializationResult;
import com.google.android.youtube.player.YouTubeStandalonePlayer;
public class PlayerActivity extends Activity {
private static final int REQ_START_STANDALONE_PLAYER = 1;
private static final int REQ_RESOLVE_SERVICE_MISSING = 2;
private static final String PLAYLIST_ID = "PL5BxbbBpI7r";
public static final String DEVELOPER_KEY = "AIwXEZQLS-U";
private NavigationDrawerFragment mNavigationDrawerFragment;
private CharSequence mTitle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player);
}
public void Play(View v) {
int startIndex = 0;
int startTimeMillis = 0;
boolean autoplay = true;
boolean lightboxMode = false;
Intent intent = null;
intent = YouTubeStandalonePlayer.createPlaylistIntent(this, DEVELOPER_KEY,
PLAYLIST_ID, startIndex, startTimeMillis, autoplay, lightboxMode);
if (intent != null) {
if (canResolveIntent(intent)) {
startActivityForResult(intent, REQ_START_STANDALONE_PLAYER);
} else {
// Could not resolve the intent - must need to install or update the YouTube API service.
YouTubeInitializationResult.SERVICE_MISSING
.getErrorDialog(this, REQ_RESOLVE_SERVICE_MISSING).show();
}
}
}
private boolean canResolveIntent(Intent intent) {
List<ResolveInfo> resolveInfo = getPackageManager().queryIntentActivities(intent, 0);
return resolveInfo != null && !resolveInfo.isEmpty();
}
}
Navigation.java
public class Navigation extends Activity
implements HomeFragment.OnFragmentInteractionListener, NavigationDrawerFragment.NavigationDrawerCallbacks, NewsFragment.OnFragmentInteractionListener{
#Override
public void onFragmentInteraction(Uri uri) {
}
private NavigationDrawerFragment mNavigationDrawerFragment;
private CharSequence mTitle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_navigation);
mNavigationDrawerFragment = (NavigationDrawerFragment)getFragmentManager().findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
}
#Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getFragmentManager();
switch(position){
case 0:
HomeFragment homeFragment = new HomeFragment();
fragmentManager.beginTransaction().replace(R.id.container, HomeFragment.newInstance("",""))
.commit();
break;
case 1:
NewsFragment newsFragment = new NewsFragment();
fragmentManager.beginTransaction()
.replace(R.id.container, NewsFragment.newInstance("",""))
.commit();
break;
case 2:
Intent intent= new Intent(this,PlayerActivity.class);
startActivity(intent);
break;
}
}
public void onSectionAttached(int number) {
switch (number) {
case 1:
mTitle = getString(R.string.title_section1);
break;
case 2:
mTitle = getString(R.string.title_section2);
break;
case 3:
mTitle = getString(R.string.title_section3);
break;
}
}
public void restoreActionBar() {
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(mTitle);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.navigation, menu);
restoreActionBar();
return true;
}
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_navigation, container, false);
return rootView;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((Navigation) activity).onSectionAttached(
getArguments().getInt(ARG_SECTION_NUMBER));
}
}
}
NavigationDrawer is meant to work with fragments, because the drawer is a fragment itself. You can access that drawer as long as you stay in the same Activity but once you change Activity you can't access to the drawer (Unless you create another instance of the drawer, but then you are missing the whole point of it). In order to accomplish what you want I'd recommend two things.
1) Instead of launching a new Activity make PlayerActivity a fragment.
2) Create a BaseActivity with a drawer and make all your other Activities extend it, that way you only have one single reference to the drawer in your project.
You should use fragment instead of activity! You should have two fragments as default when you create the project. One is for navigation drawer, and the other one is for content. You should replace that content fragment with your new content which you put in second activity..
You need to do the same thing in the PlayerActivity
mNavigationDrawerFragment = (NavigationDrawerFragment)getFragmentManager().findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
Also put navigation drawer inside R.layout.activity_player.
Like you did in R.layout.activity_navigation

Fragment replaced by first one on orientation change

I have a problem with one thing - when I change orientation my second fragment, which is active at the moment, replaces by first fragment. I have never so such a behaviour, how can If fix it?
MainActivity:
public class MainActivity extends SherlockFragmentActivity implements onDialogClickListener, ITaskLoaderListener {
FragmentManager fm;
public ActionBar actionBar;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pager_layout);
fm = getSupportFragmentManager();
actionBar = getSupportActionBar();
actionBar.setHomeButtonEnabled(false);
actionBar.setDisplayUseLogoEnabled(true);
actionBar.setDisplayShowTitleEnabled(false);
FragmentTransaction ft = fm.beginTransaction();
ft.add(android.R.id.content, new FirstActivity.FirstFragment(), "loan").commit();
}
}
FirstFragment:
public class FirstActivity extends SherlockFragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "here");
final ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayUseLogoEnabled(true);
actionBar.setDisplayShowTitleEnabled(false);
FragmentManager fm = getSupportFragmentManager();
if (fm.findFragmentById(android.R.id.content) == null) {
FirstFragment first = new FirstFragment();
fm.beginTransaction().add(android.R.id.content, first).commit();
}
}
public static class FirstFragment extends SherlockFragment implements OnClickListener, OnItemClickListener {
private static final String TAG = "LoanFragment";
private View rootView;
private Button bExtend;
private FragmentManager fm;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (session.hasLoan()) {
rootView = inflater.inflate(R.layout.fragment_loan, container, false);
bExtend = (Button) rootView.findViewById(R.id.b1);
return rootView;
}
}
#Override
public void onClick(View v) {
FragmentTransaction ft = fm.beginTransaction();
switch (v.getId()) {
case R.id.b1:
ft.add(android.R.id.content, new SecondActivity.SecondFragment(), "second").addToBackStack(null).commit();
break;
}
Second Fragment:
public class SecondActivity extends SherlockFragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayUseLogoEnabled(true);
actionBar.setDisplayShowTitleEnabled(false);
FragmentManager fm = getSupportFragmentManager();
if (fm.findFragmentById(android.R.id.content) == null) {
SecondFragment second = new secondFragment();
fm.beginTransaction().add(android.R.id.content, second).commit();
}
}
public static class SecondFragment extends SherlockFragment {
private View rootView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_extend, container, false);
return rootView;
}
That`s to say when I am in second fragment and try to change orientation then my second fragment will replaced on first fragment. Why? How to fix it?
onCreate will be called on orientation change and you add the first fragment there. You can save which fragment you want to show in onSaveInstanceState and then use the instance state in onCreate to add the correct fragment.
EDIT:
You need to maintain a variable currentFragmentIndex and save it in onSaveInstanceState like so:
protected void onSaveInstanceState(Bundle bundle) {
super.onSaveInstanceState(bundle);
bundle.putInt("currentFragment", currentFragment);
}
Then retrieve it in onCreate and initialize the fragment accordingly:
public void onCreate(Bundle bundle) {
if (bundle!= null){
currentFragmentIndex= bundle.getInt("currentFragment");
} else {
currentFragmentIndex = 0;
}
switch(currentFragmentIndex) {
case 0:
// TODO: Add first fragment
break;
case 1:
// TODO: Add second fragment
break;
}
}
Don't forget to change currentFragmentIndex to 1 when you switch to the second fragment.
I ran into the same issue, though as a note, I'm using the v4 support library. After reading Sapan Diwakar's answer, I wondered if this was necessary; instead, I tried this...
if (null == mFragmentManager.findFragmentByTag(TAG_HERE)) {
mFragmentManager.beginTransaction()./*blah blah blah*/.commit();
}
...so the original fragment is only instantiated/attached if there's nothing already attached where it's supposed to go.
I've tested this a bit and it seems to be fine... of course, the fact that it works doesn't mean it's a good idea, but I'm too new at this to know why it wouldn't be. If anyone can chime in on that, it'd be useful.
Thanks for posting this question, and also to everyone with input!

Categories

Resources