How to implement tabview in one of the fragment of bottombar? - android-layout

I want this type of design ::
Here Is My design
My mainactivity.xml only contain a frameLayout which is Replaced by Selected Fragment from bottombar menu item.
It's code is here:
b = BottomBar.attach(this,savedInstanceState);
b.setItemsFromMenu(R.xml.menu_main, new OnMenuTabClickListener() {
#Override
public void onMenuTabSelected(#IdRes int menuItemId) {
if(menuItemId == R.id.BottomBarItemOne){
PeopleFragment p = new PeopleFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.frame,p).commit();
}
else if(menuItemId == R.id.BottomBarItemTwo){
LocationFragment l = new LocationFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.frame,l).commit();
}
else if(menuItemId == R.id.BottomBarItemThree){
HistoryFragment h = new HistoryFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.frame,h).commit();
}
else if(menuItemId == R.id.BottomBarItemFour){
LikesFragment li = new LikesFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.frame,li).commit();
}
}
Now I want to create a tabview in on one of the Fragment :
For that I implement toolbar,tablayout and viewpager in required fragment xml file.
I created a separate java file contain viewPagerAdapter class.
public class viewPagerAdapter extends FragmentPagerAdapter {
ArrayList<Fragment> fragments = new ArrayList<>(); // this line can cause crashes
ArrayList<String> tabTitles = new ArrayList<>();
public void addFragment(Fragment fragment,String tabTitle){
fragments.add(fragment); // this line can cause crashes
tabTitles.add(tabTitle);
}
public viewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return fragments.get(position);
}
#Override
public int getCount() {
return fragments.size();
}
#Override
public CharSequence getPageTitle(int position) {
return tabTitles.get(position);
}
}
Now I want to add this code to implement tablayout ::
toolbar = (Toolbar) findViewById(R.id.toolBar);
setSupportActionBar(toolbar);
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
viewPager = (ViewPager) findViewById(R.id.viewPager);
viewPagerAdapter = new viewPagerAdapter(getSupportFragmentManager());
viewPagerAdapter.addFragment(new HomeFragment(),"Home"); // this line can cause crashes
viewPagerAdapter.addFragment(new MessageFragment(),"Message"); // this line can cause crashes
viewPagerAdapter.addFragment(new ContectFragment(),"Contect"); // this line can cause crashes
viewPager.setAdapter(viewPagerAdapter);
tabLayout.setupWithViewPager(viewPager);
In Fragment's onCreate method Given below ::
public class HomeFragment extends Fragment {
public HomeFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TabLyout Code Here
return inflater.inflate(R.layout.fragment_home, container, false);
}
}
But Android Studio doesn't allow Tablayout Fragment code in Fragment.
What Can I do ?
How can I implement tablayout in one of the fragment?

