Description
I have one activity in the vertical orinentation with two tabs (TabLayout) and fragments, which change with Viewpager.
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
// Assign created adapter to viewPager
viewPager.setAdapter(new TabsExamplePagerAdapter(getSupportFragmentManager()));
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
// This method setup all required method for TabLayout with Viewpager
tabLayout.setupWithViewPager(viewPager);
}
public class TabsExamplePagerAdapter extends FragmentPagerAdapter {
// As we are implementing two tabs
private static final int NUM_ITEMS = 2;
public TabsExamplePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
// For each tab different fragment is returned
public Fragment getItem(int position) {
switch (position) {
case 0:
return new TabOneFragment();
case 1:
return new TabTwoFragment();
default:
return null;
}
}
#Override
public int getCount() {
return NUM_ITEMS;
}
#Override
public CharSequence getPageTitle(int position) {
return "Tab " + (position + 1);
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MainActivity">
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:tabTextColor="#ffffff"
app:tabIndicatorColor="#fbff3a"
app:tabSelectedTextColor="#fbff3a"
app:tabIndicatorHeight="5dp"
android:elevation="4dp"
app:tabGravity="fill"
app:tabMaxWidth="0dp" />
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
In each tabs i have for one fragments.
TabOneFragment.java (TabTwoFragment is similar ):
public class TabOneFragment extends Fragment {
// Required empty public constructor
public TabOneFragment() { }
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_tab_one, container, false);
}
}
fragment_one_tab.xml (fragment_one_tab.xml is similar)
<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="innovatecode.com.tabexample.TabOneFragment">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="18dp"
android:text="#string/tab_one" />
</FrameLayout>
And i have simply result:
My problem
When my device is rotated to the horizontal position, I want to get the following result:
I create xml for horizontal markup (land):
active_main.xml (land)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/root"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<FrameLayout
android:id="#+id/fragment_left"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />
<FrameLayout
android:id="#+id/fragment_right"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
But I don't know how to change my code to get this result. I'm not very strong in working with fragments.
First, you can improve your landscape layout by adding your fragments directly to the layout file (under "res/layout-land"):
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/root"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<fragment
android:name="innovatecode.com.tabexample.TabOneFragment"
android:id="#+id/fragment_left"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
<fragment
android:name="innovatecode.com.tabexample.TabTwoFragment"
android:id="#+id/fragment_right"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
You can read move on the topic here.
For the code part, you could make use of distinct features of your landscape and portrait layouts to switch between the corresponding logic in code. For example:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (findViewById(R.id.tab_layout) != null) {
setUpPortraitLayout();
} else {
setUpLandscapeLayout();
}
}
private void setUpPortraitLayout() {
ViewPager viewPager = findViewById(R.id.pager);
// Assign created adapter to viewPager
viewPager.setAdapter(new TabsExamplePagerAdapter(getSupportFragmentManager()));
TabLayout tabLayout = findViewById(R.id.tab_layout);
// This method setup all required method for TabLayout with Viewpager
tabLayout.setupWithViewPager(viewPager);
}
private void setUpLandscapeLayout() {
// Note: with the layout definition suggested above you don't
// need any manual processing to set-up your layout for landscape
// but you still may have some extra set-up (initial binding, etc).
tabOneFragment = (TabOneFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_left);
tabTwoFragment = (TabTwoFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_right);
// ...
}
}
You can pass saved parameters to your fragments via "setArguments()" method. Alternatively consider using "onSaveInstanceState()" methods of your fragments (as opposed to activity, which you use now).
Alternative approach: dynamically add fragments in both landscape and portrait cases. It is based on your code. I think some aspects are arguable (I may be wrong), but changing direction would mean rewriting the whole thing. But it should work eventually.
res/layout-land/active_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/root"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<FrameLayout
android:id="#+id/fragment_left"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
<FrameLayout
android:id="#+id/fragment_right"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
MainActivity.java (based off the code you shared via gist)
public class MainActivity extends AppCompatActivity {
private Fragment tabOneFragment;
private Fragment tabTwoFragment;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState != null) {
//Restore the fragment's instance
tabOneFragment = (TabOneFragment) getSupportFragmentManager().getFragment(
savedInstanceState, "tabOneFragment");
tabTwoFragment = (TabTwoFragment) getSupportFragmentManager().getFragment(
savedInstanceState, "tabTwoFragment");
} else {
tabOneFragment = new TabOneFragment();
tabTwoFragment = new TabTwoFragment();
}
if (findViewById(R.id.tab_layout) != null) {
setUpPortraitLayout();
} else {
setUpLandscapeLayout();
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
getSupportFragmentManager().putFragment(outState, "tabOneFragment", tabOneFragment);
getSupportFragmentManager().putFragment(outState, "tabTwoFragment", tabTwoFragment);
}
private void setUpPortraitLayout() {
viewPager = (ViewPager) findViewById(R.id.pager);
// Assign created adapter to viewPager
viewPager.setAdapter(new TabsPagerAdapter(getSupportFragmentManager()));
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
// This method setup all required method for TabLayout with Viewpager
tabLayout.setupWithViewPager(viewPager);
}
private void setUpLandscapeLayout() {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_left, tabOneFragment);
transaction.replace(R.id.fragment_right, tabTwoFragment);
transaction.addToBackStack(null);
transaction.commit();
}
private class TabsPagerAdapter extends FragmentPagerAdapter {
// As we are implementing two tabs
private static final int NUM_ITEMS = 2;
public TabsPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
#Override
// For each tab different fragment is returned
public Fragment getItem(int position) {
switch (position) {
case 0:
return tabOneFragment;
case 1:
return tabTwoFragment;
default:
throw new IllegalStateException("Invalid tab index");
}
}
#Override
public int getCount() { return NUM_ITEMS; }
#Override
public CharSequence getPageTitle(int position) { return "Tab " + (position + 1); }
// NOTE: I think you do not really need to override "instantiateItem()", therefore I removed it.
}
}
Related
I am using a PageViewer to display fragment's data, and whenever I put a TextView into the fragment's xml, it doesn't display when the app is being run. I put it in a NestedScrollView to put more widgets in then I could without it. I tried putting an ImageView in to see if it was removing everything but that worked fine, except it was a little laggy when changing fragments.
My code for my activity is
public class MainActivity extends AppCompatActivity {
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
viewPager = (ViewPager) findViewById(R.id.view_pager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
tabLayout.setupWithViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new VolleyballFragment(), "Volleyball");
adapter.addFragment(new SoftballFragment(), "Softball");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
}
my fragment codes are the nearly same so I will only provide 1
public class VolleyballFragment extends Fragment{
public VolleyballFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_volleyball, container, false);
}
}
and the activity xml file is
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appbar"
android:layout_height="wrap_content"
android:layout_width="match_parent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways"></androidx.appcompat.widget.Toolbar>
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.tabs.TabItem
android:id="#+id/softballFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Softball" />
<com.google.android.material.tabs.TabItem
android:id="#+id/volleyballFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Vollyball" />
</com.google.android.material.tabs.TabLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<androidx.viewpager.widget.ViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
If you need any of the xml files or anything else please let me know.
I fallowed an older tutorial online since this is my first time using fragments and tabs, so I'm a little confused to begin with
Also sorry for the code being cut off and replaced as normal text
I tried your code everything else is fine but you're just missing layout_behavior on NestedScrollView.
After adding this property your code would look like this.
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
android:fillViewport="true">
<androidx.viewpager.widget.ViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</androidx.core.widget.NestedScrollView>
I'm able to click the tabs to change, but nothing happens when I swipe. I don't see the coloured bar underneath the selected tab either.
Here's my code. I've largely followed this tutorial, but I've changed tabLayout.setOnTabSelectedListener(this) to tabLayout.addOnTabSelectedListener(this) in StoriesActivity because the former is depreceated.
StoriesActivity:
public class StoriesActivity extends AppCompatActivity implements TabLayout.OnTabSelectedListener {
//This is our tablayout
private TabLayout tabLayout;
//This is our viewPager
private ViewPager viewPager;
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_stories);
/* +++ START Intent +++ */
Bundle extras = getIntent().getExtras();
final int authorID = extras.getInt("author_id");
final String authorName = extras.getString("author_name");
Log.i("click", Integer.toString(authorID));
/* +++ END Intent +++ */
toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle(authorName);
setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
//Initializing the tablayout
tabLayout = (TabLayout) findViewById(R.id.tab_layout);
//Adding the tabs using addTab() method
tabLayout.addTab(tabLayout.newTab().setText("Stories"));
tabLayout.addTab(tabLayout.newTab().setText("Collections"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
//Initializing viewPager
viewPager = (ViewPager) findViewById(R.id.pager);
//Creating our pager adapter
StoriesTabsAdapter adapter = new StoriesTabsAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
//Adding adapter to pager
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
//Adding onTabSelectedListener to swipe views
tabLayout.addOnTabSelectedListener(this);
}
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
}
activity_stories.xml:
<RelativeLayout
android:id="#+id/main_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="?attr/colorPrimary"
android:elevation="6dp"
android:minHeight="?attr/actionBarSize"
app:navigationIcon="?attr/homeAsUpIndicator"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/toolbar"
android:background="?attr/colorPrimary"
android:elevation="6dp"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_below="#id/tab_layout"/>
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/stories_list_view" />
</RelativeLayout>
StoriesTabsAdapter:
public class StoriesTabsAdapter extends FragmentPagerAdapter {
int mNumOfTabs;
public StoriesTabsAdapter(FragmentManager fm, int NumOfTabs) {
super(fm);
this.mNumOfTabs = NumOfTabs;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
StoriesFragment tab1 = new StoriesFragment();
return tab1;
case 1:
CollectionsFragment tab2 = new CollectionsFragment();
return tab2;
default:
return null;
}
}
#Override
public int getCount() {
return mNumOfTabs;
}
}
StoriesFragment:
public class StoriesFragment extends Fragment {
public StoriesFragment() {
// Required empty public constructor
}
private ListView storiesListView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_stories, container, false);
}
}
You are missing to setupWithViewPager your TabLayout.
mTabLayout.setupWithViewPager(mViewPager)
Regarding the problem of your text not to be appearing, try to move the code below straight after you setupWithViewPager
//Adding the tabs using addTab() method
tabLayout.addTab(tabLayout.newTab().setText("Stories"));
tabLayout.addTab(tabLayout.newTab().setText("Collections"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
You should follow below two points.
Use FragmentStatePagerAdapter for good approach.
setupWithViewPager
If you're using a ViewPager together with this layout, you can call
setupWithViewPager(ViewPager) to link the two together. This layout
will be automatically populated from the PagerAdapter's page titles.
Secondly
_tablayoutOBJ.setupWithViewPager(_viewpagerOBJ); // After addOnTabSelectedListener .
For, Demo case you can visit Material Design working with Tabs.
I recently started coding and have been following tutorials. I'm trying to learn how to use a tab activity right now and followed a tutorial to do it by swiping pages. Here's what I've come up with
public class MainActivity extends FragmentActivity {
ViewPager pager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn1 = (Button) findViewById(R.id.btn1);
Button btn2 = (Button) findViewById(R.id.btn2);
pager = (ViewPager) findViewById(R.id.viewPager);
pager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
}
public void onClickBtn1(View v) {
//when clicked, take to Main2Activity.java
}
public void onClickBtn2(View v) {
//when clicked, take to Main3Activity.java
}
private class MyPagerAdapter extends FragmentPagerAdapter {
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int pos) {
switch(pos) {
case 0: return Main2Activity.newInstance("FirstFragment, Instance 1");
case 1: return Main3Activity.newInstance("SecondFragment, Instance 1");
case 2: return Main4Activity.newInstance("ThirdFragment, Instance 1");
default: return Main4Activity.newInstance("ThirdFragment, Default");
}
}
#Override
public int getCount() {
return 3;
}
}
}
Can someone please explain to me what's going on in the MyPageAdapter class please?
Also, is it possible that instead of swiping pages that I use a button? For instance, onClickBtn1 will take me to Main2Activity and onClickBtn2 will take me to Main3Activity. I'd like to continue using the tabs instead of creating a new intent.
Thanks in advance!
Your MyPageAdapter will have as many childs as of your tabs.
For example if you select 1st tab ie position will be 0.
Now in below code new instance of fragment is created for pos 0(First Fragment).
public Fragment getItem(int pos) {
switch(pos) {
case 0: return Main2Activity.newInstance("FirstFragment, Instance 1");
case 1: return Main3Activity.newInstance("SecondFragment, Instance 1");
case 2: return Main4Activity.newInstance("ThirdFragment, Instance 1");
default: return Main4Activity.newInstance("ThirdFragment, Default");
}
}
Switching the tabs on button click is not a cool idea as per user experience.You are using view pager which will help swiping the tabs easily.Execute the code & you will get to know more about the functionality of the code.
if you want to use tabs, you could use 4 fragments in an activity and manage them with ViewPager, by this you can go from one to another by clicking on the tabs and swipe left and right
private void initPager() {
ViewPager pager = (ViewPager) findViewById(R.id.pager);
mAdapter = new MyPagerAdapter(getSupportFragmentManager());
mAdapter.addFragment(firstFragment.newInstance(), getString(R.string.first_fragment_Title));
mAdapter.addFragment(secondFragment.newInstance(), getString(R.string.second_fragment_title));
pager.setAdapter(mAdapter);
TabLayout tabs = (TabLayout) findViewById(R.id.tabs);
tabs.setupWithViewPager(pager);
TextView firstFragmentTabTitle = (TextView) getLayoutInflater().inflate(R.layout.tab_indicator, null);
firstFragmentTabTitle.setText(mAdapter.getPageTitle(0).toString());
TextView secondFragmentTabTitle = (TextView) getLayoutInflater().inflate(R.layout.tab_indicator, null);
secondFragmentTabTitle.setText(mAdapter.getPageTitle(1).toString());
tabs.getTabAt(0).setCustomView(firstFragmentTabTitle);
tabs.getTabAt(1).setCustomView(secondFragmentTabTitle);
pager.setCurrentItem(mAdapter.getCount());
}
and the main activity XML add view pager and tab layout like this :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
tools:context=".fragments.BankCounterFragment">
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layoutDirection="ltr"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:contentInsetEnd="16dp"
app:popupTheme="#style/AppTheme.PopupOverlay">
<TextView
android:id="#+id/toolbar_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:gravity="center|start"
android:text="#string/app_name"
android:textAppearance="#style/TextAppearance.AppCompat.Title"/>
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:layoutDirection="ltr"
app:tabGravity="fill"
app:tabIndicatorColor="#android:color/white"
app:tabIndicatorHeight="3dp"
app:tabMode="fixed"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
I have used a sectionsPageAdapter class in Java which is given below.
This is a tabbed activity and I later added a navigation drawer to it.
Now I wish to let user navigate through tabs from the main activity by swiping (which works successfully) and also through nav drawer as I have included the same fragments names there also.
what code should i write in the switch case to direct user to the clicked fragment activity?
Main Activity.java
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private SectionsPageAdapter mSectionsPageAdapter;
private ViewPager mViewPager;
private ArrayAdapter<String> mAdapter;
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG,"onCreate: Starting");
mSectionsPageAdapter =new SectionsPageAdapter(getSupportFragmentManager());
mViewPager =(ViewPager)findViewById(R.id.container);
setupViewPager(mViewPager);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
mDrawerLayout =(DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList=(ListView)findViewById(R.id.navList);
addDrawerItems();
mDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
switch (position)
{
case 0:
// what Code??
break;
case 1:
break;
}
}
});
}
private void setupViewPager(ViewPager viewPager){
SectionsPageAdapter adapter=new SectionsPageAdapter(getSupportFragmentManager());
adapter.addFragment(new Tab1Fragment(),"Our Picks");
adapter.addFragment(new Tab2Fragment(),"Technology");
adapter.addFragment(new Tab3Fragment(),"Fashion");
viewPager.setAdapter(adapter);
}
private void addDrawerItems() {
String[] osArray = { "Our Picks", "Technology","Fashion" };
mAdapter = new ArrayAdapter<String>(this,R.layout.drawerpart1, osArray);
mDrawerList.setAdapter(mAdapter);
}
SectionsPageAdapter.java
public class SectionsPageAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList=new ArrayList<>();
private final List<String> mFragmentTitleList=new ArrayList<>();
public void addFragment(Fragment fragment,String title){
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
public SectionsPageAdapter(FragmentManager fm) {
super(fm);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
}
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:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:id="#+id/drawer_layout"
android:layout_height="match_parent"
tools:context="com.example.aa.news.MainActivity">
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
>
<android.support.v4.view.ViewPager
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/appbar_padding_top"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
<ListView
android:id="#+id/navList"
android:layout_width="250dp"
android:layout_height="match_parent"
android:layout_gravity="left|start"
android:background="#ffeeeeee"/>
</android.support.v4.widget.DrawerLayout>
drawerpart1.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/label"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dip"
android:textSize="16dip"
android:textStyle="bold" >
</TextView>
Tab1Fragment
public class Tab1Fragment extends Fragment {
private static final String TAG = "Tab1Fragment";
private Button btn1;
#Nullable
#Override
public View onCreateView(#Nullable LayoutInflater inflater, #Nullable ViewGroup container,#Nullable Bundle savedInstanceState)
{
View view= inflater.inflate(R.layout.tab1_fragment,container,false);
btn1=(Button) view.findViewById(R.id.btn1);
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(),"Button 1 Clicked",Toast.LENGTH_SHORT).show();
}
});
return view;
}
}
tab1_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="#+id/btn1"
android:text="Button 1" />
<TextView
android:layout_height="60dp"
android:layout_width="120dp"
android:id="#+id/tv1"
android:text="Fragment 1"/>
</LinearLayout>
The other fragments tab2 and 3 are same as tab 1.
Use setCurrentItem() on viewpager
mDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener(){
#Override
public void onItemClick (AdapterView < ? > parent, View view,int position, long id){
mViewPager.setCurrentItem(position);
}
});
I have a tablayout in which I have included five fragments, but when I go to any other tab, the fragments XML (layout) is not showed, instead a black screen appears only.
I am including my tab activity code and the screenshot of the app and for reference one fragment with its XML.
TABS_ACTIVITY
public class Bottom_Tabs_Activity extends AppCompatActivity {
private TabLayout tabLayout;
private ViewPager viewPager;
private int[] tabIcons = {
R.drawable.ic_friends,
R.drawable.ic_chat,
R.drawable.ic_map,
R.drawable.ic_status,
R.drawable.ic_profile
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tabs);
viewPager = (ViewPager) findViewById(R.id.viewpager);
if (viewPager != null)
setupViewPager(viewPager);
else {
Log.e("test", "i am null");
}
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
setupTabIcons();
}
private void setupTabIcons() {
tabLayout.getTabAt(0).setIcon(tabIcons[0]);
tabLayout.getTabAt(1).setIcon(tabIcons[1]);
tabLayout.getTabAt(2).setIcon(tabIcons[2]);
tabLayout.getTabAt(3).setIcon(tabIcons[3]);
tabLayout.getTabAt(4).setIcon(tabIcons[4]);
}
private void setupViewPager(ViewPager viewPager)
{
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFrag(new MapFragment(),"MAPS");
adapter.addFrag(new PeopleFragment(),"PEOPLE");
adapter.addFrag(new HomeFragment(),"HOME");
adapter.addFrag(new ChatFragment(),"CHAT");
adapter.addFrag(new ProfileFragment(),"PROFILE");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter
{
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager)
{
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFrag(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
// return null to display only the icon
return null;
}
}
}
TABS_LAYOUT.xml
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#ffffff" />
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom"
android:layout_gravity="bottom"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:tabMode="fixed"
app:tabGravity="fill"/>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
MapFragment.java
public class MapFragment extends Fragment{
public MapFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.mapfragment, container, false);
}
}
Mapfragment.xml
<RelativeLayout 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=".Fragments.MapFragment">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="MAP"
android:textSize="40dp"
android:textStyle="bold"
android:layout_centerInParent="true"/>
</RelativeLayout>
SCREENSHOT of APP
getChildFragmentManager() instead of getSupportFragmentManager()
private void setupViewPager(ViewPager viewPager)
{
FragmentManager cfManager = getChildFragmentManager();
ViewPagerAdapter adapter = new ViewPagerAdapter(cfManager);
// ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
...
...
}
You could rearrange the layout like this.
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_behavior="#string/appbar_scrolling_view_behavior" >
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/background"
app:tabIndicatorColor="#color/tab_indicator_color"
app:tabMode="scrollable" />
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
I think it will work. May be this app:layout_behavior="#string/appbar_scrolling_view_behavior" one is the key.
Try including this line before :
tabLayout.setupWithViewPager(viewPager);
viewPager.setOffscreenPageLimit(2);
I am afraid CoordinatorLayout do not support weight, wrap your ViewPager and AppBarLayout with LinearLayout first and then put it in CoordinatorLayout