Illegalargumentexception with fragment transaction commit - android

I am developing an App with TabHost, which contains 4 different Tabviews. Each tabview contains different fragment views added with following code
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.tabcontent, fragment);
ft.commit();
The 3rd Tab contains a Google Maps View extends SupportMapFragment.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.map_layout, container,
false);
//Calls Asynctask to fetch map location details from server
return view;
}
From AsyncTask onPostExecute, The following code is used to plot markers on Google Maps :
mFragment = new SupportMapFragment() {
#Override
public void OnActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if ((map = mFragment.getMap()) != null) {
setUpMap();
}
}
};
FragmentManager mangaer = this.getActivity()
.getSupportFragmentManager();
FragmentTransaction fragmentTransaction = mangaer
.beginTransaction();
fragmentTransaction.add(R.id.new_map_layout, mFragment);
fragmentTransaction.commit();
Now When I add map fragments for the first time, everything works normal and mapview is getting plotted on the Tab view. But while testing the App, changing the tabviews frequently without any delay, the App crashes from 3rd Tab with the following error in transaction.commit :
E/AndroidRuntime(4392): java.lang.IllegalArgumentException: No view
found for id 0x7f060218 for fragment CustomMap$4{42e3cea0 #3> id=0x7f060218}
E/AndroidRuntime(4392): at
android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:865)
Please suggest what changes I need to make to avoid the crash.
Note : The crash only happens when I change the Tabs frequently

Related

Shared element back animation without backstack

I use one activity multiple fragments in my app. I use a shared element animation. I have two fragments, one of them is a detail page.
I don't want to addToBackStack function for fragment transition. And the detail fragment returns without animation for some cases. (fragmentMain->fragmentDetail)
DetailFragment detailFragment = new DetailFragment();
Transition moveTransition = TransitionInflater.from(MainActivity.singleInstance)
.inflateTransition(android.R.transition.move); // android.R.transition.move
moveTransition.setDuration(400);
detailFragment.setSharedElementEnterTransition(moveTransition);
FragmentManager fragmentManager = MainActivity.getActivityFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction()
.addSharedElement(sharedView, sharedView.getTransitionName())
.replace(R.id.mainLayout, detailFragment);
fragmentTransaction.commitAllowingStateLoss();
fragmentManager.executePendingTransactions();
This code works for me. I know that if I use addToBackStack, fragmentDetail->fragmentMain reveal animation works automatically. But I don't want to the use back stack.
Below code doesn't works for fragmentDetail->fragmentMain.
detailFragment.setSharedElementReturnTransition(moveTransition);
mainFragment.setSharedElementEnterTransition(moveTransition);
FragmentManager fragmentManager = MainActivity.getActivityFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction()
.addSharedElement(textView, textView.getTransitionName())
.replace(R.id.mainLayout, mainFragment);
fragmentTransaction.commitAllowingStateLoss();
fragmentManager.executePendingTransactions();
How can I do shared element animation for this case?
Look at your onCreateView function. If It recreate the layout, it breaks the transition id.
Solution:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
if(inflatedView != null)
return inflatedView;
inflatedView = inflater.inflate(R.layout.fragment_blank, container,
return inflatedView;
}

Populate ListView only once on fragment with SlidingMenu android

I'm new on android developing, and I'm developing an app with SlidingMenu library from jfeinstein10, and i'm listing some top rated data on main screen...
Now i'm doing this by getting data from SQLite and putting on a ListView inside a fragment activity
HomeFragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.home_fragment, container, false);
new ManageSQLiteResponse((ListView)rootView.findViewById(R.id.lv_top_rate)).execute();
return rootView;
}
ManagerSQLiteResponse call:
public void updateList(ListView listView){
DietsListAdapter adapter = new DietsListAdapter(getActivity(), R.layout.single_top_rate, dietList);
listView.setAdapter(adapter);
}
And every time i switch the fragment by selecting on SlidingMenu, all the ListView is populated again, and it causes some lag, and the menu won't open or close smoothly...
So, is there some way to run AsyncTask.execute() and populate the ListView only once, and not every time the fragment is created? by this i think it will stop lagging the SlidingMenu
TVM
use this method to add fragment in your container layout.
public void replaceFragment(Fragment fragment) {
String backStateName = fragment.getClass().getName();
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
ft.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
Fragment fragmentPopped = manager.findFragmentByTag(backStateName) ;
if ( fragmentPopped != null )
manager.popBackStack(backStateName, 0);
else
ft.replace(R.id.container, fragment);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.addToBackStack(backStateName);
ft.commit();
}
and look make a condition in code like this, if
if ( adapter.getCount() > 0 )
{
// dont add listview.setadapter() method here.
}
elsse
{
// load data in listview.
}