Try the following approach :
Add this to your fragment layout as per your requirement.
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="50dp"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:tabIndicatorColor="#color/tab_indicator"
app:tabIndicatorHeight="2.5dp"
app:tabPaddingBottom="-1dp"
app:tabPaddingEnd="-1dp"
app:tabPaddingStart="-1dp"
app:tabPaddingTop="-1dp"
app:tabBackground="#color/white"/>
Create one model for your tabs which you want to show.
Now add the following code in your fragment:
this.navigationData = new ArrayList<>();
this.navigationData.add(new MainNavigationViewModel("TAB-1", R.drawable.TAB-1, R.drawable.TAB-1, true));
this.navigationData.add(new MainNavigationViewModel("TAB-2", R.drawable.TAB-2, R.drawable.TAB-2, false));
this.navigationData.add(new MainNavigationViewModel("TAB-3", R.drawable.TAB-3, R.drawable.TAB-23, false));
for (MainNavigationViewModel vm : this.navigationData) {
tabLayout.addTab(tabLayout.newTab().setCustomView(ViewHelper.buildTabWithText(getContext(), vm.getText(), vm.getIsSelected())));
}
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
adapter = new MainFragmentPagerAdapter(getChildFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
Now create FragmentPagerAdapter (New class) like this.
public class MainFragmentPagerAdapter extends FragmentPagerAdapter {
private interface FragmentFactory {
Fragment create();
}
private static final FragmentFactory[] fragments = new FragmentFactory[] {
() -> LiveFeedFragment.getInstance(),
() -> GroupsFragment.getInstance(),
() -> NewsFragment.getInstance()
};
public MainFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
#Override
public Fragment getItem(int position) {
return fragments[position].create();
}
#Override
public int getCount() {
return fragments.length;
}
}
And access the fragment like this way.

Related

How to change text title in viewpager to image [duplicate]

I am using design support to create tabs. I am also using ViewPager for swipable tabs.
Now, I don't know how to use only icons instead of texts in tabs. I tried finding out but didn't get any success.
My code:
Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.pager);
setupViewPager(viewPager);
setupTablayout();
}
private void setupTablayout() {
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setupWithViewPager(viewPager);
}
class MyPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public MyPagerAdapter(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) {
mFragmentTitleList.get(position)
}
}
private void setupViewPager(ViewPager viewPager) {
MyPagerAdapter adapter = new MyPagerAdapter(getSupportFragmentManager());
adapter.addFrag(new frag(), "CAT");
adapter.addFrag(new frag(), "DOG");
adapter.addFrag(new frag(), "BIRD");
viewPager.setAdapter(adapter);
}
One approach is setting the icons after TabLayout.setupWithViewPager() method.
mTabLayout.setupWithViewPager(mViewPager);
for (int i = 0; i < mTabLayout.getTabCount(); i++) {
mTabLayout.getTabAt(i).setIcon(R.drawable.your_icon);
}
The tutorial shown in the following link should cover what you want. https://github.com/codepath/android_guides/wiki/Google-Play-Style-Tabs-using-TabLayout#add-icons-to-tablayout
I copied the relevant section below.
Add Icons to TabLayout
Currently, the TabLayout class does not provide a clean abstraction model that allows for icons in your tab. There are many posted workarounds, one of which is to return a SpannableString, containing your icon in an ImageSpan, from your PagerAdapter's getPageTitle(position) method as shown in the code snippet below:
private int[] imageResId = {
R.drawable.ic_one,
R.drawable.ic_two,
R.drawable.ic_three
};
// ...
#Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
// return tabTitles[position];
Drawable image = context.getResources().getDrawable(imageResId[position]);
image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
SpannableString sb = new SpannableString(" ");
ImageSpan imageSpan = new ImageSpan(image, ImageSpan.ALIGN_BOTTOM);
sb.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return sb;
}
By default, the tab created by TabLayout sets the textAllCaps property to be true, which prevents ImageSpans from being rendered. You can override this behavior by changing the tabTextAppearance property.
<style name="MyCustomTabLayout" parent="Widget.Design.TabLayout">
<item name="tabTextAppearance">#style/MyCustomTextAppearance</item>
</style>
<style name="MyCustomTextAppearance" parent="TextAppearance.Design.Tab">
<item name="textAllCaps">false</item>
</style>
In new version of TabLayout, google added TabItem which easily can add Icon through your XML with following code:
<android.support.design.widget.TabLayout
app:tabTextColor="#color/gray"
app:tabMode="fixed"
app:tabBackground="#color/red"
app:tabIndicatorHeight="4dp"
app:tabIndicatorColor="#color/purple"
app:tabPadding="2dp"
app:tabSelectedTextColor="#color/white"
app:tabMinWidth="64dp"
android:layout_height="wrap_content"
android:layout_width="match_parent">
<!--add height and width to TabItem -->
<android.support.design.widget.TabItem
android:text="#string/tab_text"/>
<android.support.design.widget.TabItem
android:icon="#drawable/ic_android"/>
</android.support.design.widget.TabLayout>
See more here.
try this
public class GlobalActivity extends AppCompatActivity {
Toolbar toolbar;
ViewPager viewPager;
TabLayout tabLayout;
ViewPagerAdapter adapter;
private int[] tabIcons = {
R.drawable.home_ic,
R.drawable.biz_ic,
R.drawable.network_ic,
R.drawable.offers_ic,
R.drawable.message_ic_b
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_global_hub);
tab();
}
public void tab(){
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tablayout);
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]);
}
public void setupViewPager(ViewPager viewPager){
adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFrag(new GlHubFragment(),"HOME");
adapter.addFrag(new BizForumFragment(), "BIZ FORUM");
adapter.addFrag(new NetworkFragment(), "NETWORK");
adapter.addFrag(new MessagesFragment(), "MESSAGEs");
adapter.addFrag(new OfferFragmentActivity(), "OFFER");
viewPager.setAdapter(adapter);
}
public class ViewPagerAdapter extends FragmentPagerAdapter{
private final List<Fragment> mfragmentlist =new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#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 mFragmentTitleList.get(position);
}
}
}
In TabLayout, setting icon is easy:
getPageTitle(position) should return null (if you don't want title to show).
Next :
tabLayout.getTabAt(0).setIcon(resId);
tabLayout.getTabAt(1).setIcon(resId);
......
None of these methods are elegant when using TabLayout as the ViewPager "decor" scenario. TabLayout Documentation Here is a simple extension of TabLayout and PagerAdapter that provides a simple drop in replacement for TabLayout that should be able to be used in either scenario without manually adding icons outside of the TabLayout class and following the usage of PagerAdapter to get the tab information.
/**
* Created by JDL on 1/18/2017.
*/
public class TabLayoutExt extends TabLayout {
protected ViewPager mViewPager;
public abstract static class TabLayoutViewPagerAdapter extends PagerAdapter {
public TabLayoutViewPagerAdapter() {
}
/**
* This method may be called by the TabLayout to obtain an icon drawable
* to for the specified tab. This method may return null
* indicating no tab icon for this page. The default implementation returns
* null.
*
* #param position The position of the title requested
* #return A drawable icon for the requested page
*/
public Drawable getPageIcon(Context context, int position) {
return null;
}
}
public TabLayoutExt(Context context) {
super(context);
}
public TabLayoutExt(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TabLayoutExt(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onAttachedToWindow() {
//Cover the implicit setup in TabLayout
if (mViewPager == null) {
final ViewParent vp = getParent();
if (vp instanceof ViewPager) {
mViewPager = (ViewPager)vp;
}
}
super.onAttachedToWindow();
}
public void addTab(#NonNull Tab tab, int position, boolean setSelected) {
if (mViewPager != null && mViewPager.getAdapter() instanceof TabLayoutViewPagerAdapter) {
Drawable icon = ((TabLayoutViewPagerAdapter) mViewPager.getAdapter()).getPageIcon(getContext(),position);
tab.setIcon(icon);
}
super.addTab(tab,position,setSelected);
}
#Override
public void setupWithViewPager(#Nullable ViewPager viewPager, boolean autoRefresh) {
mViewPager = viewPager;
super.setupWithViewPager(viewPager, autoRefresh);
}
}
So all that needs be done is extend TabLayoutViewPagerAdapter instead of PageAdapter and implement getPageIcon(Context,int) instead of or in addition to title. The drop in TabLayoutExt in your XML file, instead of the normal TabLayout. This could be extended for further modifying the tab, either with a custom view instead or something else.
With the TabLayout provided by the Material Components Library you can use:
the method setIcon to define the resourceId
the method setTabLabelVisibility to set the TAB_LABEL_VISIBILITY_UNLABELED.
Something like:
for (int i=0;i<tabLayout.getTabCount();i++){
tabLayout.getTabAt(i).setIcon(iconResId);
tabLayout.getTabAt(i).
setTabLabelVisibility(TabLayout.TAB_LABEL_VISIBILITY_UNLABELED);
}
The easiest way I've found to use icons is to use Tablayout.Tab.setIcon(drawable). This also makes it easy to highlight the selected icon. If you want to do this, follow these steps.
Step 1.
Add your images to the res.mipmap folders. (mipmap-mdpi, hdpi etc.) Judging by the other answers here it's also fine to put then in the res.drawable folders.
Step 2.
Call setIcon on all your tabs after setting up your TabLayout and ViewPager. I did this in my AdapterTabs to keep the Activity tidy.
So in your activity do this:
tablayout = (TabLayout) findViewById(R.id.tab_layout);
viewPager = (ViewPager) findViewById(R.id.viewPager);
adapterTabs = new AdapterTabs(this, getSupportFragmentManager(), fragments, tablayout, viewPager);
viewPager.setAdapter(adapterTabs);
tablayout.setupWithViewPager(viewPager);
adapterTabs.setTabIcons();
and in your AdapterTabs, which should extend FragmentPagerAdapter, put your setTabIcons() method.
public void setTabTitlesToIcons() {
Drawable icon1 = context.getResources().getDrawable(R.mipmap.ic_1);
Drawable icon2 = context.getResources().getDrawable(R.mipmap.ic_2);
Drawable icon3 = context.getResources().getDrawable(R.mipmap.ic_3);
Drawable icon1Hilighted = context.getResources().getDrawable(R.mipmap.ic_1_selected);
Drawable icon2Hilighted = context.getResources().getDrawable(R.mipmap.ic_2_selected);
Drawable icon3Hilighted = context.getResources().getDrawable(R.mipmap.ic_3_selected);
icons.add(icon1);
icons.add(icon2);
icons.add(icon3);
iconsHilighted.add(icon1Hilighted);
iconsHilighted.add(icon2Hilighted);
iconsHilighted.add(icon3Hilighted);
for(int i = 0; i < icons.size(); i++) {
if(i == 0) {
//noinspection ConstantConditions
tabLayout.getTabAt(i).setIcon(iconsSelected.get(i));
}
else {
//noinspection ConstantConditions
tabLayout.getTabAt(i).setIcon(icons.get(i));
}
}
}
Make sure to store a reference to the two lists 'icons' and 'iconsHilighted'. You'll need them later. Also store a reference to the TabLayout and the ViewPager which you passed in from the activity.
Step 3.
Make sure AdapterTabs.getPageTitle() returns null.
At this point, if you run it you should see that the first icon is highlighted.
Step 4.
Implement ViewPager.OnPageChangeListener in AdapterTabs and add that listener to your viewPager
public AdapterTabs(Context context, FragmentManager fragmentManager, List<Fragment> fragments, TabLayout tabLayout, ViewPager viewPager) {
super(fragmentManager);
this.context = context;
this.tabLayout = tabLayout;
this.viewPager = viewPager;
this.viewPager.addOnPageChangeListener(this);
tabs.add(fragments.get(0));
tabs.add(fragments.get(1));
tabs.add(fragments.get(2));
}
Step 5.
Update the icons in the tabs in the onPageSelected callback in your AdapterTabs.
#Override
public void onPageSelected(int position) {
for (int i = 0; i < tabs.size(); i++) {
if(i == position) {
//noinspection ConstantConditions
tabLayout.getTabAt(i).setIcon(iconsSelected.get(i));
}
else {
//noinspection ConstantConditions
tabLayout.getTabAt(i).setIcon(icons.get(i));
}
}
}
Now you should see the hilighted icon being updated when you change tabs.
Try this this will definitely work .
private TabLayout tabLayout;
private ViewPager viewPager;
private int[] tabIcons = {
R.drawable.single,
R.drawable.multiple};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contact_picker);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle("Choose contact");
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
tab();
}
public void tab(){
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
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]);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new Login());
adapter.addFragment(new Register());
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = 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) {
mFragmentList.add(fragment);
}
}
As mentioned in the comments, defining the icons in the TabLayout does not work when using a PagerAdapter. For those using Kotlin, one workaround is to create an extension function like this:
fun TabLayout.setupWithViewPagerAndKeepIcons(viewPager : ViewPager?) {
val icons = mutableListOf<Drawable?>()
repeat(tabCount) {
icons.add(getTabAt(it)?.icon)
}
setupWithViewPager(viewPager)
repeat(tabCount) {
getTabAt(it)?.setIcon(icons.get(it))
}
}
Then in the layout.xml add your icons to the TabLayout:
<com.google.android.material.tabs.TabLayout
android:id="#+id/tab_layout">
<com.google.android.material.tabs.TabItem
android:icon="#drawable/your_icon"/>
</com.google.android.material.tabs.TabLayout>
Finally, use the extension function to setup the TabLayout with a ViewPager.
tab_layout.setupWithViewPagerAndKeepIcons(view_pager)
the simplest way is create new table by setting Icon on tablayout. below code will create two tab with icon only. use this code on onCreate() method
tablayout = (TabLayout) findViewById(R.id.order_tablayout);
tablayout.addTab( tablayout.newTab().setIcon(getResources().getDrawable(R.mipmap.ic_shopping_cart_white_24dp)) );
tablayout.addTab( tablayout.newTab().setIcon(getResources().getDrawable(R.mipmap.ic_like2_fille_white_24dp)) );
Using a ViewPager. This is how I have a tab with an icon only and no text.
TabLayout tabs...
TabLayout.Tab tab = tabs.getTabAt(0);
tab.setText("");
tab.setIcon(R.drawable.yourIcon);
This may not be the best answer for all cases, but what I found did not solve my problem yet.
After having a look at Androids implementation of tabLayout.setupWithViewPager(ViewPager pager) I came up with a solution using just listeners.
The layout structure:
| LinearLayout (vertical)
|-- TabLayout (width: match_parent)
|---- TabItem (without text, just icons)
|---- TabItem
|---- ...
|-- ViewPager
Code for the both listeners:
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
pager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
tabLayout.setScrollPosition(position, positionOffset, false);
}
#Override
public void onPageSelected(int position) {
TabLayout.Tab tab = tabLayout.getTabAt(position);
if (tab != null) {
tab.select();
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
Have a look at the tabLayout.setScrollPosition call inside OnPageChangeListener.onPageScrolled for the more or less good moving of the indicator while scrolling.
This may not work if the TabLayout's width is not set to match_parent (or must be scrollable).

NestedScrollView inside fragment not programatically scrolling

I have a tablayout with a viewpager2 and FragmentStateAdapter. I have 3 tabs, each with a NestedScrollView that wraps a Linear Layout:
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:id="#+id/scrollView"
android:focusableInTouchMode="true"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:descendantFocusability="blocksDescendants">
/* ... */
</LinearLayout>
</androidx.core.widget.NestedScrollView>
When I switch between the tabs in the tablayout, the scrollview does not start at the top. In the onViewCreated() method of each Fragment for the viewPager, I added the following lines, however the scrollview still does not scroll to the top, it starts where it was left off.
public static class MyFragment extends Fragment {
private NestedScrollView scrollView;
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
scrollView = view.findViewById(R.id.scrollView);
scrollView.smoothScrollTo(0, 0);
}
}
The solution from #star4z should work, but there is an easier option. What you could do instead, use FragmentPagerAdapter for this and set it's behavior to BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT.
Every time, you change your tab, onResume will be called and there you can call your scrollView.smoothScrollTo(0, 0);
public class MyAdapter extends FragmentPagerAdapter {
...
public MyAdapter(FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
...
}
And then in your Fragment:
public class MyFragment extends Fragment {
...
public void onResume() {
super.onResume();
scrollView.smoothScrollTo(0, 0);
}
...
}
onViewCreated is only called when the Fragments are first created. A ViewPager does not change the state of the Fragments. You can think of the hidden Fragments being stored, visible, to the sides of the currently visible Fragment.
I accomplished by setting up a callback when the TabLayout changes. The TabLayout is where the listener for this is. You can then have it call a callback method in your FragmentPagerAdapter. In each Fragment, you should implement a method that returns a callback. In the FragmentPagerAdapter, use the getItem(int position) to store the callback from the Fragment in a Map. The callback method in the adapter takes the position from the TabLayout
First, in your Fragments, give them a method that returns some kind of callback (I used a Runnable) that will be called from the adapter.
public class PlaceHolderFragment extends Fragment {
...
public Runnable getOnTabChangedListener() {
return new Runnable() {
#Override
public void run() {
scrollView.smoothScrollTo(0, 0);
}
};
}
...
}
Then, in your FragmentPagerAdapter (I called mine SectionsPagerAdapter), store the callbacks in a map in the getItem() method, and then add a custom callback.
public class SectionsPagerAdapter extends FragmentPagerAdapter {
...
HashMap<Integer, Runnable> tabChangedCallbacks = new HashMap<>();
...
#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).
PlaceholderFragment fragment = PlaceholderFragment.newInstance(position + 1);
tabChangedCallbacks.put(position, fragment.getOnTabChangedListener());
return fragment;
}
public void onTabChanged(int position) {
tabChangedCallbacks.get(position).run();
}
...
}
In your activity that contains the TabLayout, you will want to call addOnTabSelectedListener() on the TabLayout in the onCreate() method.
protected void onCreate(Bundle savedInstanceState) {
...
final SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
final ViewPager viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(sectionsPagerAdapter);
TabLayout tabs = findViewById(R.id.tabs);
tabs.setupWithViewPager(viewPager);
tabs.addOnTabSelectedListener(
new TabLayout.ViewPagerOnTabSelectedListener(viewPager) {
#Override
public void onTabSelected(TabLayout.Tab tab) {
super.onTabSelected(tab);
sectionsPagerAdapter.onTabChanged(tab.getPosition());
}
});
...
}
EDIT
The principle is the same, but for this to work using ViewPager2 and FragmentStateAdapter, you will need the follow changes:
The Fragment stays the same.
The adapter is the same, functionally, with some updated methods:
public class SectionsStateAdapter extends FragmentStateAdapter {
HashMap<Integer, Runnable> tabChangedCallbacks = new HashMap<>();
...
public void onTabChanged(int position) {
tabChangedCallbacks.get(position).run();
}
#NonNull
#Override
public Fragment createFragment(int position) {
PlaceholderFragment fragment = PlaceholderFragment.newInstance(position + 1);
tabChangedCallbacks.put(position, fragment.getOnTabChangedListener());
return fragment;
}
#Override
public int getItemCount() {
return 2;
}
...
}
The activity changes the most:
public class MainActivity extends AppCompatActivity {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
...
final SectionsStateAdapter sectionsStateAdapter = new SectionsStateAdapter(this);
final ViewPager2 viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(sectionsStateAdapter);
TabLayout tabs = findViewById(R.id.tabs);
// connect the TabLayout to the ViewPager2
new TabLayoutMediator(tabs, viewPager, new TabLayoutMediator.TabConfigurationStrategy() {
#Override
public void onConfigureTab(#NonNull TabLayout.Tab tab, int position) {
// set tab text, etc
}
}).attach();
// set the change listener on the ViewPager2
viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
#Override
public void onPageSelected(int position) {
super.onPageSelected(position);
sectionsStateAdapter.onTabChanged(position);
}
});
...
}
}
Note that the only real change is that the ViewPager2 doesn't need the TabLayout to handle the page change. You could still use TabLayout.addOnTabSelectedListener() if you wanted, but you would have to implement your own TabLayout.OnTabSelecterListener since TabLayout.ViewPagerOnTabSelectedListener doesn't work with ViewPager2.
For example:
tabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
sectionsStateAdapter.onTabChanged(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});

