I have created a screen which has some read only data fields on it and at the bottom has a horizontal
set of tabs
.
Each tab has a fragment
representing the tab content
and is backed up by an array of data objects for instance one of the tabs is previous addresses, of which there can be 0 to many.
I want the tab
content fragment
to be swipeable
such that it will initally show the most recent previous address and a swipe
to the left
will pull in the next from an array
initially, continued swiping will navigate through the addresses in either direction if appropriate.
I have been looking FragmentPageAdapter
but I dont want anything in the title bar
and I also want to use the same fragment
for each swipe
as the only thing that changes is the data that is displayed, the layout
would be the same everytime.
I do still want the swipe
action that makes it look like the page swiped from one page to another though.
Is this the best way forward for this and are there better options? There are currently 5 tabs
and 3 of those tabs
will have swipe-able
content which will show more data but the view itself will not change.
I thought I would edit this and add some code so it might be easier to see what I want to achieve:
I have a fragment which repsents a vertical tab that was clicked and inside that fragment is a set of horizontal tabs:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginTop="5dp">
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:stretchColumns="1"
android:id="@+id/name_table">
</TableLayout>
</LinearLayout>
<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"
android:background="@color/white"
android:layout_marginTop="5dp">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:weightSum="20">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="3"
android:orientation="horizontal">
<TabWidget android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone"/>
<LinearLayout
android:id="@+id/tab_btn_container"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_weight="1.0"
android:background="@color/lightest_grey"
android:id="@+id/temp_addr_tab_btn"
android:text="Temporary Addresses"
android:layout_marginRight="1dp"
android:textSize="7sp"
android:gravity="bottom|center"
android:drawableTop="@mipmap/ic_launcher"
android:paddingTop="4dp"
/>
<Button
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_weight="1.0"
android:background="@color/lightest_grey"
android:id="@+id/postal_addr_tab_btn"
android:text="Postal Addresses"
android:layout_marginRight="1dp"
android:textSize="7sp"
android:gravity="bottom|center"
android:drawableTop="@mipmap/ic_launcher"
android:paddingTop="4dp"
/>
<Button
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_weight="1.0"
android:background="@color/lightest_grey"
android:id="@+id/home_addr_tab_btn"
android:text="Home Addresses"
android:layout_marginRight="1dp"
android:textSize="7sp"
android:gravity="bottom|center"
android:drawableTop="@mipmap/ic_launcher"
android:paddingTop="4dp"
/>
<Button
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_weight="1.0"
android:background="@color/lightest_grey"
android:id="@+id/tel_fax_tab_btn"
android:text="Telephone / Fax"
android:layout_marginRight="1dp"
android:textSize="7sp"
android:gravity="bottom|center"
android:drawableTop="@mipmap/ic_launcher"
android:paddingTop="4dp"
/>
<Button
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_weight="1.0"
android:background="@color/lightest_grey"
android:id="@+id/email_other_tab_btn"
android:text="Email / Other"
android:textSize="7sp"
android:gravity="bottom|center"
android:drawableTop="@mipmap/ic_launcher"
android:paddingTop="4dp"
/>
</LinearLayout>
</FrameLayout>
<FrameLayout android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_weight="17"
android:background="@color/white"/>
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
So when a user clicks the first tab or the page has just rendered it will show another fragment in the android:id="@android:id/tabcontent".
This works and it shows my temporary address fragment:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.mockattempt1.TemporaryAddressesFragment">
<TextView android:layout_width="match_parent" android:layout_height="match_parent"
android:text="Temp Addresses Fragment that will show address information soon" />
Currently the temporary address fragment is just a hardcoded text view but I want this to be a swipeable set of temporary address fragments that the user is able to swipe through to view the addresses.
I am trying to fit this tutorial http://www.101apps.co.za/articles/swipe-view-tutorial.html into my application but I am unsure of where the ViewPager xml should go, it almost seems like it should be my tabcontent xml in the parent fragment?
I do not think that this is right through because in the parent fragment the tab content is set up like this:
mTabHost = (FragmentTabHost)rootView.findViewById(android.R.id.tabhost);
mTabHost.setup(getActivity(), getChildFragmentManager(), android.R.id.tabcontent);
mTabHost.addTab(mTabHost.newTabSpec("temp_addresses").setIndicator("Temporary Addresses"), TemporaryAddressesFragment.class, null);
mTabHost.setCurrentTab(0);
I almost need to replace that with the page adaptor functionality or somehow get them to work together but I am not sure how to do this.
I have managed to do this but not entirely sure its the best way but I will detail my attempts as it works:
Fragment with horizontal tabs displayed for the first tab content, previous addresses (fragment_record.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"
android:background="@color/white"
android:layout_marginTop="5dp">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:weightSum="20">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="3"
android:orientation="horizontal">
<TabWidget android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone"/>
<LinearLayout
android:id="@+id/tab_btn_container"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_weight="1.0"
android:background="@color/lightest_grey"
android:id="@+id/temp_addr_tab_btn"
android:text="Temporary Addresses"
android:layout_marginRight="1dp"
android:textSize="7sp"
android:gravity="bottom|center"
android:drawableTop="@mipmap/ic_launcher"
android:paddingTop="4dp"
/>
<Button
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_weight="1.0"
android:background="@color/lightest_grey"
android:id="@+id/postal_addr_tab_btn"
android:text="Postal Addresses"
android:layout_marginRight="1dp"
android:textSize="7sp"
android:gravity="bottom|center"
android:drawableTop="@mipmap/ic_launcher"
android:paddingTop="4dp"
/>
<Button
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_weight="1.0"
android:background="@color/lightest_grey"
android:id="@+id/home_addr_tab_btn"
android:text="Home Addresses"
android:layout_marginRight="1dp"
android:textSize="7sp"
android:gravity="bottom|center"
android:drawableTop="@mipmap/ic_launcher"
android:paddingTop="4dp"
/>
<Button
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_weight="1.0"
android:background="@color/lightest_grey"
android:id="@+id/tel_fax_tab_btn"
android:text="Telephone / Fax"
android:layout_marginRight="1dp"
android:textSize="7sp"
android:gravity="bottom|center"
android:drawableTop="@mipmap/ic_launcher"
android:paddingTop="4dp"
/>
<Button
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_weight="1.0"
android:background="@color/lightest_grey"
android:id="@+id/email_other_tab_btn"
android:text="Email / Other"
android:textSize="7sp"
android:gravity="bottom|center"
android:drawableTop="@mipmap/ic_launcher"
android:paddingTop="4dp"
/>
</LinearLayout>
</FrameLayout>
<FrameLayout android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_weight="17"
android:background="@color/white"/>
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
Set up the tabs and an intent for the temporary address fragment detailed below (RecordFragment.java):
mTabHost = (FragmentTabHost)rootView.findViewById(android.R.id.tabhost);
mTabHost.setup(getActivity(), getChildFragmentManager(), android.R.id.tabcontent);
mTabHost.addTab(mTabHost.newTabSpec("temp_addresses").setIndicator("Temporary Addresses"), TemporaryAddressesFragment.class, null);
mTabHost.setCurrentTab(0);
Placeholder fragment for the ViewPager (fragment_temporary_addresses.xml):
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/temp_addr_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
</android.support.v4.view.ViewPager>
Class that represents above fragment and also contains inner class (TemporaryAddressesFragment.java):
private ViewPager temporaryAddressViewPager;
private TemporaryAddressDetailFragmentStatePageAdapter temporaryAddressStateAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = (View)inflater.inflate(R.layout.fragment_temporary_addresses, container, false);
temporaryAddressStateAdapter = new TemporaryAddressDetailFragmentStatePageAdapter(getFragmentManager());
temporaryAddressViewPager = (ViewPager)rootView.findViewById(R.id.temp_addr_pager);
temporaryAddressViewPager.setAdapter(temporaryAddressStateAdapter);
return rootView;
}
The inner class contained in this fragment class which is the adapter, this currently just serves up 3 hardcoded temp address detail fragments:
public class TemporaryAddressDetailFragmentStatePageAdapter extends FragmentStatePagerAdapter {
public TemporaryAddressDetailFragmentStatePageAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
@Override
public int getCount() {
return 3;
}
@Override
public Fragment getItem(int position) {
Fragment fragment = null;
fragment = new TemporaryAddressDetailFragment();
return fragment;
}
}
}
Another fragment which represents the actual content\detail that I want to have swipeable (fragment_temporary_address_detail.xml):
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.oxygenmockattempt1.TemporaryAddressDetailFragment">
<!-- TODO: Update blank fragment layout -->
<TextView android:layout_width="match_parent" android:layout_height="match_parent"
android:text="This is the temporary address detail fragment screen" />
There is also a class that represents the above fragment (TemporaryAddressDetailFragment.java) which currently doesnt do anything as the fragment xml displays a hardcoded string.
I also implement the following inerfaces in my actual activity class (MainActivity.java):
TemporaryAddressesFragment.OnFragmentInteractionListener, TemporaryAddressDetailFragment.OnFragmentInteractionListener
So now when the first tab is displayed on my fragment i have 3 address panes which are swipeable but this does not swipe the tabs in anyway.