I have a simple app that contains an Activity(acts as host activity) with two Fragments(FragmentA and FragmentB).
There is a SwipeRefreshLayout in the FragmentA. When the SwipeRefreshLayout is refreshing, we replace FragmentA with FragmentB. If we go back to FragmentA(by pressing back button), the SwipeRefreshLayout disappears. For understanding what I mean, please see this image:
How can I prevent SwipeRefreshLayout from disappearing after replacing the Fragments? My classes are very simple, I just replaced FragmentA with FragmentB
fragment_a.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swRefresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/click"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click Me!"
android:layout_gravity="center"/>
</FrameLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
Instead of this may be you should use your SwipeFreshLayout in activity's xml file which is parent to both fragments.
Related
I have two fragment for my current application, In FragmentA I have a search view in Toolbar and on clicking on the search view , I have to show another fragment,FragmentB on top of fragmentA using my framelayout,with transparent view so that the contents in FragmentA can be seen as blurred. The newly opened fragment with transparent background has to show some content in the recycler view . How can we achieve the transparency and the recycler view inside the layout.
Layout code:
<androidx.drawerlayout.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<LinearLayout
android:id="#+id/dot_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/drawer_layout"
android:elevation="50dp"
android:gravity="center"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/tools"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/palate_survey_bg"
app:ignore="NamespaceTypo"
local:popupTheme="#style/ThemeOverlay.AppCompat.Light"
local:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<androidx.appcompat.widget.SearchView
android:id="#+id/Advance_search"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="#drawable/filter_search_bar_bg_lyt"
app:iconifiedByDefault="false"
app:queryHint="Search">
</androidx.appcompat.widget.SearchView>
</androidx.appcompat.widget.Toolbar >
<FrameLayout
android:id="#+id/search_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/toolbar">
</FrameLayout>
</LinearLayout>
</androidx.drawerlayout.widget.DrawerLayout
Based on the detailed image you provided. Fragment B is a child fragment of
Fragment A. So if you want to show Fragment B when a click event is emitted from the SearchView, you should use Fragment A's FragmentManager. Normally, every fragment has a FragmentManager that can house other fragment views and layouts. To retrieve Fragment A's FragmentManager use this code:
Inside Fragment A:
Advance_search.setOnClicklistener( v -> {
getChildFragmentManager()
.beginTransaction()
.replace(R.id.search_container, new FragmentB())
.commit();
}
And then inside Fragment B's onViewCreated() method, you can now inflate the RecyclerView you want into Fragment B's view hierachy.
If you want Fragment B to be transparent, set
<item name="android:windowBackground">#android:color/transparent</item>
Or you can just remove windowBackground entirely.
And set android:backgroud="#android:color/transparent" on Fragment B or just remove it if you have set windowBackround to transparent.
I'm trying to create a layout with a MainActivity which incorporates a BottomNavigationBar and a FrameLayout for swapping out fragments. I want the BottomNavigationBar to stay fixed with every fragment having a fab which on the other hand disappears when scrolling. The problem is that I'm not sure which layout to use for the MainActivity and the Fragments and where to put the fab, I could put the fab either in the MainActivity's layout and change the behaviour of the fab for each fragments (don't know how though) or add a fab to every fragment's layout. When I do the latter I cannot reference the MainActivity's bottom bar to stay over it.
I tried #1:
MainActivity:
<CoordinatorLayout>
<FrameLayout/>
<BottomNav/>
<FAB/>
</CoordinatorLayout>
And #2:
<CoordinatorLayout>
<FrameLayout/> -> fabs defined in each fragment layout
<BottomNav/>
</CoordinatorLayout>
My Main activites xml file looks somewhat like this:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#id/bottom_navigation"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="#menu/bottom_navigation"
android:layout_gravity="bottom"
android:background="?android:attr/windowBackground"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
And one of my fragments with FAB:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".View.MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="#layout/note_item"
android:layout_gravity="top" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/button_add_note"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_marginBottom="64dp"
android:layout_marginEnd="16dp"
android:src="#drawable/ic_add"
app:layout_anchor="#id/recycler_view"
app:layout_anchorGravity="bottom|right|end"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
I want the bottom nav and coordinator layout to be aware of the fab and the fab to be above the bottom nav without using hard-coded dp values but how do I do that?
If you want to use CoordinatorLayout.Behavior logic, your fab should at the same level with CoorditorLayout.
For you i recommend this logic: Activity contains BottomNavigation, FrameLayout (fragment container). Then all your fragment contains:
<CoordinatorLayout>
<RecyclerView/>
<FloatingButton/>
</CoordinatorLayout>
It will give a power to construct UI of fragment exactly how you want.
I am looking for a way to run activity and fragment at the same time where activity will show two buttons to transition from one activity to the other whereas fragment will show live camera view in the background.
is it possible?
Fragments are the part of activity. So it's obvious that activity and fragment run simultaneously run. Fragment does not have it's own context. After read your question I think you want that you can change the fragments but buttom buttom are place there for all fragment. You can do this like:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/container"
android:layout_above="#+id/button"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:id="#+id/button"/>
</RelativeLayout>
add and replace your fragment on framelayout so each fragment have the button at bottom which is the part of activity.
How can I have my BottomNavigationView in several activities but without declaring it there?
i declared my Bottom navigation view in my main_activity.xml and handle the click logic within MainActivity class, but since I want to switch between 3 activities (Map, Friends, Chats) with the Bottomnavigationview i'd have to have 3 bottom navigation views over three activities, but since that's performance inefficient, I want to handle all the click events and initialisation of the view inside one class and one Layout
(MainActivity class and main_activity.xml ).
What can I do? or is there a better way of doing this?
You should use fragments instead of activities. Have only 1 activity ie MainActivity, add BottomNavigationView and fragments above the BottomNavigationView. And on clicking the BottomNavigationView, replace the fragments.
Your XML would be something like,
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="#+id/bottom_nav_view"
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="match_parent"
android:layout_alignParentTop="true"
android:layout_above="#id/bottom_nav_view"></FrameLayout>
From your activity, add fragments in FrameLayout. Your BottomNavigationView will remain intact. Just replace fragments in this FrameLayout on clicking NavigationView tabs.
I'm trying to replace a fragment in a composite layout. Here's my root layout XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/buttons"
android:name="com.kippygo.android.touch_talker.ButtonsFragment"
android:layout_width="200dp"
android:layout_height="match_parent"
class="com.kippygo.android.touch_talker.ButtonsFragment" >
<!-- Preview: layout=#layout/buttons_fragment -->
</fragment>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/buffer"
android:name="com.kippygo.android.touch_talker.BufferFragment"
android:layout_width="match_parent"
android:layout_height="80dp" >
<!-- Preview: layout=#layout/buffer_fragment -->
</fragment>
<FrameLayout
android:id="#+id/grid_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/detailsElementBackground" >
</FrameLayout>
</LinearLayout>
</LinearLayout>
As you can see, I have three areas in my layout, a fixed left column containing a fragment with buttons the rest of the layout is divided vertically with a fragment managing a textView at the top and a grid of data in the lower section.
I want to use a common layout to place various GridView elements in the "grid_frame" as I press buttons in the "buttons" fragment. Here is the "grid_fragment" layout that I want to use for each GridView fragment:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/grid_fragment_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical">
<GridView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/grid_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="80dp"
android:clipToPadding="true"
android:gravity="center"
android:horizontalSpacing="20dp"
android:numColumns="auto_fit"
android:orientation="vertical"
android:stretchMode="columnWidth"
android:verticalSpacing="20dp" >
<!-- Preview: listitem=#android:layout/simple_list_item_2 -->
</GridView>
<TextView
android:id="#+id/android:empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="22sp"
android:textStyle="bold"
android:text="#string/no_list_items"/>
</LinearLayout>
This composite layout opens up fine when I start my app. and I set my first fragment in the FrameLayout id "grid_frame" in my initial activity with the following code:
// Execute a transaction to put the categoriesFragment in the grid_view
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.grid_frame, new CategoriesFragment(), "category_fragment");
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
This works perfectly fine and I see my buttons on the left, text input box on top and a grid of nicely filled cells to the right of the buttons.
When I click one of the list items in the GridView presented by the dynamic fragment I want to replace the fragment in the "grid_frame" FrameLayout. I do this with the following code in the onItemClick listener method of the "grid_frame" fragment with the following code:
// Execute a transaction to put the categoriesFragment in the grid_view
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.grid_frame, categoryWordsFragment, "category_words_fragment");
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
Which looks remarkably similar to the code I used in the activity to set the initial fragment which worked fine.
When I do this my entire screen is replaced with the new fragment layout, which is another GridView with different data. My root layout appears to be totally replaced with the layout that was inflated by the new fragment even though I specify the "grid_frame" FrameLayout as the container view id in the replace method call.
I have tried everything I can find to make my layout stay intact and just change the fragment in the FrameLayout container.
What am I doing wrong please?
Problem solved! It was a very stupid mistake. I had converted my Activity classes to Fragment classes and in this one class I had forgotten to remove the call to setContentView in the class onCreate method. So the fragment was setting a new layout each time I created a new instance