Fragment is transparent and shows Activity below - android

My Android application launches into BeginActivity which is a subclass of SherlockFragmentActivity and shows it's first view using:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getSupportFragmentManager().findFragmentById(android.R.id.content) == null) {
Fragment f = LoginFragment.newInstance();
getSupportFragmentManager()
.beginTransaction()
.add(android.R.id.content, f, "loginfragment")
.attach(f)
.commit();
}
}
LoginFragment shows a view like this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.login, container, false);
// Get pointers to text views
usernameField = (EditText) v.findViewById(R.id.usernameLog);
passwordField = (EditText) v.findViewById(R.id.passwordLog);
progressBar = (ProgressBar) v.findViewById(R.id.progressBarLog);
// Set button click listeners for both buttons
Button b = (Button) v.findViewById(R.id.loginButton);
b.setOnClickListener(this);
return v;
}
when clicking login I show a list view like this:
BeginActivity top = (BeginActivity) getActivity();
Fragment f = OfferListFragment.newInstance();
top.getSupportFragmentManager()
.beginTransaction()
.add(android.R.id.content, f, "offerList")
.addToBackStack(f.getClass().getSimpleName())
.commit();
and finally, OfferListFragment displays its view like this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.offers, container, false);
return v;
}
Now the problem I am having, is that the final OfferListFragment seems to be transparent and I can see the login screen below it. I am using Theme.Sherlock that has a black background. Should I be manually setting the views backgrounds to black also? Or would the black in the theme be customisable by the user on the system? (I'm not an Android user).
Thanks

IMHO I do not agree with this answer.
You may want to replace your fragment or you may want to add it.
For example let's say that you are in a fragment that is a list retrieved by a network request, if you replace the fragment with let's say the detailFragment and you add it to backStack.
When you go back your fragment will redo the network query, of course you can cache it but why? It is a back to a previous state, so with add the last fragment will be in exactly the same status with no code whatsoever.
Fragments are transparent backgrounded by default because they can be used to paint only a small portion of the screen but if your fragment is match_parent then just set its background to a color and keep using add on the fragmentTransaction.
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrollView1"
android:background="#android:color/white"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
That will be your root element on the fragment layout XML, could be linear, etc etc
and the transaction code is:
YourFragment detail = YourFragment.newInstance(Id);
ft.add(R.id.contentHolder, detail);
ft.addToBackStack(TAG);
ft.commit();
Hope this helps someone that wants to know how to see a solid background without changing the add to replace which is usually not the best case.
Regards

Try using FragmentTransaction class to replace the fragments instead of just adding.
Explanation:
Each transaction is a set of changes that you want to perform at the same time. You can set up all the changes you want to perform for a given transaction using methods such as add(), remove(), and replace(). Then, to apply the transaction to the activity, you must call commit().
Before you call commit(), however, you might want to call addToBackStack(), in order to add the transaction to a back stack of fragment transactions. This back stack is managed by the activity and allows the user to return to the previous fragment state, by pressing the Back button.
For example, here's how you can replace one fragment with another, and preserve the previous state in the back stack:
Example:
// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
Reference:
Please have a look at Managing Fragments
I hope it will be helpful !!

i used many techniques but no gain
Finally i fixed it by adding background of the container or the fragment layout like this
android:background="#android:color/white"
you just need to add in your Layout or the container view of you Fragment
Hope it will help

Well, giving background to fragment is not always enough. For example if your background activity or fragment contains buttons, then we should set elevation for our FragmeLayout so that our fragment comes on top of other elements. Something like this:
<FrameLayout
android:elevation="5dp"
... />
and then inside our fragment layout, we should set a background and make clickable attribute true to prevent working of buttons in background activity or fragment. Something like this :
<androidx.constraintlayout.widget.ConstraintLayout
...
android:background="#android:color/darker_gray"
android:clickable="true">

Nobody mentioned that if you added a background to your Fragment but you are still getting a transparent background, you need to check that your FrameLayout is the last view in your XML.
Because z-index in Android is calculated by XML position and lowest view in the hierarchy have the highest z-index.
For example I fixed this problem recently simply moving the FrameLayout from here:
<androidx.coordinatorlayout.widget.CoordinatorLayout
...>
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<RelativeLayout
...>
</RelativeLayout>
<RelativeLayout
...>
</RelativeLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
to here:
<androidx.coordinatorlayout.widget.CoordinatorLayout
...>
<RelativeLayout
...>
</RelativeLayout>
<RelativeLayout
...>
</RelativeLayout>
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

Related

set android:name of <fragment> programmatically

Is it possible to set the name of added in XML layout from activity class, I need to make transition between fragments which are includes on the activity but only on and replace the fragment name by new one.
<fragment
android:name="com.example.harry.comparateur_de_prix.Accueil.AccueilFragment" //To change
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragment1">
</fragment>
Firstly you will need to change your Activity's XML layout to include a FrameLayout like this:
<!--Other XML layout elements, view-groups, views etc...; other stuff-->
<FrameLayout
android:id="#+id/id_1"
android:layout_width="#dimen/fl_width"
android:layout_height="#dimen/fl_height">
</FrameLayout>
What we want to do now is; to be able to replace that FrameLayout in the Activity's XML layout above that we just added with the layout of one of your Fragment's layout file.
Now in your Activity file,
instantiate a FragmentManger object
obtain a fragmentTransaction instance via the fragmentManagers beginTransaction() method.
/*1)*/ FragmentManager fragmentManager = getSupportFragmentManager();
/*2)*/ FragmentTransaction ft = fragmentManager.beginTransaction();
Then make these changes
ft.replace(R.id.id_1, new YourFragment());
ft.commit();
The argument YourFragment() will require you to insert an instance of one of your Fragments
, this will replace the FrameLayout's current layout with that of YourFragments(). We finally commit the fragmentTransaction.
If you want to replace the Fragment that the FrameLayout displays, simple begin a new fragment transaction and replace the frame layout with a new Fragment as shown above.
You want to use a FrameLayout instead here.
Then use FragmentTransaction to replace that ViewGroup by its ID attribute

Replacing activity with fragment just overlays latter on top of former

When I try to replace an activity with a fragment, my app ends up rendering the fragment on top of the activity:
<!-- activity.xml -->
<CoordinatorLayout
android:id="#+id/coord_layout">
... stuff ...
</CoordinatorLayout>
here is the fragment:
<!-- fragment.xml -->
<LinearLayout
android:id="#+id/frag_layout">
... stuff ...
</LinearLayout>
Here is my Main class:
private void selectDrawerItem(MenuItem menuItem) {
Fragment f = fragment.newInstance();
FragmentManager fragManager = getSupportFragmentManager();
fragManager.beginTransaction().replace(R.id.coord_layout, f).commit();
}
What am I doing wrong?
FragmentTransactions deal only with (dynamically created) Fragments. Any Views within the container ViewGroup you're using to hold the Fragment are not affected by a replace(). That is, the Fragment will just be added on top of them. If you want to completely replace the existing layout, you should replace the CoordinatorLayout in your activity.xml with an empty ViewGroup - usually a FrameLayout - and use the CoordinatorLayout as the layout for another Fragment that you can load upon startup, which can then be swapped out accordingly with your FragmentTransaction.

Fragments, How to overlay Fragment layout to an existing Layout XML and vice-a-versa?

In my App, an Activity having a layout xml (first page) inflates onCreate method. On some event(like button click), i want to use Fragment class, and inflate layout xml via Fragments, on the above said layout xml as a container. like below , is my layout xml(first page).
<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">
<Button ... . >
</FrameLayout>
On Button click, i want to use Fragments within the same Layout container. So i use below code in Activity (on button click).
FragmentManager fManager= getFragmentManager();
FragmentTransaction fTransaction = fManager.beginTransaction();
MyFragment frag = new MyFragment();
fTransaction.replace(R.id.container,frag);
fTransaction.commit();
Now, new layout via Fragment is visible but the old layout is also in the background and visible.
I don't want to use Fragments from the very first layout, as i am doing.
I want to inflate a layout xml first, then on some event, use Fragments layout, and again , from Fragments , i want to switch to Layout xml, means vice-a-versa.
like,
Layout xml inflate via setContentView() -> layout via Fragments -> Layout xml inflate via setContentView()
How to hide or make invisible layout xml (first page) when Fragment layout gets inflates and vice-a-versa ?
If the fragment covers the whole screen, you can set the background of the fragment a solid color.

Android - Activity inside linear layout

I am creating an app with a WebView and an invisible menu on top of the page (it only appears when double clicked on the screen). That menu is a simple linear layout with buttons inside. Each button will start a different activity and I would like to make it so the menu would work in all activities.
I was thinking of creating a main layout that would consist of (invisible) menu on top and on the rest of the screen it would have the space for other activities. I want each activity to have its own layout aswell.
Maybe I could create that layout with menu on top and the rest of the space would be linear layout. Then I would call each activity inside that linear layout.
Is that possible and if it is, how to do it?
Any help will be appreciated.
as i understand you can do it like that :
1- create a class which extneds LinearLayout for the menu.
2- create a class extends activity and inside of it create that menu view
3- all your other activities should extends the activity you created in step 2.
4- inside all other activities onStart you should add menu view to the screen
but i strongly suggest you to use navigation Drawer.
http://developer.android.com/design/patterns/navigation-drawer.html and
http://developer.android.com/training/implementing-navigation/nav-drawer.html
You can achieve this by creating one Activity which have your invisible layout at top and a FrameLayout as container for your Fragments :
MainActivit.java
public class MainActivity(){
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main)
}
}
and activity_main.xml
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/invisible_menu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true" >
<!-- your other views here -->
</LinearLayout>
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/invisible_menu" />
</RelativeLayout>
That's the MainActivity which will hold all your Fragments. For using Fragments in your app you should check Android Developers - Fragments
Edit: Here is how you can add/replace Fragments via code:
To add your first Fragment simply call :
FragmentTransaction transaction = getFragmentManager().beginTransaction();
ExampleFragment fragment = new ExampleFragment();
transaction.add(R.id.fragment_container, fragment);
transaction.commit();
// Commit the transaction
transaction.commit();
And after that to replace the content with another Fragment , you should do something like this in your onClick :
// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
So basically you should use FragmentTransaction.add() and FragmentTransaction.replace() .
If you want to support older versions of Android (i.e. avoiding fragments), you can use an <include> to add the menu layout to each activity. You'll need to hook up the click events in the onCreate of each activity, though you can encapsulate this code in another class.

