I am trying to get a fragment to show that contains an EditText and a button. I am new to using fragments, so I am not sure exactly what the error message I get when trying to create the fragment means.
I have a class that extends Fragment, this is where the EditText and button are created.
public class EditNameFragment extends android.support.v4.app.Fragment {
EditText editText;
ImageButton button;
public EditNameFragment(){
}
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.edit_name_dialog, container, false);
editText = (EditText) view.findViewById(R.id.editTextDialog);
button = (ImageButton) view.findViewById(R.id.submitNewItemButtonDialog);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//stuff
}
});
return view;
}
Here is edit_name_dialog.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:id="#+id/edit_name_dialog"
>
<EditText
android:id="#+id/editTextDialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<ImageButton
android:id="#+id/submitNewItemButtonDialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
</LinearLayout>
And here in my main activity (which must extend FragmentActivity because of another part) is where I try to set up my Fragment. I think it has something to do with what id I am referencing. I have seen some people using container classes when using fragments, but I do not understand why this is done.
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
EditNameFragment fragment = new EditNameFragment();
fragmentTransaction.add(R.id.edit_name_dialog, fragment, "tag");
fragmentTransaction.commit();
I get the error message when trying to run the code above
No view found for id 0x7f09002a (com.myapp:id/edit_name_dialog) for fragment EditNameFragment
If anyone could explain what I am missing here/ why people use container classes, that would be great. I know some people add fragments using XML, but I would like to do this only using java.
EDIT
I have added a class that extends FragmentActivity, following the model for a container class
public class EditNameFragmentActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.edit_name_fragment_container);
}
}
Is the parameter for setContentView supposed to be the layout, or an id?
Here is the xml file that defines where the fragment should be
edit_name_fragment_container.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
>
<fragment android:name="com.returnjump.spoilfoil.EditNameFragment"
android:id="#+id/edit_name_fragment_container"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout="#layout/edit_name_fragment" />
</LinearLayout>
So for the parameter in
fragmentTransaction.add(R.id.edit_name_dialog, fragment, "tag");
this is supposed to reference the id of the fragment, correct?
It still gives me the same error, what am I missing?
There are basically two ways to add a fragment to an activity like the documentation say:
"statically": by declaring the fragment inside the activity's layout file.
"dynamically": adding the fragment programmatically. Like you tried to do.
Here is the documentation: http://developer.android.com/guide/components/fragments.html
If you wish to add it dynamically, here is the documentation part that you want to read:
At any time while your activity is running, you can add fragments to your activity layout. You simply need to specify a ViewGroup in which to place the fragment.
To make fragment transactions in your activity (such as add, remove, or replace a fragment), you must use APIs from FragmentTransaction. You can get an instance of FragmentTransaction from your Activity like this:
FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
You can then add a fragment using the add() method, specifying the fragment to add and the view in which to insert it. For example:
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
The first argument passed to add() is the ViewGroup in which the fragment should be placed, specified by resource ID, and the second parameter is the fragment to add.
Once you've made your changes with FragmentTransaction, you must call commit() for the changes to take effect.
And about why to use dynamic fragments instead of static fragments, it has been made for interactive UI allowing you to simply handle different fragments into one activity as you please.
Related
even though i googled extensively, i cant find a solution to my problem. I am new to programming, so please consider that in your answer.
I have a Main Activity and a Menu bar at the bottom. Since the menu bar is scrollable and i want to have it for all the different screens, i figured out that i could - instead of making an intent for a new activity - just put a fragment on top of the existing screen (and spare out the menu bar).
But i fail at programatically opening that fragment. I tried the following, but it doesnt even recognice the ID of the FrameLayout.
I was trying to replace a FrameLayout in my Main Activities' xml file with the fragment:
FragmentManager fragmentManager = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction ft =
fragmentManager.beginTransaction();
ft.replace(R.id.idOfFrameLayout, new nameOfFragmentClass());
ft.commit();
EDIT:
It works after i implemented OnFragmentInteractionListener into the Main Activity. Thanks to everyone!
My original answer suggested using add instead of replace for the Fragment transaction. I have since learned that either can be used in this case. For more info on the differences, see this, this and this
Since my add/replace idea was off base, I've changed my answer to a simple Fragment tutorial. One Fragment inflated from one Activity. I've included the code for Fragment to Activity communication (the reason for the OPs problem) but left comments on what could be deleted if that's not needed. The only thing done in the Activity is launching the Fragment then receiving a message back from that Fragment. The Fragment has a button that will cause a message to be sent back to the Activity. The message will then be Logged.
In both classes, if no communications is needed from the Fragment to the Activity, delete anything that is marked TODO:
// this is what controls whether you use a Fragment from the support library
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class SimpleActivity extends AppCompatActivity
// TODO: delete "implements SimpleFragment.OnFragmentInteractionListener" from this
// line (leave the '{')
implements SimpleFragment.OnFragmentInteractionListener {
private static final String TAG = SimpleActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simple);
SimpleFragment fragment = new SimpleFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.add(R.id.fragment_container, fragment)
.commit();
}
// TODO: this entire method can be deleted
#Override
public void onFragmentInteraction(String message) {
// This is where you can act on the message from the Fragment. You would do
// things that are done from an Activity or you may pass the message on
// to another Fragment.
Log.d(TAG, message);
}
}
Most import statements aren't shown, I left this one in to indicate using the support library
import android.support.v4.app.Fragment;
public class SimpleFragment extends Fragment {
private OnFragmentInteractionListener mListener; // TODO: delete this line
public SimpleFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_simple, container, false);
Button button = (Button)rootView.findViewById(R.id.msg_button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// TODO: delete these 3 lines, do something else with the button click
if (mListener != null) {
mListener.onFragmentInteraction("Message from Fragment");
}
}
});
return rootView;
}
// TODO: this entire method can be deleted
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
// TODO: this entire method can be deleted
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
// TODO: this entire method can be deleted
public interface OnFragmentInteractionListener {
void onFragmentInteraction(String message);
}
}
Now the layout files. 1st activity_simple.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragment_container"
>
</FrameLayout>
</android.support.constraint.ConstraintLayout>
Then fragment_simple.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Info to Activity"
android:id="#+id/msg_button"
/>
</RelativeLayout>
This is a very basic sample. Here is a more extensive guide for Fragment usage.
When you use the 'replace' method, you need 3 things:
1- the container id, which is the view that is going to hold your fragment's view.
2- the fragment instance you want to use and
3- the fragment instance's tag, but this is optional.
Given that, let's say you have the following layout for your activity:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
...
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.v4.widget.NestedScrollView>
<android.support.design.widget.BottomNavigationView
android:id="#+id/navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="?android:attr/windowBackground"
app:menu="#menu/navigation" />
</android.support.design.widget.CoordinatorLayout>
The FrameLayout which id is "container" is the holding view, so that's the id you've gotta use:
ft.replace(R.id.container, new nameOfFragmentClass());
I suggest use this library to manage fragments:
FragmentManagerAndroid
Solved! Thanks everyone for your help.
I am struggling with Fragments as a concept, and especially seem stuck on this one thing. What I'm trying to do is, using my fragment, manipulate its own layout's data. Every time I try to access an ImageButton from within the Fragment, it crashes the application. It works fine from the activity. Am I just misunderstanding Fragments fundamentally?
Code(cut down for size)-
This is the beginning of the activity my fragment is called from:
Display.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
MyFragmentClass MyFragment = new MyFragmentClass();
fragmentTransaction.add(R.id.fragment_container, MyFragment);
fragmentTransaction.commit();
The XML for that Activity:
activity_display.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.mycompanyname.myprojectname.Display"
android:id="#+id/display_layout">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragment_container">
</FrameLayout>
</RelativeLayout>
The Fragment
MyFragmentClass.java
public class MyFragmentClass extends Fragment
{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_layout_screen, container, false);;
}
public void MethodTest()
{
}
}
The Fragment's XML file:
fragment_layout_screen.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragment_layout_screen"
tools:context="com.mycompanyname.myprojectname.MyFragmentClass">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/my_button"
android:clickable="true"
android:onClick="buttonPress"
android:src="#drawable/button"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"/>
</RelativeLayout>
Basically I had all of this originally in Display.java, but wanted to add fragments, so I'm trying to move stuff out and into fragments, but I still need the ability to manipulate the xml info, I just can't.
From inside the Display.java activity I can easily call the ImageButton like this:
ImageButton myButton = (ImageButton) findViewById(R.id.my_button)
but if I do the same from MethodTest in the fragment, the app crashes.
I've searched many suggestions on here, trying various solutions from here: findViewById in Fragment but none of those seemed to work.
I've been reading through this for the setup: http://developer.android.com/guide/components/fragments.html and can't seem to find what I'm doing wrong.
Any help would be appreciated, and if you have any questions about my setup, please ask.
declare on fragment private View rootView;
On the onCreateView(...) set rootView = inflater.Inflate(..); and then access the imagebutton as ImageButton mButton =(ImageButton) rootView.findViewById(..);
Do like this in fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.gridview, container, false);
GridView gridview = (GridView) view.findViewById(R.id.grid);
return view ;
I'm quite new to Android dev and I followed the official Android's "Get started".
The fact is, my fragment is not displayed on the main activity ( it worked well few days ago but I changed some lines, I don't remember which ones ). I think it's a very basic problem as I don't use sophisticated fragments : it's basically one fragment inside an activity.
This is my activity :
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container1"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.mysecond.MainActivity"
tools:ignore="MergeRootFrame" />
My fragment :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
</RelativeLayout>
And the java code for this activity (I have some other activities in the app, based on the same pattern "one fragment inside one activity" and they work well...)
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container1, new PlaceholderFragment()).commit();
}
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
return rootView;
}
}
}
Any ideas ?
Thank you :)
[edit]
so this is my new onCreate method :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportFragmentManager().beginTransaction().replace(
R.id.container1, new PlaceholderFragment()).commit();
}
Still not working for this activity (If I add a button in activity_main.xml I'll be able to see it but the I'm not able to see the TextView in the fragment...)
No errors in logcat and yes the activity is launched (I added some Log.e in onCreate and onCreateView and I cas see them)
In your onCreate methode you don't have to check if the savedInstanceState is null but if the the content of the FrameLayout you use is null
Or you simply always replace the fragment with a new one and ommit any checking.
Instead of add, you can use replace.
You can do it like below shown code:
getSupportFragmentManager().beginTransaction().replace(
R.id.container1, new PlaceholderFragment());
For me this work. Implementa a interface FragmentActions with the init() method and use this
private void showFragment(String fragmentTag){
FragmentTransaction trasaction = getSupportFragmentManager().beginTransaction();
FragmentActions fragment = (FragmentActions) getSupportFragmentManager().findFragmentByTag(fragmentTag);
if(fragment==null ){
if(lastFragmentviewed!=null)
trasaction.hide(lastFragmentviewed);
fragment = (FragmentActions) newInstance(fragmentTag);
trasaction.add(R.id.content_frame,(Fragment) fragment,fragmentTag);
}else{
if(lastFragmentviewed!=null && !lastFragmentviewed.equals(fragment))
trasaction.hide(lastFragmentviewed);
if(getSupportFragmentManager().findFragmentByTag(fragmentTag)!=null){
fragment.init();
trasaction.show((Fragment) fragment);
}else
trasaction.add(R.id.content_frame,(Fragment) fragment,fragmentTag);
}
lastFragmentviewed=(Fragment) fragment;
trasaction.commit();
}
I decided to switch from multiple activities to one activity which switches between fragments however the application now crashes.
Here is the activity I am adding the fragment to
public class MainActivity extends SherlockFragmentActivity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyFragment fragment = new MyFragment();
fragment.setArguments(getIntent().getExtras());
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, fragment).commit();
}
Here is the fragment its an observer and has functionality but to save space ill just show the creation
public class MyFragment extends SherlockFragment implements Observer{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.my_fragment, container, false);
}
Heres my_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/my_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" >
... HAS SOME TEXT VIEWS HERE!
</RelativeLayout>
The crash I get is
02-15 16:17:41.079: E/AndroidRuntime(18668): FATAL EXCEPTION: main
02-15 16:17:41.079: E/AndroidRuntime(18668): java.lang.RuntimeException:
Unable to start activity ComponentInfo{com.example.myapp/com.example.myapp.MainActivity}:
java.lang.IllegalArgumentException:
No view found for id 0x7f040036 for fragment MyFragmentt{41a05910 #0 id=0x7f040036}
Can anyone help me out here? I can't really figure out what is causing this. I know if I comment out getSupportFragmentManager() in main activity (the top code block in this post) it will run just not draw anything in my fragment.
UPDATE
The frame_container which I'm not sure where to place
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
So the way you can use Fragments in your applications are two.
First way is if you declare the Fragment in your xml file like this :
<fragment android:name="com.example.news.ArticleReaderFragment"
android:id="#+id/viewer"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />
The second way is if you add / replace your Fragments dynamically to your container which in the most examples is FrameLayout. Here is how you can do that :
In your main FragmentActivity :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.myFragmentContainer);
}
and in your xml myFragmentContainer.xml is where you place your fragment_container and it looks like :
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
and you are adding and replacing your Fragments like this :
if (findViewById(R.id.fragment_container) != null) {
if (savedInstanceState != null) {
return;
}
// Create an instance of ExampleFragment
HeadlinesFragment firstFragment = new HeadlinesFragment();
// if there are any extras
firstFragment.setArguments(getIntent().getExtras());
// Add the fragment to the 'fragment_container' FrameLayout
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, firstFragment).commit();
}
and for the next Fragment which you want to show just do :
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container, secondFragment).commit();
I am trying to make my app more tablet-friendly, and so I'm trying to learn fragments. I want the typical two-pane layout, where the left side is the "navigation", and you click on one of the elements, and it changes the fragment on the right.
I can duplicate the tutorials that use a ListFragment for the left, and if you click on one of them, it updates the "details" fragment on the right.
I've tried the best I can to duplicate that code, and just use a LinearLayout, with buttons for the left side, so that if a button is clicked, it loads the appropriate fragment on the right, but it's not working.
When I commit the FragmentTransaction, I get java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. What is the child's parent, and why do I have to call removeView on it?
I'm trying to load the fragment into a FrameLayout, but I've also just tried replacing another Fragment in the layout, and still get the error.
Ideally I want the left fragment to take up the whole screen until a button is pressed that requires a fragment to come in from the left, but one problem at a time I suppose.
Code
Main Activity
public class FragmentExample2Activity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
SelectorFragment (Left side)
public class SelectorFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View fragment = inflater.inflate(R.layout.selector, container);
Button button1 = (Button) fragment.findViewById(R.id.button1);
button1.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
getFragmentManager().beginTransaction().replace(R.id.detail_holder, new DetailsFragment(), "stuff").commit();
}
});
return fragment;
}
}
DetailsFragment
public class DetailsFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
return inflater.inflate(R.layout.details, container);
}
}
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<fragment class="com.coreno.testfragment.SelectorFragment"
android:id="#+id/select"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
/>
<fragment class="com.coreno.testfragment.DetailsFragment"
android:id="#+id/detail_holder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2"
/>
<!--
<FrameLayout
android:id="#+id/detail_holder"
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight="2"
/>
-->
</LinearLayout>
When you inflate a layout xml file, don't specify the parent view. It sounds very counter-intuitive to not specify where you're putting this inflated view but it works.
So, for example, in your SelectorFragment change the line:
View fragment = inflater.inflate(R.layout.selector, container);
to
View fragment = inflater.inflate(R.layout.selector, null);
or even better
View fragment = inflater.inflate(R.layout.selector, container, false);
Don't forget to do the same in your DetailsFragment too.
When you inflate a layout inside the getView method of a Fragment, you must use the next inflate method:
inflater.inflate(R.layout.details, container, false);
The key is the third parameter. It must be false not to attach the inflated layout to the container, because the system already done it. If it is true or is not indicated a redundant group view is created.