NullPointerException when setting text on fragment from activity

I set the text on the textview located on the fragment, it returns a NullPointerException. It works when the fragments are added statically but it crashes when i'm using dynamically added fragments.
this is the function that is called when I want to set the text on the fragment.
#Override
public void countrySelected(String wordIn) {
word = wordIn;
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
display.setCountryText(wordIn);
}else{
display = new DisplayFragment();
//display.setCountryText(wordIn);
fragmentTransaction.addToBackStack(list.getTag());
fragmentTransaction.replace(R.id.fragment_place,display,"disp");
fragmentTransaction.commit();
display.setCountryText(wordIn);
}
}
this is the fragment.
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.right,container, false);
txt = (TextView) view.findViewById(R.id.txtView);
Log.d("LOOOOADED", "Loaded");
return view;
}
public void setCountryText(String word){
txt.setText(word);
}
When I set the text on the statically added fragments, it works just fine. But when I set the text on the dynamically added fragment, it doesn't log "LOOOOADED", which means it never reached the onCreateView() method.
You are calling the method display.setCountryText(wordIn); too soon before the fragment is attached to activity.
Look at framgent lifecycle. You need to wait till the fragment is attached to the activity and then call display.setCountryText(wordIn).

Fragment Management?

I am Using android Library_JakeWharton_ActionBarSherlock for implementing facebook, linked-in and other application like sliding bar,
Facing a problem going to back from i.e. Fragment B - > Fragment A.
I have a fragment called Result and another one is Details, when user click on particular item in Result Detail Fragment will called.
private void switchFragment(Fragment fragment) {
if (getActivity() == null)
return;
if (getActivity() instanceof FragmentInitializer) {
FragmentInitializer fca = (FragmentInitializer) getActivity();
fca.switchContent(fragment);
}
}
used this method for navigate from one fragment to another fragment.
How can I back from Details Fragment to Result Fragment.
Below is my Result Fragments class
public class Result_Fragments extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
LinearLayout lnr_main = (LinearLayout) inflater.inflate(R.layout.result_layout, null);
getInit(lnr_main);
return lnr_main;
}
}
I have tried below code.
1) getFragmentManager().popBackStack();
2) android.support.v4.app.FragmentManager mFragmentManager = getFragmentManager();
if(mFragmentManager.getBackStackEntryCount() > 0){
mFragmentManager.popBackStack();
}
Try this code when you launch detail fragment from result fragment.
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.left_framelayout, DetailFragment);
transaction.addToBackStack(null);
transaction.commit();

Android Fragment: the specified child already has a parent fragment - Error

i´m stock on a Problem with Androids Fragments.
I have a Fragment-Activity which consits of a TabHost with 4 Tabs.
One of these Tabs shows a diagramm. The calculation of the data for the diagram is complex and takes a while.
The Problem: Let us assume the User clicks on the specific Tab, the computing of the diagramm starts and everything works fine. Now the user clicks on the next tab, and the app shows the content. After that the User switches back to the Diagramm-Tab. So it does not reload, i do the following in the onCreateView of the Diagramm-Fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if(layout == null){
layout = new PedelecRelativeLayout(getActivity());
initUI();
}
return layout;
}
As you can see, if the layout is null, it will be initiate and the initUI() generates the Diagramm.
The first click of the tab works, but on the second click on the tab, the app is crashing with the following Error:
11-20 10:32:36.928: E/AndroidRuntime(9888): FATAL EXCEPTION: main
11-20 10:32:36.928: E/AndroidRuntime(9888): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
Heres a Code-Snipplet of my Fragment-Activity with the Tab-Host:
summaryDiagram = (SummaryDiagramFragment) fm.findFragmentByTag(TAB_DIAGRAM);
...
if(summaryDiagram != null){
ft.detach(summaryDiagram);
}
...
if(tabId.equals(TAB_DIAGRAM)){
if(summaryDiagram==null){
/** Create AndroidFragment and adding to fragmenttransaction */
summaryDiagram = new SummaryDiagramFragment();
ft.add(R.id.realtabcontent, summaryDiagram, TAB_DIAGRAM);
}else{
/** Bring to the front, if already exists in the fragmenttransaction */
ft.attach(summaryDiagram);
}
}
Thanks for your help, and my sry for my bad english :-)
You must not detach and then re-attach fragment by yourself. It should remain on activity.
To obtain the fragment instance after each onCreate(Bundle arg) call you must find your fragment in the FragmentManager if activity is restoring from saved state.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layout);
if (savedInstanceState != null) {
fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
} else {
fragment = Fragment.instantiate(this, YourFragment.class.getName());
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.fragment_container, fragment, YourFragment.class.getName());
ft.commit();
}
}

Categories

Resources