EzDevInfo.com

fragment.js

A tiny tool for easily loading html fragments and templates fragment.js

Android: When is onCreateOptionsMenu called during Activity lifecycle?

I put a couple of breakpoints in onCreate (one at the beginning, and one at the end of the method), and I also put one at the beginning of onCreateOptionsMenu. The onCreate method is called first, and before it finishes onCreateOptionsMenu is called.

I'm trying to separate the Fragment navigation code in my app, so I have a couple of objects that I delegate onCreateOptionsMenu to depending on if the app is running on phone/tablet (I'm using screen size to determine this, my layout file for large screens has a View I check for after the layout is inflated). The problem I'm having is, I create these objects in onCreate, and I'm getting a null pointer exception when I reference the object in onCreateOptionsMenu.


Source: (StackOverflow)

android:configChanges="orientation" does not work with fragments

I am just trying to adapt some of my applications for HoneyComb.

The issue iI am facing is the destruction of my activity on orientation change (landscape/portrait)

When I was using a classic activity, I wrote in the manifest:

But now, all these lines aren't working anymore!

Is there a workaround for that?

My code:

    <activity android:name=".TwitterActivity" android:label="@string/app_name"
        android:configChanges="keyboardHidden|orientation" />

    <activity android:name=".TwitterActivity$AppListFragment"
    android:configChanges="keyboardHidden|orientation"  />

Source: (StackOverflow)

Advertisements

Fragment not receiving menu callbacks

I have a fragment class that extends Fragment and calls setHasOptionsMenu to participate in the menu. This class also implements onCreateOptionsMenu, onPrepareOptionsMenu and onOptionsItemSelected.

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
        ....
}

I'm dynamically loading this fragment using a FragmentTransaction in my Activity (that extends FragmentActivity).

