I'm having a Fragment from a mother activity and I want inside it to display two tabs using FragmentTabHost. But I would like the tabs to be located at the bottom of the fragment not at the top, as it is the default.
MainFragment.java:
public class MainFragment extends Fragment {
private FragmentTabHost tabHost;
private View rootView;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
//tabHost = new FragmentTabHost(getActivity());
rootView = inflater.inflate(R.layout.fragment_main, container, false);
tabHost = (FragmentTabHost) rootView.findViewById(R.id.tabhost);
tabHost.setup(getActivity(), getChildFragmentManager(), R.id.realtabcontent);;
tabHost.addTab(tabHost.newTabSpec("tab1").setIndicator("Tab 1"), ConnectFragment.class, null);
tabHost.addTab(tabHost.newTabSpec("tab2").setIndicator("Tab 2"), ManageFragment.class, null);
tabHost.setCurrentTab(0);
return tabHost;
}
}
The layout which I am using is pretty basic and when I run this version everything works but the tabs are displayed at the top of the fragment.
fragment_main.xml:
<android.support.v4.app.FragmentTabHost
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<FrameLayout
android:id="#+id/tabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<TabWidget
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"/>
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
When I am running a slightly different version which is supposed to put the tabs at the bottom of the fragment-according to other threads of this site- i get an error.
fragment_main_v2.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<FrameLayout
android:id="#+id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" />
<android.support.v4.app.FragmentTabHost
android:id="#+id/tabhost"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<FrameLayout
android:id="#+id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0" />
</android.support.v4.app.FragmentTabHost>
</LinearLayout>
Thrown error:
android.view.InflateException: The specified child already has a parent. You must call removeView() on the child's parent first.
I can imagine that something is going wrong with the
android.view.InflateException: The specified child already has a parent. You must call removeView() on the child's parent first.
Related
My edittext's methods work properly as I have checked it on debbug, but in the graphical layout there are no changes at all.
When changing the text programatically, in the graphical layout doesn't appear, but if I try myedittext.getText() on the debbug expressions/watches it returns the correct string, so the settext() method is working OK but the changes are not shown.
Here is the code:
public class easmpartne extends FragmentActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.easmpartne);
FragmentTabHost tabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
tabHost.setup(this,
getSupportFragmentManager(), android.R.id.tabcontent);
tabHost.addTab(tabHost.newTabSpec("tab1").setIndicator("General"),
Tab1.class, null);
tabHost.addTab(tabHost.newTabSpec("tab2").setIndicator("Categ"),
Tab2.class, null);
LayoutInflater inflater = this.getLayoutInflater();
viewGeneral= inflater.inflate(R.layout.tab1, null);
viewCateg= inflater.inflate(R.layout.tab2, null);
txtRef=(EditText)viewGeneral.findViewById(R.id.txtRef);
txtRef.setText("example");
txtRef.setEnabled(false);
}
}
Neither settext nor setenabled seems no have any effect on the graphical layout when executing.
easmpartne.xml:
<android.support.v4.app.FragmentTabHost
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<HorizontalScrollView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:scrollbars="none">
<TabWidget
android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:orientation="horizontal" />
</HorizontalScrollView>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</android.support.v4.app.FragmentTabHost>
tab1.xml:
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/scrollView2"
android:layout_marginLeft="5dp"
android:fillViewport="true"
android:layout_alignParentBottom="true"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/linlayouteasmpartne"
android:orientation="vertical">
<TableLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tablelayout1">
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="5dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="#string/ref"
android:id="#+id/textView" />
<EditText
android:layout_width="170dp"
android:layout_height="wrap_content"
android:id="#+id/txtRef" />
</TableRow>
....
(I don't know if this could be a problem with de tabhost as it is the first time I use it)
Is that the correct way to get the edittext in this case?
What are the possible problems/solutions?
Thanks.
the point is, you see, that the layout is not kind of a shared variable so when you or the runtime reads it, it instances all views referenced inside and you have to stick to it. Then you follow the lifecycle of the components so to set the values you want you should do it in onViewStateRestored(Bundle) when the view is actually done or something like that, or onStart or so
I am getting overlapped Fragments in PageViewer of Android .
PFB my layout for PageViewer
<TabHost
android:id="#android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="900dp"
android:layout_alignParentBottom="true" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#android:id/tabs" >
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</android.support.v4.view.ViewPager>
</FrameLayout>
<TabWidget
android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal" >
</TabWidget>
</RelativeLayout>
</TabHost>
I am calling it via my First Fragment Say FragmentA of first Tab . I need to replace it with Fragment A1
Calling this from the button click of list from BaseAdapter
Fragment duedateFrag = new FieldVisitFragment();
FragmentTransaction ft = fragmentActivity.getSupportFragmentManager().beginTransaction();
ft.replace(android.R.id.tabcontent, duedateFrag);
ft.commit();
My Fragment gets called but its overlapped on viewpager .
The tabs runs from below the new Fragment . kindly help
On the hindsight , I think somewhere Nested Fragment or Child Fragment should come into play . Please guide.
I have used ViewPager, extending from PagerAdapter. I think you're not referencing the correct layout, you're using id/tabcontent. I can show an example of what I did, and I think you can follow the same.
In the Fragment xml:
<LinearLayout
...
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
android:background="#android:color/white" />
...
</LinearLayout>
In Fragment code :
mViewPager = (ViewPager) view.findViewById(R.id.viewpager);
In the ViewPager code,
#Override
public Object instantiateItem(ViewGroup container, int position) {
...
View view = getActivity().getLayoutInflater().inflate(R.layout.pager_item, container, false);
...
return view
}
Note: I did not use FragmentTransaction class for displaying the fragment or the tab view.
Keep us posted...
I have a generic layout, to which I attach fragments:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/back"
android:orientation="vertical" >
<include
android:id = "#+id/login_header"
layout="#layout/header_layout"/>
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
I have a fragment which I want to display on the right side of the screen.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="#dimen/two_third_width"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_margin="#dimen/small_margin"
android:background="#drawable/stock_price_bg"
tools:context=".FoundItemFragment" >
</RelativeLayout>
The layout is displayed left-justified rather than right justified. When I color the fragment_container FrameLayout, I see that it takes the entire width of the screen. I attach the fragment with the following code in my "FoundItemFragment extends Fragment implements OnClickListener" class:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View fragView = null;
try {
fragView = inflater.inflate(layoutID, container, false);
//LoadData(fragView);
} catch (Exception ex) {
ex.printStackTrace();
}
return fragView;
}
The container parameter passed to this routine has the id of the fragment_container layout, so I am not attaching it to some other object which might have settings that override the alignParentRight setting. Why is the fragment displayed left-justified rather than right-justified?
The layout parent should be Relative Layout so that alignParentRight will work .
You are using the alignParentRight for a root element RelativeLayout
Just edit your container xml to
<?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:background="#drawable/back" >
<include
android:id = "#+id/login_header"
layout="#layout/header_layout"
android:layout_alignParentTop = "true"/>
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:below = "#id/login_header"
android:layout_alignParentRight="true"/>
</LinearLayout>
<?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:background="#drawable/back"
android:orientation="vertical" >
<include
android:id = "#+id/login_header"
layout="#layout/header_layout"/>
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" />
</RelativeLayout>
Since generic layout hold the container of the fragment, you should align/place the fragment there.
Placement of the views of the fragment should be done in fragment specific xml file
I am trying to create an activity with 2 Fragment
First fragment show a list of galleries using a LisFragment
Second fragment show the preview images of the gallery selected in the first fragment
When I declare the fragment in the view it works. But now I want to manage fragment dynamically :
GalleriesFragment gfs = new GalleriesFragment();
GalleryFragment gf = new GalleryFragment();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(R.id.layout_m,gfs);
ft.add(R.id.layout_m,gf);
ft.commit();
My Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:id="#+id/layout_m">
</LinearLayout>
When doing this only the first fragment added is shown, I tried to invert their order when adding fragment...
When I was working on the layout I could set my fragment width with:
android:layout_width="400dp"
Now I have 2 questions :
How can I make my 2 fragments to display?
How can I set the width (programmatically?) of the 1st fragment and the second to fill the remaining width?
Thanks for your help!
PS:
GalleriesFragment doesn't have a layout and is not overriding onCreateView, but has an ArrayAdapter returning view like this for each rows:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/idimage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10sp"
android:layout_marginLeft="10sp"
android:layout_marginTop="10sp"
android:contentDescription="preview"
>
</ImageView>
<LinearLayout
android:id="#+id/LinearLayout01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/texttitre"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5sp"
android:layout_marginRight="7sp"
android:layout_marginTop="10sp"
android:background="#layout/roundcorner"
android:gravity="center"
android:text="Title here" >
</TextView>
<TextView
android:id="#+id/itemdescription"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10sp"
android:layout_marginRight="10sp"
android:text="description" >
</TextView>
</LinearLayout>
</LinearLayout>
GalleryFragment :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Gallery
android:id="#+id/gallery"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Update 2 :
I added an onCreateView in my GalleriesFragment class :
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
FrameLayout.LayoutParams lparams = new FrameLayout.LayoutParams(400, LayoutParams.MATCH_PARENT);
container.setLayoutParams(lparams);
return super.onCreateView(inflater, container, savedInstanceState);
}
This fixes the first fragment's width, but the second one is still not showing...
How can I make my 2 fragments to display ?
Your current approach will make the first fragment supplied to the add method to take all the space of your container layout. One solution is to use a layout that reserves space for each of the two fragments that get added, something like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout_m"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<FrameLayout
android:id="#+id/frame1"
android:layout_width="100dp"
android:layout_height="match_parent" />
<FrameLayout
android:id="#+id/frame2"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Then in code:
ft.add(R.id.frame1, gfs);
ft.add(R.id.frame2, gf);
ft.commit();
How can I set the width (programmatically ?)of the 1st fragment and
the second to fill the remaining width?
Fragments are not just ordinary views but one way to do that is to use your single LinearLayout layout file and set the LayoutParams of the fragment's view in onActivityCreated:
getView().setLayoutParams(new LinearLayout.LayoutParams(100, LinearLayout.LayoutParams.WRAP_CONTENT));
Of course this will make your fragments to be tied to the parent container, also I don't know how well this will work in the overall fragment system.
I have started currently an portfolio application for HoneyComb tablet. I have used ActionBar.Tab to implement three tab on the ActionBar and Fragment for each Tab. The three tab name About, Gallery, Settings. In the Settings ActionBar.Tab, I want to have TabHost.
That means How to have TabHost inside Fragment. Thanks in advance for your ideas!!!
Have a layout with a tabhost like (assuming you define this as my_fragment_tabhost):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TabWidget
android:id="#android:id/tabs"
android:visibility="gone"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
</TabHost>
</LinearLayout>
In your fragment, have a TabHost member variable and get it in the onCreateView like:
private TabHost mTabHost;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.my_fragment_tabhost, container, false);
mTabHost = (TabHost) view.findViewById(android.R.id.tabhost);
mTabHost.setup();//very important to call this
TabHost.TabSpec tab = mTabHost.newTabSpec("my tab content");
tab.setIndicator("my tab content")
//... add your content by one of the tab.setContent() methods
mTabHost.addTab(tab);
return view;
}