Fragments in a linear layout after configuration change

I have an activity that contains a linear layout and a fragment placeholder.
<RelativeLayout >
<LinearLayout/>
<fragment />
</RelativeLayout>
In onCreate() for the activity I place a fragment in the fragment placeholder and multiple fragments in the linear layout. This works fine until the phone goes through a configuration change (e.g. orientation change).
I do nothing special for an orientation or configuration change. What happens is really strange: the fragment placeholder is populated correctly but the linear layout now contains duplicate fragments. i.e. if the linear layout had fragment1 and fragment2 in it before, it will now show fragment1 fragment2 fragment1 fragment2. What is going on here?
As an additional note: I am using reflection to create the fragment objects, but I don't think that should change anything.
The framework will automatically add the fragments to your view when the orientation is changed. Only execute the add fragment transactions when the paramBundle is null.
Example (using support library):
#Override
public void onCreate(Bundle paramBundle) {
super.onCreate(paramBundle);
if (paramBundle == null) {
FragmentManager localFragmentManager = getSupportFragmentManager();
FragmentTransaction localFragmentTransaction = localFragmentManager
.beginTransaction();
localFragmentTransaction.add(R.id.fragmentHost,
new MyFragment(), MY_FRAGMENT_TAG);
localFragmentTransaction.commit();
}
}

Categories

Resources