Hide Button if not data in recyclerview

I had created a app in which i have multiple edittext and one buttonwith recyclerviuew and one button which are setvisibilty as Gone.On Button click it add all my data in my recyclerview list with by chnaging visibality of my recycelr view and my button.In my Custom Adapter i am using a image view to delete the item from postion now i want that if it delete all data from list then it should automatically hide my Button and recyclerview.
//Recycler_view Adapter
public class Myviewholder extends RecyclerView.ViewHolder {
public TextView land_Detail, area_detail, s_no1;
public Button delete;
public Myviewholder(View view) {
super(view);
land_Detail = view.findViewById(R.id.hint31);
area_detail = view.findViewById(R.id.hint21);
s_no1 = view.findViewById(R.id.hint11);
delete = view.findViewById(R.id.hint41);
}
}
public Land_adapters(List<Land_list> land_list, Context context) {
this.laand_list = land_list;
this.context = context;
}
#NonNull
#Override
public Land_adapters.Myviewholder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.land_list, parent, false);
return new Myviewholder(itemView);
}
#Override
public void onBindViewHolder(#NonNull Myviewholder holder, final int position) {
final Land_list current_year = laand_list.get(position);
holder.area_detail.setText("District :" + current_year.getDistrict_name() + "\n" + "Village :" + current_year.getVillage_name());
holder.s_no1.setText(String.valueOf(position + 1));
holder.land_Detail.setText("Acre :" + current_year.getAcre() + "\n" + "Kanal :" + current_year.getKanal() + "\n" + "Marla :" + current_year.getMarla());
holder.delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "", Toast.LENGTH_SHORT).show();
Land_list theRemovedItem = laand_list.get(position);
// remove your item from data base
laand_list.remove(position); // remove the item from list
notifyItemRemoved(position); // notify the adapter about the removed item
}
});
}
#Override
public int getItemCount() {
return laand_list.size();
}
//how i am using my recycler in mainactivity class
public void final_step() {
// marla_edit.setError(null);
recyclerView = findViewById(R.id.recycler_view_last1);
mAdapter1 = new Land_Adapter(last_Year1);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setAdapter(mAdapter1);
Land_list last_year1 = new Land_list(land_acre, land_kanal, village_selected1, land_marla, district_selected1, teshil_selected1, block_selected1, block_code, teshil_code1, village_code1, district_code);
last_Year1.add(last_year1);
mAdapter1.notifyDataSetChanged();
if (!(last_Year1.size() == 0)) {
RelativeLayout linearLayout = findViewById(R.id.linear123);
recyclerView.setVisibility(View.VISIBLE);
next_button.setVisibility(View.VISIBLE);
}
else
{
next_button.setVisibility(View.INVISIBLE);
}
// i just want that when it press delete image in recycelr view it should hide my button automatically.
you can use an interface to inform the fragment/activity, the list is empty.
Adapter like as below:
public class CustomAdapter extends RecyclerView.Adapter<CustomViewHolder> {
AdapterListener listener;
public void setListener(AdapterListener listener) {
this.listener = listener;
}
...
#Override
public void onBindViewHolder(#NonNull Myviewholder holder, final int position) {
...
holder.delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
...
// remove your item from data base
laand_list.remove(position); // remove the item from list
notifyItemRemoved(position); // notify the adapter about the removed item
if (laand_list.size()==0)
listener.onDataListIsEmpty();
}
});
}
public interface AdapterListener {
void onDataListIsEmpty();
}
}
The Activity/Fragment like as below:
class MyActivity extends Activity implements CustomAdapter.AdapterListener {
CustomAdapter adapter;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
adapter = new CustomAdapter();
adapter.setListener(this);
...
}
#Override
public void onDataListIsEmpty() {
// set visible or gone views
}
}

