Fragment not showing up - android

I'm having an issue where I can create a Fragment, its view appears to be created, but it doesn't show up. The fragment itself is created and any code inside runs without issue, but it is just invisible somewhere. The back button also interacts with it just fine (it "closes" it), it just doesn't physically show up on screen (only the main layout is displayed).
From my FragmentActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_view);
// some logic here that sets a button listener that calls openAddNamePane() when pressed
}
public void openAddNamePane(){
AddNamePane addNamePane = new AddNamePane();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.layout_root, addNamePane, "AddnamePane");
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
This is the layout for the View that is first displayed (activity_main_view.xml aka my 'root layout'):
<LinearLayout 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"
android:orientation="vertical"
android:background="#color/white"
android:id="#+id/layout_root">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button android:id="#+id/addPlayerButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add Player" />
<Button android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/buttonLabel" />
</LinearLayout>
<ListView android:id="#+id/playerListView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:cacheColorHint="#color/white"
android:entries="#array/testStringArray" >
</ListView>
</LinearLayout>
This is my fragment class:
public class AddNamePane extends Fragment {
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
System.out.println("AddNamePane.onCreateView()");
View view = inflater.inflate(R.layout.add_player_pane_layout, container, false);
return view;
}
// a few other methods here, onAttach(), onStop(), onPause(), etc
// all are empty of logic with just a println to see if they are being called correctly (in which they are)
}
This is the layout for that "AddNamePane" fragment:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
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"
android:orientation="vertical" >
<EditText
android:id="#+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:text="test name here"
android:hint="Name here" >
<requestFocus />
</EditText>
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
I am pretty new to using fragments, not too sure if my issue is in code or if it is something to do with the layouts. My goal is to add the "AddNamePane" to the 'root layout' replacing the main view temporarily. What I did to attempt this was to give my root layout an id and use that in the FragmentTransaction. If it matters, the api level I am using is 8 (Android 2.2) thus using things from android.support.v4.app package.

You're trying to programmatically replace a LinearLayout, while also expecting it to have the hard-coded children. This won't work. You should use a FrameLayout for your FragmentTransaction that is also a child of your layout_root.
If you update your post with the actual xml, I can show you exactly how to do this.

I had a similar problem, when fragment wasn't showing up. The problem was that I removed AndroidAnnotations, but forgot to move the code from onViewCreated and onCreate methods to the onCreateView. I found this mistake by comparing the code of two fragments - one, that was showing up and the other that wasn't. So, if you have similar problems, try to check the code of fragments. It may not show any errors at first glance, but will not still work or show up because of those errors.
Particularly, check that you have this method and that you inflate a view:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.your_fragment_layout, container, false);
return v;
}

tools:layout="#layout/fragment_up"
Use your layout file as above

Related

How can i use fragment xml tag in layout for another fragment?

i'm trying to do a three page which contains list fragment in an activity. All of the pages are fragment(from v4 support library) but i need list fragment inside them. When i tried that i have encountered a problem(https://stackoverflow.com/questions/29473626/viewpager-gives-error-if-i-turn-page) then i have done some research and learned that there can not be fragment(i mean xml fragment tag not adding dynamically nested fragment) in fragment. But for instance, in the last android update of whatsapp there are three page in one activity and one of them has list fragment(chat list) so i wonder how whatsapp have done that? Thanks.
my xml layout which contains list 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" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="17dp"
android:text="Welcome to newsfeed" />
<Button
android:id="#+id/nfButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="52dp"
android:text="#string/signout" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textView1"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:orientation="vertical" >
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swipe_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/nfListFragment"
android:name="com.comp.buzz.newsfeed.NFQuestionFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
tools:layout="#layout/item_question" />
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
onCreativeView method of main fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.activity_newsfeed, container, false);
Fragment fragment = new ListFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.swipe_container, fragment).commit();
return view;
}
You can nest fragments with a few restrictions (according to the doc):
Android 4.2 or higher
You can nest them only programmatically
Update 1
Something like this should do the job:
Fragment fragment = new YourFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.swipe_container, fragment).commit();

Android: Fragment overlay another fragment with semi transparent

