Fragment still visible after replace - android

I have looked all over on here and pretty much tried everything. I have my main activity which contains my Toolbar and TabLayout, this loads a fragment known as ActiveThreadFragment. I then replace ActiveThreadFragment with another called PostFragment. Here is the issue that's happening:
PostFragment Overlapping ActiveThreadFragment
Here's my code for replacing ActiveThreadFragment with PostFragment
private void showItemSelectedAtPosition(int position) {
Threads selectedThread = mData.getItem(position);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.content_thread,
PostFragment.newInstance(selectedThread.getThreadItem()));
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commitAllowingStateLoss();
}
Here is the layout for ActiveThreadFragment where the FrameLayout 'content_thread' is to replace with it.
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="2"
android:background="#color/primaryColor">
<FrameLayout
android:id="#+id/content_thread"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:padding="15dp"
android:id="#+id/threadRecyclerView"
android:layout_height="0dp"
android:layout_width="match_parent"
android:layout_weight="1.7"/>
</LinearLayout>
Is there anything I'm doing wrong and can't figure out? Am I just being really silly? I can provide more code or anything else if needed.

Related

Transparent Toolbar background with fragment behind it

What is the best way to handle the situation where I have fragments that should not include a ToolBar (Those would be handle by the Activity) and some including the Toolbar? I know how to make it transparent, but how can I create a template that can easily be modular to handle both situation?
For a specific Fragment I want a transparent Toolbar with the Fragment content partly behind the Toolbar like this:
I tried to have another FrameLayout that cover all the screen and then is replace by the FragmentTransaction but nothing happens...
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activityv2.ActivityHome">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<include layout="#layout/action_bar" />
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<LinearLayout
android:id="#+id/left_drawer_item"
android:layout_width="200dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:alpha="0.92"
android:background="#color/gray_very_dark"
android:orientation="vertical">
</LinearLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/full_content_frame"
android:background="#color/dark_red"
android:fitsSystemWindows="true"/>
</android.support.v4.widget.DrawerLayout>
For the fragment that doesn't require a Toolbar, I replace the FrameLayout "content_frame" and for the one that require an invisible ToolBar I replace "full_content_Frame". For the second one, nothing happens when I replace it. Here is the code to replace the fragment:
private void selectProfilFragment() {
BackHandledFragment fragment = new FragmentUserProfil();
setSelectedFragment(fragment);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.pull_in_right, R.anim.push_out_left, R.anim.pull_in_left, R.anim.push_out_right);
ft.replace(R.id.full_content_frame, fragment)
.addToBackStack(fragment.getTagText())
.commit();
setTitle("Profil");
mDrawerLayout.closeDrawer(mDrawerLinear);
}

Not able to understand Fragment replace, role of FrameLayout and where does it fall in place

In one of my fragment I have the below layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/email_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="3">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="matrix"
android:src="#drawable/banner_dashboard" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:orientation="vertical">
<include layout="#layout/settings_nested" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
Now the following:
<include layout="#layout/settings_nested" />
Consists of some buttons, on click of one such button I want to replace the framelayout with new contents - new fragment which has a different layout. Here is how I do it:
Fragment fragment = null;
fragment = new FragmentEmails();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.email_container, fragment);
fragmentTransaction.commit();
Now I can see the optionsMenu change when I click the button (As I have defined a different menu file for this new Fragment) However the contents remain the same. Advice any? I think I am doing something wrong the way I am defining the framlayout as the parent of my views, but what exactly, beats me.
According to my Thoughts and Views, You should Do as below
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/email_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
This is the Parent Layout of all fragment and email_container will be used for the transactions of other fragments.
then Create another layout that consists of the inner elements that i have erased.
on startup what you want to display , Change this email_container inneer elements with another fragment like
Fragment fragmentStartPage = null;
fragmentStartPage = new FragmentEmails();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.email_container, fragmentStartPage);
fragmentTransaction.commit();
then change it with another fragment by replacing the fragmentStartPage with another fragment.

Having trouble with starting a new fragment, app is built using ViewPager Swipe template

I have an activity that holds a ViewPager, set up as the template Swipe ViewPager. I have attached two fragments to that ViewPager via an adapter. I am now trying to open a new fragment but I am having great trouble getting it to work. I don't fully understand this idea of changing fragments with FragmentTransaction (I tried reading the Android docs to no avail) so I pieced the FragmentTransaction code together from places over the web.
This is my activity_main.xml
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"/>
This is the code I used to try to open the fragment
private void openVolumeSettingsFragment() {
Activity activity = getActivity();
FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.pager, new VolumeSettingsFragment());
transaction.addToBackStack(null);
transaction.commit();
}
This is the blank xml file for my new fragment fragment_volume_settings.xml
<FrameLayout 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"
tools:context="com.velixo.bitchtalkandroid.fragments.VolumeSettingsFragment">
<ListView
android:id="#+id/volume_settings_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
The only thing this does is freezes my current fragment from being swipeable. Does anybody have any idea of what I should be doing?
Posted the same question on reddit, x-posting the answer from jeffinmadison in case anyone reading this question will need it:
If you want to replace the pager fragment with your settings fragment you should make the activity_main be a FrameLayout with a #+id/content and within the FrameLayout put the ViewPager with #+id/pager and then call the replaceFragment on the R.id.content
<FrameLayout
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/content">
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"/>
</FrameLayout>

Creating a Multi-pane layout using android actionbar and navigation drawer

