I'm ripping my hair out trying to display a thumbnail sized map in either an AlertDialog or preferably in a SherlockDialogFragment.
I have this in my xml
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/map"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
class="com.google.android.gms.maps.MapFragment" />
And with just this in my SherlockDialogFragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
getDialog().setCanceledOnTouchOutside(true);
getDialog().setTitle(offer.retailer);
View v = inflater.inflate(R.layout.businesstmpalert, container, false);
return v
}
I get an Error inflating class fragment error
What am I doing wrong?
This doesn't work because you are nesting fragment (MapFragment inside a DialogFragment) AND specifying the MapFragment in the <layout>.
From http://developer.android.com/about/versions/android-4.2.html#NestedFragments
Note: You cannot inflate a layout into a fragment when that layout includes a <fragment>. Nested fragments are only supported when added to a fragment dynamically.
You could either nest the fragment programmatically:
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.map_fragment_host, MapFragment.newInstance()).commit();
in DialogFragment's onActivityCreated(), or (preferably, IMHO) switching to MapView, which you can safely use as a <layout>. In this case, remember to propagate fragment lifecycle events to the MapView, as specified in https://developers.google.com/maps/documentation/android/reference/com/google/android/gms/maps/MapView
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
1-Add these lines a the end of the within manifest file.
if this not work then...
2-extends android.support.v4.app.FragmentActivity
public class MainActivity extends android.support.v4.app.FragmentActivity
Related
Hello I'm trying to replace view in FrameLayout with fragment. I want to make this like in Android guides, when I create fragment and it does't have enough space then it create new Activity. example from android side
I have problem with it. My fragment container is FrameLayout
<FrameLayout
android:id="#+id/fragment"
android:layout_width="344dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
fragment transaction suite my fragment to FrameLayout size. It makes that my fragment is not all visible (it's layout is bigger than FrameLayout size) I don't know why I have this problem. Here is my fragment transaction code (it makes when I click on Text View):
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.add(R.id.fragment, new FragmentPlan());
transaction.commit();
my Fragment
public class FragmentPlan extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_plan, container, false);
ButterKnife.bind(this, view);
return view;
}
}
I believe your code is running ok.
When you add/replace a viewGroup with a fragment, the fragment inherits the size from the viewGroup, for that reason, it is very small.
As I see, you can either increase the size of the frameLayout. Or like it was mentioned above int he comments, use an Intent to start a new Activity.
I have the following Layout with static fragment and RelativeLayout as parent:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="#dimen/activity_vertical_margin">
<fragment
android:id="#+id/list_fragment"
android:name="com.listfragmenttest.MyListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
Yet the container or parent comes up null in OnCreateView:
public class MyListFragment extends ListFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.my_list_fragment, container, false);
}
}
Is this the normal behavior for Static fragment?
Yes, that's how it is implemented. Fragments inflated statically from XML get a null as parent container.
For details, consult FragmentManager source. In particular, onCreateView() that handles fragment instantiation from layout inflation, setting mInLayout = true and calls to performCreateView() that are conditional on mInLayout.
I am trying to navigate from on fragment to another by click a button in original fragment. How ever I got a Exception
Image of exception
Image of my code for the original Fragment
The problem is that you are passing a Layout in your call of transaction.Replace(), instead you should pass the Id the of the ViewGroup where the fragment will be inserted in your layout.
so the layout of the activity containing your fragments should look something like this:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="fill_parent" />
</FrameLayout>
And in your FragmentStockSearch fragment, override OnCreateView to something like this:
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.Inflate(Resource.Layout.your_layout, null, false);
}
and finally your fragment transaction code:
var trans = new FragmentManager.BeginTransaction();
trans.Replace(Resource.Id.content_frame, new FragmentStockSearch(), "FragmentStockSearch");
trans.AddToBackStack(null);
trans.Commit();
I have a layout which contains a <fragment> called MenuFragment. Whenever I launch the application howver, I get a Trying to instantiate a class com.usmaan.whackem.MenuFragment that is not a Fragment.
Layout:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_below="#id/layoutHeader"
android:layout_marginTop="20dp">
<fragment android:name="com.usmaan.whackem.MenuFragment"
android:id="#+id/menu_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Fragment:
public class MenuFragment extends Fragment{
public MenuFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.menu_fragment, container, false);
}
}
I've tried
1) Adding an ID to the <fragment>
2) Adding a namespace to <fragment>
I fixed the issue by extending the Activity which holds the fragment from FragmentActivity and not Activity.
Ok, whenever I try to replace a fragment in my application, it only adds the fragment inside of the container the other fragment is, and leaves the current fragment. I've tried calling replace and referencing the view the contains the fragment, and by referencing the fragment itself. Neither of these work. I can add a fragment to a view with the fragment transaction manager, but even if I try to remove it after its been added, it doesn't work. Any help would be appreciated. Here are my files.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//Setup the actionabar. Use setDrawableBackground to set a background image for the actionbar.
final ActionBar actionbar = getActionBar();
actionbar.setDisplayShowTitleEnabled(false);
actionbar.setDisplayUseLogoEnabled(true);
actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionbar.addTab(actionbar.newTab().setText(R.string.home_tab_text).setTabListener(this),true);
actionbar.addTab(actionbar.newTab().setText(R.string.insert_tab_text).setTabListener(this));
Fragment fragment = new insert_button_frag();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.button_fragment, fragment);
transaction.addToBackStack(null);
transaction.commit();
}
Here is the layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:id="#+id/button_fragment_container"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<fragment
android:name="com.bv.silveredittab.home_button_frag"
android:id="#+id/button_fragment"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<fragment
android:name="com.bv.silveredittab.quick_insert_frag"
android:id="#+id/quick_insert_frag"
android:layout_width="350dip"
android:layout_height="fill_parent" />
<fragment
android:name="com.bv.silveredittab.editor_frag"
android:id="#+id/editor_frag"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
</LinearLayout>
And here is the fragment code
public class insert_button_frag extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
return inflater.inflate(R.layout.insert_buttons,container, false);
}
}
Like I have said. I have tried referencing the fragments parent view to replace it, and the fragment itself (by id) and still, it only adds the new fragment, inside the containing view the original fragment is in.
I solved this by using a placeholder in my Layout and then attaching my Fragment to it at runtime.
Like you, if I instantiated my Fragment within my xml layout then the contents would remain visible after replacing it with another Fragment at runtime.
The problem is this line:
transaction.replace(R.id.button_fragment, fragment);
replace has two overloaded forms. In both of them, the first argument is the container of the Fragment to be replaced, not the Fragment itself. So, in your case, you need to call
transaction.replace(R.id.button_fragment_container, fragment);
edit: I see in your question that you have tried both. I have tested and verified the behavior. This appears to be a bug in the FragmentTransaction API.
Edit2: not a bug after all. You simply cannot replace fragments added statically in a layout file. You can only replace those you have added programmatically ( Android: can't replace one fragment with another )
I had the same issue. Take a look at this link: Android Fragment Duplication
I wonder if the fact that you're passing the container into the inflater.inflate() method causes it to create the new fragment inside of the old one instead of a wholesale replace. I've been providing 'null' to my inflaters in the working version.
Here's the essentials from the version I have working...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View newFrag = new View(getActivity().getApplicationContext());
newFrag = inflater.inflate(R.id.frag, null);
return newFrag;
}
The google developer guide is quite confusing because it shows first to implement hard coded fragment in you xml. But if you really want to replace existing fragment with the new one, then you should add it(the first) at runtime.
What official site state is
FragmentTransaction replace (int containerViewId, Fragment fragment, String tag)
Replace an existing fragment that was added to a container. This is
essentially the same as calling remove(Fragment) for all currently
added fragments that were added with the same containerViewId and then
add(int, Fragment, String) with the same arguments given here.
You should noticed that it says that Replace an existing fragment that was added to container
So, your xml should look like
someActivity.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
tools:context="someActivity">
<ImageView
.../>
<LinearLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="bottom"/>
</RelativeLayout>
And than in your activity do in OnCreate()
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
[...]
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, new FirstFragment).commit();
}
Than you may easily replace fragment with your animations and event add it to back stack in order to save its state.
private SecondFrag getSecondFrag(){
if(secondFrag == null)
secondFrag = new SecondFrag()
return secondFrag;
}
private void openRechargeFragment(){
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.show_frag, R.anim.hide_frag,
R.anim.show_frag, R.anim.hide_frag);
ft.replace(R.id.fragment_container, getSecondFrag(), "myTAG");
ft.addToBackStack(null);
ft.commit();
}