Open basefragment from activity - java

How can I open fragment from activity on android app. I tried to do this, but fragment didn't open:
BaseFragment manager = new SurveysFragment();
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager
.beginTransaction()
.replace(R.id.test_l, manager)
.commit();

Use this function
public void openFragment(Fragment fragment) {
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.test_1, fragment).commit();
}
and call this function like this
openFragment(new BaseFragment());

When you want to open BaseFragment than why you are making instance of
surveysFragment it holds surveyFragment instance to BaseFragment
reference so change it like below and note check your BaseFragment
that extended Fragment must be android.support.v4.app.FragmentManager,
for this you can check the import of Fragment inside your
BaseFragment.
BaseFragment manager = new BaseFragment();
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager
.beginTransaction()
.replace(R.id.test_l, manager)
.commit();

Related

Fragment UX choice and genericity

I find myself switching between a lot of Fragments in my card game app.
When my user creates a deck he goes through the following fragments:
Deck List Fragment (Click on 'New Deck') -> Class Selection Fragment (Mage, Warrior etc.) -> Name Selection Fragment -> Back to Deck List Fragment with our new deck listed.
I do this in order to have a smooth deck creation process but here are my two questions:
1) Is it recommended to use more Fragments than required if it makes the UX better and smoother?
2) Note that I do the following in order to switch Fragment:
Fragment fragment = new MyFragment();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
// Set argument(s) - Not all fragments set arguments
Bundle args = new Bundle();
args.putString("deckName", deckName);
fragment.setArguments(args);
fragmentTransaction.replace(R.id.content_frame, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
Instead of having similar methods from one Fragment to the other, I wish to create a generic method that takes a variable amount of parameters and the type of Fragment to create and switches to said Fragment.
But I can't seem to figure out how to do it.
Please excuse this lengthy post, and thank you.
Check out my code :
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
replaceFragment(new HomeFragment());
}
public void replaceFragment(final Fragment fragment) {
getFragmentManager()
.beginTransaction()
.replace(R.id.container, fragment, fragment.getClass().getSimpleName())
.commit();
}
public void addFragment(final Fragment fragment) {
final Fragment hideFragment = getFragmentManager().findFragmentById(R.id.container);
getFragmentManager()
.beginTransaction()
.add(R.id.container, fragment, fragment.getClass().getSimpleName())
.hide(hideFragment)
.addToBackStack(hideFragment.getClass().getSimpleName())
.commit();
}
}
Call above methods in Fragment :
final HomeFragment homeFragment = new HomeFragment();
final Bundle bundle = new Bundle();
bundle.putString("KEY","VALUE");
homeFragment.setArguments(bundle);
((MainActivity) getActivity()).addFragment(homeFragment);

Opening fragment on clicking on Notification

I have one SplashActivity and one MainActivity and all the fragments are associated with MainActivity. Now whenever I recive Notification from server I want to open one specific fragment. I am opening this like
final android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if(getIntent().getAction().equals("OpenNotificationFragment")) {
fragmentManager.beginTransaction()
.replace(R.id.fragment_main_container, new NotificationFragment()).addToBackStack(PastOrderFragment.TAG)
.commitAllowingStateLoss();
}
but during my splash image is loading it is throwing NullPointerException, should I call this method in SplashActivity or edit some of my code.

Type error - Switch fragments in the Navigation Drawer

I have problem of type with my code. I don't understand because my "extends" is correctly put.
#Override
public void onNavigationDrawerItemSelected(int position) {
FragmentManager fragmentManager = getSupportFragmentManager();
if (position == 0) {
fragmentManager.beginTransaction()
.replace(R.id.container, new HomeFragment())
.commit();
} else if (position == 1) {
fragmentManager.beginTransaction()
.replace(R.id.container, new AnnouncesFragment())
.commit();
}
}
There is problem with new HomeFragment() and new AnnouncesFragment().
Prototype of HomeFragment && AnnoncesFragment:
public class HomeFragment extends Fragment {
public class AnnouncesFragment extends Fragment {
Error on AndroidStudio is:
replace (int, android.support.v4.app.Fragment) in
FragmentTransaction cannot be applied to (int, com.xxx.xxxx.xx.AnnouncesFragment)
On android doc:
http://developer.android.com/reference/android/support/v4/app/FragmentTransaction.html
How I use function ->
replace(int containerViewId, Fragment fragment)
Thanks,
This is because you're using the latest version of android.app.Fragment when extending your classes. You want to use android.support.v4.app.Fragment instead.
Make sure your fragments are instances of android.support.v4.app.FragmentActivity and not android.app.Fragment in this case.
Make sure that all your fragment related components are instances of android.support.v4.app... and not of android.app....
Also create the transaction using the correct fragment manager: use Activity.getSupportFragmentManager() instead of Activity.getFragmentManager()
So your fragment must look like:
import android.support.v4.app.Fragment;
...
public class MyFragment extends Fragment {
...
}
And the code for the FragmentTransaction:
import android.support.v4.app.FragmentTransaction;
...
{
MyFragment myFragment = new MyFragment();
FragmentTransaction ftx = getSupportFragmentManager().beginTransaction();
...
ftx.replace(R.id.my_fragment_id, myFragment);
...
ftx.commit();
}

Check if a fragment exists and reuse it

I'm using the following code to create a fragment everytime the user click on an item in a list view.
But in this way the fragment is created at every user click. What I want is to reuse the old fragment (if it exists) and only reload its content (don't create a new one).
MagazineViewFragment fragment = new MagazineViewFragment();
fragment.openStream(itemSelected);
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, fragment)
.commit();
How can I do?
There're multiple ways, probably the most easy one is to check if the current Fragment in your container is an instance of FragmentXYZ (in your case MagazineViewFragment).
Example
Fragment mFragment = getFragmentManager().findFragmentById(R.id.container);
if (mFragment instanceof MagazineViewFragment)
return;
Add tag when you call your fragment from activity:
FragmentManager fm = getFragmentManager();
Fragment fragment = fm.findFragmentByTag( MagazineViewFragment.TAG);
if (fragment == null) {
MagazineViewFragment fragment = new MagazineViewFragment();
fragment.openStream(itemSelected);
getFragmentManager()
.beginTransaction()
.add(R.id.container, fragment, MagazineViewFragment.TAG)
.commit();
}
If you need only to update itemSelected - see broadcasts or listeners.
Something like this might help:
getFragmentManager().findFragmentById(fragmentId);
Do not forget the null check.

What's wrong with the code below?

I'm learning from the book from big nerd ranch.
FragmentManager fm = getFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragmentContainer);
if (fragment == null) {
fragment = new CrimeFragment();
fm.beginTransaction().add(R.id.fragmentContainer, fragment).commit();
}
Got a type mismatch error.
However, if I call
CrimeFragment fragment = fm.findFragmentById(R.id.fragmentContainer);
it will not work. So my question is how to call a CustomFragment(CrimeFragment) using an id from the layout?
Thanks in advance.
I usually do it like this:
CrimeFragment fragment = new CrimeFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragmentContainer, fragment).commit();
or
transaction.add(R.id.fragmentContainer, fragment).commit();
More information:
The screen orientation change will cause the fragment update once more if it is create in onCreate method.
you can prevent this here:
if (savedInstanceState == null){
CrimeFragment fragment = new CrimeFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragmentContainer, fragment, "fragment").commit();
}else{
CrimeFragment homeFragment = (CrimeFragment) getSupportFragmentManager().findFragmentByTag("fragment");
}

Categories