EzDevInfo.com

fragment interview questions

Top fragment frequently asked interview questions

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)

Advertisements

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)

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)

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)

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)

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 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)

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)

How do I start an activity from within a Fragment?

I have a set of tabs inside of a FragmentActivity that each hold their own fragment. When I tried to start a new activity from within that fragment via an onClickListener, and using the startActivity(myIntent) method, my application force closes.

After looking around for a while, I found a reference or two to a method called startActivityFromFragment, but after searching around for an hour or so I can't find any explanations or examples of how to use it or whether this is what I should be using.

I guess what I'm asking is whether there is any difference between launching a new activity from an activity, and launching a new activity from a fragment, and if so, what do I need to implement?


Source: (StackOverflow)

FragmentStatePagerAdapter IllegalStateException: is not currently in the FragmentManager

I'm getting this on some cases, in onResume(), of an activity which uses a FragmentStatePagerAdapter. When using device's back button. Not always. Not reproducible.

I'm using support package v4, last revision (8).

Already searched with google, no success finding a useful answer.

Looking in the source, it's thrown here: FragmentManager.java

@Override
public void putFragment(Bundle bundle, String key, Fragment fragment) {
    if (fragment.mIndex < 0) {
        throw new IllegalStateException("Fragment " + fragment
                + " is not currently in the FragmentManager");
    }
    bundle.putInt(key, fragment.mIndex);
}

But why is the index of fragment < 0 there?

The code instantiating the fragments:

@Override
public Fragment getItem(int position) {
    Fragment fragment = null;

    switch(position) {
        case 0:
            fragment = MyFragment.newInstance(param1);
            break;
        case 1:
            fragment = MyFragment2.newInstance(param2, param3);
            break;
    }
    return fragment;
}

@Override
public int getCount() {
    return 2;
}

I also can't debug through the source since the support package doesn't let me attach the source, for some reason... but that's a different question...


Source: (StackOverflow)

Android Fragment does not respect match_parent as height

Sorry for the huge code dump, but I'm truly lost.

MyActivity.java onCreate:

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_singlepane_empty);
mFragment = new PlacesFragment();
getSupportFragmentManager().beginTransaction()
                    .add(R.id.root_container, mFragment)
                    .commit();

PlacesFragment.java onCreateView:

mRootView = (ViewGroup) inflater.inflate(R.layout.list_content, null);
return mRootView;

Notes: mRootView is a ViewGroup global, no problem about it, I believe. PlacesFragment is a ListFragment.

Layouts:

activity_singlepane_empty.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root_container"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#00f">
    <include layout="@layout/actionbar"/>

    <!-- FRAGMENTS COME HERE! See match_parent above -->

</LinearLayout>

list_content.xml:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/listContainer"
        android:background="#990"
        >

        <ListView android:id="@android:id/list"
                android:layout_width="match_parent" 
                android:layout_height="match_parent"
                android:drawSelectorOnTop="false" />

        <TextView android:id="@id/android:empty"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:gravity="center"
                android:textAppearance="?android:attr/textAppearanceMedium" 
                android:text="@string/no_data_suggest_connection"/>

</FrameLayout>

Problem: as you can see, the expected behavior would be to have the empty TextView above to appear centered on the screen. On the design preview in Eclipse, it is OK. Only when added to root_view as a fragment the FrameLayout won't fill the whole screen.

root_container is blue, and FrameLayout is yellowish, see below for debug purposes. Shouldn't the yellow pane fill the whole screen?!?!?!?

enter image description here


Source: (StackOverflow)

Unit Test an Android Fragment

I want to unit test an Android Fragment class.

Can I set up a test using AndroidTestCase or do I need to use ApplicationTestCase?

Are there any useful examples of how these two TestCases can be used? The testing examples on the developer site are minimal and just seem to focus on testing Activities.

All I've found elsewhere are examples where the AndroidTestCase class is extended but then all that's tested is adding two numbers together or if the Context is used, it just does a simple get and tests that something is not null!

As I understand it, a Fragment has to live within an Activity. So could I create a mock Activity, or get the Application or Context to provide an Activity within which I can test my Fragment?

Do I need to create my own Activity and then use ActivityUnitTestCase?

Thanks for your assistance.

Trev


Source: (StackOverflow)

Android 4.4 — Translucent status/navigation bars — fitsSystemWindows/clipToPadding don't work through fragment transactions

When using the translucent status and navigation bars from the new Android 4.4 KitKat APIs, setting fitsSystemWindows="true" and clipToPadding="false" to a ListView works initially. fitsSystemWindows="true" keeps the list under the action bar and above the navigation bar, clipToPadding="false" allows the list to scroll under the transparent navigation bar and makes the last item in the list scroll up just far enough to pass the navigation bar.

However, when you replace the content with another Fragment through a FragmentTransaction the effect of fitsSystemWindows goes away and the fragment goes under the action bar and navigation bar.

I have a codebase of demo source code here along with a downloadable APK as an example: https://github.com/afollestad/kitkat-transparency-demo. To see what I'm talking about, open the demo app from a device running KitKat, tap an item in the list (which will open another activity), and tap an item in the new activity that opens. The fragment that replaces the content goes under the action bar and clipToPadding doesn't work correctly (the navigation bar covers the last item in the list when you scroll all the way down).

Any ideas? Any clarification needed? I posted the before and after screenshots of my personal app being developed for my employer.

One Two


Source: (StackOverflow)

On showing dialog i get "Can not perform this action after onSaveInstanceState"

Some user are reporting, if they use the quick action in the notification bar, they are getting a force close.

I show a quick action in the notification who calls the "TestDialog" class. In the TestDialog class after pressing the button "snooze", I will show the SnoozeDialog.

private View.OnClickListener btnSnoozeOnClick() {
    return new View.OnClickListener() {

        public void onClick(View v) {
            showSnoozeDialog();
        }
    };
}

private void showSnoozeDialog() {
    FragmentManager fm = getSupportFragmentManager();
    SnoozeDialog snoozeDialog = new SnoozeDialog();
    snoozeDialog.show(fm, "snooze_dialog");
}

The error is IllegalStateException: Can not perform this action after onSaveInstanceState.

The code line where the IllegarStateException gets fired is:

snoozeDialog.show(fm, "snooze_dialog");

The class is extending "FragmentActivity" and the "SnoozeDialog" class is extending "DialogFragment".

Here is the complete stack trace of the error:

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1327)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1338)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)
at android.support.v4.app.DialogFragment.show(DialogFragment.java:127)
at com.test.testing.TestDialog.f(TestDialog.java:538)
at com.test.testing.TestDialog.e(TestDialog.java:524)
at com.test.testing.TestDialog.d(TestDialog.java:519)
at com.test.testing.g.onClick(TestDialog.java:648)
at android.view.View.performClick(View.java:3620)
at android.view.View$PerformClick.run(View.java:14292)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4507)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
at dalvik.system.NativeStart.main(Native Method)

I can't reproduce this error, but I am getting a lot of error reports.

Can anybody help that how can I fix this error?


Source: (StackOverflow)