I'm wondering if it would be possible, to use the XML-onclick attribtue to call another XML-"View".
Means if I'm in a menu and click on the button "Create new Drawing", shouldn't I be able to call just another XML-View to bring up more options?
What I know is: android:onclick="hellothere" calls the method public void hellothere(View view) in the Activity to whom the view belongs, but why does it has to be used with code, instead that I'd just call another XML-Layout?
Example: andorid:onclick="new_page" (new_page.xml opens)
Calling another xml without a context is not possible in android. The context would be something like an activity, fragment etc.
If you want to inflate another xml into an area on your desired layout without activity transition, use fragments instead.
Heres's a simple code how to attach a fragment in a specific or generic area:
attaching to generic fragment area:
FragmentTransaction ft;
Fragment mFragment = new MySampleFragment();
ft = getFragmentManager().beginTransaction();
ft.replace(android.R.id.content, mFragment, "samplefragment");
ft.commit();
as you can see above, we attach the Fragment into the default fragment inflater of android which is "android.R.id.content".It gives you the root element of a view, without having to know its actual name/type/ID. Check out Get root view from current activity
attaching to specific fragment area:
FragmentTransaction ft;
Fragment mFragment = new MySampleFragment();
currentFragment = mFragment;
ft = getFragmentManager().beginTransaction();
ft.replace(R.id.myfragmentid, mFragment, "samplefragment");
ft.commit();
Here we inflated the fragment inside a specific area with an actual ID which is R.id.myfragmentid. In this case you can specify which area in your page you will show your desired output upon a specific events like button click, hover, etc.
Hope it helps. Cheers! :)
Related
I am facing some weird issue with fragments, I am displaying google map on these two fragments, while switching from Home Fragment to Request cab fragment, in Request cab fragment, fragments are overlapping, I can see Home Fragment in background and its also clickable I can move map of Home Fragment too. This issue occur when I use fragmentTransaction.add(R.id.frame, fragment, fragmenttag);
but if I use replace then its working fine, but I want to get the view back onBackPressed that is not possible with replacing the fragmnet. I am attaching screenshots and code.
public void changeFragment(final Fragment fragment, final String fragmenttag) {
try {
drawer_close();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction =
fragmentManager.beginTransaction().addToBackStack(null);
fragmentTransaction.add(R.id.frame, fragment, fragmenttag);
fragmentTransaction.commit();
} catch (Exception e) {
}
}
You just need to add background when you add fragment.
add(): adds the new fragment on the top of another fragment that's why you can see below fragment
replace(): removes everything then adds the new fragment
add and replace work quite differently, while replace removes current fragment from inflated view group. add method just adds new layout inside of ViewGroup. thats why you can see your fragment and thats why its clickable just think them as normal views and not fragments. now you could just add white background to root layout of second fragment and make it clickable it should solve all your problems.
I'll jump straight to the point.
I'm making an application with has three tabs (MainFragment, FragmentCategories, FragmentList). What I want to do next is this:
From the second tab, FragmentCategories, I open up a certain category. Using getFragmentManager and FragmentTransaction, I open up a FragmentCategoriesList. From there, when I choose a certain object, I want to open it in yet another "subfragment".
Following a number of tutorials, MyFragmentCategoriesList uses a ListView layout.
context = getActivity().getApplicationContext();
view = inflater.inflate(R.layout.fragment_categories_list, container, false);
Later in the code, I initialize a ListView object which uses that same layout (R.layout.fragment_categories_list == R.id.frag_cat_list).
final ListView lv1 = (ListView) view.findViewById(R.id.frag_cat_list);**
lv1.setAdapter(new MyCustomBaseAdapter(context, searchResults));
Here's a snippet where I select an object:
...
data.putString("selection",test);
FragmentManager fragManager = myContext.getSupportFragmentManager();
FragmentTransaction fragTrans = fragManager.beginTransaction();
FragmentCategoriesDetail FragCatDetail = new FragmentCategoriesDetail();
FragCatDetail.setArguments(data);
fragTrans.add(R.id.frag_cat, FragCatDetail);
fragTrans.addToBackStack(null);
fragTrans.commit();
...
Anyway, the problem is this:
fragTrans.add(R.id.frag_cat, FragCatDetail);
In this case, my FragCatDetail works, but I can't go BACK to the FragmentCategoriesList. If I put R.id.listview (a relative layout xml containing two textviews), my Fragment opens WITHIN an object of a ListView, and I can go back to FragmentCategoriesList.
If I put R.id.frag_cat_list (which is, after all, the layout of the current fragment, FragmentCategoriesList), my app crashes with
java.lang.UnsupportedOperationException: addView(View) is not supported in AdapterView
which seems logical because FragCatDetail is a Fragment with a relative layout.
My question is this: what can I do in order to have my FragCatDetail fragment work like in the first case (relative layout) AND go back to FragmentCategoriesList like in the second case (listview layout).
Thanks in advance! Much appreciated.
Figured out what was the problem.
FragmentManager fragManager = myContext.getSupportFragmentManager();
FragmentTransaction fragTrans = fragManager.beginTransaction();
FragmentCategoriesDetail FragCatDetail = new FragmentCategoriesDetail();
FragCatDetail.setArguments(data);
fragTrans.add(R.id.frag_cat, FragCatDetail);
fragTrans.addToBackStack(null);
fragTrans.commit();
Throughout the application, I used
getFragmentManager().popBackStack(). Since I was going to a new fragment (FragmentCategoriesDetail), I was doing that by getSupportFragmentManager.
In my Main Activity, I overrode onBackPressed() and inside I was using
getFragmentManager().popBackStack();
where in fact I should have been using
getSupportFragmentManager().popBackStack();
at least for this specific fragment.
Once again, it is a story of a FragmentManager vs SupportFragmentManager. I hope I helped someone with this. :)
Working with fragments I've always used replace() for my transactions, but I wish I didn't have to save instance states anymore to restore a fragment's view and prevent reloading when coming back to that fragment. So, I've decided to work with add(). The thing is when I add another fragment, the previous fragment view remains in the background and that's fine (that's the behavior I expected), but the problem is I can actually interact with the views in the background. Example:
Fragment A has a Button
Fragment B has a TextView
When I add Fragment A and later add Fragment B, I'm able to click on Fragment A's Button, even staying on Fragment B's view.
I'm using:
FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction().
add(getRootViewContainer(),fragment,fragment.getClass().getSimpleName());
if (shouldGoBack)
fragmentTransaction.addToBackStack(fragment.getClass().getSimpleName());
where getRootViewContainer() returns the id of the FrameLayout I'm using as my activity main container.
Now, is it really the default behavior of add()?
If so, is there a proper way to avoid this or one just has to use replace()?
What you can do here is just hide previous fragment at the time of transaction of current fragment.
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment newFragment= new MyFragment ();
ft.hide(CurrentFragment.this);
ft.show(newFragment);
ft.commit();
It worked for me just try it.
FragmentTransaction.hide(fragmentBehind); //works for me!
example :
//I have it globally available
FragmentTransaction trans = MainActivity.getManager().beginTransaction();
//not globally
FragmentTransaction trans = getFragmentManager().beginTransaction();
MapFragment newFragment = new newFragment();
trans.add(R.id.fragmentContainer, newFragment, tag);
trans.hide(this);
trans.addToBackStack(tag);
trans.commit();
Yes, this is a default behaviour of add().
If you really don't want to user replace(), you can try to disable views which are inside "old" fragment.
I have an activity with a FrameLayout in it.
The activity should show four steps, and each step is a Fragment. When I want to go back-further, I don't want my fragments to be recreated. I would like to retain them and simply replace their view in my fragment.
I used to first create my Fragments and add them in the backstack like this:
Fragment step= new Frag1ActCompleteFragsCommTrack();
FragmentTransaction ft= getSupportFragmentManager().beginTransaction();
ft.add(step, ""+onStepNr);
ft.addToBackStack(null);
ft.commit();
notice that I don't show it, I simply create it and add to the backstack.
So, once I need one of my fragments to show, I add it (in this example I don't remove any fragment from the framelayout just because it's my first add):
FragmentTransaction ft= getSupportFragmentManager().beginTransaction();
ft.add(R.id.my_frameLayout, step);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
So: the problem is that I obtain a
Caused by: java.lang.IllegalStateException: Fragment already added: Frag1ActCompleteFragsCommTrack{410dcb20 #0 id=0x7f050041 -1}
But I think I can't add directly into my framelayout the first time, otherwise the next time I replace it, I could lose my fragment. Am I right? So.. what's the best practice for retaining fragments that could interchange each other in a framelayout?
Ladies and gentlemen, I did it!
If you add a Fragment, and you want it to be shown in a framelayout, remember to put it in the Fragment backstack. That's it! If you replace it in the framelayout with another one, no worries: you can put it back by finding it thanks to its tag.
It was easier than I thought actually
//step is an int describing the step associated to the fragment I wanna place
FragmentTransaction ft= getSupportFragmentManager().beginTransaction();
ft.replace(R.id.act_complete_track_frameLayout, f, ""+step);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
if(firstAttach)
ft.addToBackStack(null);
ft.commit();
imagine a fragment with tag "1" replaced through the code above by a fragment with tag "2". If I want to go back to step1, I reuse that code by obtaining my old fragment with getSupportFragmentManager().findFragmentByTag("1")
To be short, I thought that FragmentTransaction.replace removed the fragment from the backstack as well. That seems not to be the case (luckily)
You can always do something like fragmentManager.putFragment(yourFragment);
If I understand correctly, you are trying to add all the fragments but not show them until you are ready. FragmentTransaction.add() doesn't exactly do that though. It will also be shown after its added. You should use hide() after adding each fragment, and then later you can use show() to make it visible, and hide() again to make other fragments invisible.
Like this:
Fragment step = new Frag1ActCompleteFragsCommTrack();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(step, ""+onStepNr);
ft.hide(step);
ft.commit();
Then later:
Fragment step = getSupportFragmentManager().findFragmentByTag(""+onStepNr);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.show(step);
// may want to hide other fragments here
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
When I press a button, my app creates a fragment. I'd like to make sure that only one of this fragment is created, e.g. disable the button if the fragment already exists.
How do I check that it creates only one fragment? Is it possible to get a Fragment count or is there some option that limits it to creating only one?
You can use the methods that sandrstar mentioned. When attaching a fragment u can first check to see if its already attached.
For example if you are adding the fragment dynamically you can stop the fragment from being re-added by doing the following:
MyFragment myFragment = getFragmentManager().findFragmentByTag("MyFragmentTag")
if(myFragment == null)
{
myFragment = MyFragment.newInstance();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(R.layout.mylayout,myFragment,"MyFragmentTag");
ft.commit();
}