However none of the menu callbacks (onCreateOptionsMenu, onPrepareOptionsMenu and onOptionsItemSelected) are being called (I've debugged with some breakpoints in those methods) and the menu isn't shown.

Am I missing something? Do I need to add something in my Activity?

I'm using the Android Compatibility Library, compiling with L11 SDK and testing in a Xoom.

EDIT: I've found the problem. My AndroidManifest is targeting L11, this seems to hide the menu button and prevent from the callbacks being called. However if I remove this from the manifest I loose some other features I need (for example the activated state in lists). Does anyone know how to solve this issue (enable the menu button) without removing the targetSdkVersion=11 from the Manifest?


Source: (StackOverflow)

Fragment already added IllegalStateException

I use this method on my container Activity to show a BFrag

public void showBFrag()
{
    // Start a new FragmentTransaction
    FragmentTransaction fragmentTransaction = mFragmentMgr.beginTransaction();

    if(mBFrag.isAdded())
    {
        Log.d(LOG_TAG, "Show() BFrag");
        fragmentTransaction.show(mBFrag);   
    }
    else
    {
        Log.d(LOG_TAG, "Replacing AFrag -> BFrag");
        fragmentTransaction.replace(R.id.operation_fragments_frame, mBFrag);
    }

    // Keep the transaction in the back stack so it will be reversed when backbutton is pressed
    fragmentTransaction.addToBackStack(null);

    // Commit transaction
    fragmentTransaction.commit();        
}

I call it from my container Activity; for the first time:

  • gets into the else statement and mBFrag replace mAFrag.

Then I press the back button:

  • and the operation is reversed (mAFrag is shown but.. does mBFrag is removed?).

Then I go forward again by calling showBFrag() from the same Activity:

  • and it gets AGAIN into the else statement. (so I can deduce that mBFrag is NOT ADDED)
  • but I got a Fragment already added IllegalStateException... (so why it didn't get into the if statement instead?)

So:

  1. Why is the isAdded() method not returning TRUE if I'm getting a Fragment already added IllegalStateException??
  2. Does popBackStack operation completely remove previously added fragments?
  3. What behaviour am I misunderstanding?

EDIT: Here is the complete info of the exception.

06-07 12:08:32.730: ERROR/AndroidRuntime(8576): java.lang.IllegalStateException: Fragment already added: BFrag{40b28158 id=0x7f0c0085}
06-07 12:08:32.730: ERROR/AndroidRuntime(8576):     at android.app.BackStackRecord.doAddOp(BackStackRecord.java:322)
06-07 12:08:32.730: ERROR/AndroidRuntime(8576):     at android.app.BackStackRecord.replace(BackStackRecord.java:360)
06-07 12:08:32.730: ERROR/AndroidRuntime(8576):     at android.app.BackStackRecord.replace(BackStackRecord.java:352)
06-07 12:08:32.730: ERROR/AndroidRuntime(8576):     at myPackageName.containerActivity.showBFrag() // This line: "fragmentTransaction.replace(R.id.operation_fragments_frame, mBFrag);"

Source: (StackOverflow)

How to dismiss a DialogFragment when pressing outside the dialog?

I am using a DialogFragment, and while I have successfully set an image to close (i.e. dismiss) the dialog when pressed, I am having a hard time finding the way to dismiss the dialog when the user clicks anywhere outside it, just as it works with normal dialogs. I thought there would be some sort of

dialogFragment.setCanceledOnTouchOutside(true);

call, but I don't see that in the documentation.

Is this possible with DialogFragment at all? Or am I looking in the wrong places? I tried intercepting touch events in the 'parent' activity but apart from not getting any touch event, it didn't seem right to me.


Source: (StackOverflow)

Best practice to handle orientation change: Android

I was going through various practices to handle orientation change with threads and AsyncTask. I came across following solutions:

  1. Attach-detach model : Attaching and detaching activity to threads and AsyncTask while preserving their instance. (Source: 1, 2)

  2. Headless fragment way : Using a non-UI/headless fragment to do all the thread related operations and retaining its instance on configuration change. (Source: 1, 2)

Are there any other approaches to handle this scenario? What is the recommended practice? I'm asking this because I couldn't find a generic solution anywhere in the Android docs.


Source: (StackOverflow)

display alert dialog in a fragment

I want to display an alert dialog in my app. I am using fragments. I tried the below code to do this:

 AlertDialog ad = new AlertDialog.Builder(context)
            .create();
    ad.setCancelable(false);
    ad.setTitle(title);
    ad.setMessage(message);
    ad.setButton(context.getString(R.string.ok_text), new DialogInterface.OnClickListener() {

        public void onClick(DialogInterface dialog, int which) {
            dialog.dismiss();
        }
    });
ad.show();

but it was crashing and the error in logcat was:

04-18 15:23:01.770: E/AndroidRuntime(9424): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application

From internet I came to know that the crash is due to context issue. I had given context as

context = this.getActivity().getApplicationContext();

I don't know what is the problem with this. Can anybody help me?


Source: (StackOverflow)

How to determine fragment restored from backstack

Been searching for this issue for a while to no avail now:

How to determine fragment is being restored from backstack? I'm using the compatibility library and a ListFragment inside a FragmentActivity. When an item inside ListFragment is selected, a new Fragment is started to replace the ListFragment.

I noticed that when the FragmentActivity gets paused, the Fragment's onSaveInstanceState is called. But when the Fragment is put into the back stack via FragmentTransaction, onSaveInstanceState doesn't get called, then the lifecycle methods onCreateView and onActivityCreated gets called with null savedInstanceState Bundle.

I'm asking this because I want to load some data when the Fragment is created or restored, but not so when user comes back via. backstack.

I've looked at How to check if Fragment was restored from a backstack? but want to add more details in hopes this would incite an answer.

Edit: just noticed http://developer.android.com/reference/android/app/Fragment.html#onSaveInstanceState(android.os.Bundle) says

Note however: this method may be called at any time before onDestroy(). There are many situations where a fragment may be mostly torn down (such as when placed on the back stack with no UI showing), but its state will not be saved until its owning activity actually needs to save its state.

So onSaveInstanceState is definitely out of the question...


Source: (StackOverflow)

Impossible to override onCreateOptionsMenu in ListFragment

I create an app that supports both phone and tablet version so i use the android-support-v4.jar library.

My activity extends the ListFragment and I try to override the onCreateOptionsMenu(Menu menu, MenuInflater inflater) like here: http://developer.android.com/resources/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentMenuSupport.html

I previously called setHasOptionsMenu.

Unfortunately, it seems that I cannot override onCreateOptionsMenu()!!

it keeps telling me:

The method onCreateOptionsMenu(Menu menu, MenuInflater inflater) of type MyFragment must override or implements a supertype method.

And I did that with:

Public class MyFragment extends ListFragment

I am completely lost here.. Thank a lot for any help.


Source: (StackOverflow)

Fragment inner class should be static

I have a FragmentActivity class with inner class that should display Dialog. But I am required to make it static. Eclipse offers me to suppress error with @SuppressLint("ValidFragment"). Is it bad style if I do it and what are the possible consequences?

public class CarActivity extends FragmentActivity {
//Code
  @SuppressLint("ValidFragment")
  public class NetworkConnectionError extends DialogFragment {
    private String message;
    private AsyncTask task;
    private String taskMessage;
    @Override
    public void setArguments(Bundle args) {
      super.setArguments(args);
      message = args.getString("message");
    }
    public void setTask(CarActivity.CarInfo task, String msg) {
      this.task = task;
      this.taskMessage = msg;
    }
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
      // Use the Builder class for convenient dialog construction
      AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
      builder.setMessage(message).setPositiveButton("Go back", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int id) {
          Intent i = new Intent(getActivity().getBaseContext(), MainScreen.class);
          startActivity(i);
        }
      });
      builder.setNegativeButton("Retry", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int id) {
          startDownload();
        }
      });
      // Create the AlertDialog object and return it
      return builder.create();
    }
  }

