Update: I modified my adapter class to the following, and it works fine now:
public class SectionsPagerAdapter extends FragmentPagerAdapter {
R.string.tab_text_2, R.string.tab_text_3};
//private final Context mContext;
private static int tab_count;
private Context mContext;
public SectionsPagerAdapter(FragmentManager fm, int tab_count, Context context) {
super(fm);
mContext = context;
this.tab_count = tab_count;
}
#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).
//return PlaceholderFragment.newInstance(position + 1);
switch (position)
{
case 0:
Tab1Pagina_Inicial tab1 = new Tab1Pagina_Inicial();
return tab1;
case 1:
Tab2Apartamentos tab2 = new Tab2Apartamentos();
return tab2;
case 2:
Tab3ItensDeApartamentos tab3 = new Tab3ItensDeApartamentos();
return tab3;
default:
return null;
}
}
#Override
public CharSequence getPageTitle(int position) {
switch (position)
{
case 0:
return mContext.getString(R.string.tab_text_1);
case 1:
return mContext.getString(R.string.tab_text_2);
case 2:
return mContext.getString(R.string.tab_text_3);
default:
return null;
}
}
#Override
public int getCount()
{
return tab_count;
}
}
Adding the getPageTitle worked!
Thank you for the tips. ^^
I'm creating an app with a tab menu but the tabs' titles are not displaying properly.
I've tried rereading and looking again at every tutorial I've seen so far, as well as comparing my code to others with similar questions here on stackoverflow but I still can't seem to identify what I'm doing wrong and where. Could anyone enlighten me as to my mistake?
Thank you in advance for any clarification.
Edit: I don't think it's the color. I've tried messing with the colors and themes of both TabLayout, AppBarLayout and each tab item separately (as well as removing the themes altogether) and the titles are still not showing like they should. But I'll post the code for my colors.xml and styles.xml files just in case.
Edit 2: Guys, I've found out something curious. Now I'm not sure I really understand TabLayout as I thought I did.
Before I set my TabLayout with my ViewPager with the setupWithViewPager method, everything appears as it should. The titles show up I mean. But I can only actually change tabs by swiping. Clicking on each tab does nothing.
I'll attach an image to show what I mean.
Here's what I thought I understood:
I know I need an adapter to render each fragment as content for each tab.
I know the ViewPager is the component responsible for the swiping between tabs.
TabLayout is a layout where I can display my tabs.
I need to hook my TabLayout to my ViewPager in order to display the correct content whenever I click a specific tab.
Am I missing something?
MainActivity:
package com.example.pousadaviladascores.Activities;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.ViewPager;
import android.os.Bundle;
import com.example.pousadaviladascores.DAO.SqlAccess;
import com.example.pousadaviladascores.UI.SectionsPagerAdapter;
import com.example.pousadaviladascores.R;
import com.google.android.material.tabs.TabLayout;
public class MainActivity extends AppCompatActivity {
SqlAccess sqlAccess;
//Declaring TabLayout and ViewPager
TabLayout tabLayout;
ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
setContentView(R.layout.activity_main);
sqlAccess = new SqlAccess(this);
//Initializing TabLayout
tabLayout = findViewById(R.id.tabLayout);
//Initializing viewPager
viewPager = findViewById(R.id.view_pager);
//Initializing page adapter
//OBS: In Android, Adapter is a bridge between UI component and data source that helps us to fill data in UI component.
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
//Sets a PagerAdapter that will supply views for this pager as needed
viewPager.setAdapter(sectionsPagerAdapter);
tabLayout.setupWithViewPager(viewPager);
}
#Override
protected void onDestroy() {
sqlAccess.getDbHelper().close();
super.onDestroy();
}
}
Fragment class (I have three classes, one for each fragment and they all have the same code, so I'm just posting one):
package com.example.pousadaviladascores.Activities;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
import com.example.pousadaviladascores.R;
public class Tab1Pagina_Inicial extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.tab1_fragment_pagina_inicial, container, false);
}
}
Page Adapter class:
package com.example.pousadaviladascores.UI;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import com.example.pousadaviladascores.Activities.Tab1Pagina_Inicial;
import com.example.pousadaviladascores.Activities.Tab2Apartamentos;
import com.example.pousadaviladascores.Activities.Tab3ItensDeApartamentos;
/**
* A [FragmentPagerAdapter] that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private static int tab_count;
public SectionsPagerAdapter(FragmentManager fm, int tab_count) {
super(fm);
//mContext = context;
this.tab_count = tab_count;
}
#Override
public Fragment getItem(int position) {
switch (position)
{
case 0:
Tab1Pagina_Inicial tab1 = new Tab1Pagina_Inicial();
return tab1;
case 1:
Tab2Apartamentos tab2 = new Tab2Apartamentos();
return tab2;
case 2:
Tab3ItensDeApartamentos tab3 = new Tab3ItensDeApartamentos();
return tab3;
default:
return null;
}
}
#Override
public int getCount()
{
return tab_count;
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
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/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<TextView
android:id="#+id/textViewAppName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="20dp"
android:paddingTop="5dp"
android:paddingRight="20dp"
android:text="#string/pousada_name"
android:textSize="24sp" />
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="34dp"
android:theme="?attr/actionBarTheme"
app:layout_scrollFlags="scroll|enterAlways" />
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed">
<com.google.android.material.tabs.TabItem
android:id="#+id/tab1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/tab_text_1" />
<com.google.android.material.tabs.TabItem
android:id="#+id/tab2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/tab_text_2" />
<com.google.android.material.tabs.TabItem
android:id="#+id/tab3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/tab_text_3" />
</com.google.android.material.tabs.TabLayout>
</com.google.android.material.appbar.AppBarLayout>
<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.coordinatorlayout.widget.CoordinatorLayout>
Tab layout (again, all the same except for the text):
<?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:orientation="vertical">
<TextView
android:id="#+id/textTab"
android:layout_width="369dp"
android:layout_height="54dp"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_marginStart="27dp"
android:layout_marginLeft="27dp"
android:layout_marginTop="0dp"
android:layout_marginEnd="15dp"
android:text="#string/tab_text_1"
android:textSize="30sp"
android:layout_alignParentRight="true"
android:layout_marginRight="15dp" />
</RelativeLayout>
colors.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#008577</color>
<color name="colorPrimaryDark">#00574B</color>
<color name="colorAccent">#D81B60</color>
</resources>
styles.xml:
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
</resources>
To better illustrate what I mean, here's the design of activity_main and how it's supposed to look:
Here's what's actually happening:
The text for each page shows up fine, but not the titles. :/
There are 2 issues.
The method tabLayout.setupWithViewPager() removes all tabs and then adds tabs from the adapted using: addTab(newTab().setText(pagerAdapter.getPageTitle(i)), false);
You have to override in your adapter the method getPageTitle to obtain the title string. The default value is null. Something like:
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "....";
case 1:
return "....";
....
}
return null;
}
Also to use the com.google.android.material.tabs.TabLayout you have to use a Material Components Theme in your app. You are using an AppCompat theme.
You can:
switch to a Material Components theme (suggested and required in the next releases)
add app:tabTextColor attribute:
<com.google.android.material.tabs.TabLayout
app:tabTextColor="#color/mySelector"
.../>
define the style:
<com.google.android.material.tabs.TabLayout
style="#style/Widget.MaterialComponents.TabLayout"
The default style used by the TabLayout in a Material Component theme is Widget.MaterialComponents.TabLayout while in an AppCompat is Widget.Design.TabLayout
There are some difference, in your case it is the issue:
<style name="Widget.Design.TabLayout" >
<item name="tabIndicatorColor">?attr/colorAccent</item>
<item name="tabTextColor">#null</item>
Activity main
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
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/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<TextView
android:id="#+id/textViewAppName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="20dp"
android:paddingTop="5dp"
android:paddingRight="20dp"
android:text="#string/pousada_name"
android:textSize="24sp" />
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="34dp"
android:theme="?attr/actionBarTheme"
app:layout_scrollFlags="scroll|enterAlways" />
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="fill"/>
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Your main activity
public class MainActivity extends AppCompatActivity {
SqlAccess sqlAccess;
//Declaring TabLayout and ViewPager
TabLayout tabLayout;
ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
setContentView(R.layout.activity_main);
sqlAccess = new SqlAccess(this);
viewPager = (ViewPager) findViewById(R.id.view_pager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
tabLayout.setupWithViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager) {
SectionsPagerAdapter adapter = new SectionsPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new Tab1Pagina_Inicial(), "ONE");
adapter.addFragment(new Tab2Apartamentos(), "TWO");
adapter.addFragment(new Tab3ItensDeApartamentos(), "THREE");
viewPager.setAdapter(adapter);
}
#Override
protected void onDestroy() {
sqlAccess.getDbHelper().close();
super.onDestroy();
}
}
And replace your section pager adapter with this
class SectionPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public SectionPagerAdapter(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);
}
}
in activity_main.xml, remove android:theme="#style/AppTheme.AppBarOverlay from appbarlayout(). i think text color problem. it is the same color as appbar. so it is not showing. if you change your theme probably your text will be appeared.
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>
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.
}
}
I'm trying to create a navigation drawer with swipe tab. But my viewpager is not working fine. I can only select the tab. Viewpager can not load any fragment. so I can not swipe it. If i change the height of the viewpager it hides the tab and load all the fragment.
Activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<include
android:id="#+id/app_bar"
layout="#layout/app_bar" />
<android.support.v4.widget.DrawerLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/drawer_layout">
<FrameLayout
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<android.support.design.widget.TabLayout
android:id="#+id/sliding_tab"
style="#style/MyCustomTabLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
app:tabMode="scrollable" />
<android.support.v4.view.ViewPager
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#android:color/white" />
</FrameLayout>
<fragment
android:id="#+id/nav_drawer"
android:name="com.example.usaukglu.tablayoyt.NavigationDrawer"
android:layout_width="#dimen/drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
app:layout="#layout/navigation_drawer"
tools:layout="#layout/navigation_drawer" />
</android.support.v4.widget.DrawerLayout>
</LinearLayout>
Here is my MainActivity.java Code:
package com.example.usaukglu.tablayoyt;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.widget.LinearLayout;
public class MainActivity extends AppCompatActivity {
private Toolbar toolbar;
NavigationDrawer navigationDrawer;
DrawerLayout drawerLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_appbar);
ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);
TabLayout tabLayout= (TabLayout) findViewById(R.id.sliding_tab);
toolbar= (Toolbar) findViewById(R.id.app_bar);
drawerLayout= (DrawerLayout) findViewById(R.id.drawer_layout);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
viewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager(),MainActivity.this));
tabLayout.setupWithViewPager(viewPager);
navigationDrawer= (NavigationDrawer) getSupportFragmentManager().findFragmentById(R.id.nav_drawer);
navigationDrawer.setUp(R.id.nav_drawer,drawerLayout,toolbar);
}
}
Here is my ViewpagerAdapter.java code
package com.example.usaukglu.tablayoyt;
import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
class ViewPagerAdapter extends FragmentPagerAdapter {
final int PAGE_COUNT = 3;
private String tabTitles[] = new String[] { "Tab1", "Tab2", "Tab3" };
private Context context;
public ViewPagerAdapter(FragmentManager fm, Context context) {
super(fm);
this.context = context;
}
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public Fragment getItem(int position) {
Fragment fragment=null;
if (position==0){
fragment=new FragmentPage();
}
if (position==1){
fragment=new FragmentExpense();
}
if (position==2){
fragment=new FragmentIncome();
}
return fragment;
}
#Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
return tabTitles[position];
}
}
You shouldn't use FrameLayout as container for the tab + pager. FrameLayout is used mostly to put views above others. To fix it you should change this FrameLayout to LinearLayout with vertical orientation. Also the view page height should be match_parent.
the title not appear in the PagerTabStrip after i set it from the adapter
this is my activity
public class MainActivity extends AppCompatActivity {
private ViewPager pager ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(new PagerAdapter(getSupportFragmentManager(),this));
}
}
this is my layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.PagerTabStrip
android:id="#+id/titlepage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="top"
/>
</android.support.v4.view.ViewPager>
and this is the adapter
public class PagerAdapter extends FragmentPagerAdapter {
public PagerAdapter(FragmentManager fm , Context ctxt) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return MyFragment.newInstance(position);
}
#Override
public int getCount() {
return 10;
}
#Override
public String getPageTitle(int position) {
return "title" + position ;
}
and this is the theme used in application :-
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
the result :-
enter image description here
as u see in above picture there is no title appear in viewpager even i set the title in getPageTitle method , can someone tell me what is the error that prevent me to add the title in viewpager ?
Use this in your layout
<android.support.design.widget.AppBarLayout
android:id="#+id/Parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="60dp">
<android.support.v7.widget.Toolbar
android:id="#+id/my_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar" />
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.design.widget.AppBarLayout>
Its my code, you can customize it according to your convenience.
PagerTabStrip gets ignored by Google a lot. You may wish to consider switching to some other ViewPager tab indicator.
If your compileSdkVersion is 23, make sure that you are using the latest version of the v23 Android support libraries. Right now, that is 23.4.0. So, for example, you might have a dependency on support-v4:23.4.0. The problem that you are seeing was fixed.
If your compileSdkVersion is 24, keep an eye on this issue, as there seems to be a new bug.
for this project, I have tabs that have to display something under them and i'm using view pager but for some reason, the fragment layout isn't showing up on screen. I get a blank screen but there is no error or anything. I have been googling and searching for hours now and even started a new project just to make sure it was not a build error but still no luck in finding a solution to my problem.
I have done examples like this many times and used the exact same steps but for some reason, it just isn't working this time. Any help would be greatly appreciated
Here is my mainActivity class
public class MainActivity extends ActionBarActivity {
Toolbar toolbar;
ViewPager myViewPager;
SlidingTabLayout mySlidingTabs;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
myViewPager = (ViewPager) findViewById(R.id.viewPager);
myViewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager(), this));
mySlidingTabs = (SlidingTabLayout) findViewById(R.id.sliding_tabs);
mySlidingTabs.setViewPager(myViewPager);
}
}
Here is my custom adapter class
public class MyPagerAdapter extends FragmentPagerAdapter {
private Context context;
private String[] tabNames = {"Beverages", "Deli & Bakery", "Fresh Produce", "Health & Beauty", "Meat & Seafood", "Natural Foods", "Pet Care"};
public MyPagerAdapter(FragmentManager fm, Context context) {
super(fm);
this.context = context;
}
#Override
public Fragment getItem(int position) {
if (position == 0) {
return new Beverages();
}
else if (position == 1) {
return new DeliBakery();
}
return null;
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
return tabNames[position];
}
}
Here is my main activty.xml
<?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">
<include
android:id="#+id/toolbar"
layout="#layout/toolbar_layout"
android:layout_height="wrap_content"
android:layout_width="match_parent" />
<!-- The Sliding tab -->
<bello.myapplication.SlidingTabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/sliding_tabs"/>
<!-- The pager that allows us to swipe between fragments -->
<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>
and here is one of my tab's xml file
<?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">
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tab fragment 1"
android:textSize="50dp"
android:padding="5dp" />
</RelativeLayout>
Here is one of my fragment classes
public class Beverages extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.beverages_tab, container, false);
return view;
}
}
When something strange like this happens, try to use Log.i("title", "message") to track if every class/methods are being called.
In your case, it seens that your viewpager isn't in the screen.
If I understood your code, your <include> tag is including the second xml code you posted right?
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tab fragment 1"
android:textSize="50dp"
android:padding="5dp" />
</RelativeLayout>
It looks like your layout_height="match_parent" is filling all the space on your screen, giving no space to your ViewPager being inflated by the system, try to change it to layout_height="wrap_content and you should be done.
If not, try to change the background of your ViewPager to check if it is on the screen and is not being hided by something else.
Figured out the problem. The viewpager background color and the background color of the tabs where the same so it made it look like there was a black activity. So for anyone else out there with the same problem, try changing either the text color of your tabs.xml or change the background of your viewpager