I want to check if the Activity I create in a test is showing a Fragment. How can I do this? I've tried searching through Stack Overflow and Google but I couldn't find anything.
You need to find the fragment by id with
activity.getFragmentManager.findFragmentById(R.id.your_fragment_container);
If this returns something different from null, then it means that your container has a Fragment.
Related
Suppose I have a Fragment called Fragment MenuFragment and it have R.id android:id="#+id/MenuFragment" inside nav_graph.xml
Question 1: Can I programmatically find R.id if I have just MenuFragment.class ?
Question 2: Can I programmatically get MenuFragment.class if I have just R.id.MenuFragment ?
No. A fragment can have infinitely many ids. If you have an instance of a fragment you can get its id, but you could have the same fragment in a dozen activities with a dozen different ids. Heck, you can have a dozen copies in the same activity with a dozen ids.
This, yes. If you use the id to get the actual instance of the fragment, you can then use .getClass() to get its class.
I'm really sorry, but atm I can't test any code. But I have a question. How should we work with fragment manager? I got an error when I was trying to add fragmentA, then fragmentB, and then again A. I got an error : fragment is already added. And here is the question: should I call transaction.Add at launch and then replace it with others fragments or I shouldn't.
Thanks for attention and sorry for my English, it is not my native language
You can add it if you want but you on first launch you can actually just use .replace even if there isn't a fragment currently loading into the frame and it will still work.
I've seen the various other Android posts that talk about editing the part of the XML file that determines the main activity. But this simple solution isn't working for me at all, presumably because I'm trying to change the main activity in a large app, and the resulting loose ends leads to a ton of bugs.
In addition to changing the startup activity, I've also added an activity tag for the ex-startup activity that is replacing it. But I don't know which changes I should add to deal with the Fragments that are messed up by the startup activity change.
I'm getting this error:
/AndroidRuntime( 741): Caused by: java.lang.IllegalArgumentException: No view found for id 0x7f05003c for fragment PlaceholderFragment{42894810 #0 id=0x7f05003c}
Would appreciate any help.
Edit: I have also changed my layout settings to correspond to the fragment layout instead of the activity layout. I also made it so that the new activity extended Activity instead of ActionBarActivity. Is there anything else I should do?
I think you have not used PlaceHolderFragment that was automatically added when a new project was created. You must have edited the fragment_main xml file and try to use findviewby id in your MainActivity oncreate method. The new update to adt has many people making this simple mistake.
Is there some way I get already created currently displayed same instance of fragment in my activity. I DON'T to use
findFragmentById(int id), simply I never created that
findFragmentByTag(String tag), because I am not adding tag in every fragment .offcourse due to some requirement.
getFragment(Bundle bundle, String key), because I never am putting in bundle.
Although I may look like fool to mention that, but I want something like this. Is activity keep some fragment instance somewhere.??
What can be the best approach I can take to achieve this requirement.
UPDATE
Okay, so let me tell you why I can't use above methods. If I am adding various fragment in one activity, where I always want to come back to one fragment when back is clicked. (As we have in navigation drawer, u know). And unless there are inner fragment. so for that I don't want to add in the back stack.
Now even if I have the tag associated with my fragments, I cant say for 8 fragment if- else-if-else for getting the tag. That I know is not correct. So first two ways goes out of my option. Now third one. I exactly don't know where to keep it. And even if I keep it where will I get the bundle and key every time I just want my fragment.
You can get from fragment Manager
List<Fragment> fragList=fManager.getFragments();
for(Fragment fr: fragList){
String fragClassName = fr.getClass().getName();
if(fragClassName.equals(Abc.class.getName())){
Log.i("Fragment:","Abc");
}else if (fragClassName.equals(Xyz.class.getName())) {
Log.i("Fragment:","Xyz");
}
}
Alright. My first question here. And I already found some solution, but honestly do not really get the stuff that happens in the background. So perhaps there’s someone who could clear up this stuff a little bit. After days of debugging I’m just glad that it works... and hope I did not make some serious error. So let’s have a look.
I got some Main-Activity. Just a FragmentActivity extending JFeinstein’s SlidingFragmentActivity. Further I decided to go the fragment-way and just put any content (list-fragment, article-fragment, …) as a fragment into a container (to right of the sliding-menu); my main-container. So far, so good.
One essential fragment is my article-fragment. A ViewPager (with a FragmentStatePagerAdapter) - containing some pages with text and perhaps another list-fragment. Still no problem so far, until I decide to rotate the device. And to be more precise, rotating the device works too as long as I do not decide to update my article-fragment.
I understood (correct me if I am wrong) that Android handles the fragments state on its own when rotating the device. And it seems to be everything fine just until I want to reload/update its content.
Ok let’s dig deeper into that.
On first start I got some empty main-container. Then I am loading my article-fragment for the first time. Just getting the SupportFragmentAdapter, creating my ArticleFragment and replace the main-container with the newly created fragment - tagged. No rocket-science - just a simple transaction:
ViewPagerFragment pagerFragment = (ViewPagerFragment)
getSupportFragmentManager().findFragmentByTag(TAG_FRAGMENT_ARTICLE);
if(pagerFragment != null){
if(pagerFragment.isResumed()){
pagerFragment.triggerReload();
}
} else {
pagerFragment = new ViewPagerFragment();
FragmentTransaction t = getSupportFragmentManager().beginTransaction();
t.replace(R.id.id_main_root_frame, pagerFragment, TAG_FRAGMENT_ARTICLE);
t.commitAllowingStateLoss();
}
To avoid creating a fragment each time I reload my content, I’m trying to fetch the fragment before the transaction and - if it is found and resumed - trigger some reload on the existing fragment.
Now I rotate my device in this state. To avoid messing with the fragment state I left onSaveInstanceState() inside the fragment untouched. So I guess the fragment is just destroyed and recreated. And everything still works so far. But I think this part has something of a black box.
After that - normal startup, creating fragment and put into main-container, rotating device - I trigger some update. But instead of finding the old (recreated) fragment by tag, nothings found and a new fragment is created and inserted. At least tried to be inserted, because this is where I got the following exception:
java.lang.IllegalStateException: Activity has been destroyed
To be precise, I get the above exception when finish my transaction with a commitAllowingStateLoss(). When I just commit() the transaction I get the following exception:
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
So that’s where the error comes up. And after ages of debugging and searching I found some hint on this question/answer to get the SupportFragmentManager on a WeakReference of my MainActivity. And what should I say. Since I implemented that, it works. I had to change my update-process a bit, but it works. But leaves some questions ...
The behaviour seems to be similiar. First creation works perfect. Reload just the same - fragment is found by tag. After rotation, article is still shown. And when I reload the fragment with that state it is not found by tag so a new one is created, but the commit()-request does not throw an exception. A look inside the debugger shows that the WeakReference is some other instance (other id), than the one(this) all of this takes place in. And thats where I lose the plot. ..
If some of you could give me some hints, would be great!
Thanks in advance!
try this:
commitAllowingStateLoss(); instead commit();