startDownload() starts Asynctask.


Source: (StackOverflow)

Callback to a Fragment from a DialogFragment

Question: How does one create a callback from a DialogFragment to another Fragment. In my case, the Activity involved should be completely unaware of the DialogFragment.

Consider I have

public class MyFragment extends Fragment implements OnClickListener

Then at some point I could do

DialogFragment dialogFrag = MyDialogFragment.newInstance(this);
dialogFrag.show(getFragmentManager, null);

Where MyDialogFragment looks like

protected OnClickListener listener;
public static DialogFragment newInstance(OnClickListener listener) {
    DialogFragment fragment = new DialogFragment();
    fragment.listener = listener;
    return fragment;
}

But there is no guarantee that the listener will be around if the DialogFragment pauses and resumes through its lifecycle. The only guarantees in a Fragment are those passed in through a Bundle via setArguments and getArguments.

There is a way to reference the activity if it should be the listener:

public Dialog onCreateDialog(Bundle bundle) {
    OnClickListener listener = (OnClickListener) getActivity();
    ....
    return new AlertDialog.Builder(getActivity())
        ........
        .setAdapter(adapter, listener)
        .create();
}

But I don't want the Activity to listen for events, I need a Fragment. Really, it could be any Java object that implements OnClickListener.

Consider the concrete example of a Fragment that presents an AlertDialog via DialogFragment. It has Yes/No buttons. How can I send these button presses back to the Fragment that created it?


Source: (StackOverflow)

HTML position:fixed page header and in-page anchors

If I have a non-scrolling header in an HTML page, fixed to the top, having a defined height:

Is there a way to use the URL anchor (the #fragment part) to have the browser scroll to a certain point in the page, but still respect the height of the fixed element without the help of JavaScript?

http://foo.com/#bar
WRONG (but the common behavior):         CORRECT:
+---------------------------------+      +---------------------------------+
| BAR///////////////////// header |      | //////////////////////// header |
+---------------------------------+      +---------------------------------+
| Here is the rest of the Text    |      | BAR                             |
| ...                             |      |                                 |
| ...                             |      | Here is the rest of the Text    |
| ...                             |      | ...                             |
+---------------------------------+      +---------------------------------+

Source: (StackOverflow)

reusing fragments in a fragmentpageradapter

I have a viewpager that pages through fragments. My FragmentPagerAdapter subclass creates a new fragment in the getItem method which seems wasteful. Is there a FragmentPagerAdapter equivalent to the convertView in the listAdapter that will enable me to reuse fragments that have already been created? My code is below.

public class ProfilePagerAdapter extends FragmentPagerAdapter {

    ArrayList<Profile> mProfiles = new ArrayList<Profile>();

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

    /**
     * Adding a new profile object created a new page in the pager this adapter is set to.
     * @param profile
     */
    public void addProfile(Profile profile){
        mProfiles.add(profile);
    }

    @Override
    public int getCount() {
        return mProfiles.size();
    }

    @Override
    public Fragment getItem(int position) {
        return new ProfileFragment(mProfiles.get(position));
    }
}

Source: (StackOverflow)

Fragment onResume() & onPause() is not called on backstack

I have multiple fragment inside an activity. On a button click I am starting a new fragment, adding it to backstack. I naturally expected the onPause() method of current Fragment and onResume() of new Fragment to be called. Well it is not happening.

LoginFragment.java

public class LoginFragment extends Fragment{
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
      final View view  =   inflater.inflate(R.layout.login_fragment, container, false);
      final FragmentManager mFragmentmanager =  getFragmentManager();

      Button btnHome  = (Button)view.findViewById(R.id.home_btn);
      btnHome.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view){
           HomeFragment fragment    = new HomeFragment();
           FragmentTransaction ft2   =  mFragmentmanager.beginTransaction();
           ft2.setCustomAnimations(R.anim.slide_right, R.anim.slide_out_left
                    , R.anim.slide_left, R.anim.slide_out_right);
           ft2.replace(R.id.middle_fragment, fragment);
           ft2.addToBackStack(""); 
           ft2.commit();    
         }
      });
  }

  @Override
  public void onResume() {
     Log.e("DEBUG", "onResume of LoginFragment");
     super.onResume();
  }

  @Override
  public void onPause() {
    Log.e("DEBUG", "OnPause of loginFragment");
    super.onPause();
  }
}

