I am not that experienced in Java so I can't figure it out myself.
I bought a template with a tablayout which looks like this (image 1):
I want to disable the swipe function between these two tabs, so it should only be possible to get to "TAB 2" by clicking on the tab "TAB 2".
There are a lot of tutorials in the Internet but non of them fits to my code so I'm a bit confused.
Here is my TabFragment:
public class TabFragment extends Fragment {
public static TabLayout tabLayout;
public static ViewPager viewPager;
public static int int_items = 2 ;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View x = inflater.inflate(R.layout.tab_layout,null);
tabLayout = (TabLayout) x.findViewById(R.id.tabs);
viewPager = (ViewPager) x.findViewById(R.id.viewpager);
viewPager.setAdapter(new MyAdapter(getChildFragmentManager()));
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
public void onPageScrollStateChanged(int state) {}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
tabLayout.post(new Runnable() {
#Override
public void run() {
tabLayout.setupWithViewPager(viewPager);
}
});
return x;
}
class MyAdapter extends FragmentPagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position)
{
if(position == 0){
return new Tab1();
}
if(position == 1){
return new Tab2();
}
return null;
}
#Override
public int getCount() {
return int_items;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position){
case 0 :
return "Tab 1";
case 1 :
return "Tab 2";
}
return null;
}
}}
and my tab_layout.xml
<?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"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
app:tabGravity="fill"
app:tabMode="fixed"
android:background="#color/material_blue_grey_800"
app:tabIndicatorColor="#color/orange"
app:tabSelectedTextColor="#color/orange"
app:tabTextColor="#color/white"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="50dp">
</android.support.v4.view.ViewPager>
</LinearLayout>
I tried my best to figure out how to solve it but didn't succeed, so I hope one of you can help me with this small problem :)
Thanks a lot.
You need to create a custom ViewPager that intercepts the onTouch events and avoid the default behaviour. This way the user wont be able to swipe between pages but will be able to touch on the tabs.
You can check this link where is already answered: How do disable paging by swiping with finger in ViewPager but still be able to swipe programmatically?
EDIT
I'll explain it by steps:
Create a new class called NonSwipeableViewPager
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.DecelerateInterpolator;
import android.widget.Scroller;
import java.lang.reflect.Field;
public class NonSwipeableViewPager extends ViewPager {
public NonSwipeableViewPager(Context context) {
super(context);
setMyScroller();
}
public NonSwipeableViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
setMyScroller();
}
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
// Never allow swiping to switch between pages
return false;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
// Never allow swiping to switch between pages
return false;
}
//down one is added for smooth scrolling
private void setMyScroller() {
try {
Class<?> viewpager = ViewPager.class;
Field scroller = viewpager.getDeclaredField("mScroller");
scroller.setAccessible(true);
scroller.set(this, new MyScroller(getContext()));
} catch (Exception e) {
e.printStackTrace();
}
}
public class MyScroller extends Scroller {
public MyScroller(Context context) {
super(context, new DecelerateInterpolator());
}
#Override
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
super.startScroll(startX, startY, dx, dy, 350 /*1 secs*/);
}
}
}
Modify your layout to use the new ViewPager
<?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"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
app:tabGravity="fill"
app:tabMode="fixed"
android:background="#color/material_blue_grey_800"
app:tabIndicatorColor="#color/orange"
app:tabSelectedTextColor="#color/orange"
app:tabTextColor="#color/white"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.design.widget.TabLayout>
<NonSwipeableViewPager <!-- You will need to import this correctly with your class package -->
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="50dp">
</NonSwipeableViewPager>
</LinearLayout>
Update your activity with the new ViewPager
public class TabFragment extends Fragment {
public static TabLayout tabLayout;
public static NonSwipeableViewPager viewPager; // This line changed
public static int int_items = 2 ;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View x = inflater.inflate(R.layout.tab_layout,null);
tabLayout = (TabLayout) x.findViewById(R.id.tabs);
viewPager = (NonSwipeableViewPager) x.findViewById(R.id.viewpager); // This line changed
viewPager.setAdapter(new MyAdapter(getChildFragmentManager()));
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
public void onPageScrollStateChanged(int state) {}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
tabLayout.post(new Runnable() {
#Override
public void run() {
tabLayout.setupWithViewPager(viewPager);
}
});
return x;
}
You can keep the same adapter MyAdapter.
This will avoid the swipe between tabs but will keep the click on each one.
I know this is quite old but you need to switch to ViewPager2.
ViewPager2 replaces androidx.viewpager.widget.ViewPager, addressing most of its predecessor’s pain-points, including right-to-left layout support, vertical orientation, modifiable Fragment collections, etc.
If you need to disable user swipe support then you can call:
viewPager2.isUserInputEnabled = false
Related
I am using view pager to show some fragments.
I tried to achieve this by referring this : Android ViewPager - Smooth Transition for this Design
My View pager containing layout:
<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:background="#color/white"
android:orientation="vertical"
android:weightSum="1"
tools:context="com.tpayerapp.Fragments.DepositMoneyFragment">
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_centerInParent="true"
android:clipToPadding="false"
android:layout_above="#+id/indicator"
android:layout_below="#+id/tabs"
android:padding="80dp" />
<me.relex.circleindicator.CircleIndicator
android:id="#+id/indicator"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:layout_centerInParent="false"
app:ci_drawable="#drawable/radius"
app:ci_drawable_unselected="#drawable/grey_radius"
app:ci_height="6dp"
app:ci_width="6dp">
</me.relex.circleindicator.CircleIndicator>
Fragment 1 layout:
<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:layout_marginLeft="40dp"
android:layout_marginRight="40dp"
tools:context="com.tpayerapp.Fragments.PayPalFragment">
<ImageView
android:id="#+id/imageView25"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="false"
android:layout_alignParentRight="false"
android:layout_alignParentTop="false"
android:layout_alignWithParentIfMissing="false"
android:layout_centerHorizontal="false"
android:layout_centerInParent="true"
android:background="#color/colorAccent"
app:srcCompat="#drawable/paypal" />
View pager fragment java code:
public class DepositMoneyFragment extends Fragment {
private ViewPager viewPager;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_deposit_money, container, false);
setUpUI(view);
return view;
}
public void setUpUI(View view) {
viewPager = (ViewPager) view.findViewById(R.id.viewpager);
setupViewPager(viewPager);
CircleIndicator indicator = (CircleIndicator) view.findViewById(R.id.indicator);
indicator.setViewPager(viewPager);
viewPager.setPageTransformer(false, new ViewPager.PageTransformer() {
#Override
public void transformPage(View page, float position) {
int pageWidth = viewPager.getMeasuredWidth() - viewPager.getPaddingLeft() - viewPager.getPaddingRight();
int pageHeight = viewPager.getHeight();
int paddingLeft = viewPager.getPaddingLeft();
float transformPos = (float) (page.getLeft() - (viewPager.getScrollX() + paddingLeft)) / pageWidth;
final float normalizedposition = Math.abs(Math.abs(transformPos) - 1);
page.setAlpha(normalizedposition + 0.5f);
int max = -pageHeight / 10;
if (transformPos < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
page.setTranslationY(0);
} else if (transformPos <= 1) { // [-1,1]
page.setTranslationY(max * (1-Math.abs(transformPos)));
} else { // (1,+Infinity]
// This page is way off-screen to the right.
page.setTranslationY(0);
}
}
});
}
#Override
public void onResume() {
super.onResume();
((OnFragmentTitleChangeListener) getActivity()).onFragmentTitle(getResources().getString(R.string.deposite));
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager());
adapter.addFragment(new PayPalFragment(), "");
adapter.addFragment(new PayStackFragment(), "");
adapter.addFragment(new NIBBSFragment(), "");
viewPager.setAdapter(adapter);
}
}
What needs to be done to get this design? Please help. Thank you..
Try Change margin to padding
<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:paddingLeft="40dp"
android:paddingRight="40dp"
tools:context="com.tpayerapp.Fragments.PayPalFragment">
<ImageView
android:id="#+id/imageView25"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="false"
android:layout_alignParentRight="false"
android:layout_alignParentTop="false"
android:layout_alignWithParentIfMissing="false"
android:layout_centerHorizontal="false"
android:layout_centerInParent="true"
android:background="#color/colorAccent"
app:srcCompat="#drawable/paypal" />
try this link carousel layout with viewpager, if you need more code related to this view, this are main classes you need.
CarouselLinearLayout.java
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.LinearLayout;
public class CarouselLinearLayout extends LinearLayout {
private float scale = CarouselPagerAdapter.BIG_SCALE;
public CarouselLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CarouselLinearLayout(Context context) {
super(context);
}
public void setScaleBoth(float scale) {
this.scale = scale;
this.invalidate();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// The main mechanism to display scale animation, you can customize it as your needs
int w = this.getWidth();
int h = this.getHeight();
canvas.scale(scale, scale, w/2, h/2);
}
}
CarouselPagerAdapter.java
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
public class CarouselPagerAdapter extends FragmentPagerAdapter implements
ViewPager.OnPageChangeListener {
public final static float BIG_SCALE = 1.0f;
public final static float SMALL_SCALE = 0.7f;
public final static float DIFF_SCALE = BIG_SCALE - SMALL_SCALE;
private MainActivity context;
private FragmentManager fragmentManager;
private float scale;
public CarouselPagerAdapter(MainActivity context, FragmentManager fm) {
super(fm);
this.fragmentManager = fm;
this.context = context;
}
#Override
public Fragment getItem(int position) {
// make the first pager bigger than others
try {
if (position == MainActivity.FIRST_PAGE)
scale = BIG_SCALE;
else
scale = SMALL_SCALE;
position = position % MainActivity.count;
} catch (Exception e) {
e.printStackTrace();
}
return ItemFragment.newInstance(context, position, scale);
}
#Override
public int getCount() {
int count = 0;
try {
count = MainActivity.count * MainActivity.LOOPS;
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return count;
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
try {
if (positionOffset >= 0f && positionOffset <= 1f) {
CarouselLinearLayout cur = getRootView(position);
CarouselLinearLayout next = getRootView(position + 1);
cur.setScaleBoth(BIG_SCALE - DIFF_SCALE * positionOffset);
next.setScaleBoth(SMALL_SCALE + DIFF_SCALE * positionOffset);
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
#SuppressWarnings("ConstantConditions")
private CarouselLinearLayout getRootView(int position) {
return (CarouselLinearLayout) fragmentManager.findFragmentByTag(this.getFragmentTag(position))
.getView().findViewById(R.id.root_container);
}
private String getFragmentTag(int position) {
return "android:switcher:" + context.pager.getId() + ":" + position;
}
}
I see you have hard coded the viewPager height to android:layout_height="200dp". Can you try using android:layout_height="match_parent" instead?
EDIT: I have tried to find textView under bad View.
I have activity with tabView which contains two tabs. For each tab i want to have different layout. How can i initiate my element from each view? I´m trying to do that from my activity but when i´m searching for my element it returns null. Here is my code with only one tab.
My activity.
public class MyTariffListActivity extends AppCompatActivity {
TextView tariffName;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tab_view_layout);
tariffName = (TextView) findViewById(R.id.tariffName);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.addTab(tabLayout.newTab().setText("Basic Info"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
final PageAdapterTariff adapter = new PageAdapterTariff
(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
Tariff tariff = getIntent().getParcelableExtra(MyCommonListActivity.TARIFF);
tariffName.setText(tariff.getName()); // HERE tariffName is null
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#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) {
}
});
}
}
My pageAdapter
public class PageAdapterTariff extends FragmentStatePagerAdapter {
int mNumOfTabs;
public PageAdapterTariff(FragmentManager fm, int NumOfTabs) {
super(fm);
this.mNumOfTabs = NumOfTabs;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
TariffInfoTab tariffInfoTab = new TariffInfoTab();
return tariffInfoTab;
default:
return null;
}
}
#Override
public int getCount() {
return mNumOfTabs;
}
}
My tab definition:
public class TariffInfoTab extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.activity_my_show_tariff, container, false);
}
}
My activity_my_show_tariff layout:
<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" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivity">
<TextView
android:id="#+id/tariffName"
android:gravity="center"
android:layout_span="3"
android:padding="3dip" />
</RelativeLayout>
Refer this. It will help you.
android-material-design-working-with-tabs
I'm trying to let my ViewPager to show my Fragments, however, it doesn't seem to do the work. All it does is just not showing anything, not even a height. Can someone tell me what step am I missing? thanks
main_activity.xml:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorBackground">
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/bottomNavigation" />
<com.aurelhubert.ahbottomnavigation.AHBottomNavigation
android:id="#+id/bottomNavigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom" />
</android.support.design.widget.CoordinatorLayout>
MainActivity.java:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
AHBottomNavigation bottomNavigation;
ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bottomNavigation = (AHBottomNavigation) findViewById(R.id.bottomNavigation);
viewPager = (ViewPager) findViewById(R.id.viewpager);
ViewPagerAdapter pagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
// Buttom Navigation
// Add items
AHBottomNavigationItem item1 = new AHBottomNavigationItem("Rooms", R.drawable.ic_chatboxes);
AHBottomNavigationItem item2 = new AHBottomNavigationItem("User", R.drawable.ic_contact_outline);
bottomNavigation.addItem(item1);
bottomNavigation.addItem(item2);
// Customize Buttom Navigation
bottomNavigation.setTitleState(AHBottomNavigation.TitleState.ALWAYS_SHOW);
// Set colors
bottomNavigation.setAccentColor(ContextCompat.getColor(this, R.color.colorAccent));
bottomNavigation.setInactiveColor(ContextCompat.getColor(this, R.color.colorTabDefault));
// Set background color
bottomNavigation.setDefaultBackgroundColor(ContextCompat.getColor(this, R.color.colorBackground));
bottomNavigation.setTranslucentNavigationEnabled(true);
// Viewpager setup
pagerAdapter.addFragment(new Rooms(), "Rooms");
pagerAdapter.addFragment(new User(), "User");
viewPager.setAdapter(pagerAdapter);
viewPager.setCurrentItem(bottomNavigation.getCurrentItem());
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
bottomNavigation.setCurrentItem(position);
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
bottomNavigation.setOnTabSelectedListener(new AHBottomNavigation.OnTabSelectedListener() {
#Override
public boolean onTabSelected(int position, boolean wasSelected) {
viewPager.setCurrentItem(position, true);
return true;
}
});
}
ViewPagerAdapter.java:
public class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
private Fragment currentItem;
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);
}
#Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
if (getCurrentItem() != object) {
currentItem = ((Fragment) object);
}
super.setPrimaryItem(container, position, object);
}
public Fragment getCurrentItem() {
return currentItem;
}
}
I'm starting with some Design support Library resources, specifically the TabLayout.
It's a simple snippet, but I'm not able to populate my TabLayout, the Fragments are sliding normally but my TabLayout is not getting populatad with the Titles as we can see in the attached picture.
I'm not sure if I should wrap ViewPager inside a fragment together with the TabLayout, it just make sense to me.
Follow, thanks.
http://postimg.org/image/x1z6zvlqd/
Main fragment Xml
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="#+id/tab_sliding_tabs_about"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable"
android:background="#color/yellow"
/>
<android.support.v4.view.ViewPager
android:id="#+id/vp_about_fragment_content"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
android:background="#android:color/white" />
</LinearLayout>
Main fragment java
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_about, container, false);
ViewPager viewPager = (ViewPager) rootView.findViewById(R.id.vp_about_fragment_content);
mAdapter = new AboutPageAdapter(getFragmentManager(),
getContext());
viewPager.setAdapter(mAdapter);
TabLayout tabLayout = (TabLayout) rootView.findViewById(R.id.tab_sliding_tabs_about);
tabLayout.setupWithViewPager(viewPager);
mAdapter.notifyDataSetChanged();
return rootView;
}
Page Adapter java
public class AboutPageAdapter extends FragmentPagerAdapter {
final int PAGE_COUNT = 2;
private String tabTitles[] = new String[]{"Tab A", "Tab B"};
private Context context;
public AboutPageAdapter(FragmentManager fm, Context context) {
super(fm);
this.context = context;
}
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return FragA.newInstance(position);
default:
return FragB.newInstance(position);
}
}
#Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
return tabTitles[position];
}
}
Thanks for all your tips, I was able to make it work with:
mViewPager.setAdapter(adapter);
mTabLayout.post(new Runnable() {
#Override
public void run() {
mTabLayout.setupWithViewPager(mViewPager);
}
});
"Official" Workaround:
https://code.google.com/p/android/issues/detail?id=180462#c17
if (ViewCompat.isLaidOut(tabLayout)) {
tabLayout.setupWithViewPager(viewPager);
} else {
tabLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
#Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
tabLayout.setupWithViewPager(viewPager);
tabLayout.removeOnLayoutChangeListener(this);
}
});
}
I have problems with implementation of my custom PagerAdapter and using it with a ViewPager.
This sample PagerAdapter has 10 items, every item is a button with it's index as text.
When I run my program, I see a button with text '1' insted of '0'. And when I swipe to other items I get only blank views. When I swipe backwards sometimes I see a button with some number, but it disappears (maybe it is destroying and I remove it from the container), and sometimes I see a button with a number, but the number changes after the swipe (I think I create a new Button and I add it to the container, and for some reasons the viewpager shows this new button).
How can I fix this implementation? I haven't seen difference in examples.
My PagerAdapter implementation:
public class MyPagerAdapter extends PagerAdapter {
#Override
public int getCount() {
return 10;
}
#Override
public boolean isViewFromObject(View view, Object o) {
return o.getClass()==view.getClass();
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
Button button = new Button(container.getContext());
ViewGroup.LayoutParams params = new ActionBar.LayoutParams(-1,-1);
button.setLayoutParams(params);
button.setText(String.valueOf(position));
container.addView(button);
return button;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((Button)object);
}
}
And my Activity:
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(new MyPagerAdapter());
}
}
Here is complete code:
xml layout:
<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"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.example.androidviewpagerapp.MainActivity" >
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
MyPagerAdapter class:
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;
public class MyPagerAdapter extends PagerAdapter {
#Override
public int getCount() {
return 10;
}
#Override
public boolean isViewFromObject(View view, Object o) {
return o==view;
}
#Override
public Object instantiateItem(final ViewGroup container, int position) {
Button button = new Button(container.getContext());
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
button.setLayoutParams(params);
button.setText(String.valueOf(position));
final int page = position;
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(container.getContext(), "You clicked: " + page + ". page.", Toast.LENGTH_SHORT).show();
}
});
container.addView(button);
return button;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((Button)object);
}
}
MainActivity:
import android.support.v4.view.ViewPager;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
ViewPager viewPager;
MyPagerAdapter myPagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager)findViewById(R.id.pager);
myPagerAdapter = new MyPagerAdapter();
viewPager.setAdapter(myPagerAdapter);
}
}
You will see that Buttons are full screen. To avoid that you need to create some layout (like LinearLayout) and add button to that layout.
Example:
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;
public class MyPagerAdapter extends PagerAdapter {
#Override
public int getCount() {
return 10;
}
#Override
public boolean isViewFromObject(View view, Object o) {
return o==view;
}
#Override
public Object instantiateItem(final ViewGroup container, int position) {
Button button = new Button(container.getContext());
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
button.setLayoutParams(params);
button.setText(String.valueOf(position));
LinearLayout layout = new LinearLayout(container.getContext());
layout.setOrientation(LinearLayout.VERTICAL);
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
//add buton to layout
layout.addView(button);
final int page = position;
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(container.getContext(), "You clicked: " + page + ". page.", Toast.LENGTH_SHORT).show();
}
});
//to container add layout instead of button
container.addView(layout);
//return layout instead of button
return layout;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
//cast to LinearLayout
container.removeView((LinearLayout)object);
}
}
if you want to inflate views in pager you must have to implement two methods.
instantiateItem and destroyItem
public class DialogPagerAdapter extends PagerAdapter {
private Context mContext;
//view inflating..
#Override
public Object instantiateItem(ViewGroup collection, int position) {
LayoutInflater inflater = LayoutInflater.from(mContext);
ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.account_dialog_signin_viewpagers,
collection, false);
TextView tvLabel = (TextView) layout.findViewById(R.id.textView);
switch (position) {
case 0:
tvLabel.setText("Log In");
tvLabel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
break;
case 1:
tvLabel.setText("Sign Up");
tvLabel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
break;
case 2:
tvLabel.setText("Send Reset Link");
tvLabel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//onOptionClickForgot.OnOptionClick();
}
});
break;
}
collection.addView(layout);
return layout;
}
#Override
public void destroyItem(ViewGroup collection, int position, Object view) {
collection.removeView((View) view);
}
#Override
public int getCount() {
return 3;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
}
Simply call it like
viewPager.setAdapter(new DialogPagerAdapter);
xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="#dimen/dialog_button_height"
android:paddingLeft="#dimen/dimen_2"
android:paddingRight="#dimen/dimen_2"
android:minHeight="#dimen/dialog_button_height">
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:gravity="center"
android:text="#string/app_name"
android:textColor="#color/white"
android:textSize="#dimen/text_size_medium" />
</RelativeLayout>
Here i post ViewPagerAdapter that attached between TabLayout to ViewPager
public class ViewPagerAdapter extends FragmentPagerAdapter {
ArrayList<String> titleList = new ArrayList<>();
List<Fragment> fragment = new ArrayList<>();
public void addFragment(String title, Fragment fragment) {
this.titleList.add(title);
this.fragment.add(fragment);
}
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#NonNull
#Override
public Fragment getItem(int position) {
return fragment.get(position);
}
#Override
public int getCount() {
return titleList.size();
}
public CharSequence getPageTitle(int position) {
return titleList.get(position);
}
}
How to use ViewPagerAdapter.
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment("TAB 1", new YOUR_FRAGMENT1());
adapter.addFragment("TAB 2", new YOUR_FRAGMENT2());
// Keep adding fragments.
viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager);