I have a main layout of this form
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/fragment1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
<LinearLayout
android:id="#+id/fragment2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
And I am doing FragmentTransaction calling .replace() on both of them to invoke two Fragments that use the following XML:
Fragment1.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:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="true">
...
</LinearLayout>
Fragment2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
Why are the two fragments appearing on top of each other? I want Fragment1 to appear directly above Fragment2, which has a RecyclerView.
Edit: Replacement code:
fragment1 = Fragment1.newInstance();
fragment2 = Fragment2.newInstance();
FragmentManager fragmentManager = getChildFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment1, fragment1, "fragment1");
fragmentTransaction.replace(R.id.fragment2, fragment2, "fragment2");
fragmentTransaction.commit();
This is because you put two layouts inside CoordinatorLayout. CoordinatorLayout behaves like RelativeLayout. Try this instead.
<?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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<FrameLayout
android:id="#+id/fragment1"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="#+id/fragment2"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
You can import fragments directly to activity's layout:
<fragment
android:layout_width="match_parent"
android:layout_height="wrap_content"
class="com.packacge.Fragment1"/>
<fragment
android:layout_width="match_parent"
android:layout_height="wrap_content"
class="com.packacge.Fragment2"/>
Related
My application is pretty simple.
I have 1 Activity, and three fragments.
When activity is being loaded it loads fragment that consist of ViewPager.
I use ViewPager to show news, first fragment in ViewPager shows new news, the second shows read news.
Everything works good, but when I click on news and open ContentFragment to show it and then click back button to return to fragment with ViewPager. ContentFragment disappear but Fragment with ViewPager remains blank. I debugged and made sure that methods like onCreateView and etc. are being called, but fragment is still blank, I'm confused.
What is wrong with it?
MainActivity
<androidx.drawerlayout.widget.DrawerLayout
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=".activity.MainActivity"
android:id="#+id/activity_main_layout_id">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/main_content">
</RelativeLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.material.navigation.NavigationView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
android:id="#+id/navigation_view">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/swipe_refresh_layout">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/drawer_recycler">
</androidx.recyclerview.widget.RecyclerView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</com.google.android.material.navigation.NavigationView>
</androidx.drawerlayout.widget.DrawerLayout>
On startup it shows Fragment with ViewPager
private fun showList() {
val fragmentTransaction = supportFragmentManager.beginTransaction()
val newsPagerFragment = NewsPagerFragment()
fragmentTransaction.replace(R.id.main_content, newsPagerFragment)
fragmentTransaction.commit()
}
NewsPagerFragment
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragment.NewsPagerFragment"
android:orientation="vertical"
android:id="#+id/news_list_fragment">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/swipe_refresh_layout">
<androidx.viewpager.widget.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.viewpager.widget.ViewPager>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<com.google.android.gms.ads.AdView
android:id="#+id/adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
ads:adUnitId="#string/ads_banner_id_test"
ads:adSize="BANNER" />
</LinearLayout>
NewsListDataFragment used in ViewPager to show news.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_height="match_parent"
tools:context=".fragment.NewsPagerFragment"
android:orientation="vertical"
android:id="#+id/news_list_fragment">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/news_list_recycler"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
And when we click on some news it calls
private fun onPreviewNewsClick(news: PostEntity) {
val contentFragment = NewsContentFragment()
val transaction = fragmentManager.beginTransaction()
transaction.replace(R.id.main_content, contentFragment)
transaction.commit()
}
NewsContentFragment
<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=".fragment.NewsContentFragment"
android:padding="5dp"
>
<WebView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/news_content_webview"
>
</WebView>
</FrameLayout>
Why is this happening?
When RelativeLayout is clicked, fragment should start, but not like this. What Am I doind wrong. P.S. I am new to Fragments
Source code: DrawerActivity.java:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_del_h);
RelativeLayout rl = (RelativeLayout) findViewById(R.id.sss);
rl.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FragmentManager fragmentManager = DelHome.this.getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragment fragment = new LocationPicker();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
}
});
Fragment.xml code:
<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="datasite.com.aroba.LocationPicker">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_blank_fragment"
android:textColor="#color/black"
android:textSize="20sp"/>
DrawerActivity.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
android:id="#+id/fragment_container">
..........
.......
.......
</FrameLayout>
You're adding a new Fragment on top of what you currently have. That Fragment doesn't have a background, so you can just see through it.
You could add a background to the Fragment, or perhaps you would want to replace the Fragment instead?
fragmentTransaction.replace(R.id.fragment_container, fragment);
For the layouts, this is what I have for my NavDrawer.
This is my activity_main.xml.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.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">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:itemTextColor="#color/white_alpha"
app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
And here is my app_bar_main.xml, which contains the container I'm replacing.
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/appBarLayout"/>
</RelativeLayout>
And then when I replace an item into the container, it keeps the Toolbar and everything where it is.
Insde of your MainActivity add fragment and then replace current fragment with the another one that will be the better way of doing what you are wanted to do
you can find demo here : http://chrisrisner.com/Using-Fragments-with-the-Navigation-Drawer-Activity
I have an activity where I show a map. I want to can change when click an item on my navigation drawer with a different fragment.
I have next main xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.main.activities.Activity_main">
<include layout="#layout/my_bar" />
<android.support.design.widget.NavigationView
android:layout_marginTop ="45dp"
android:id="#+id/navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="#menu/navigation_menu"
app:itemIconTint="#000000"
android:background="#FFFFFF"
app:itemTextColor="#000000"
app:headerLayout="#layout/navigation_header">
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
Bar layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/tools"
android:orientation="vertical"
android:id="#+id/my_bar"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Toolbar -->
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
android:background="#color/primary_color"
android:titleTextAppearance="#color/text_and_icon_color"
app:popupTheme="#style/Theme.AppCompat"
android:elevation="1dp"
android:textAlignment="center"
android:layout_height="45dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="My app"
android:layout_gravity="center"
android:id="#+id/toolbar_title"
android:layout_weight="1"
android:textSize="24sp"
android:textColor="#android:color/white" />
</android.support.v7.widget.Toolbar>
<include layout="#layout/my_content" />
</LinearLayout>
My content:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/my_content"
android:background="#color/window_background_color">
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_below="#+id/adView"/>
</RelativeLayout>
I try to replace the map with a fragment :
<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.main.activities.catalog">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_blank_fragment" />
</FrameLayout>
I call with this code:
catalog fragment2 = new catalog();
android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.my_content, fragment2, "fragment2");
fragmentTransaction.commit();
But my map isn't replaced with new fragment. Where I do wrong?
As #MikeM says in a comment to your question, the problem is that my_content.xml contains a static fragment specified directly in the XML. FragmentManager will not replace such a fragment dynamically at run time. Instead, you should remove the fragment tag and add the map fragment dynamically in onCreate(). Typically this is done with a FrameLayout but I think it will also work with a RelativeLayout.
For more information, see the Fragment Developer Guide.
I made a shared element transition for fragment. My transition code as below
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Transition changeTransform = TransitionInflater.from(this).
inflateTransition(R.transition.change_image_transform);
mainFragment.setSharedElementReturnTransition(changeTransform);
secondFragment.setSharedElementEnterTransition(changeTransform);
FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransaction.addSharedElement(findViewById(R.id.button_view), "MyTransition");
fragmentTransaction
.replace(R.id.fragment_container, secondFragment, MainFragment.TAG);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
My transition xml as below
<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<changeBounds />
<changeTransform />
</transitionSet>
My mainFragment as below
```<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="#+id/button_view"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#00f"
android:transitionName="MyTransition"
android:onClick="clickButton"/>
</LinearLayout>
My secondFragment as below
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="#+id/base_view"
android:layout_width="match_parent"
android:layout_height="1dp"/>
<LinearLayout
android:layout_width="match_parent"
android:padding="20dp"
android:layout_height="100dp">
<View
android:id="#+id/button_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0f0"
android:transitionName="MyTransition"/>
</LinearLayout>
</LinearLayout>
The transition happen from mainFragment to secondFragment smoothly. However upon return from secondFragment to mainFragment, the transition would only be okay if I have the base_view in the secondFragment. If I remove the base_view from the secondFragment, then the returnTransition is not working. Why is the 'additional' view needed to make the return transition happen?
After some experiment, in order to ensure the return transition animation still works when base_view is not there anymore... use layout_margin instead of padding as below
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_margin="20dp"
android:layout_height="100dp">
<View
android:id="#+id/button_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0f0"
android:transitionName="MyTransition"/>
</LinearLayout>
</LinearLayout>
I am having a layout with four Fragment layouts as shown below.
Now I need to access only two or three Fragments depending upon my selection which is from the database.
How to access only the desired Fragments?
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<FrameLayout xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_height="match_parent"
tools:context="com.example.rknikhil.myapplication.fragment_sample">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<fragment
android:id="#+id/list_Fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
class="com.example.rknikhil.myapplication.ProfileFragment" >
</fragment>
<fragment
android:id="#+id/list_Fragment1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
class="com.example.rknikhil.myapplication.Notificationfragment">
</fragment>
<fragment
android:id="#+id/list_Fragment2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
class="com.example.rknikhil.myapplication.ProfileFragment">
</fragment>
<fragment
android:id="#+id/list_Fragment3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
class="com.example.rknikhil.myapplication.Notificationfragment" >
</fragment>
</LinearLayout>
</FrameLayout>
</ScrollView>
You can simple show and hide the fragment on the basis of the selection.
Use below code in OnCreateView() method . i.e
Fragment f= getFragmentManager().findFragmentById(R.id.list_Fragment);
Fragment f1= getFragmentManager().findFragmentById(R.id.list_Fragment1);
Fragment f2= getFragmentManager().findFragmentById(R.id.list_Fragment2);
f1.getView().setVisibility(View.GONE);