Can't add the fragment to activity programmatically - android

Yes. I know that there are a lot of the questions like mine, BUT I watched them all (I guess)
I think that I am doing everything right, but it still does not work
I have a frameLayout. I tried to use add() instead of replace() and that does not work.
I try to add a fragment in OnLoadFinished() - method.
My code:
Bundle fragBundle = new Bundle();
fragmentManager = getFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
ContactInfoFragment contactInfoFragment = (ContactInfoFragment) fragmentManager.findFragmentByTag("contactInfo");
if (contactInfoFragment == null){
switch(type) {
case "44": {
//passing some data to bundle
break;
}
case "223":{
//passing some data to bundle
break;
}
}
contactInfoFragment = new ContactInfoFragment();
contactInfoFragment.setArguments(fragBundle);
fragmentTransaction.replace(R.id.contact_layout, contactInfoFragment, "contactInfo");
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
fragmentManager.executePendingTransactions();
}
Please, help me
My Layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="0dp"
android:paddingRight="0dp"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:background="#ffffff"
tools:context="com.example.tenderplan.activities.ElementActivity">
<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/scrollView"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="0dp"
android:paddingRight="0dp"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:background="#ffffff"
tools:context="com.example.tenderplan.activities.ElementActivity"
android:id="#+id/element_layout"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/contact_layout">
</FrameLayout>
<fragment
android:name="com.example.tenderplan.fragments.DocumentsFragment"
android:id="#+id/documents_fragment"
android:layout_height="wrap_content"
android:layout_width="match_parent"
tools:layout="#layout/documents_fragment"
android:layout_below="#+id/contact_info_fragment"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="16dp" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/attachmentslayout2"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="#+id/documents_fragment">
</LinearLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id = "#+id/comments_layout">
</FrameLayout>
</LinearLayout>
</ScrollView>
Actually, I need the contact_layout to be replaced.

You should not commit fragment transactions in onLoadFinish, you can read:
Called when a previously created loader has finished its load. Note that normally an application is not allowed to commit fragment transactions while in this call, since it can happen after an activity's state is saved. See FragmentManager.openTransaction() for further discussion on this.
https://developer.android.com/reference/android/app/LoaderManager.LoaderCallbacks.html#onLoadFinished%28android.content.Loader%3CD%3E,%20D%29
http://developer.android.com/reference/android/app/FragmentManager.html#beginTransaction()
so what you should do is to use commitAllowingStateLoss() instead of commit().

Related

How to have fragment-replace and additional UI change happen together?

My MainActivity has a TabLayout that I'm showing(View.VISIBILE) when certain fragments(say type A) are loaded and hiding(View.GONE) when other fragments(say type B) are loaded.
Now while transitioning between type A and type B fragments - the TabLayout and the fragment don't load together. First the TabLayout becomes visible and the previous fragment shifts down, then the new fragment replaces the old fragment. Of course this happens in milliseconds but some visible effect is there on looking carefully.
How can I make sure both TabLayout visibility change and fragment replace happen together?
Here is the code to load fragments in MainActivity.java:
...
private View mTitleWithTabs = findViewById(R.id.title_and_hometabs);
...
#UiThread
public void loadFragment(Fragment fragment) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction
.add(R.id.frameLayout, fragment)
.addToBackStack(null)
.commit();
if (/* type A fragment */) {
setTabsHomeButtonSelected(true); // setting an ImageView as selected or not
scrollAndSelectTabAtPositionOnlyUI(0);
mTitleWithTabs.setVisibility(View.VISIBLE);
} else {
setTabsHomeButtonSelected(false);
mTitleWithTabs.setVisibility(View.GONE);
}
}
Here is the relevant code from activity_main.xml
...
<include
android:id="#+id/title_and_hometabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
layout="#layout/title_with_hometabs"/>
<FrameLayout
android:id="#+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#id/exo_mini"
android:layout_below="#id/title_and_hometabs"/>
...
Here is title_with_hometabs.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/title_with_hometabs"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:showIn="#layout/activity_main">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:orientation="horizontal"
android:weightSum="1">
<TextView
android:id="#+id/title"
android:paddingStart="35dp"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight=".90"
android:gravity="center"
android:text="#string/app_name"
android:textColor="#color/colorViewAll"
android:textSize="#dimen/text_size_22" />
<ImageView
android:id="#+id/search_browser"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
android:layout_weight=".10"
android:src="#drawable/ic_search_black_14dp" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/colorDivider" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="42dp"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="?actionBarSize"
android:layout_height="42dp"
android:gravity="center">
<ImageView
android:id="#+id/home_button_tabs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="#mipmap/home" />
</RelativeLayout>
<View
android:layout_width="0.5dp"
android:layout_height="match_parent"
android:background="#color/colorDivider" />
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabs_list"
android:layout_height="42dp"
android:layout_width="match_parent"
app:tabBackground="#android:color/transparent"
app:tabRippleColor="#null"
app:tabMode="scrollable"
app:tabIndicatorColor="#android:color/holo_red_dark"
app:tabSelectedTextColor="#android:color/holo_blue_dark"
app:tabTextAppearance="#style/CustomTabLanguages"/>
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="#color/colorDivider" />
</LinearLayout>
</LinearLayout>
The thing that worked for me was to use getSupportFragmentManager().executePendingTransactions() after calling commit() inside the loadFragment() method in MainActivity.java.
This is because the delay between additional UI element in MainActivity and fragment-load was coming because of FragmentManager.commit() being asynchronous.
Other ways that I explored and didn't work:
Using FragmentManager.commitNow() doesn't work because I need the backstack.
Using FragmentManager.runOnCommit(additionUIElementChangeRunnable) doesn't also allow the fragment transaction to be added the backstack.
Note: FragmentManager.commitNow() doesn't allow using backstack because ordering guarantee in backstack can't be provided when commitNow is used with commit.

