What's wrong with the code below? - java

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");
}

Related

Handle onBackPressed in android in fragment

I want to handle onBackPressed in fragment
I use following code in my activity but this return 0
#Override
public void onBackPressed() {
int count = getFragmentManager().getBackStackEntryCount();
Toast.makeText(getBaseContext(), ""+count, Toast.LENGTH_SHORT).show();
if (count == 1) {
super.onBackPressed();
//additional code
} else {
getFragmentManager().popBackStack();
}
}
Just add .addToBackStack(null) in your Activity or Fragment . When you adding or replacing fragment. Like below
getSupportFragmentManager().beginTransaction().replace(R.id.parent_layout, new MyFragment()).addToBackStack(null).commit();
Note:- you don't have to do anything in your onBackPressed() method.
Just app this line when you want to replace any fragment and manage backsack on Fragment.
ClientHome per = new ClientHome();
Bundle bundle = new Bundle();
bundle.putString("usertype", "client");
per.setArguments(bundle);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.slide_from_left, R.anim.slide_to_right);
fragmentTransaction.replace(R.id.content_frame, per, "tag");
fragmentTransaction.addToBackStack("tag");
fragmentTransaction.commit();

Passing data from a adapter to fragment using startActivityForResult within same activity

I want to pass a data from my adapter class to another fragment with the help of startActivityForResult. If I used the below code same activity recreates it i don't want that. How to solve this issue?
Bundle mBundle = new Bundle();
mBundle.putString(Constants.SELECTED_PLOCATION, pLocation);
mBundle.putString(Constants.SELECTED_RLOCATION, rLocation);
mBundle.putString(Constants.SELECTED_FROM, selectedFrom);
mBundle.putString(Constants.FROM_TYPE, fromType);
mBundle.putString(Constants.AREA_TYPE, Constants.AREA);
getActivity().getFragmentManager().popBackStackImmediate();
Intent mIntent = new Intent(getActivity(), AuthorizedCustomerActivity.class);
getActivity().startActivityForResult(mIntent, PICK_LOCATION_REQUEST, mBundle);
Use below code for data transfer from adapter to fragment;
Fragment fragment = new YourFragmentName();
FragmentManager fm = getActivity().getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.commit();
Bundle mBundle= new Bundle();
mBundle.putString(Constants.SELECTED_PLOCATION, pLocation);
mBundle.putString(Constants.SELECTED_RLOCATION, rLocation);
mBundle.putString(Constants.SELECTED_FROM, selectedFrom);
mBundle.putString(Constants.FROM_TYPE, fromType);
mBundle.putString(Constants.AREA_TYPE, Constants.AREA);
fragment.setArguments(mBundle);

What is the best way to add fragment in the Tabs android

My application had a bottom navigation bar which has 5 tabs.
So according to these tabs, I have 5 fragments
When I click on the tab, the fragment changed according to that tab.
I can switch fragment by using the method beginTransaction().replace...
I dont want the fragment to be destroyed and recreated again each time I switch tabs, so my solution is sth like this
//I init 5 fragments
Fragment1 frag1 = new Fragment1();
Fragment2 frag2 = new Fragment2();
Fragment3 frag3 = new Fragment3();
Fragment4 frag4 = new Fragment4();
Fragment5 frag5 = new Fragment5();
//When I click on tab, for example tab1, I hide all fragments except tab1
//hide all fragments
getSupportFragmentManager()
.beginTransaction()
.hide(fragment1) //Fragment2, 3, 4, 5 as well
.commit();
//show fragment 1
getSupportFragmentManager()
.beginTransaction()
.show(fragment1)
.commit();
It works very well, but the problem is sometimes 2 fragments show at once time (I dont know why because I hide all fragments)
Any other way to achieve that? Switch fragment without destroying it and creating it again.
for adding fragment I make this code for my project, hope it will be help.
public static void replaceFragment(Fragment fragment, FragmentManager fragmentManager) {
String backStateName = fragment.getClass().getName();
String fragmentTag = backStateName;
Fragment currentFrag = fragmentManager.findFragmentById(R.id.frame_container);
Log.e("Current Fragment", "" + currentFrag);
// boolean fragmentPopped = fragmentManager.popBackStackImmediate(backStateName, 0);
int countFrag = fragmentManager.getBackStackEntryCount();
Log.e("Count", "" + countFrag);
if (currentFrag != null && currentFrag.getClass().getName().equalsIgnoreCase(fragment.getClass().getName())) {
return;
}
FragmentTransaction ft = fragmentManager.beginTransaction();
// if (!fragmentPopped) {
ft.replace(R.id.frame_container, fragment);
ft.addToBackStack(backStateName);
ft.commit();
// }
currentFrag = fragmentManager.findFragmentById(R.id.frame_container);
Log.e("Current Fragment", "" + currentFrag);
}
hope this will be help you, and use this method in entire project for replacing fragment.
Using ViewPager with FragmentPagerAdapter suits for you in this case.
Then use ViewPager#setOffsetPageLimit(5). This will help you show/hide your fragments without recreating it again.
Follow this tutorial
Let try it, then tell me if your problem is solved or not. ;)
you don't have to need to hide the fragment just replace the fragment like this method:
public void setFragment(Fragment fragmentWhichYouWantToShow) {
fm = getSupportFragmentManager();
ft = fm.beginTransaction();
ft.replace(R.id.container, fragmentWhichYouWantToShow);
ft.commit();
}
Try to make it in a singe transaction.
protected void showAsRootFragment(Fragment fragment, #NonNull String tag) {
FragmentManager supportFragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = supportFragmentManager.beginTransaction();
if (supportFragmentManager.getFragments() != null) {
for (Fragment attachedFragment : supportFragmentManager.getFragments()) {
if (attachedFragment != null && !tag.equals(attachedFragment.getTag())) {
transaction.hide(attachedFragment);
attachedFragment.setUserVisibleHint(false);
}
}
}
if (!fragment.isAdded()) {
transaction.add(R.id.frame_container, fragment, tag);
fragment.setUserVisibleHint(true);
} else {
transaction.show(fragment);
fragment.setUserVisibleHint(true);
}
transaction.commit();
}

