Different navhost fragment for every activity - java

Im building an app with conditional navigation based on the values of the login token received.
So I have three different landing pages for my app based on three diffrent values i revceive after decoding the token.
So Iam using three different activties each with its own set of Navigation Graphs and NavHostFragment.
Problem is as soon as I declare another navhost fragment in second activity, app is crashing whenever that activity is opened, with error: "Binary XML file line #36: Duplicate id 0x7f09018a, tag null, or parent id 0xffffffff with another fragment for androidx.navigation.fragment.NavHostFragment"
Following is how I declare navhost fragment in first activity:
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/bottomNav"
android:layout_below="#+id/appbar"
app:defaultNavHost="true"
app:navGraph="#navigation/navigation_graph" />
And this is how I declare navhost fragment in second activity:
<fragment
android:id="#+id/nav_host_fragment_supervisor"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/bottomNav"
android:layout_below="#+id/appbar"
app:defaultNavHost="true"
app:navGraph="#navigation/navigation_graph_supervisor" />
Please help.

Related

Replace fragment by another using default navigation drawer activity template

I have a navigation drawer using fragments created from the default "Navigation Drawer Activity" template in Android Studio. Inside a fragment A, I want to open another fragment B. So the fragment B must replace fragment A. I saw on google, that I should use FrameLayout to Dynamically change the current displayed fragment.
<FrameLayout
android:id="#+id/nav_host_frame_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/mobile_navigation" />
</FrameLayout>
To change fragment, I am using the code below, when I am clicking on a button in the fragment that I want to be replaced
NewCalendarEvent newEventFrag = new NewCalendarEvent();
getActivity().getSupportFragmentManager().beginTransaction()
.replace(R.id.nav_host_frame_layout, newEventFrag)
.addToBackStack(null)
.commit();
Currently, when I click on the button, the two fragments are show. Is because I am using fragment and frameLayout together ? What I am doing wrong ?
If you are using a NavHostFragment and the Navigation Component, then you never use a FragmentTransaction. Instead you navigate to a screen by using the APIs on NavController.

Android fragment preloading data

Hello I'm trying to make an application that has multiple bottomnaviagtion tabs.
Currently it works because fragment data (for example, images) are static. However, if I want to make them dynamic, I'll have to create a preloader.
So I want to display a loading layout (for example R.layout.loading) UNTIL (async) function has completed and obtained data from server. Then I want to replace the layout in the fragment with a new layout (R.layout.datafragment)
Fragment onCreateView:
return inflater.inflate(R.layout.loading, container, false);
In summary it should work exactly like youtube bottom tabs.
You should create in your activity layout a placeholder for those dynamic fragments and a loader which is by default gone, but when you start loading data from the server you should make it visible (loader). Then, when you load necessary data, just start fragment transition and place whatever fragment you have loaded.
Your parent activity's layout should be like this:
<?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">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--Navigation View and Fragment Container-->
</RelativeLayout>
<RelativeLayout
android:id="#+id/progress_layout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
</RelativeLayout>
</RelativeLayout>
Then you simply show/hide progressLayout based on your requirement. Thanks

How can I change the way I display the fragments in differents display sizes?

I'm currently making an app for Android devices and I would like to know how can I change the way I display the fragments in differents display sizes (ex. Tablet).
At this point I have an activity for all my fragments and this causes me to replace the fragments when I change page but for tablets I would like to display 2 fragments inside that activity.
I've created a layout-large version for my main activity:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".PaginaInicial"
tools:showIn="#layout/app_bar_pagina_inicial">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
class="pt.ipp.estg.schoolhelperapp.apontamento.ListaApontFragment"
android:id="#+id/a_fragment"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
<fragment
class="pt.ipp.estg.schoolhelperapp.apontamento.VerApontFragment"
android:id="#+id/b_fragment"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
The fragment container is inside layout-small version of the main activity.
One of the fragments displays a list of items (#+id/a_fragment) and the other one displays the information of one specific item that I previously selected (#+id/b_fragment).
For further details refer to this document: https://developer.android.com/training/multiscreen/screensizes
Create a default alias resource value file in res/values/refs.xml and place the following code inside it. This value will refer to your layout file that has only one fragment.
<resources>
<item name="activity_masterdetail" type="layout">#layout/layout_with_single_fragment</item>
</resources>
Now need to create an alternative resource so that the activity_masterdetail alias will point to layout_with_two_fragment.xml on larger devices.
Create a new file with same name refs.xml but with resource qualifiers for Smallest Screen Width under Available qualifiers. Use smallest dimension of 600dp or more (sw600dp qualifier)
<resources>
<item name="activity_masterdetail" type="layout">#layout/layout_with_two_fragment</item>
</resources>
Your goal here is to have logic that works like this:
For devices that are under a specified size i.e mobile phones, use layout_with_single_fragment.xml.
For devices that are over a specified size, use layout_with_two_fragment.xml.
Now in your man activity which shows a list, use setContentView(R.layout.activity_masterDetail) i.e the name of referenced layout
If this code will run on mobile phones, normal refs.xml file will be referenced by activity_masterDetailbut if this code runs on a tablet, resource qualified refs.xml file will be used.
In your activity logic, where you want to show master and detail layout on the same screen on tables but open another activity on phones, use the following logic inside onClick() of your list items
if (findViewById(R.id.a_fragment) == null) {
Intent intent = A_Activity.newIntent(this, listItem.getId());
startActivity(intent);
} else {
Fragment newDetail = B_Fragment.newInstance(list_item.getId());
getSupportFragmentManager().beginTransaction()
.replace(R.id.b_fragment, newDetail)
.commit();
}
You should take a look at this before link it should help you understand for sure more about supporting different screen sizes.
And here is an example that you can try.

How to use SwipeRefresh's refresh icon Without Listview?

My app consists of different activities where I use a SwipeRefreshLayout to refresh data in listViews by swiping. When this happen a refresh icon is displayed at the top of the screen.
However, for 2 other specific activities that contain no list view, I only want to display the refresh icon while the data is refreshing by using pullToRefresh.setRefreshing(true); & pullToRefresh.setRefreshing(false);. I don't need to use it for swiping.
This is how it looks in my list view layout xml file:
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/pullToRefresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/ListView"
android:dividerHeight="8dp"
android:divider="#000000"
android:layout_below="#+id/feedLinearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
Use SwipeRefreshLayout as a regular layout, and call pullToRefresh.setRefreshing(true) when you want to show the loading wheel, and pullToRefresh.setRefreshing(false) to hide it.

going to another xml from the main xml

I m totally new to program and I m trying to make a simple app.
I need to jump from one xml to another xml by clicking a button, and I m stopped here.
I only know how to use graphical layout and how should I do it???
I want to jump from Activity_Main.xml to 2bb.xml, and 2bb.xml to 2result.xml and at last from 2result.xml back to Activity_Main.xml.
my A_M.xml
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnCount="1"
tools:context="com.example.soo.MainActivity"
tools:ignore="MergeRootFrame,NewApi,UnusedAttribute" >
<Button
android:id="#+id/button1"
android:layout_width="150dp"
android:layout_height="215dp"
android:layout_column="0"
android:layout_gravity="left|top"
android:layout_row="0"
android:text="#string/B2"
android:onClick="2bb" />
There are a few ways to achieve this, depends on what your looking for.
You can call a new activity from your MainActivity and inflate 2bb.xml when the new activity is created, or you can use different fragments, and just transition between fragments in the same activity. I suggest going over some tutorials regarding Activities and Fragments in Android.
Try this
To go to other xml, you have to create one activity for one xml and each button has to put action startactivity.

Categories

Resources