Android Fragment view does not scroll when keyboard is up

I am loading a fragment like this
String tag = fragment.getClass().getSimpleName();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(android.R.id.content, fragment,tag);
transaction.addToBackStack(tag);
transaction.commit();
The activity has this property set
android:windowSoftInputMode="adjustResize"
In my view I have a button at the bottom that I want to keep on top of the keyboard. This is what my fragment layout file looks like
<RelativeLayout xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:fillViewport="true"
android:isScrollContainer="true">
<LinearLayout..../>
</ScrollView>
<Button
android:id="#+id/activate_button"
style="#android:style/Widget.DeviceDefault.Light.Button.Borderless.Small"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />
</RelativeLayout>
I have an EiditText in this view and when I request focus the soft keyboard appears but view doesn't scroll.
Can anyone tell me why view is not resizing when keyboard is up?
I found two solutions that worked for me
Put this in the onCreate of your fragment:
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE|WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
Or
Use a ScrollView as parent of your FrameLayout in the Activity, like this:
<ScrollView>
<FrameLayout/>
</ScrollView>
Try this, Change Parent RelativeLayout `
android:layout_height="wrap_content"
into
android:layout_height="match_parent"
<RelativeLayout xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="#+id/activate_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="10dp"/>
</RelativeLayout>

SlidingUpPanel loads wrong panel with FragmentStatePagerAdapter

I'm having a problem using SlidingUpPanel (https://github.com/umano/AndroidSlidingUpPanel) and FragmentStatePagerAdapter.
I have 3 fragments in the pager: the first two with a sliding panel (one a fragment and one a hardcoded layout) and the third without it.
When I had a pager with just two fragments the panel were working perfectly fine. Now that I've added a third they are not working anymore.
At first the fragment are created correctly, but when I swipe all the way to the third and then come back the panel get messed up.
Basically the panel that used to be on the first fragment is now on the panel of the second one, the hardcoded layout of the second panel is now gone and the panel of the first fragment is empty.
The main content of all fragment is still correct and behaves as intended.
I've drawn a schema of the situation to explain better:
My code to select the fragment is:
public Fragment getItem(int i) {
Fragment fragment = null;
switch (i) {
case 0:
fragment = new MatchListFragment();
break;
case 1:
fragment = new StreamFragment();
break;
case 2:
fragment = new PendingMatches();
break;
default:
break;
}
return fragment;
}
Layout of first fragment (MatchListFragment):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
android:gravity="center"
android:orientation="vertical"
android:visibility="visible">
CONTENT
</RelativeLayout>
<FrameLayout
android:id="#+id/scrollable_panel"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Layout of second fragment (StreamFragment)
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:id="#+id/log_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="false"
android:divider="#drawable/material_divider"
android:dividerHeight="1dp"
android:visibility="visible" />
</LinearLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/scrollable_panel"
android:layout_width="match_parent"
android:layout_height="88dp"
android:background="#color/white"
android:gravity="center">
<ImageView
android:id="#+id/icon"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_alignParentBottom="true"
android:background="#color/light_gray" />
<ImageView
android:layout_width="25dp"
android:layout_height="10dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_margin="5dp"
android:src="#drawable/green_pill" />
<LinearLayout 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:layout_above="#id/icon"
android:layout_alignParentTop="true"
android:orientation="horizontal">
<com.coffeestrap.android.Widgets.IconAndText
android:id="#+id/profile_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:layout_weight="1"
app:resource="#drawable/ic_profile_icon"
app:undertext="New" />
<com.coffeestrap.android.Widgets.IconAndText
android:id="#+id/talk_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:layout_weight="1"
app:resource="#drawable/ic_talk_icon"
app:undertext="Learning" />
<com.coffeestrap.android.Widgets.IconAndText
android:id="#+id/conversation_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:layout_weight="1"
app:resource="#drawable/ic_conversation_icon"
app:undertext="Teaching" />
<com.coffeestrap.android.Widgets.IconAndText
android:id="#+id/all_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:layout_weight="1"
app:resource="#drawable/ic_all_icon"
app:undertext="All" />
</LinearLayout>
</RelativeLayout>
I cant really understand how to solve this especially because on the second fragment (StreamFragment()) the sliding panel layout is hardcoded and I can't understand why it loads everything else correctly and the replace the panel with the one from the first fragment(MatchListFragment).
In the end I strongly believe it's an issue with the library I'm using and not one caused by me.
I've opened an issue on their github page
here

FragmenManager replace makes overlay

I'm using supportlib v4 to reach master-detail flow.
Problem:
New instance of "details" fragment overlays the first one (xml created) instead replace it.
My Activity layout is:
<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:orientation="horizontal"
tools:context=".TrackListActivity" >
<fragment
android:id="#+id/fragmentList"
android:name="pl.com.digita.BikeComputerUi.TrackList.TrackListFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<fragment
android:id="#+id/fragmentTrack"
android:name="pl.com.digita.BikeComputerUi.TrackList.TrackInfoFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2" />
</LinearLayout>
Method called after click:
private void showDetails(long trackId){
View fragmentContainer = getActivity().findViewById(R.id.fragmentTrack);
TrackInfoFragment trackInfoFragment = TrackInfoFragment.newInstance(trackId);
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(fragmentContainer.getId(), trackInfoFragment).commit();
}
Note: When you add a fragment to an activity layout by defining the fragment in the layout XML file, you cannot remove the fragment at runtime. If you plan to swap your fragments in and out during user interaction, you must add the fragment to the activity when the activity first starts, as shown in the next lesson.
Which is very last thing on http://developer.android.com/training/basics/fragments/creating.html
Here is solution - just need to change fragment to FrameLayout without loading it at activity creation:
<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:orientation="horizontal"
tools:context=".TrackListActivity" >
<fragment
android:id="#+id/fragmentList"
android:name="pl.com.digita.BikeComputerUi.TrackList.TrackListFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<FrameLayout
android:id="#+id/details"
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight="2" />
</LinearLayout>
Check following code it will work.
View fragmentContainer = ClassName.this.findViewById(R.id.fragmentTrack);
TrackInfoFragment fragment = new TrackInfoFragment();
getSupportFragmentManager().beginTransaction()
.replace(fragmentContainer.getId(), fragment).commit();

Android replace fragment still displays some of the replaced fragment

I have a tab that contains a linear layout with a searchview and a listview. When the user clicks one of the search results, I want to replace that layout with another layout containing the details of the selection.
What happens when I replace the search fragment only the listview portion of the layout gets replaced; the searchview is still visible and active on the screen.
Here is my search layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/search_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<SearchView
android:id="#+id/public_calendar_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:iconifiedByDefault="false"
</SearchView>
<ListView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:choiceMode="singleChoice" />
<TextView
android:id="#android:id/empty"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:gravity="center"/>
</LinearLayout>
Here is the detail layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/detail_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:orientation="vertical" >
<Space
android:layout_width="0dip"
android:layout_height="20dip"
android:layout_weight="1" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:orientation="horizontal" >
<Space
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".1" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".8"
android:text="#string/label_Name" />
<Space
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".1" />
</LinearLayout>
.........
</LinearLayout>
And my code to replace the search fragment:
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack.
DetailFragment fragment = DetailFragment.newInstance(cal);
transaction.replace(R.id.search_layout, fragment);
transaction.addToBackStack(null);
transaction.commit();
Detail fragment creation:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.detail_layout, container, false);
return v;
}
static DetailFragment newInstance(String cal) {
DetailFragment d = new DetailFragment();
return d;
}
What am I doing wrong? How can I get the entire search layout to be replaced.
Thanks!
I figured out my problem. Marco wasn't exactly right but he pointed me in the right direction.
The problem was the the container ID I was passing to the replace method was the ID of the fragment I was replacing, not the ID of the fragment container. This seems to explain why some of the original fragment controls were remaining after the replace - that entire fragment wasn't being replaced.
I changed it to get the fragment container view ID, and that worked! Here's the code:
transaction.replace(((ViewGroup)(getView().getParent())).getId(), fragment);
I found the answer for getting the container view ID of a fragment here, Get fragment's container view id.
I was using the correct ID, then also it wasnt going away. Turns out that you need to set the Background color to your needed color in new Fragment layout, like this.
<RelativeLayout 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:orientation="vertical"
android:background="#color/white_color">
To solve the problem, set the android:background property to “?android:windowBackground” in the fragment layout files.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:windowBackground"
tools:context=".MainFragment">
...
</LinearLayout>
In Fragment_2
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:windowBackground"
tools:context=".SomeFragment">
...
</LinearLayout>
I was having the same problem, and the solution didn't work for me. Maybe this will help someone...
I had added a fragment inside the activity layout xml file. This caused a lot of issues.
Instead, add a frame layout in your xml file, and then programatically add and replace fragments. This causes the whole fragment to be replaced.
I had the same problem once, and this is my solution.
Try to do this, use FrameLayout instead of fragment in your layout file. Just like this:
<fragment android:id="#+id/your_fragment" />
Then, add your default fragment in activity method onCreate().
getFragmentManager().beginTransaction()
.add(R.id.your_fragment, YourFragment)
.commit();
Now, the old fragment can be replaced correctly, it looks great.
This worked for me, and I hope it helps you too.

Categories

Resources