I get IndexOutOfBoundsException error when i want selecting the tab in the TabLayout :
This is the initTablayout function , that called in the onCreate method:
//======================================== Init Tablayout and view pager
private void initTabLayout() {
mainActivityViewPager = (ViewPager) findViewById(R.id.view_pager_main_activity);
mainActivityTabLayout = (TabLayout)findViewById(R.id.tab_layout_main_activity);
TabLayout.Tab tab = mainActivityTabLayout.getTabAt(1);
tab.select();
FragmentManager manager = getSupportFragmentManager();
MainActivityPagerAdapter adapter = new MainActivityPagerAdapter(manager);
mainActivityViewPager.setAdapter(adapter);
mainActivityTabLayout.setupWithViewPager(mainActivityViewPager);
mainActivityViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mainActivityTabLayout));
mainActivityTabLayout.setTabsFromPagerAdapter(adapter);
}
I got this error where i choose index of selected tab on the getTabAt(1) method , i have three tab on the PagerAdapter class :
public class MainActivityPagerAdapter extends FragmentStatePagerAdapter {
//============================================ Constructor
public MainActivityPagerAdapter(FragmentManager fm) {
super(fm);
}
//============================================ GetItem Method ()
#Override
public Fragment getItem(int position) {
Fragment frag = null;
switch (position) {
case 0:
frag = new Fragment_one();
break;
case 1:
frag = new Fragment_two();
break;
case 2:
frag = new Fragment_three();
break;
}
return frag;
}
//============================================= GetCount Method ()
#Override
public int getCount() {
return 3;
}
//============================================= GetPageTitle
#Override
public CharSequence getPageTitle(int position) {
String title = "";
switch (position) {
case 0:
title = "اول ";
break;
case 1:
title = "دوم ";
break;
case 2:
title = "سوم ";
break;
}
return title;
}
}
Complete error is :
java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
It seem like you forget to addTab to your mainActivityTabLayout so your TabLayout will have 0 item. Therefore, you got IndexOutOfBoundsException when you access to tab1
mainActivityTabLayout.addTab(tabLayout.newTab().setText("1"));
mainActivityTabLayout.addTab(tabLayout.newTab().setText("2"));
mainActivityTabLayout.addTab(tabLayout.newTab().setText("3"));
Select tab3
Do following :
mainActivityTabLayout.addTab(tabLayout.newTab().setText("3"),true);
Related
Good Afternoon, I have an activity that contains 4 Fragments using tab layout, when I initialize the Activity only two fragments are initialized at a time, for example while I am in the first fragment, Fragment 1 and 2 are initialized, when I slide to 2 it initializes the third and then 2 and 3 are initialized and the first is destroyed, is it possible for everyone to be initialized together?
this is my Adapter:
public class TabManualAdapter extends FragmentStatePagerAdapter {
private String[] tituloTabsManual = {"TAB1","TAB2","TAB3","TAB4"};
public TabManualAdapter(#NonNull FragmentManager fm) {
super(fm);
}
#NonNull
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position){
case 0 :
fragment = new Fragment1();
break;
case 1 :
fragment = new Fragment2();
break;
case 2:
fragment = new Fragment3();
break;
case 3:
fragment = new Fragment4();
break;
}
return fragment;
}
#Override
public int getCount() {
return tituloTabsManual.length;
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return tituloTabsManual[position];
}
}
and Activity Code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manual);
SlidingTabLayout slidingTabLayout = findViewById(R.id.stl_tabs_manual);
viewPager = findViewById(R.id.vp_pagina_manual);
viewPager.setPageTransformer(true,new ZoomOutPageTransformer());
slidingTabLayout.setSelectedIndicatorColors(ContextCompat.getColor(this,R.color.colorPrimary));
slidingTabLayout.setDistributeEvenly(true);
slidingTabLayout.setBackgroundColor( ContextCompat.getColor( this, R.color.black ) );
TabManualAdapter tabManualAdapter = new TabManualAdapter(getSupportFragmentManager());
viewPager.setAdapter(tabManualAdapter);
CircleIndicator indicator = findViewById(R.id.indicator);
indicator.setViewPager(viewPager);
slidingTabLayout.setViewPager(viewPager);
I have an activity with 4 Fragments and in each fragment I have a thread the 4 fragments are started together but I need to slide between them so that each one is visible, what I would like to know is how can I leave only the thread of the fragment that is being viewed and Interrupt the others, when you slide to the other fragments the same thing starts a thread and interrupts the others
Adapter
public TabManualAdapter(#NonNull FragmentManager fm) {
super(fm);
}
#NonNull
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position){
case 0 :
fragment = new Fragment1();
break;
case 1 :
fragment = new Fragment2();
break;
case 2:
fragment = new Fragment3();
break;
case 3:
fragment = new Fragment4();
break;
}
return fragment;
}
#Override
public int getCount() {
return tituloTabsManual.length;
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return tituloTabsManual[position];
}
}
Host Activity :
viewPager.setPageTransformer(true,new ZoomOutPageTransformer());
viewPager.setOffscreenPageLimit(4);
slidingTabLayout.setSelectedIndicatorColors(ContextCompat.getColor(this,R.color.colorPrimary));
slidingTabLayout.setDistributeEvenly(true);
slidingTabLayout.setBackgroundColor( ContextCompat.getColor( this, R.color.black ) );
TabManualAdapter tabManualAdapter = new TabManualAdapter(getSupportFragmentManager());
viewPager.setAdapter(tabManualAdapter);
I Have 4 Fragments in 1 Activity. I need to make sure that on every fragment change the fragment is refreshed because I load JSON Data in every fragment. I use FragmentPager Adapter and RecyclerView to Show Data
This is my Adapter ( SickAdapter.java ) the code :
public class SickAdapter extends FragmentPagerAdapter{
private static final String TAG = SickAdapter.class.getSimpleName();
private static final int FRAGMENT_COUNT = 4;
public SickAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position){
case 0:
return new SickFragmentToAll();
case 1:
return new SickFragmentToPending();
case 2:
return new SickFragmentToApproved();
case 3:
return new SickFragmentToDenied();
}
return null;
}
#Override
public int getCount() {
return FRAGMENT_COUNT;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position){
case 0:
return "All";
case 1:
return "Pending";
case 2:
return "Approved";
case 3:
return "Denied";
}
return null;
}
}
In my Class ( SickClass.java ) I create SickClass and I Call SickAdapter, I explode them, and this is my Code :
public class SickClass extends Fragment {
private static final String TAG = SickClass.class.getSimpleName();
private SickAdapter mAdapter;
private TabLayout tabLayout;
private ViewPager viewPager;
public SickClass() {
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.employee_leave_class, container, false);
tabLayout = (TabLayout)view.findViewById(R.id.tabs);
viewPager = (ViewPager)view.findViewById(R.id.view_pager);
if(mAdapter == null) {
mAdapter = new SickAdapter(getChildFragmentManager());
}
viewPager.setAdapter(new SickAdapter(getChildFragmentManager()));
tabLayout.setupWithViewPager(viewPager);
viewPager.setCurrentItem(1, true);
tabLayout.post(new Runnable() {
#Override
public void run() {
tabLayout.setupWithViewPager(viewPager);
}
});
return view;
}
}
Try below code for reload your fragment;
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.detach(YOUR_FRAGMENT_NAME.this).attach(YOUR_FRAGMENT_NAME.this).commit();
You can use startActivityForResult() to get the result from the activity.
References:
ViewPager PagerAdapter not updating the View
How to refresh a Fragment of a FragmentPagerAdapter?
I'm showing fragments in viewpager, and each fragment contains data connection.
I don't want to do something, before selected fragment is shown.
How can I do?
I mean, I don't want to initiate fragments when the activity calls oncreate.(because there's data connection, and I don't want it)
I just want to initiate each fragment, when fragment is selected.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
viewPager = (ViewPager) findViewById(R.id.view_pager);
List<Fragment> listFragments = new ArrayList<>();
listFragments.add(new Fg_1());
listFragments.add(new Fg_2());
listFragments.add(new Fg_3());
listFragments.add(new Fg_4());
listFragments.add(new Fg_5());
listFragments.add(new Fg_6());
a_pagerAdapter = new A_PagerAdapter(getSupportFragmentManager(), listFragments);
viewPager.setAdapter(a_pagerAdapter);
viewPager.addOnPageChangeListener(this);
}
Instead of creating all of your fragments in your activity onCreate, have your viewPager create them when requested, so for a simple example:
in your implementation of A_PagerAdapter, override getCount() and getItem(int) to be something like:
public class A_PagerAdapter extends FragmentPagerAdapter {
...
private final static int NUM_PAGES = 6;
private final Fragment[] listFragment = new Fragment[NUM_PAGES];
...
public int getCount() {
return NUM_PAGES;
}
...
public Fragment getItem(int index) {
Fragment itemFragment = null;
if (listFragment[index] == null) {
// Hard-coded class factory.. yuck.
switch(index) {
case 0:
itemFragment = new Fg_1();
break;
case 1:
itemFragment = new Fg_2();
break;
case 2:
itemFragment = new Fg_3();
break;
case 3:
itemFragment = new Fg_4();
break;
case 4:
itemFragment = new Fg_5();
break;
case 5:
itemFragment = new Fg_6();
break;
}
// Save this instance in case it is asked for again later..
listFragment[index] = itemFragment;
} else {
// get the fragment we created earlier to avoid re-initializing
itemFragment = listFragment[index];
}
return itemFragment;
}
...
This is a fairly simple/horrible implementation.. in reality it sounds more like you need a caching/lazy loading strategy, possibly triggered in the onResume of the fragments in your view pager..
public class SampleFragmentPagerAdapter extends FragmentPagerAdapter implements ViewPager.OnPageChangeListener {
final int PAGE_COUNT = 5;
private String tabTitles[] = new String[] { "Chats", "Groups", "Contacts","Profile" ,"Settings"};
public SampleFragmentPagerAdapter() {
super(getSupportFragmentManager());
}
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public CharSequence getPageTitle(int position) {
return tabTitles[position];
}
#Override
public Fragment getItem(int position) {
// return PageFragment.create(position + 1);
switch (position) {
case 0:
ChatScreenActivity chatScreenActivity = new ChatScreenActivity();
return chatScreenActivity;
case 1:
GroupChatActivity groupChatActivity = new GroupChatActivity();
return groupChatActivity;
case 2:
ContactsActivity contactsActivity = new ContactsActivity();
return contactsActivity;
case 3:
ProfileActivity profileActivity= new ProfileActivity();
return profileActivity;
case 4:
SettingActivity settingActivity = new SettingActivity();
return settingActivity;
default:
return null;
}
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}*use this code and do setadapter for your viewpager*
}
I have one question, how do I implement icons for tablayout.
I have 3 tabs and for all tabs I have icons selected and unselected. (White-Yellow color).
But, dunno how to implement those.
Here is mine UserActivity class:
public class UserActivity extends AppCompatActivity {
FragmentPagerAdapter adapterViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user);
// Get the ViewPager and set it's PagerAdapter so that it can display items
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
adapterViewPager = new UserFragmentPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapterViewPager);
// Give the TabLayout the ViewPager
TabLayout tabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
tabLayout.setupWithViewPager(viewPager);
tabLayout.setTabTextColors(getResources().getColorStateList(R.color.selector));
}
UserFragmentPageAdapter:
public UserFragmentPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
#Override
public int getCount() {
return NUM_ITEMS;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0: // Fragment # 0 - This will show FirstFragment
return SmallMoveFragment.newInstance(0, "Small Move");
case 1: // Fragment # 0 - This will show FirstFragment different title
return DeliveryFragment.newInstance(1, "Delivery");
case 2: // Fragment # 1 - This will show SecondFragment
return GarbageFragment.newInstance(2, "Garbage");
default:
return null;
}
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0: // Fragment # 0 - This will show FirstFragment
return "Small Move";
case 1: // Fragment # 0 - This will show FirstFragment different title
return "Delivery";
case 2: // Fragment # 1 - This will show SecondFragment
return "Garbage ";
default:
return "No name";
}
}
}
And ONE of 3 tabs:
public class DeliveryFragment extends Fragment {
// Store instance variables
private String title;
private int page;
// newInstance constructor for creating fragment with arguments
public static DeliveryFragment newInstance(int page, String title) {
DeliveryFragment fragmentFirst = new DeliveryFragment();
Bundle args = new Bundle();
args.putInt("someInt", page);
args.putString("someTitle", title);
fragmentFirst.setArguments(args);
return fragmentFirst;
}
// Store instance variables based on arguments passed
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
page = getArguments().getInt("someInt", 0);
title = getArguments().getString("someTitle");
}
// Inflate the view for the fragment based on layout XML
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_delivery, container, false);
TextView tvLabel = (TextView) view.findViewById(R.id.DeliveryTxt);
tvLabel.setText(page + " -- " + title);
return view;
}
}
Any ideas where and how... I would do it with TabHost, but I would like it this way.
I have 6 icon 48x48 in drawable/hdpi.
There's a solution but not very well.
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
int pos = tab.getPosition();
switch (pos) {
case 0 :
tab.setIcon(R.drawable.select_0);
break;
case 1 :
tab.setIcon(R.drawable.select_1);
break;
case 2 :
tab.setIcon(R.drawable.select_2);
break;
}
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
int pos = tab.getPosition();
switch (pos) {
case 0 :
tab.setIcon(R.drawable.unselect_0);
break;
case 1 :
tab.setIcon(R.drawable.unselect_1);
break;
case 2 :
tab.setIcon(R.drawable.unselect_2);
break;
}
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
but this code may be in your User Activity, pagerAdapter doesn't support tab with icon directly.