Open basefragment from activity

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();

Android Studio Failing to Store Arguments as Part of Fragment Bundle

I've been wracking my brain for the greater part of the weekend, trying to solve an issue related to Android Studio. The assignment is to create a list fragment that will update when the user clicks buttons in the overhead bar, but despite my best efforts only one of the fragments actually displays (and it's the same no matter which button the user clicks). I've narrowed it down to the point where I'm fairly certain the problem has to do with the constructor's handling of bundles, but I'm not sure where the error is. Here's the related code:
public static ItemFragment newInstance(String title, int position) {
ItemFragment fragment = new ItemFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1,title);
args.putInt(ARG_PARAM2,position);
fragment.setArguments(args);
return fragment;
}
And later on, the call to getArguments():
public void onCreate(Bundle savedInstanceState) {
setRetainInstance(true);
if (getArguments() != null) {
mTitle=getArguments().getString(ARG_PARAM1);
mPosition=getArguments().getInt(ARG_PARAM2);
getActivity().setTitle(mTitle);
}
if (mPosition == 0) {
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, android.R.id.text1, listItems));
} else if (mPosition == 1) {
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, android.R.id.text1, newGoalItems));
} else if (mPosition == 2) {
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, android.R.id.text1, markProgressItems));
} else if (mPosition == 3) {
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, android.R.id.text1, settingsItems));
}
}
This is the related code in MainActivity:
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_list) {
list=ItemFragment.newInstance("List", 0);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction.add(R.id.list_frame, new ItemFragment());
fragmentTransaction.commit();
}
else if (id==R.id.action_newGoal) {
newGoal=ItemFragment.newInstance("New Goal", 1);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction.add(R.id.list_frame, new ItemFragment());
fragmentTransaction.commit();
}
else if (id==R.id.action_markProgress) {
markProgress=ItemFragment.newInstance("Mark Progress", 2);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction.add(R.id.list_frame, new ItemFragment());
fragmentTransaction.commit();
}
else if (id==R.id.action_settings) {
settings=ItemFragment.newInstance("Settings", 3);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction.add(R.id.list_frame, new ItemFragment());
fragmentTransaction.commit();
}
return super.onOptionsItemSelected(item);
}
I know from testing that the code simply crashes through the if statement above. What I don't know is why... It looks to me like there should be some values in getArguments that prevent it from returning null.
Write this piece of code in fragments onCreate method() it will work
if (getArguments() != null) {
mTitle=getArguments().getString(ARG_PARAM1);
mPosition=getArguments().getInt(ARG_PARAM2);
getActivity().setTitle(mTitle);
}
It sounds like you are trying to read the arguments in your Fragment's constructor. The context will not be established yet in the constructor, so you should be reading from the bundle in the onCreate() method.
public static Fragment newInstance(String title, int position) {
Fragment fragment = new ItemFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1,title);
args.putInt(ARG_PARAM2,position);
fragment.setArguments(args);
return fragment;
}
Change this line ItemFragment fragment = new ItemFragment(); to this Fragment fragment = new ItemFragment(); and all your code is perfect.
I finally figured this out! So the issue was that during the process of loading the fragments into the frame (the third section of code), the professor gave us a line of code that instantiated a new fragment instead of using the one that we'd just created a few lines above. I simply replaced
fragmentTransaction.add(R.id.list_frame, new ItemFragment());
with
fragmentTransaction.add(R.id.list_frame, list);
and now everything runs. Thanks for all the help everyone!

Categories