My project consists of a main activity which loads different fragments into view when tabs are pressed on the bottom navigation bar. Blue depicts the activity controls, orange what should be included from one of the fragments. In this case, it is a MapBox MapView with FABs in the corners.
My problem is that I can't seem to get the fragment container height correct; either the top or bottom button (sometimes both) is always cut off vertically underneath the status bar or bottom navigation bar.
My current layout (irrelevant attributes removed for brevity):
activity_main.xml:
<ConstraintLayout
android:layout_height="match_parent">
<RelativeLayout
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#id/nav_bottom">
<FrameLayout
android:id="#+id/fragment_container"
android:layout_height="wrap_content">
</FrameLayout>
</RelativeLayout>
<BottomNavigationView
android:id="#+id/nav_bottom"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:menu="#menu/nav_bottom">
</BottomNavigationView>
</ConstraintLayout>
fragment_map.xml:
<ConstraintLayout
android:layout_height="wrap_content">
<MapView
android:id="#+id/map_view"
android:layout_height="match_parent"
mapbox:layout_constraintTop_toTopOf="parent"
mapbox:layout_constraintBottom_toBottomOf="parent">
</MapView>
<FloatingActionButton
android:id="#+id/button_top"
android:layout_height="wrap_content"
mapbox:layout_constraintTop_toTopOf="#id/map_view"
mapbox:layout_constraintRight_toRightOf="#id/map_view" />
<FloatingActionButton
android:id="#+id/button_bottom"
android:layout_height="wrap_content"
mapbox:layout_constraintBottom_toBottomOf="#id/map_view"
mapbox:layout_constraintRight_toRightOf="#id/map_view" />
</ConstraintLayout>
I am adding the fragment to the activity like this:
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, fragment, "myFrag")
.commit();
Change your layout style activity_main.xml:
<LinearLayout
android:layout_height="match_parent"
orientation = vertical>
<FrameLayout
android:id="#+id/fragment_container"
android:layout_height="0dp"
weight = "1">
</FrameLayout>
<BottomNavigationView
android:id="#+id/nav_bottom"
android:layout_height="wrap_content"
app:menu="#menu/nav_bottom">
</BottomNavigationView>
</LinearLayout>
and your fragment_map.xml:
<RelaytiveLayout
android:layout_height="match_parent">
<MapView
android:id="#+id/map_view"
android:layout_height="match_parent">
</MapView>
<FloatingActionButton
android:id="#+id/button_top"
android:layout_height="wrap_content"
alignParentRight = true />
<FloatingActionButton
android:id="#+id/button_bottom"
android:layout_height="wrap_content"
alignParentRight = true
alignParentBottom = true />
</RelaytiveLayout>
edited your fragment_map.xml see the changes
Related
my floating action button shows up too low, even though it looks just fine in the Android Studio preview (see below).
FB is placed in root under CoordinatorLayout and set to show at the bottom end using android:layout_gravity.
This Layout is used in Fragment (extends Fragment) with Tabbed Activity using ViewPager. Android X.
Thanks
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragmentTableCoordinator"
tools:context=".fragment.FragmentTable">
<!-- CoordinatorLayout for Floating Button -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/fragmentTable"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorBackgroundCards">
<!-- Total Card -->
<androidx.cardview.widget.CardView
android:id="#+id/card_viewNew"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dp"
card_view:cardCornerRadius="2dp"
card_view:contentPadding="10dp"
card_view:layout_constraintEnd_toEndOf="parent"
card_view:layout_constraintStart_toStartOf="parent"
card_view:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="fill_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.Guideline
android:id="#+id/Total_guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
card_view:layout_constraintGuide_percent="0.5" />
<!-- some textViews here -->
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<!-- RecyclerView with months -->
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/Total_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:scrollbars="vertical"
android:visibility="visible"
card_view:layout_constraintEnd_toEndOf="parent"
card_view:layout_constraintStart_toStartOf="parent"
card_view:layout_constraintTop_toBottomOf="#+id/card_viewNew" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- Floating button -->
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/floating_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
android:contentDescription="TODO"
app:srcCompat="#android:drawable/ic_dialog_email" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
My own fix : after hours trying to fix in in Fragment Layout - the best for me worked :
place Floating button into activity_main layout
hide it (setVisibility) for Fragment you dont need.
This solved this for me
You're setting ConstraintLayout inside the CoordinatorLayout and also CoordinatorLayout in the Fragment layout. You'll need to change it a bit.
Use FloatingActionButton inside your main activity layout with CoordinatorLayout, AppBarLayout and maybe a NestedScrollView, use ConstraintLayout in your Fragment layout and then, as you already mentioned, you'll be able to see FloatingActionButton with desire effect which is also stable at the bottom of the page and then you can hide it in the Fragments you don't want to use.
I'm working on an android app and am using a toolbar at the top of the screen and a navigation bar at the bottom of the screen. I'm using a single activity to create the top and bottom toolbars and fragments to change the content between the toolbars. However, when the contents in the fragment go beyond the size of the screen, the bottom bar disappears.
Here is my home activity xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_home"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.rentables.testcenter.HomeActivity">
<include
android:id="#+id/toolbar_main"
layout="#layout/toolbar_main"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<fragment android:name="com.rentables.testcenter.HomeFragment"
android:id="#+id/fragment_place"
android:layout_weight="0"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:layout="#layout/fragment_home" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="bottom">
<include
android:id="#+id/toolbar_navigate"
layout="#layout/toolbar_navigate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center|bottom"/>
</LinearLayout>
</LinearLayout>
Im guessing it's because of the inner linear layout I have, but I wasn't sure how else to get the nav bar to stay static at the bottom. Any help would be awesome. Thanks
Figured it out. I just changed the whole thing to a relative layout, got rid of the inner linear layout, and instead of gravity I used alignParentBottom="true".
In my app, I want to keep a same Ad banner at the bottom of all the screens, so I use one Activity with multiple fragments.
In the Activity's layoutfile(activity_mail.xml), I have a FrameLayout as the container of the fragments and a AdView at the bottom to show the banner Ads from Admob.
<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=".MainActivity"
tools:ignore="MergeRootFrame">
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<fragment
android:id="#+id/adFragment"
android:name="com.jiyuzhai.wangxizhishufazidian.MainActivity$AdFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />
</RelativeLayout>
Layout of the fragment to replace the existing fragment
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:background="#drawable/theme_color"
android:layout_alignParentTop="true"
android:text="Topbar in fragment"
android:textColor="#android:color/white"
android:textSize="30sp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:background="#drawable/theme_color"
android:layout_alignParentBottom="true"
android:text="Bottombar in fragment"
android:textColor="#android:color/white"
android:textSize="30sp"/>
</RelativeLayout>
Code to replace the existing fragment
fragment = new LinmoFragment();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.fade_in, R.anim.fade_out, R.anim.fade_in, R.anim.fade_out);
fragmentTransaction.replace(R.id.container, fragment);
fragmentTransaction.commit();
But when I replace the fragments in the container, the bottom area of the fragment was hide by the AdView, in other words, the fragment was out of the Framelayout, I want the fragment totally inside the container. is that possible?
The following is what I want
and this is what I get(The Ad banner hide the bottombar of the fragment)
Any idea?
By the way, I find there is no way to keep a same banner for all screens with multiple Activities in Android, many people on SO said you need to use Single Activities with multiple fragments, then you can add/remove your fragments dynamically without reload new banner, but, there is no code found for this approach, so I try it myself. if you have better solutions, please help me.
Try this:
<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=".MainActivity"
tools:ignore="MergeRootFrame">
<fragment
android:id="#+id/adFragment"
android:name="com.jiyuzhai.wangxizhishufazidian.MainActivity$AdFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#id/adFragment" />
</RelativeLayout>
The changes I made to your original layout file were moving the adFragment definition above the frame layout, made the frame layout height wrap content, and added the layout_above attribute to make the frame layout appear above the ad fragment.
An alternative approach would have been to use a vertical linear layout with the frame layout first with a layout weight of 1 (and the ad fragment would not have a layout weight).
By the way, the fragment is contained completely within your frame layout. The frame layout was just being overlapped by the ad fragment in your original layout. The above suggestion makes it so that there is no overlap.
Hope this helps.
If you want to both avoid overlapping and make the container fill the screen then you should just change RelativeLayout to LinearLayout.
<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=".MainActivity"
tools:ignore="MergeRootFrame"
android:orientation:"vertical"
>
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<fragment
android:id="#+id/adFragment"
android:name="com.jiyuzhai.wangxizhishufazidian.MainActivity$AdFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
I'm creating the layout for a tablet and I have a DrawerLayout, which has a Fragment on the left menu (so the drawer) and should have two fragments as main content.
The way I'm doing it is the following:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"/>
<View
android:id="#+id/right_card_group_divider"
android:layout_width="1dip"
android:layout_height="match_parent"
android:background="#drawable/grey_line_bg"/>
<FrameLayout
android:id="#+id/menu_frame_two"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1.3"/>
</LinearLayout>
<!-- The navigation drawer -->
<FrameLayout
android:id="#+id/menu_frame"
android:layout_width="300dp"
android:layout_gravity="start"
android:layout_height="match_parent"/>
</android.support.v4.widget.DrawerLayout>
Nevertheless, I notice that if I manually hide the "menu_frame_two", the DrawerLayout works perfectly, but if that Fragment isn't hidden, then when opening the DrawerLayout nothing appears on the screen: it gets darker, just like if the drawer has been opened.
Is there any reason why the left drawer menu isn't showing?
Your menu_frame_two FrameLayout seems coming over the menu_frame Navigation Drawer. So navigation drawer is not visible that time
Solution :
Use single FrameLayout and add all elemets of main content screen inside it
<FrameLayout android:id = "#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="#+id/content_frame_inside"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"/>
<View
android:id="#+id/right_card_group_divider"
android:layout_width="1dip"
android:layout_height="match_parent"
android:background="#drawable/grey_line_bg"/>
<FrameLayout
android:id="#+id/menu_frame_two"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1.3"/>
</FrameLayout>
Reason :
As per Documentation there should be one content_frame with height and width equal to match_parent
I have been trying to add Button's below a GraphView, and all these elements are part of a Fragment. Tried many approaches but none of them worked properly.
This is the layout file for the Fragment (fragment_graph.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.nma.util.sdcardtrac.GraphFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/graph_fragment_layout"
android:orientation="vertical"
/>
</FrameLayout>
And this is the Java code dynamically adding a graph and button, placed in the Fragment's onViewCreated (View view, Bundle savedInstanceState).
storageGraph = new LineGraphView(getActivity(), graphLabel);
storageGraph.addSeries(graphSeries); // More config calls follow
...
LinearLayout view = (LinearLayout)getView().findViewById(R.id.graph_fragment_layout);
Button button = new Button(getActivity());
button.setText("Test");
view.addView(storageGraph);
view.addView(button);
The Button is not visible though I have set orientation to vertical for the LinearLayout containing it.
EDIT - solved!
I found that nesting the graph under its own LinearLayout and the buttons under another LinearLayout, and both of these wrapped in a LinearLayout fixed the problem! The LinearLayout containing the graph must be weighted (I chose a weight of 0.8).
Layout file looks like:
<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.nma.util.sdcardtrac.GraphFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/graph_fragment_wrap"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.8"
android:id="#+id/graph_fragment_layout"
android:orientation="vertical" />
<LinearLayout
android:id="#+id/graph_buttons"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="#drawable/ic_navigation_previous_item"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_navigation_next_item"/>
</LinearLayout>
</LinearLayout>
</FrameLayout>
I've just tried it and it works. Perhaps your graph is taking all the available space, so added button is below the screen? Try to wrap your LinearLayout into a ScrollView and see if there is a button in the bottom.