Change the selected tab background and text color of TabLayout

I want to change the selected tab background and text color from Java.
I created this activity from Android studio build in activity and make a little change for me.
My code is
public class BanglalinkInternetPack extends AppCompatActivity {
private SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {#link ViewPager} that will host the section contents.
*/
private ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_banglalink_internet_pack);
//getSupportActionBar().setBackgroundDrawable(new ColorDrawable(Color.parseColor("#f37022")));
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
switch (position){
case 0:
return new Montly_pack_bl();
case 1:
return new Daily_packs_bl();
case 2:
return new Weekly_pack_bl();
case 3:
return new Montly_pack_bl();
}
return null;
}
#Override
public int getCount() {
// Show 4 total pages.
return 4;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Most Used";
case 1:
return "Daily";
case 2:
return "Weekly";
case 3:
return "Monthly";
}
return null;
}
}
}
Where do I need to change?
Use app:tabSelectedTextColor and app:tabTextColor:
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIndicatorColor="#color/blue"
app:tabSelectedTextColor="#color/blue"
app:tabTextColor="#color/black"
/>
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
// void setTabTextColors(int normalcolour, int selectedcolour)
tabLayout.setTabTextColors(-1,-256);
Use this method to change colour of your tab title , keep parameters same in case you dont want to change colour on selected and also check this
https://developer.android.com/reference/android/support/design/widget/TabLayout.html#setSelectedTabIndicatorColor(int)

