Please any one help me, I am new in android studio, my app getting crash while resume application,
I have three different fragment layout which have
<fragment
android:id="#+id/map_online"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/action_bar" /> with different ID.
while resume application I need to load one Fragment with map,
I am getting following error:
Caused by: java.lang.IllegalArgumentException: Binary XML file line
39: Duplicate id 0x7f0f018a, tag null, or parent id 0xffffffff with another fragment for com.google.android.gms.maps.SupportMapFragment
Please any one sugggest how to solve this.
This is my fragment class:
public class ClientRequestFragment extends Fragment implements OnMapReadyCallback {
View clientRequestView;
private static final String TAG = ClientRequestFragment.class.getSimpleName();
GoogleMap googleMap;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
SupportMapFragment mapFragment = (SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.map_online);
mapFragment.getMapAsync(this);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LayoutInflater li = (LayoutInflater) getActivity().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
clientRequestView = li.inflate(R.layout.offline_fragment, container, false);
return clientRequestView;
}
public void addFragment(Fragment fragment, boolean addToBackStack,
String tag, boolean isAnimate) {
FragmentManager manager = getActivity().getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
if (isAnimate) {
ft.setCustomAnimations(R.anim.slide_in_right,
R.anim.slide_out_left, R.anim.slide_in_left,
R.anim.slide_out_right);
}
if (addToBackStack) {
ft.addToBackStack(tag);
}
ft.replace(R.id.content_frame, fragment, tag);
ft.commitAllowingStateLoss();
}
#Override
public void onClick(View view) {
}
#Override
public void onMapReady(GoogleMap googleMap) {
this.googleMap = googleMap;
//googleMap.setMyLocationEnabled(true);
/* try {
// Customise the styling of the base map using a JSON object defined
// in a raw resource file.
boolean success = googleMap.setMapStyle(
MapStyleOptions.loadRawResourceStyle(
getActivity(), R.raw.retro_style_json));
if (!success) {
Log.e(TAG, "Style parsing failed.");
}
} catch (Resources.NotFoundException e) {
Log.e(TAG, "Can't find style. Error: ", e);
}*/
}
#Override
public void onDestroyView() {
super.onDestroyView();
FragmentManager fm = getActivity().getSupportFragmentManager();
Fragment fragment = (fm.findFragmentById(R.id.map_online));
FragmentTransaction ft = fm.beginTransaction();
ft.remove(fragment);
ft.commit();
}
#Override
public void onPause() {
super.onPause();
}
}
Thank you.
Your app getting crash because static fragment inside fragment can not be remove or replace , you can only hide or show this static fragment.
make your xml file like this:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/coreLayout"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical">
<FrameLayout
android:id="#+id/fragment_home_container"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
in your fragment.java file write this code:
PlaceAutocompleteFragment autocompleteFragmentSourceAddress = new PlaceAutocompleteFragment();
replaceFragment(autocompleteFragmentSourceAddress, R.id.fragment_home_container);
You need to remove fragment before push new one in your fragment view have been re-created so add ==null condition in onCreatedView method,
View mainView;// this should be global variable.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if(mainview==null){
mainView = inflater.inflate(R.layout.fragment_layout, container, false);
initializeView();//initialize all views in this method instead of onActivityCreated
}
return mainView;
}
Add this when you push above fragment to avoid duplication
try {
android.app.Fragment fragment = getFragmentManager().findFragmentById(R.id.map_online);
if (fragment != null) {
android.app.FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.remove(fragment);
ft.commit();
}
} catch (Exception e) {
e.printStackTrace();
}
Related
I am using PlaceAutoCompleteFragment inside a Fragment. First time when Fragment(App fragment in which PlaceAutoCompleteFragment is placed) opens it works fine like a charm. But, then second time I hit button to open Fragment it crashes with below error. It works only a single time.
FATAL EXCEPTION:
android.view.InflateException: Binary XML file line #64: Error inflating class fragment
Caused by: java.lang.IllegalArgumentException: Binary XML file line #64: Duplicate id 0x7f0d0094, tag null, or parent id 0xffffffff with another fragment for com.google.android.gms.location.places.ui.PlaceAutocompleteFragment
This is how i am using this:
SupportPlaceAutocompleteFragment placeAutocompleteFragment = (SupportPlaceAutocompleteFragment) getActivity().getSupportFragmentManager().
findFragmentById(R.id.place_autocomplete_fragment);
placeAutocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
System.out.println(place.getAddress());
}
#Override
public void onError(Status status) {
}
});
Error is on this line in onCreateDialog method, where layout is inflating:
View view = inflater.inflate(R.layout.add_geofence_layout, null);
XML:
<fragment
android:id="#+id/place_autocomplete_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:name="com.google.android.gms.location.places.ui.SupportPlaceAutocompleteFragment" />
Wondering! Why this code works only once?
DialogFragment class:
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.add_geofence_layout, null);
viewHolder = new ViewHolder();
viewHolder.initializeView(view);
viewHolder.placeAutocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
System.out.println(place.getAddress());
}
#Override
public void onError(Status status) {
}
});
}
Note:- I am using a PlaceautoCompleteFragment inside a DialogFragment. If i use this inside an Activity it works fine.
Don't add PlaceAutocompleteFragment directly to your fragment layout. you need to add PlaceAutocompleteFragment dynamically and remove it on onDestroyView().
layout.xml
<LinearLayout
android:id="#+id/placeLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="visible">
</LinearLayout>
Add PlaceAutocompleteFragment
PlaceAutocompleteFragment autocompleteFragment=new PlaceAutocompleteFragment();
FragmentManager fragmentManager = getActivity().getFragmentManager();
android.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.placeLayout,autocompleteFragment);
fragmentTransaction.commit();
Remove it onDestroy
#Override
public void onDestroyView() {
super.onDestroyView();
if (getActivity() != null) {
FragmentManager fragmentManager = getActivity().getFragmentManager();
android.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.remove(autocompleteFragment);
fragmentTransaction.commit();
}
}
Try this if this works:
View view;
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = getActivity().getLayoutInflater();
if(view == null) {
view = inflater.inflate(R.layout.add_geofence_layout, null);
}
viewHolder = new ViewHolder();
viewHolder.initializeView(view);
viewHolder.placeAutocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
System.out.println(place.getAddress());
}
#Override
public void onError(Status status) {
}
});
}
You should give more context regarding the layout. The Exceptions states: "Duplicate id " are you sure you aren't using the same id twice?
Try to remove the fragment at onDestroyView()
#Override
public void onDestroyView() {
super.onDestroyView();
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.remove(mPlaceAutocompleteFragment);
ft.commit();
}
I have Navigation Drawer menu in that I have fragments Frag1,Frag2 and Frag3.
Frag2 is being replaced with Frag21, Frag21 with Frag22 and so on.
If I press back button from Frag22 to Frag21 and Frag2 the app closes properly.
But if I go directly from Frag22 to Frag1 and try to close the app, its getting crashed and I m getting the error
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.IllegalArgumentException: No view found for id 0x7f0f00c4 (com.NuSS.MyPAS:id/root_frame) for fragment CategoriesDisplayList{4260ca00 #1 id=0x7f0f00c4}
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:947)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1138)
at android.support.v4.app.BackStackRecord.popFromBackStack(BackStackRecord.java:960)
at android.support.v4.app.FragmentManagerImpl.popBackStackState(FragmentManager.java:1553)
at android.support.v4.app.FragmentManagerImpl$2.run(FragmentManager.java:497)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1501)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:458)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5306)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
at dalvik.system.NativeStart.main(Native Method)**
Have also given
#Override
public void onBackPressed() {
if(fragmentManager.getBackStackEntryCount() != 0) {
fragmentManager.popBackStack();
} else {
super.onBackPressed();
}
}
in MainFragment Activity.
Kindly give solution stuck up with this error for few days.
UPDATE
Code snippets
RootFragment
public class RootFragment extends Fragment {
private static final String TAG = "RootFragment";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
/* Inflate the layout for this fragment */
View view = inflater.inflate(R.layout.activity_root_fragment, container, false);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
/*
* When this container fragment is created, we fill it with our first
* "real" fragment
*/
transaction.replace(R.id.root_frame, new CategoriesDisplayList());
transaction.commit();
return view;
}
#Override
public void onDestroyView() {
// TODO Auto-generated method stub
super.onDestroyView();
try {
Fragment fragment = (getFragmentManager()
.findFragmentById(R.id.root_frame));
FragmentTransaction ft = getActivity().getSupportFragmentManager()
.beginTransaction();
ft.remove(fragment);
ft.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
}
CategoryDisplayList
public class CategoriesDisplayList extends Fragment implements SwipeRefreshLayout.OnRefreshListener{
categoryListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
FragmentTransaction trans = getFragmentManager().beginTransaction();
trans.replace(R.id.root_frame, new RootFragmentService());
trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
trans.addToBackStack(null);
trans.commit();
}
});
//registerForContextMenu(vendorListView);
return rootView;
}
RootFragmentService
public class RootFragmentService extends Fragment {
private static final String TAG = "RootFragment";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_root_fragment, container, false);
FragmentTransaction transaction = getFragmentManager()
.beginTransaction();
/*
* When this container fragment is created, we fill it with our first
* "real" fragment
*/
transaction.replace(R.id.root_frame, new ServicesList());
transaction.commit();
return view;
}
#Override
public void onDestroyView() {
// TODO Auto-generated method stub
super.onDestroyView();
try {
Fragment fragment = (getFragmentManager()
.findFragmentById(R.id.root_frame));
FragmentTransaction ft = getFragmentManager()
.beginTransaction();
ft.remove(fragment);
ft.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Thanks in advance.
make an onClickButton listener to the back button more info in android developers: View.OnClickListener
if you want to go to the back-stack you don't need call popBackStack on onBackPressed event. if you use addToBackStack method on your transAction, onBackPressed will do it without extra code.
fragmentManager.beginTransaction().setCustomAnimations(animationIn, animationOut).replace(layout, fragment, tag).addToBackStack(backStackTag).commit();
I tried to create a ProgressFragment to be used in the whole application:
public class ProgressFragment extends Fragment {
private static final String KEY = "info";
private CustomProgressView mProgress;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(...);
mProgress = (CustomProgressView) root.findViewById(...);
mProgress.start();
if (getArguments() != null) {
mProgress.setText(getArguments().getString(KEY, ""));
}
return root;
}
public void setInformation(String text) {
if (mProgress != null) {
if (this.isHidden()) {
show(getActivity().getSupportFragmentManager());
}
mProgress.setText(text);
} else {
Bundle b = new Bundle();
b.putString(KEY, text);
setArguments(b);
}
}
public void hide(FragmentManager fm) {
FragmentTransaction ft = fm.beginTransaction();
ft.hide(this);
ft.commit();
}
private void show(FragmentManager fm) {
FragmentTransaction ft = fm.beginTransaction();
ft.show(this);
ft.commit();
}
}
The ProgressFragment is expected to attached(added) to the activity once, and there should be only one instance, then the client should only update its' information or hide it.
Usage in client(activity):
class MainActivity...{
ProgressFragment mFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFragment = ProgressFragment.newInstance(null);
FragmentTransaction fs = getSupportFragmentManager().beginTransaction();
fs.add(id, mFragment);
fs.commit();
}
//close the progress
mFragment.hide()
//show the progress
mFragment.setInformation("..")
}
However it does not worked as expected, sometime the progress view will show only at the first call or it does not even show.
Did I miss anything?
Don't set your onCreateView as #Nullable;
Use commitAllowingStateLoss();
Instead of just add(), use addToBackStack(). When you want to close it, just use the FragmentManager popBackStack():
getActivity().getSupportFragmentManager().popBackStack();
I'm getting this error while trying to launch a Fragment from a first Fragment :
java.lang.NullPointerException: Attempt to invoke virtual method 'android.app.FragmentTransaction android.app.FragmentManager.beginTransaction()' on a null object reference
Here's the method where I'm getting the error :
#Override
public void onClick(View v) {
Fragment fragment = new PropertyFragment();
if (fragment != null) {
FragmentManager fragmentManager = fragment.getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
fragmentTransaction.replace(R.id.rent_viewer, fragment);
fragmentTransaction.addToBackStack(null);
// Commit the transaction
fragmentTransaction.commit();
}
}
Precisely, the following code instruction is causing the error :
fragmentManager.beginTransaction();
Here's how the class and the nested class look like :
public class RentFragment extends Fragment {
...
#SuppressWarnings("unused")
private OnRentFragmentInteractionListener mListener;
public RentFragment() {
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnRentFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnRentFragmentInteractionListener");
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_rent, container, false);
myOnClickListener = new RentOnClickListener(getActivity());
return rootView;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnRentFragmentInteractionListener {
public void onRentFragmentInteraction(Uri uri);
}
private static class RentOnClickListener implements View.OnClickListener {
private final Context context;
private RentOnClickListener(Context context) {
this.context = context;
}
#Override
public void onClick(View v) {
Fragment fragment = new PropertyFragment();
if (fragment != null) {
FragmentManager fragmentManager = fragment.getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
fragmentTransaction.replace(R.id.rent_viewer, fragment);
fragmentTransaction.addToBackStack(null);
// Commit the transaction
fragmentTransaction.commit();
}
}
}
}
FragmentManager will be null until it is attached to the activity.So use below code ,
If it is a nested Fragment use this.getChildFragmentManager() for your fragment class else use getActivity().getFragmentManager() or getActivity().getSupportFragmentManager().
Declare your FragmentTransaction and initialize it like this
FragmentTransaction fm;
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
fm = getFragmentManager();
}
Then on your code, you can call this
Fragment fragment = new PropertyFragment();
FragmentTransaction transaction = fm.beginTransaction();
transaction.add(R.id.rent_viewer, fragment).addToBackStack(null).commit();;
Use the Customize Method in Base Class and use it.
public void replaceFragment(Fragment newFragment, Bundle bundle, boolean isAddToBackStack) {
String tag = newFragment.getClass().getSimpleName();
if (bundle != null) {
newFragment.setArguments(bundle);
}
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if (getCurrentFragment() != null) {
ft.hide(getCurrentFragment());
}
ft.add(R.id.frameContainer, newFragment, tag);
newFragment.setRetainInstance(true);
if (isAddToBackStack) {
ft.addToBackStack(tag);
}
try {
ft.commitAllowingStateLoss();
} catch (Exception ex) {
ex.printStackTrace();
// ft.commitAllowingStateLoss();
}
}
You have to set context of activity as shown below on code HomeActivity.this.getSupportFragmentManager();
private Fragment fragment;
private FragmentManager fragmentManager;
fragmentManager=HomeActivity.this.getSupportFragmentManager();
transaction = fragmentManager.beginTransaction();
transaction.add(R.id.main_container, new ProfileFragment()).commit();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
fragmentTransaction.replace(R.id.rent_viewer, fragment);
fragmentTransaction.addToBackStack(null);
// Commit the transaction
fragmentTransaction.commit();
When i try to update the value of a Textview after a dialogfragment i get the right value but if the previous value is longer its old view is still visible (and ugly) in the background.
I tried calling onResume() for the current fragment but no improvements.
I just call a dialog and when the listener onFinishEditDialog() is called i just set the text
If i open another app and i come back it is perfect (the old is gone)
how is this possible?
in the xml layout:
<TextView
android:id="#+id/txttotalcho"
style="#style/importantTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="40dp"
android:text="33 cho"
android:textSize="64dp" />
in the MainActivity:
#Override
public void onGoToPage(int pageNumber,boolean verso, Pasto p,ArrayList<CiboSelezionato> cibiSelezionati,String extra) {
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
Fragment firstDetail =
(Fragment)fm.findFragmentByTag(SECOND_DETAIL_FRAGMENT_TAG);
ft.remove(firstDetail);
ft.commit();
FragmentTransaction ft2 = fm.beginTransaction();
switch (pageNumber){
case Constants.P_SCELTA_PASTO:{
WizardPasti10 secondDetail = WizardPasti10.getInstance(this);
ft2.replace(R.id.anchor_layout,secondDetail,SECOND_DETAIL_FRAGMENT_TAG);
break;
}
case Constants.P_TOTAL_CHO:{
WizardPastiTotalCho secondDetail = WizardPastiTotalCho.getInstance(this);
ft2.replace(R.id.anchor_layout,secondDetail,SECOND_DETAIL_FRAGMENT_TAG);
break;
}
ft2.commit();
View v1,v2;
v1=(View)findViewById(R.id.anchor_left);
v2=(View)findViewById(R.id.anchor_layout);
v1.setVisibility(View.GONE);
v2.setVisibility(View.VISIBLE);
v2.setBackgroundColor(getResources().getColor(R.color.white));
}
in the fragment WizardPastiTotalCho:
private TextView txtTotalCho;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View firstView = inflater.inflate(R.layout.wizardpastitotalcho, container, false);
txtTotalCho = (TextView)firstView.findViewById(R.id.txttotalcho);
txtTotalCho.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View button) {
FragmentTransaction ft = getFragmentManager().beginTransaction();
DialogFragment newFragment = new TastierinoDialogFragment(WizardPastiTotalCho.this,Constants.CARBOIDRATI,0);
newFragment.show(ft, "totalchoDialog");
}
});
}
#Override
public void onFinishEditDialog(int dialogType, String inputText) {
//called when i close the dialogFragment
txtTotalCho.setText(inputText+" cho");
txtTotalCho.setBackgroundColor(Color.YELLOW);//just to see the difference
try {
totalCho=Float.parseFloat(inputText);
tmpPasto.setCarboidrati(totalCho);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}