Let's say I have 2 fragments, one contain a list view and another contain a loading text. I want when I click on one list item, the loading text fragment appears on top of the list view. I have adjusted the opacity of the loading text background to: android:background="#33FFFFFF" . But still it just shows the loading text on a solid grey background.
<?xml version="1.0" encoding="utf-8"?>
<ListView
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#android:id/list"
android:background="#e8e9ee"
android:divider="#ccc"
android:dividerHeight="1dp"/>
Fragment that contains a textview:
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="#string/loadingText"
android:id="#+id/loadingText"
android:textColor="#e8e9ee"
android:background="#33FFFFFF"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
My java code is basically something like this: onItemClick:
FragmentTransaction transaction=manager.beginTransaction();
transaction.show(loadingFragment);
transaction.commit();
I did it and it works perfectly but instead of using .show I used .add:
Activity layout:
<RelativeLayout
android:id="#+id/layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginRight="5dp"
android:layout_marginEnd="5dp">
<FrameLayout
android:id="#+id/list_view_container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true">
</FrameLayout>
<FrameLayout
android:id="#+id/loading_text_fragment_container"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true">
</FrameLayout>
</RelativeLayout>
In the Activity:
First add your List View:
ListViewFragment listViewFragment = new ListViewFragment();
fragmentManager.beginTransaction().add(R.id.list_view_container, listViewFragment).commit();
Then the loading text:
// Create a new Fragment to be placed in the activity layout
YourFragment yourFragment = new YourFragment();
// Add the fragment to the 'loading_text_fragment_container' FrameLayout
fragmentManager.beginTransaction().add(R.id.loading_text_fragment_container, yourFragment).commit();
In YourFragment.java
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.your_fragment_layout, container, false);
}
And the your_fragment_layout.xml has a common TextView without any special attribute.
Hope it to be useful,
regards!
I think you are actually replacing the original fragment rather than overlaying it. You should create two framelayouts that cover the full screen and then assign the loading fragment to the overlaying frame layout
in you activity
<FrameLayout id="#+id/ListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
<FrameLayout id="#+id/LoadingFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
and then to load them
FragmentTransaction transaction=manager.beginTransaction();
transaction.add(R.id.ListFragment, listFragment);
transaction.commit();
FragmentTransaction transaction=manager.beginTransaction();
transaction.add(R.id.LoadingFragment, loadingFragment);
transaction.commit();

Using Fragment layour ..... findbyViewId always NULL

I am pretty newbie with android development and I am trying to make work an easy example.
When the layout contains fragments, this fragments are inflated and the method findByViewId returns a NULL pointer. I would like to konw how to avoid that.
activity_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.todoit.MainActivity"
tools:ignore="MergeRootFrame" />
so far the only solution I found was to dont use fragment layout :/
fragment_main.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.example.todoit.MainActivity$PlaceholderFragment">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/myEditText"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true" />
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/myListView"
android:layout_below="#+id/myEditText"
android:layout_alignRight="#+id/myEditText"
android:footerDividersEnabled="false" /> </RelativeLayout>
this code returned a NULL pointer
setContentView(R.layout.activity_main); ListView myListView=
(ListView)findViewById(R.id.myListView);
the only way I found was to use this one instead.
setContentView(R.layout.fragment_main); ListView myListView=
(ListView)findViewById(R.id.myListView);
all this code in the onCreate method.
could someone tell me how to solve this issue? is there a way to inflate the whole layout including fragments?
thanks a lot.
Jose
You should inflate the fragment's view in the fragment code only, not in the activity code. You use onCreateView method to do this.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_main, container, false);
ListView myListView= (ListView) v.findViewById(R.id.myListView);
return v;
}
If you want to find your ListView after onCreateView has already been called, you can use getView() method:
ListView myListView= (ListView) getView().findViewById(R.id.myListView);
ListView myListView= (ListView) fragment.getView().findViewById(R.id.myListView); needs to be called from inside the fragment class code and not the main activity. Call it inside method onActivityCreated, by that time the onCreateView function of fragment would have succeeded

ListFragment Layout from xml