ActionBar tabs with MapView

I've created app using SherlockActionBar tab. One with my tabs contains MapView (Google Maps v2). Currently I have problem when I change tabs (screen below):
enter link description here
Next tab should contain ListView. Sometimes context second tab loaded correctly. Also I have problem with swiping my MapView. Currently I can only swiping up and down direction. I hope that somebody help me.
My code:
myfragment.xml
<com.google.android.gms.maps.MapView
android:id="#+id/mapview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true" />
TabFragment_Map.java
public class TabFragment_Map extends SherlockFragment {
MapView mapView;
GoogleMap map;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.map_fragment, container, false);
mapView = (MapView) view.findViewById(R.id.mapview);
mapView.onCreate(savedInstanceState);
map = mapView.getMap();
map.getUiSettings().setMyLocationButtonEnabled(false);
map.setMyLocationEnabled(true);
try {
MapsInitializer.initialize(this.getActivity());
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(43.1, -87.9), 10);
return view;
}
#Override
public void onResume() {
mapView.onResume();
super.onResume();
}
#Override
public void onDestroy() {
mapView.onDestroy();
super.onDestroy();
}
#Override
public void onLowMemory() {
mapView.onLowMemory();
super.onLowMemory();
}
}
MainActivity.java
public class MainActivity extends SherlockFragmentActivity {
ViewPager mViewPager;
TabsAdapter mTabsAdapter;
String TabFragment_Cafes;
String TabFragment_Details;
//Settery & gettery używane w mechanizmie przesyłania informacji pomiędzy fragmentami
public String getTabFragment_Cafes() {
return TabFragment_Cafes;
}
public void setTabFragment_Cafes(String tabFragment_Cafes) {
TabFragment_Cafes = tabFragment_Cafes;
}
public String getTabFragment_Details() {
return TabFragment_Details;
}
public void setTabFragment_Details(String tabFragment_Details) {
TabFragment_Details = tabFragment_Details;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mViewPager = new ViewPager(this);
mViewPager.setId(R.id.pager);
setContentView(mViewPager);
final ActionBar bar = getSupportActionBar();
bar.setNavigationMode(ActionBar.DISPLAY_SHOW_HOME);
bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
mTabsAdapter = new TabsAdapter(this, mViewPager);
mTabsAdapter.addTab(bar.newTab().setText("Mapa"), TabFragment_Map.class, null);
mTabsAdapter.addTab(bar.newTab().setText("Kawiarnie"), TabFragment_Cafes.class, null);
mTabsAdapter.addTab(bar.newTab().setText("Szczegóły"), TabFragment_Details.class, null);
if (savedInstanceState != null)
bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
}
#Override
protected void onSaveInstanceState(Bundle outState) {
//super.onSaveInstanceState(outState);
outState.putInt("tab", getSupportActionBar().getSelectedNavigationIndex());
}
public static class TabsAdapter extends FragmentPagerAdapter implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
static final class TabInfo {
private final Class<?> clss;
private final Bundle args;
TabInfo(Class<?> _class, Bundle _args) {
clss = _class;
args = _args;
}
}
public TabsAdapter(FragmentActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = ((SherlockFragmentActivity)activity).getSupportActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
mActionBar.addTab(tab);
notifyDataSetChanged();
}
public void onPageScrollStateChanged(int arg0) {}
public void onPageScrolled(int arg0, float arg1, int arg2) {}
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Object tag = tab.getTag();
for (int i = 0; i < mTabs.size(); i++) {
if (mTabs.get(i) == tag)
mViewPager.setCurrentItem(i);
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {}
public void onTabReselected(Tab tab, FragmentTransaction ft) {}
#Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
#Override
public int getCount() {
return mTabs.size();
}
}
}
You need a custom viewpager that intercepts the swipes
package com.ecs.google.maps.v2.component;
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.View;
public class CustomViewPager extends ViewPager {
public CustomViewPager(Context context) {
super(context);
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
// When using Maps V1
// if(v instanceof MapView){
// return true;
// }
// return super.canScroll(v, checkV, dx, x, y);
// When using Maps V2
if (v.getClass().getPackage().getName().startsWith("maps.")) {
return true;
}
return super.canScroll(v, checkV, dx, x, y);
}
}
Put this in your layout :
<com.ecs.google.maps.v2.component.CustomViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/tabs"
tools:context=".MainActivity">
And the swiping gestures should work.

Resources