HomeFragment.java

public class HomeFragment extends Fragment{
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
     final View view  =   inflater.inflate(R.layout.login_fragment, container, false);
  }

  @Override
  public void onResume() {
     Log.e("DEBUG", "onResume of HomeFragment");
     super.onResume();
  }

  @Override
  public void onPause() {
     Log.e("DEBUG", "OnPause of HomeFragment");
     super.onPause();
  }
}

What I expected, was,

  1. When button is clicked, LoginFragment gets replaced with HomeFragment, onPause() of LoginFragment, and onResume() of HomeFragment gets called
  2. When back is pressed, HomeFragment is poped out and LoginFragment is seen, and onPause() of HomeFragment and onResume() of LoginFragment gets called.

What I am getting is,

  1. When button is clicked, HomeFragment is correctly replacing LoginFragment, onResume() of HomeFragment is called, but onPause() of LoginFragment is never called.
  2. When back pressed, HomeFragment is correctly popping to reveal LoginFragment, onPause() of HomeFragment gets called, but onResume() of LoginFragment never gets called.

Is this the normal behaviour? Why is onResume() of LoginFragment not getting called when I press the back button.


Source: (StackOverflow)

How to resume Fragment from BackStack if exists

Hello I am using Fragment. I have created three instances of Fragment and initialize them at the top of the class. I am adding fragment to an activity like this:

Decalring and initializing:

Fragment A = new AFragment();
Fragment B = new BFragment();
Fragment C = new CFragment();

Replacing/Adding Fragment:

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, A);
ft.addToBackStack(null);
ft.commit();

These snippets are working properly. And every Fragment is attached on activity and saved to backStack successfully.

So when I launch A and then launch C and then launch B, the stack becomes

| |
|B|
|C|
|A|
___

And when I press back button, B is destroyed and C is resumed.

But when I again launch fragment A, instead of resuming from backstack, it is added on the top of the backstack

| |
|A|
|C|
|A|
___

But I want to resume A and destroy all fragments upon it (if any). Actaully I just like the deafult backStack behavior of activity. So how can I do that?

Expected: (A should be resumed and top Fragments are to be destroyed)

| |
| |
| |
|A|
___

Edit: (suggested by A--C)

This is my trying code:

private void selectItem(int position) {
        Fragment problemSearch = null, problemStatistics = null;
        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction ft = manager.beginTransaction();
        String backStateName = null;
        Fragment fragmentName = null;
        boolean fragmentPopped = false;
        switch (position) {
        case 0:
            fragmentName = profile;
            break;
        case 1:
            fragmentName = submissionStatistics;
            break;
        case 2:
            fragmentName = solvedProblemLevel;
            break;
        case 3:
            fragmentName = latestSubmissions;
            break;
        case 4:
            fragmentName = CPExercise;
            break;
        case 5:
            Bundle bundle = new Bundle();
            bundle.putInt("problem_no", problemNo);
            problemSearch = new ProblemWebView();
            problemSearch.setArguments(bundle);
            fragmentName = problemSearch;
            break;
        case 6:
            fragmentName = rankList;
            break;
        case 7:
            fragmentName = liveSubmissions;
            break;
        case 8:
            Bundle bundles = new Bundle();
            bundles.putInt("problem_no", problemNo);
            problemStatistics = new ProblemStatistics();
            problemStatistics.setArguments(bundles);
            fragmentName = problemStatistics;
        default:
            break;
        }
        backStateName = fragmentName.getClass().getName();
        fragmentPopped = manager.popBackStackImmediate(backStateName, 0);
        if (!fragmentPopped) {
            ft.replace(R.id.content_frame, fragmentName);
        }
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
        ft.addToBackStack(backStateName);
        ft.commit();

        // I am using drawer layout
        mDrawerList.setItemChecked(position, true);
        setTitle(title[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
    }

The problem is - when i launch A and then B, then press back button, B is removed and A is resumed. and pressing again back button should exit the app. But it is showing a blank window and need another press to close it.

Also when I launch A, then B, then C and then again B, expected:

| |
| |
|B|
|A|
___

But it is showing as:

| |
|B|
|B|
|A|
___

hould I override onBackPressed() with any customization or am I missing anything?


Source: (StackOverflow)