My MainActivity layout includes a bottom navigation bar because I would like to use this as the main navigation components within my application's fragments. However, I have a login page which I do not want the navigation bar to be visible on. Since the fragment is being created from the MainActivity, it inherits the navigation bar and I can't find a way to hide it on the login fragment and show it on subsequent fragments.
For ease:
I have a MainActivity layout with a BottomNavigationBar
All fragments natively inherit the BottomNavigationBar from the MainActivity layout
I want the visibility of the navigation bar to be "GONE" on the user login fragment
I want the visibility of the navigation bar to be "VISIBLE" on the remaining fragments
Is there a way to do this?
The reason I am defining the BottomNavigationBar within the MainActivity is that I initially had a separate navigation bar on each fragment which required separate listeners on each fragment (making the code more extensive than it should be). Additionally, when I implemented the navigation bar as an individual component within each fragment, the item selected animations no longer functioned.
I have tried to use <include layout="#layout/main_activity android:visibility="GONE" android:layout_width="match_parent" android:layout_height="wrap_content"/> from within the login fragment but this has not worked.
I would appreciate any help people have on this matter.
Please feel free to let me know if you would like to see any of my code. I wasn't really sure which parts of my code would be relevant.
I would suggest you to use separate activities for this case - LoginActivity and MainActivity. Since you may at some point add ForgotPasswordFragment and maybe something else. To hide something you don't need in the first place is bad practice IMHO.
In case you don't want to change your approach you can create BaseFragment that will have abstract val showBottomNavBar() and will override it in every fragment.
And then in onViewCreated you'll check that flag and update UI accordingly.
Something like this:
abstract class BaseFragment : Fragment() {
abstract val showBottomNavBar: Boolean
//.. your other stuff
}
class FragmentA : BaseFragment() {
override val showBottomNavBar = false
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if (!showBottomNavBar) {
(requireActivity() as YourAcitivy).hideNavBar() //this is bad
someKindOfBroadcastManager.sendEvent(hideNavBar) // this is somewhat better
}
}
}
But I would still suggest you to decouple login/main logic from single activity
You can access activity from fragment with getActivity() method and cast to your activity. Of course you have to add hideBottomNavigationBar method to your activity and also you have to be sure that your fragments host activity is MyActivity.
MyActivity activity = ((MyActivity)getActivity());
activity.hideBottomNavigationBar();
After that you can define a marker interface that named IFullScreen then in your BaseFragment's onCreateView method you can check if this class is instance of IFullScreen and decide to show or hide bottom navigation bar.
interface IFullScreen { }
class BaseFragment extends Fragment {
#CallSuper
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
MyActivity activity = ((MyActivity)getActivity());
if (this instanceof IFullScreen)
activity.hideBottomNavigationBar();
else
activity.showBottomNavigationBar();
}
}
class FragmentA extends BaseFragment implements IFullScreen {
//Rest of fragment code
}
I trying to create a navigation drawer in my apps. I have 3 present options(View,Claims,Report) and of course the 3 activities are extend to fragment. In View, it has a next button which will go to another page(UpdatePage1.java). Does the page need to extend to fragment or just extend to Activity?
I extend the UpdatePage1 to fragment and my app crashed.
LogCat
Unable to find explicit activity class {com.example.project.project/com.example.project.project.UpdatePage1}; have you declared this activity in your AndroidManifest.xml?
Why would this happen? I thought it never need to add fragments to manifest? Please help.
To call Fragment from another Fragment:
SecondFragment secFrag = new SecondFragment();
FragmentTransaction fragTransaction = getFragmentManager().beginTransaction();
fragTransaction.replace(R.id.fragment_layout,secFrag );
fragTransaction.addToBackStack(null);
fragTransaction.commit();
I am trying to cast an activity to a FragmentActivty object so I could get FragmentManager object
public class Main extends ListActivity {
...
public void showTimePickerDialog(View v) {
FragmentActivity myContext=(FragmentActivity) getApplicationContext(); //Here: java.lang.IllegalStateException: Could not execute method of the activity
FragmentManager fragManager = myContext.getFragmentManager();
DialogFragment newFragment = new uSharedUtility.TimePickerFragment();
newFragment.show(fragManager, "timePicker");
}
}
But when doing it I get:
java.lang.IllegalStateException: Could not execute method of the activity
I cant use getFragmentManager directly because my activity extends from ListActivity which is very necessary.
Please suggest me to get around this error, i really need to use both ListAdapter & Date/Time pickers in the same activity.
I cant use getFragmentManager directly because my activity extends from ListActivity which is very necessary.
It isn't necessary. You can have a ListView in any activity.
Since you're already using fragments, consider using a ListFragment with a FragmentActivity.
You can't cast Application Context to Activity, you must need Activity Context.
(FragmentActivity) getApplicationContext() // Not Possible
getContext(): Returns the context the view is currently running in. Usually the currently active Activity.
getApplicationContext(): Returns the context for the entire application (the process all the Activities are running inside of). Use this instead of the current Activity context if you need a context tied to the lifecycle of the entire application, not just the current Activity.
I have the following model.
A TabFragment which extends Fragment.
A ListFragment which extends Fragment.
And a DetailFragment which extends Fragment.
TabFragment hosts ListFragment which will launch a DetailFragment.
When I call getActivity().setResult(Activity.RESULT_OK, i); from DetailFragment, onActivityResult is called, but only in TabFragment. I pass from Detail Fragment, one String identifier to TabFragment.
My only problem is that I would like to pass this String from TabFragment back up to ListFragment.
What is the best way to do this?
You can find a fragment you need with FragmentManager's findFragmentById() or findFragmentByTag() where id/tag is one you use whan you add a fragment. After that you can interact with this particular fragment.
I'm doing my first Android app, and wanted to get straight into the ICS API. I have so far created an app using an ActionBar, with swipeable tabs using Viewpager and Fragments.
I do however experience some errors that I keep returning to.
Depending on how I implement it, it always keep going back to an "Type mismatch" error: "cannot convert from android.support.v4.app.Fragment to android.app.Fragment". I have tried removing all import references to either, and this error appears when I only use android.support.v4.app.Fragment in TabListener, FragmentActivity and my two Fragments.
The error occurs in my TabListener:
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.Activity;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.util.Log;
public class TabListener implements ActionBar.TabListener {
private android.app.Fragment fragment;
private Activity activity;
private ViewPager pager;
private FragmentTransaction ft;
public TabListener(Activity activity, Fragment fragment, ViewPager pager) {
this.activity = activity;
this.fragment = fragment;
this.pager = pager;
}
#Override
public void onTabSelected(Tab tab, android.app.FragmentTransaction ft){
if (fragment == null) {
ft.add(fragment, null);
} else {
ft.attach(fragment);
}
}
#Override
public void onTabReselected(Tab tab, android.app.FragmentTransaction ft){
// TODO Auto-generated method stub
}
#Override
public void onTabUnselected(Tab tab, android.app.FragmentTransaction ft){
// TODO Auto-generated method stub
}
}
By removing "android.app.FragmentTransaction ft", replacing it with just "FragmentTransaction ft", the problem goes awawy. Then new problems arise:
The method onTabReselected(ActionBar.Tab, FragmentTransaction) of type TabListener must override or implement a supertype method TabListener.java
The method onTabSelected(ActionBar.Tab, FragmentTransaction) of type TabListener must override or implement a supertype method TabListener.java
The method onTabUnselected(ActionBar.Tab, FragmentTransaction) of type TabListener must override or implement a supertype method TabListener.java
The type TabListener must implement the inherited abstract method ActionBar.TabListener.onTabReselected(ActionBar.Tab, FragmentTransaction) TabListener.java
The type TabListener must implement the inherited abstract method ActionBar.TabListener.onTabSelected(ActionBar.Tab, FragmentTransaction) TabListener.java
The type TabListener must implement the inherited abstract method ActionBar.TabListener.onTabUnselected(ActionBar.Tab, FragmentTransaction) TabListener.java
Whats going on here?
As you may understand, I'm new to Java and Android development. I feel like I'm pretty close, but I'm not able to solve this problem. I don't understand why it want to "convert from android.support.v4.app.Fragment to android.app.Fragment when I'm not even importing android.app.Fragment anywhere.
I guess it's related to using the compatibility package. (Do I have to use this package at all when creating an app for the newest version of the SDK?)
Try to use getSupportFragmentManager() instead getFragmentManager()
Whats going on here?
While the Android Support package gives you a backwards-compatible Fragment implementation, the ActionBar is not part of the Android Support package. Hence, ActionBar.TabListener is expecting native API Level 11 Fragment objects. Consider using ActionBarSherlock to have both an action bar and Android Support fragments.
but then I'm left with another problem in my FragmentPagerAdapter
The FragmentPagerAdapter in the Android Support package is a bit messy -- it wants API Level 11 Fragment objects, not Android Support Fragment objects. However, you can clone the source to FragmentPagerAdapter (source is in your SDK) and create your own implementation that uses the support.v4 flavor of Fragment and kin.
I know that it has been too late to answer this question but it might help someone with the same problem.
Go to your java folder and click on your fragment's activity.
In the imports, replace import android.app.Fragment; with
import android.support.v4.app.Fragment;
Keep the code in the MainActivity intact and this should help resolve the issue.
Note: If it doesn't work at once, don't worry. Build > Rebuild project.
This solution works for me
replace
public class MyFragment extends Fragment{
}
with
public class MyFragment extends android.support.v4.app.Fragment{
}
and also replace import
import android.app.Fragment;
with
import android.support.v4.app.Fragment;
You can remove the support package, and that should solve your problem. It is only needed when you need functions from Android 3.0 and above in apps for earlier versions.
In your case you get both the default Fragments from ICS, and the Fragments from the support package, and if you happen to get objects from the different packages they will not work together.
Short version; You use either an api level above Honecomb or the support package, not both.
I've had the same problem yesterday.
There is a really nice page by Samsung that covers ActionBarSherlock.
Check if you use one of the imports/classes/methods on the left and replace them by the imports/classes/methods on the right.
I had the same problem. Solved it by changing the interface from implements ActionBar.TabListener to implements TabListener and then implement the methods inside this interface. Its also mentioned the error you have mentioned.
look here:fragmentTransaction.add(R.id.main_container, new HomeFragment());
you add the fragment ,but follow,you use replace() method ,so you should use replace instead of add()