I'm currently creating an app which can handle different screen support and multi-pane view using fragments. Now I used the default navigation drawer and actionbar using android studio and created two fragments to test for this and layouts for portrait: fragment_1 and fragment_2 which just replaces the container on the MainActivity. But now the problem is how can I implement the fragment_1 and fragment_2 in 1 layout? I Tried to research on the multi-pane development on this link but I think to properly implement it I need to use an ActivityFragment but in this case I am limited on using just Fragments which is why I'm lost on what to do. Here's the code so far:
#Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getSupportFragmentManager();
switch (position) {
case 0:
fragmentManager.beginTransaction()
.replace(R.id.container, FragmentMain.newInstance(position + 1))
.commit();
break;
case 1:
fragmentManager.beginTransaction()
.replace(R.id.container, FragmentAbout.newInstance(position + 1))
.commit();
break;
/*create the other cases here for navigation*/
}
}
fragment_main.xml (the 1st 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"
tools:context="com.kahel.main.MainActivity$PlaceholderFragment">
<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">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/list_news"
android:choiceMode="singleChoice" />
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
fragment_about.xml (2nd 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"
tools:context="com.kahel.main.MainActivity$PlaceholderFragment">
<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">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/list_news"
android:choiceMode="singleChoice" />
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
fragment_main.xml (landscape)
<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"
tools:context="com.kahel.main.MainActivity$PlaceholderFragment"
android:orientation="horizontal"
android:weightSum="1">
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swipe_container"
android:layout_width="#dimen/land_scoop_feed"
android:layout_height="match_parent">
<ListView
android:layout_width="150dp"
android:layout_height="match_parent"
android:id="#+id/list_news"
android:choiceMode="singleChoice" />
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
When I tried to change the layout it just force close my app. :/
Please let me know what to do or what to search for. Thanks! :)
Well, I ran into the exact same problem and after doing a lot of research I was surprised on the lack of documentation for this, in my opinion, common situation. But, after trying a few things I came up with a solution.
My first approach was to replace the Navigation Drawer container with a "root fragment" that at the same time would have two layouts available containing the fragments that I want. The problem was that nested fragments declared on the layout are not permitted.
To overcome this other issue, in my "final layouts" I replaced the Fragment definitions for FrameLayouts and then load the fragments programatically on the "root fragment".
To summarize: You have your Navigation Drawer and upon clicking what you want, you replace your fragment container with a "root fragment". This "Root fragment" has two layouts: a default one and another for landscape. These layouts contain FrameLayout elements arranged as we want that upon initialization are replaced by our "final fragments".
I doubt that this is the best way to achieve the goal of having Multi-pane layouts with a Navigation Drawer but is what I was able to do that best suited my needs. I welcome any suggestions!.
I illustrate the solution with some code.
MainActivity.java (The one with the navigation drawer)
...
void drawerOptionSelected(String option) {
if(option.equals(XXXX)) {
Fragment fragment = new RootFragment();
final FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.content_frame, fragment);
transaction.commit();
drawerList.setItemChecked(menuOptions.indexOf(option), true);
drawerLayout.closeDrawer(drawerList);
}
}
...
root_fragment_layout.xml (Default)
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/entries_list_single"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="match_parent" />
root_fragment_layout.xml (Landscape)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:baselineAligned="false"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout android:id="#+id/entries_list"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" />
<FrameLayout android:id="#+id/entries_post"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="match_parent" />
</LinearLayout>
RootFragment.java
public class RootFragment extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.root_fragment_layout);
if(savedInstanceState != null) { //Fragments already loaded, avoid replacing them again
return;
}
ListFragment listFragment = new ListFragment();
final FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); //IMPORTANT! Use child fragment manager
if (findViewById(R.id.entries_list_single) == null) { //We are loading the landscape layout
PostFragment postFragment = new PostFragment();
transaction.replace(R.id.entries_list, listFragment);
transaction.replace(R.id.entries_post, postFragment);
transaction.commit();
} else { //We are loading the default layout
transaction.replace(R.id.entries_list_single, listFragment);
transaction.commit();
}
}
}

how to change fragment's class dynamically

Hi I have a linearLayout containing two fragments and I add tabs with code to this layout. What I want is when I click tab1 it is ok to fragment fill itself from indicated class, but in tab2 I want to change this class to another class. Thank you
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/frags">
<fragment class="com.tugce.MitsActionBar.DoktorlarFragment"
android:id="#+id/frag_title"
android:visibility="gone"
android:layout_marginTop="?android:attr/actionBarSize"
android:layout_width="#dimen/titles_size"
android:layout_height="match_parent" />
<fragment class="com.tugce.MitsActionBar.ContentFragment"
android:id="#+id/frag_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Change <fragment/> in xml layout to <FrameLayout/>
<FrameLayout
android:id="#+id/frag_title"
android:visibility="gone"
android:layout_marginTop="?android:attr/actionBarSize"
android:layout_width="#dimen/titles_size"
android:layout_height="match_parent" />
<FrameLayout
android:id="#+id/frag_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
and add fragments programmatically:
FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.replace(R.id.frag_content, fragment);
fragmentTransaction.commit();
But at first read this.
Shortest version of calling a fragment
getFragmentManager().beginTransaction().replace(R.id.splash_container, new ExampleFragment()).addToBackStack(null).commit();
addToBackStack(null) is optional if you want to save the fragment on stack or not..

Categories

Resources