How to create a ListFragment (of the support v4 library) layout from xml?
ListFragment sets up its layout programmatically, so if you want to modify it, you need to mess with add/remove view.
I've converted the created layout to xml, you can add/remove your widgets or e.g. add pulltorefresh solutions. You shouldn't change the needed ids.
Because of internal ids needed for some of the widgets an helper function needs to be called and it needs to be in support v4 namespace since constants are internal with default visibility.
list_loader.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/progress_container_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone" >
<ProgressBar
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<FrameLayout
android:id="#+id/list_container_id"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/empty_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center" />
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawSelectorOnTop="false" >
</ListView>
</FrameLayout>
</FrameLayout>
and the class ListFragmentLayout in android.support.v4.app (in your project, you don't need to modify support v4 jar)
package android.support.v4.app;
import your.package.R;
import android.view.View;
public class ListFragmentLayout
{
public static void setupIds(View view)
{
view.findViewById(R.id.empty_id).setId(ListFragment.INTERNAL_EMPTY_ID);
view.findViewById(R.id.progress_container_id).setId(ListFragment.INTERNAL_PROGRESS_CONTAINER_ID);
view.findViewById(R.id.list_container_id).setId(ListFragment.INTERNAL_LIST_CONTAINER_ID);
}
}
in your fragment that extends ListFragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.list_loader, container, false);
ListFragmentLayout.setupIds(view);
return view;
}
From the android sdk (ListFragment) (http://developer.android.com/reference/android/app/ListFragment.html):
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
Provide default implementation to return a simple list view. Subclasses can override to replace with their own layout. If doing so, the returned view hierarchy must have a ListView whose id is android.R.id.list and can optionally have a sibling view id android.R.id.empty that is to be shown when the list is empty.
If you are overriding this method with your own custom content, consider including the standard layout list_content in your layout file, so that you continue to retain all of the standard behavior of ListFragment. In particular, this is currently the only way to have the built-in indeterminant progress state be shown.
So when you want your own layout.xml for a FragmentList overide onCreateView and inflate your own layout.
For example:
Create a android layout (yourlistlayout.xml) and put the following xml on the position where you want to show your ListFragment.
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
</ListView>
in your ListFragment class put the following code:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.yourlistlayout, null);
return v;
}

Fragment update with a new fragment Android

I have a layout of
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical"
android:layout_width="fill_parent" android:layout_height="wrap_content" >
<LinearLayout android:id="#+id/linearLayout1" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_width="wrap_content">
<LinearLayout android:id="#+id/linearLayout13" android:layout_height="wrap_content" android:paddingRight="70dp" android:orientation="vertical" android:paddingLeft="70dp" android:layout_width="wrap_content">
<ImageView android:id="#+id/baby_icon" android:layout_height="wrap_content" android:src="#drawable/baby" android:clickable="true" android:layout_width="wrap_content"></ImageView>
</LinearLayout>
</LinearLayout>
<fragment
android:name="com.nicu.health.FragAFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/yellow_cardlist_fragment"
android:layout_weight="1"
>
</fragment>
</LinearLayout>
On the startup this does show the correct fragment(FragAFragment). Now on the button click for baby_icon I try to remove the current fragment and add a new one(FragBFragment) which has an entirely different layout.
Though I see that the onCreateView method is called and it does return a non-null view but the UI on the screen of the new fragment does not get updated. I use the below code to update the fragment.
Fragment baby = FragBFragment.newInstance(1);
FragmentTransaction ft = getFragmentManager().beginTransaction();
// ft.remove(getFragmentManager().findFragmentById(R.id.yellow_cardlist_fragment));
// ft.add(R.id.yellow_cardlist_fragment, baby);
ft.replace(R.id.yellow_cardlist_fragment, baby);
ft.addToBackStack(null);
Log.i(TAG, "Code for commit = "+ft.commit());
I had tried all combinations of remove, replace and add to get the fragment thing workng, but in vain!
Also further I tried with the code as
<fragment
android:name="com.nicu.health.FragBFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/yellow_cardlist_fragment"
android:layout_weight="1"
>
and this does work to show the second fragment on startup!!!!
Help will be reeally appreicated.
Thanks,
Answer to my question is
Android: can't replace one fragment with another
I added dynamic fragments on start of the main activity and onclick I did a ft.replace to replace the old fragment!
Ok, my first guess: You forgot to say ft.commit();
My second guess:
Lets say u have Activity AB which controls Fragment A and Fragment B.
You also have 3 layouts. Layout_ActivityAB, Layout_FragA, Layout_FragB.
So setContentView(R.layout.Layout_ActivityAB) is called inside Activity AB. That will be the layout in which u tell android where to place the fragment in the screen.
Inside Fragment A or Fragment B:
#Override
//onCreateView is called when an instance of this class is first created.
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.Layout_FragA, container, false); return rootView;
}
R.layout.Layout_FragA is called inside the Fragment. Layout_FragA is the actual content of the Fragment.

Categories

Resources