I am trying to implement Tabs with swipe using ViewPager and 4 Fragments. When I swipe the tabs the respective xml layouts of the fragmnets are displayed correctly on each tab but the code of the fragments are not executed correctly.
eg-The following tabs have the respective fragments in it.
Tab0-ButtonFragment
public class ButtonFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_button, container, false);
Log.i("inside", "button fragment");
return rootView;
}
Tab1-ImageFragment
public class ImageFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_image, container, false);
Log.i("inside", "image fragment");
return rootView;
}
Tab2-TextFragment
public class TextFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_text, container, false);
Log.i("inside", "text fragment");
return rootView;
}
Tab3-Test
public class Test extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.temp, container, false);
Log.i("inside", "tessssssssst fragment");
return rootView;
}
When the tabs are displayed
I get the log message for tab0 and tab1 simultaneously. Then after swiping and going to tab1 i get the log message for tab2. After swiping to tab2 i get log message for tab 3 and when tab 3 is reached no log message is dispalyed. Can anyone tell me how can I execute the respective codes for the respective tabs? My remaining codes are as below:
public class TabsPagerAdapter extends FragmentPagerAdapter { //Update - code formatting
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem( int index) {
Log.i("index", "" + index);
switch (index) {
case 0:
// Top Rated fragment activity
return new ButtonFragment();
case 1:
// Games fragment activity
return new ImageFragment();
case 2:
// Movies fragment activity
return new TextFragment();
case 3:
return new Test();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 4;
}
MainActivity
public class MainActivity extends FragmentActivity implements OnTabChangeListener, OnPageChangeListener {
private TabsPagerAdapter mAdapter;
private ViewPager mViewPager;
private TabHost mTabHost;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mViewPager = (ViewPager) findViewById(R.id.viewpager);
// Tab Initialization
initialiseTabHost();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
// Fragments and ViewPager Initialization
mViewPager.setAdapter(mAdapter);
mViewPager.setOnPageChangeListener(MainActivity.this);
}
// Method to add a TabHost
private static void AddTab(MainActivity activity, TabHost tabHost, TabHost.TabSpec tabSpec) {
tabSpec.setContent(new MyTabFactory(activity));
tabHost.addTab(tabSpec);
}
// Manages the Tab changes, synchronizing it with Pages
public void onTabChanged(String tag) {
int pos = this.mTabHost.getCurrentTab();
this.mViewPager.setCurrentItem(pos);
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
// Manages the Page changes, synchronizing it with Tabs
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
int pos = this.mViewPager.getCurrentItem();
this.mTabHost.setCurrentTab(pos);
}
#Override
public void onPageSelected(int arg0) {
}
// Tabs Creation
private void initialiseTabHost() {
mTabHost = (TabHost) findViewById(android.R.id.tabhost);
mTabHost.setup();
// TODO Put here your Tabs
MainActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("ButtonTab").setIndicator("ButtonTab"));
MainActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("ImageTab").setIndicator("ImageTab"));
MainActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("TextTab").setIndicator("TextTab"));
MainActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("TestingTab").setIndicator("TestingTab"));
mTabHost.setOnTabChangedListener(this);
}
This is default behaviour of viewpager you can not change it as viewpager creates fragments so that the views exist, so the user can swipe between them, so that the old view sliding off the screen and the new view sliding onto the screen. You can write your code like this
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
Log.i("inside", "button fragment");
}else{
// fragment is not visible
}
}
so that when fragment is visible your code execute
When change your tab recall your corresponding fragment.
Try this it will help you
Create TabFragment.java
public class TabFragment extends Fragment implements OnPageChangeListener,
OnTabChangeListener {
private TabHost tabHost;
private int currentTab = 0;
private SwipeDisableViewPager viewPager;
protected TabPagerAdapter pageAdapter;
private List<Fragment> fragments;
private final int TAB_BUTTON=0,TAB_IMAGE=1,TAB_TEXT=2,TAB_TEST=3;
#SuppressWarnings("unchecked")
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_tabhost, null);
viewPager = (SwipeDisableViewPager) view.findViewById(R.id.viewpager);
tabHost = (TabHost) view.findViewById(android.R.id.tabhost);
viewPager.addOnPageChangeListener(this);
fragments = new ArrayList<>();
fragments.add(new ButtonFragment());
fragments.add(new ImageFragment());
fragments.add(new TextFragment());
fragments.add(new Test());
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
pageAdapter = new TabPagerAdapter(getChildFragmentManager(), fragments, getArguments());
pageAdapter.notifyDataSetChanged();
viewPager.setAdapter(pageAdapter);
viewPager.setOffscreenPageLimit(3);
setupTabs();
}
private void setupTabs() {
tabHost.setup();
tabHost.addTab(newTab(R.string.home, R.drawable.menu_home_bg));
tabHost.addTab(newTab(R.string.likes, R.drawable.menu_likes_bg));
tabHost.addTab(newTab(R.string.matches, R.drawable.menu_matches_bg));
for (int i = 0; i < tabHost.getTabWidget().getChildCount(); i++) {
tabHost.getTabWidget().setShowDividers(LinearLayout.SHOW_DIVIDER_NONE);
}
tabHost.setOnTabChangedListener(this);
tabHost.setCurrentTab(currentTab);
}
private View getTabIndicator(Context context, int title, int icon) {
View view = LayoutInflater.from(context).inflate(R.layout.tab_view, null);
ImageView iv = (ImageView) view.findViewById(R.id.imageView);
iv.setImageResource(icon);
TextView tv = (TextView) view.findViewById(R.id.textView);
tv.setText(title);
return view;
}
private TabSpec newTab(int tabValue, int icon) {
TabSpec tabSpec = tabHost.newTabSpec(getString(tabValue));
tabSpec.setIndicator(getTabIndicator(tabHost.getContext(), tabValue, icon));
tabSpec.setContent(new Dummy(getActivity()));
return tabSpec;
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
#Override
public void onPageScrolled(int currentPosition, float arg1, int arg2) {
}
#Override
public void onPageSelected(int position) {
if (position == 0)
viewPager.setSwipeEnabled(false);
else
viewPager.setSwipeEnabled(true);
tabHost.setCurrentTab(position);
if (listener != null)
listener.onTabChanged(position);
}
#Override
public void onTabChanged(String tabId) {
currentTab = tabHost.getCurrentTab();
viewPager.setCurrentItem(currentTab);
switch(currentTab){
case TAB_BUTTON:
((ButtonFragment) fragments.get(currentTab)).recall();
break;
case TAB_IMAGE:
((ImageFragment) fragments.get(currentTab)).recall();
break;
case TAB_TEXT:
((TextFragment) fragments.get(currentTab)).recall();
break;
case TAB_TEST:
((Test) fragments.get(currentTab)).recall();
break;
}
}
create tab_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TabWidget
android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="#drawable/menu_bg"
android:fadingEdge="none"
android:gravity="center"
android:showDividers="none"
android:tabStripEnabled="false" />
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0" />
<com.mobellotech.shift.Widget.SwipeDisableViewPager
android:id="#+id/viewpager"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#FFFFFF" />
</LinearLayout>
</TabHost>
Create tab_view.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/imageView"
android:layout_width="45dp"
android:layout_height="45dp"
android:contentDescription="#string/menu_icon" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Create TabPagerAdaper
public class TabPagerAdapter extends FragmentPagerAdapter {
private Bundle args;
private List<Fragment> fragments;
public TabPagerAdapter(FragmentManager fm, List<Fragment> fragments,
Bundle args) {
super(fm);
this.fragments = fragments;
this.args = args;
}
#Override
public Fragment getItem(int position) {
Fragment fragment = fragments.get(position);
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
return fragments.size();
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
Create MainActivity.java
public class MainActivity extends AppCompatActivity {
protected TabFragment tabFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabFragment = new TabFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.frame_container, tabFragment).commit();
}
}
Create activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/DrawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<FrameLayout
android:id="#+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</android.support.v4.widget.DrawerLayout>
Finally add the recall method in your fragment class like this
public class ButtonFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_button, container, false);
Log.i("inside", "button fragment");
return rootView;
}
public void recall() {
Log.i("inside", "button fragment");
}
}
Related
I have a MainActivIty and it supports two fragments i.e Home and Profile.Home has a TabLayout which in turn has three fragments Trending,Followed and Nearby.
So the issue is when Home is first time loaded it shows the content of the Tab fragments and slider of tab layout moves properly but when I got to profile and then to home then the tab layout fragments do not load and while swiping left to right slider does not move smoothly.Here is the code.
public class MainActivity extends AppCompatActivity {
ImageButton home_btn,myProfile_btn;
FragmentManager fragmentManager;
FragmentTransaction fragmentTransaction;
TextView txt_action_bar;
Home home;
ProfileFragment profile;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
home_btn=(ImageButton)findViewById(R.id.home_btn) ;
discover_btn=(ImageButton)findViewById(R.id.discover_btn) ;
myProfile_btn=(ImageButton)findViewById(R.id.profile_btn) ;
notification_btn=(ImageButton)findViewById(R.id.notification_btn) ;
plus_btn=(ImageButton)findViewById(R.id.btn_plus) ;
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
txt_action_bar = (TextView)findViewById(R.id.toolbar_title);
displayMetrics = getResources().getDisplayMetrics();
Typeface custom_font = Typeface.createFromAsset(getAssets(),"fonts/NoteworthyLight.ttf");
txt_action_bar.setTypeface(custom_font);
setSupportActionBar(toolbar);
fragmentManager = getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
home = new Home();
profile = new ProfileFragment();
fragmentTransaction.add(R.id.main_fragment_container,home,"home");
fragmentTransaction.commit();
}
public void onClickHome(View view)
{
fragmentManager = getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.main_fragment_container,home,"home");
fragmentTransaction.commit();
}
public void onClickMyProfile(View view)
{
fragmentManager = getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.main_fragment_container,profile,"profile");
fragmentTransaction.commit();
}
}
Home.java
public class Home extends Fragment {
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
public Home() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment_home, container, false);
mSectionsPagerAdapter = new SectionsPagerAdapter(getFragmentManager());
mViewPager = (ViewPager) view.findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
return view;
}
FollowedFragment.java
public class FollowedFragment extends Fragment {
public FollowedFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.feeds_list, container, false);
new DownloadFollowedFeeds().execute();
return rootView;
}
fragment_home.xml
<LinearLayout android:layout_below="#+id/header"
android:layout_above="#+id/footer"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_gravity="center_vertical"
android:orientation="vertical"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
style="#style/TabNameStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/medium_turquoise"
app:tabGravity="fill"
app:tabMode="fixed" />
<android.support.v4.view.ViewPager
android:id="#+id/container"
android:layout_width="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_height="fill_parent"/>
SectionPagerAdapter.java
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private String tabTitles[] = new String[] { "Trending", "Followed","Nearby" };
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
Log.i("tag","number"+String.valueOf(position));
if(position==0) return new TrendingFragment();
else if(position==1) return new FollowedFragment();
else return new NearbyFragment();
}
#Override
public int getCount() {
// Show 3 total pages.
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
return tabTitles[position];
}
}
As answered here:
When you are creating the view adapter in Home.java:
instead of
mSectionsPagerAdapter = new SectionsPagerAdapter(getFragmentManager());
you should do,
mSectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager());
From what I understand from this thread, fragments can be easily replaced with another.
However in my case, I have 2 fragments combined in scrollable Activity, so when I say "move", I mean going from the fragment left to the right or right to the left without replacing any fragment with another. Is this somehow possible?
you could use ViewPager for that. And on your adapter class you will have to switch between the fragments via getItem(). Eclipse/new AndroidProject/ swipe with/out tabs. And check the example code generated by Android.
edit:
create xml file call it main_activity.xml
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Main" >
<android.support.v4.view.PagerTitleStrip
android:id="#+id/pager_title_strip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#FAFAFA"
android:paddingBottom="4dp"
android:paddingTop="4dp"
android:textColor="#36466E" />
create a class call it Main
public class Main extends FragmentActivity {
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
Context ctx;
static MySQLiteHelper db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSectionsPagerAdapter = new SectionsPagerAdapter(
getSupportFragmentManager());
mSectionsPagerAdapter.notifyDataSetChanged();
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch(position){
case 0:
fragment = new GridApp();
break;
case 1:
fragment = new ListApp();
break;
}
return fragment;
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Select App";
case 1:
return "Selected Apps";
}
return null;
}
}
}
now create a class called GridApp and ListApp
GridApp class.
public class GridApp extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.gridpp,
container, false);
}
}
ListApp class
public class GridApp extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.listapp,
container, false);
}
}
and you are done.
I want a tab with 4 scrollable tabs in a class. I implemented the following example and it works:
mAdapter = new MyAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mAdapter);
...
public static class MyAdapter extends FragmentPagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return NUM_ITEMS; //NUM_ITEMS=4
}
#Override
public ArrayListFragment getItem(int position) {
return ArrayListFragment.newInstance(position);
}
#Override
public CharSequence getPageTitle(int position) {
switch(position) {
case 0:
return "TAB1";
case 1:
return "TAB2";
case 2:
return "TAB3";
case 3:
return "TAB4";
default:
return "ERROR";
}
}
}
...
public static class ArrayListFragment extends ListFragment {
int mNum;
static ArrayListFragment newInstance(int num) {
ArrayListFragment f = new ArrayListFragment();
Bundle args = new Bundle();
args.putInt("num", num);
f.setArguments(args);
return f;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNum = getArguments() != null ? getArguments().getInt("num") : 1;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
switch(mNum) {
case 0:
View v0 = inflater.inflate(R.layout.fragment_pager_list, container, false);
return v0;
case 1:
View v1 = inflater.inflate(R.layout.fragment_pager_list, container, false);
return v1;
case 2:
View v2 = inflater.inflate(R.layout.fragment_pager_list, container, false);
return v2;
case 3:
View v3 = inflater.inflate(R.layout.fragment_pager_list, container, false);
return v3;
default:
View vd = inflater.inflate(R.layout.fragment_pager_list, container, false);
return vd;
}
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, Titles));
}
//Titles={"TAB1", "TAB2", "TAB3", "TAB4"}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Log.i("FragmentList", "Item clicked: " + id);
}
}
where fragment_pager_list layout that I put in each view is the following:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:drawable/gallery_thumb">
<TextView android:id="#+id/text"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="HELLO WORLD"/>
<!-- The frame layout is here since we will be showing either
the empty view or the list view. -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" >
<!-- Here is the list. Since we are using a ListActivity, we
have to call it "#android:id/list" so ListActivity will
find it -->
<ListView android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawSelectorOnTop="false"/>
<!-- Here is the view to show if the list is emtpy -->
<TextView android:id="#android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="No items."/>
</FrameLayout>
The problem is that I want to put a different layout in each view for each tab.
I tried to modify the code so that "ArrayListFragment" inherits from "Fragment" instead of "ListFragment" to load layouts that do not contain "ListView" but "RelativeLayout" or "LinearLayout", but can not get it to work.
Please, if anyone can help me, I need to load different views on the tabs and that they contain other elements than ListView.
Thank you very much.
You'd better make each fragment for different layout.
You can add addFragment(Fragment fragment) method to MyAdapter.
mAdapter = new MyAdapter(getSupportFragmentManager());
for(int i=0; i<4; i++) {
Fragment fragment = null;
switch(i) {
case 0:
fragment = FirstFragment.newInstance();
break;
case 1:
fragment = SecondFragment.newInstance();
break;
case 2:
fragment = ThirdFragment.newInstance();
break;
case 3:
fragment = FourthFragment.newInstance();
break;
}
mAdapter.addFragment(fragment);
}
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mAdapter);
MyAdapter : Adapter is a simple container.
public static class MyAdapter extends FragmentPagerAdapter {
private List<Fragment> mFragmentList;
public MyAdapter(FragmentManager fm) {
super(fm);
mFragmentList = new ArrayList<Fragment>();
}
publid void addFragment(Fragment fragment) {
mFragmentList.add(fragment);
}
#Override
public int getCount() {
return mFragmentList.size();
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public CharSequence getPageTitle(int position) {
return ((CustomFragment) mFragmentList.get(position)).getPageTitle();
}
}
CustomFragment : Put common methods for each fragments.
public abstract class CustomFragment extends Fragment {
public abstract Fragment newInstance();
public abstract String getPageTitle();
}
FirstFragment : Inflate different layout for each fragments.
public class FirstFragment extends CustomFragment {
#Override
public Fragment newInstance() {
Fragment f = new FirstFragment();
return f;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.LAYOUT_ID_FOR_FIRST_FRAGMENT, container, false);
// Some codes for layout such as findViewById
return view;
}
#Override
public String getPageTitle() {
// return TITLE_FOR_FRAGMENT
}
}
I hope this answer will help you.
Can anyone point me to an example or show me how to create a simple Tabbed Dialog in Android where the contents of each tab are Fragments? All the examples/tutorials I have found are about Fragments and Tabs, but nothing specific to DialogFragments.
The documentation for FragmentTabHost shows how to create tabs within normal fragments using getChildFragmentManager(). I'm assuming this should also work when the fragment is a DialogFragment but when I try it I get:
java.lang.IllegalStateException: Fragment does not have a view at android.support.v4.app.Fragment$1.findViewById(Fragment.java:1425)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:901)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
...
Here's my code for setting up the view (which is then passed to AlertDialog.setView()):
private void setupView(View v) {
mTabHost = (FragmentTabHost) v.findViewById(android.R.id.tabhost);
mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.realtabcontent);
mTabHost.addTab(mTabHost.newTabSpec("tab1").setIndicator("Tab1"),
MyDialogFragment.class, null);
}
Spent a lot of time to get it working, but no luck. The only solution I found is create dummy fragment tabhost and use viewpager with fragments instead of tabhost fragments
voters_dialog.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical"
>
<android.support.v4.app.FragmentTabHost
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/tabs"
>
</android.support.v4.app.FragmentTabHost>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"/>
</LinearLayout>
Dialog class, the trick is use onCreateView not onCreateDialog
public class VotersDialog extends DialogFragment {
private FragmentTabHost mTabHost;
private ViewPager viewPager;
private VotersPagerAdapter adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.voters_dialog, container);
getDialog().setTitle(getArguments().getString("title"));
mTabHost = (FragmentTabHost) view.findViewById(R.id.tabs);
mTabHost.setup(getActivity(), getChildFragmentManager());
mTabHost.addTab(mTabHost.newTabSpec("tab1").setIndicator("Плюсов"), Fragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("tab2").setIndicator("Минусов"), Fragment.class, null);
adapter = new VotersPagerAdapter(getChildFragmentManager(), getArguments());
adapter.setTitles(new String[]{"Плюсов", "Минусов"});
viewPager = (ViewPager)view.findViewById(R.id.pager);
viewPager.setAdapter(adapter);
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int i, float v, int i2) {
}
#Override
public void onPageSelected(int i) {
mTabHost.setCurrentTab(i);
}
#Override
public void onPageScrollStateChanged(int i) {
}
});
mTabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
#Override
public void onTabChanged(String s) {
int i = mTabHost.getCurrentTab();
viewPager.setCurrentItem(i);
}
});
return view;
}
public class VotersPagerAdapter extends FragmentPagerAdapter {
Bundle bundle;
String [] titles;
public VotersPagerAdapter(FragmentManager fm) {
super(fm);
}
public VotersPagerAdapter(FragmentManager fm, Bundle bundle) {
super(fm);
this.bundle = bundle;
}
#Override
public Fragment getItem(int num) {
Fragment fragment = new VotersListFragment();
Bundle args = new Bundle();
args.putSerializable("voters",bundle.getSerializable( num == 0 ? "pros" : "cons"));
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
return titles[position];
}
public void setTitles(String[] titles) {
this.titles = titles;
}
}
public static class VotersListFragment extends ListFragment {
List<String> voters;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.list_fragment, container, false);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
voters = (ArrayList) getArguments().getSerializable("voters");
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, voters);
setListAdapter(adapter);
getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent = new Intent(getActivity(), ProfileActivity_.class);
String login = voters.get(i);
intent.putExtra("login", Utils.encodeString(login.substring(0, login.indexOf("(")).trim()));
startActivity(intent);
}
});
}
}
}
Here is result, now you can press tabs or swipe fragments
I was looking for the same solution but nothing worked out for me so I built my own Android tabbed dialog containing fragments. might be it may help someone.
you can checkout the complete source code from here
You should use a DialogFragment, TabLayout and ViewPager. For instance, your dialog fragment's view may look like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v4.view.ViewPager
android:id="#+id/masterViewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Build your adapter and make sure you override the getPageTitleMethod, e.g:
public class CustomAdapter extends FragmentPagerAdapter {
List<Fragment> mFragmentCollection = new ArrayList<>();
List<String> mTitleCollection = new ArrayList<>();
public CustomAdapter(FragmentManager fm) {
super(fm);
}
public void addFragment(String title, Fragment fragment)
{
mTitleCollection.add(title);
mFragmentCollection.add(fragment);
}
//Needed for
#Override
public CharSequence getPageTitle(int position) {
return mTitleCollection.get(position);
}
#Override
public Fragment getItem(int position) {
return mFragmentCollection.get(position);
}
#Override
public int getCount() {
return mFragmentCollection.size();
}
}
In the OnCreateView of your dialog, you should setup your viewpager with the tabLayout:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootview = inflater.inflate(R.layout.dialog_sample,container,false);
tabLayout = (TabLayout) rootview.findViewById(R.id.tabLayout);
viewPager = (ViewPager) rootview.findViewById(R.id.masterViewPager);
CustomAdapter adapter = new CustomAdapter(getChildFragmentManager());
adapter.addFragment("Boy",CustomFragment.createInstance("John"));
adapter.addFragment("Girl",CustomFragment.createInstance("Stacy"));
adapter.addFragment("Robot",CustomFragment.createInstance("Aeon"));
viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager);
return rootview;
}
I have a blog post written on it here: here.
Try using DialogFragment instead and on your dialogfragment layout include a LinearLayout for fragmentTransaction.
FragmentTransaction t = getSupportFragmentManager().beginTransaction();
String Tag = fragment.getClass().getSimpleName();
t.replace(R.id.llTabFragmentContainer, fragment, Tag);
t.commit();
fragment is your tab fragment.
cheeers
Please, advice. I can't get ViewPager working. Here is what I'am doing:
1) This is my LinearLayout in which I will put the ViewPager. I'am sure that it's work. I can put any View in it:
<LinearLayout
android:id="#+id/view_contact_values_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/view_contact_sub_nav"
android:orientation="vertical"
android:paddingLeft="10dip" >
</LinearLayout>
2) Next I'm creating the ViewPager in code:
private void createViewPager() {
ViewPager viewPager = new ViewPager(this);
DatesPagerAdapter datesPagerAdapter = new DatesPagerAdapter(this);
viewPager.setAdapter(datesPagerAdapter);
viewPager.setCurrentItem(1);
llContainer.addView(viewPager);
}
3) And the ViewPagerAdapter (PagerAdapter):
#Override
public Object instantiateItem(ViewGroup container, int position) {
LayoutInflater inflater = (LayoutInflater) container.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.dates_carusel_item, null);
((ViewPager) container).addView(v, 0);
return v;
}
#Override
public int getCount(){
return 5;
}
But when I open my Activity, there is nothing showing in my LinearLayout.
P.S.: Sorry for the bad question styling. Code tag in this editor is strange.
Take a class extending Fragemnt
class ExampleFragment extends Fragment
{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.dates_carusel_item, null);
return v;
}
And in your PagerAdapter do this
private class DatesPagerAdapter extends FragmentPagerAdapter
{
public DatesPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int arg0) {
ExampleFragment fragment=new ExampleFragment();
Bundle bundle=new Bunlde();
//put bundle data here
fragment.setArguments(bundle);
return fragment;
}
#Override
public int getCount() {
5;
}
}
Whatever view you want to set do it on the Example Fragment and add your viewPager
ViewPager pager=new ViewPager(this);
pager.setAdapter(new DatesPagerAdapter);
llContainer.addView(pager)
Add your ViewPager in xml itself to get it proprly alligned or else you can setLayoutParams in runtime if its a visibilty error
android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:layout_below="#id/view_contact_sub_nav"android:id="+id/view_contact_values_container"
android:paddingLeft="10dip">
<android.support.v4.view.ViewPager
android:id="#+id/imagesgallery"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>