Custom background for Action bar tabs with Sherlock Fragment in Android - android

I've created a class with Sherlock Fragment to enable the Swipe view with ViewPager. Now I'm trying to change the tab background which was possible in tabspec using setBackgroundResource() method but It's not working. I would like to add custom background for each tabs while its being focused/selected/not selected.
I tried using a selector but It didn't worked
<item android:drawable="#drawable/selected" android:state_selected="true"/>
<item android:drawable="#drawable/not_selected" android:state_selected="false"/>
mActionBar.setStackedBackgroundDrawable(getResources().getDrawable(
R.drawable.tab_indicator));
Here is my main class
public class MainActivity extends SherlockFragmentActivity {
// Declare Variables
ActionBar mActionBar;
ViewPager mPager;
Tab tab;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get the view from activity_main.xml
setContentView(R.layout.activity_main);
// Activate Navigation Mode Tabs
mActionBar = getSupportActionBar();
mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Locate ViewPager in activity_main.xml
mPager = (ViewPager) findViewById(R.id.pager);
// Activate Fragment Manager
FragmentManager fm = getSupportFragmentManager();
// Capture ViewPager page swipes
ViewPager.SimpleOnPageChangeListener ViewPagerListener = new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
super.onPageSelected(position);
// Find the ViewPager Position
mActionBar.setSelectedNavigationItem(position);
}
};
mPager.setOnPageChangeListener(ViewPagerListener);
// Locate the adapter class called ViewPagerAdapter.java
ViewPagerAdapter viewpageradapter = new ViewPagerAdapter(fm);
// Set the View Pager Adapter into ViewPager
mPager.setAdapter(viewpageradapter);
// Capture tab button clicks
ActionBar.TabListener tabListener = new ActionBar.TabListener() {
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// Pass the position on tab click to ViewPager
mPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
};
// Create first Tab
tab = mActionBar.newTab().setText("Tab1").setTabListener(tabListener);
mActionBar.addTab(tab);
// Create second Tab
tab = mActionBar.newTab().setText("Tab2").setTabListener(tabListener);
mActionBar.addTab(tab);
// Create third Tab
tab = mActionBar.newTab().setText("Tab3").setTabListener(tabListener);
mActionBar.addTab(tab);
}
}

This is based on something I just did (and my, what a pain it was).
I haven't tried compiling this but hopefully it helps. Good Luck!
In main activity's onCreate method, replace your addTab statements with this:
ActionBar.Tab tab1 = mActionBar.newTab().setTabListener(tabListener);
//Create a temporary RelativeLayout and inflate it with your custom layout
RelativeLayout rl1 = (RelativeLayout) getLayoutInflater().inflate(R.layout.tabLayout, null);
//Set the title of the tab
TextView t1 = (TextView) rl1.findViewById(R.id.tab1_text);
t1.setText("Tab1 Title");
t1.setMinimumWidth(150);//Prevents the tabs from becoming too small on larger screens, Change as needed
//Set the background of the tab to the layout you just created
tab1.setCustomView(rl1);
//Add the tab to your ActionBar
mActionBar.addTab(tab1);
tab1Layout.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="0dp"
android:background="#drawable/yourDrawable"
android:layout_margin="0dp">
<TextView
android:id="#+id/tab1_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="#style/yourStyleIfYouWantToUseOne"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
android:gravity="center|center_horizontal"
android:textStyle="bold"/>
</RelativeLayout>
Basically, we're creating a "fake" tab by just putting a TextView in a layout and adding a background.
As and additional note, your drawable needs to include a selector for both the selected and unselected drawables. If you need an example, look at what is generated by the Android Asset Studio, which is what I used to make my tabs.
Repeat this for as many tabs as you need.
If any part of this is vague or confusing, feel free to ask questions. ;)

Related

How to change position of Tab Navigation?

I currently have Tab Based app and the tabs are on bottom. Is there any way to put them up?
Add Tabs To Action Bar
To create tabs using ActionBar, you need to enable
NAVIGATION_MODE_TABS, then create several instances of ActionBar.Tab
and supply an implementation of the ActionBar.TabListener interface
for each one. For example, in your activity's onCreate() method, you
can use code similar to this:
#Override
public void onCreate(Bundle savedInstanceState) {
final ActionBar actionBar = getActionBar();
// Specify that tabs should be displayed in the action bar.
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Create a tab listener that is called when the user changes tabs.
ActionBar.TabListener tabListener = new ActionBar.TabListener() {
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
// show the given tab
}
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
// hide the given tab
}
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
// probably ignore this event
}
};
// Add 3 tabs, specifying the tab's text and TabListener
for (int i = 0; i < 3; i++) {
actionBar.addTab(actionBar.newTab().setText("Tab " + (i + 1)).setTabListener(tabListener));
}
}
How you handle the ActionBar.TabListener callbacks to change tabs
depends on how you've constructed your content. But if you're using
fragments for each tab with ViewPager as shown above, the following
section shows how to switch between pages when the user selects a tab
and also update the selected tab when the user swipes between pages.
From Docs.

Change tab index of fragments with tabs programmatically

I'm getting a null pointer exception when trying to switch tabs programmatically of a tablayout inside a fragment,
So I have my main activity that has a tab layout (4 tabs) each tab has a view pager holding a fragment, and each of these fragments has a tab layout (x amount of tabs) with a view pager holding a fragment,
i can switch the tabs of my main activity tab layout from any fragment like this
TabLayout tabLayout = MainActivity.tabLayout;
TabLayout.Tab tab = tabLayout.getTabAt(2);
tab.select();
but if i try to change the tabs of one of the fragments in the same way i get a null pointer
TabLayout tabLayout2 = tabFragOne.tabLayout;
TabLayout.Tab tab2 = tabLayout2.getTabAt(2);
tab2.select();
it only happens if I click the button in question when the app first opens, which suggests that the reason for it is that the fragment hasn't been attached or created yet,
for instance if i scroll across to the fragments tab i want to switch to, and then go back to the main activity and press the button in question it will work.
does anyone know the best way to fix this?
Ok ive found half the crux to this question is actually that im using a view pager adapter, a question here sheds a lot of light on my issue
The correct way to set selected Tab, we should set selected index from Pager instead.
final ViewPager pager = (ViewPager) findViewById(R.id.pager);
final TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(pager);
pager.setCurrentItem(0);//selected position
Here is my layout design in xml
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="#ffffff"
android:background="#color/al_white"
android:elevation="0dp" />
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff"
app:tabTextColor="#494a43"
app:tabSelectedTextColor="#494a43"
app:tabIndicatorColor="#494a43"
app:tabIndicatorHeight="2dp"
app:tabMode="fixed"
app:tabGravity="fill" />
</android.support.design.widget.AppBarLayout>
TabLayout tabhost = (TabLayout) getActivity().findViewById(R.id.tabLayout);
tabhost.getTabAt(2).select();
I use this inside my fragment's create function... and it works perfectly
R.id.tabLayout is the tablayout id in your main activity layout.
you can use the setCurrentItem(Postion) in viewpager
example :
tabLayout.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
// tabLayout.setupWithViewPager(mViewPager);
mViewPager.setCurrentItem(4);
Simple example to automatically scroll from the last page to the first. Note: I added a dummy fragment at the first and last position.
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
if (position == 0) {
viewPager.setCurrentItem(viewPagerAdapter.getCount() - 2);
} else if (position == viewPagerAdapter.getCount() - 1) {
viewPager.setCurrentItem(1);
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
Using view pager, Its working simple and fine
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
CharSequence Titles[]; // This will Store the Titles of the Tabs which are Going to be passed when ViewPagerAdapter is created
int NumbOfTabs;
String mode;
AllDeals deals;
MyDeals myDeals; those are my fragments
public ViewPagerAdapter(FragmentManager fm, int mNumbOfTabsumb, String moe) {
super(fm);
this.NumbOfTabs = mNumbOfTabsumb;
mode=moe;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
if(mode.equals("Deals")){
deals=new AllDeals();
return deals;
}
break;
case 1:
if(mode.equals("Deals")){
myDeals=new MyDeals();
return myDeals;
}
break;
default:
break;
}
return null;
}
#Override
public int getCount() {
return NumbOfTabs;
}
}
add this lines into ur activity
containerViewone.setVisibility(View.VISIBLE);
tabLayout.addTab(tabLayout.newTab().setText(getResources().getString(R.string.title_all_deals)));
tabLayout.addTab(tabLayout.newTab().setText(getResources().getString(R.string.title_my_deals)));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setTabTextColors(getResources().getColor(R.color.tabunselect), getResources().getColor(R.color.black));
viewpagerad = new ViewPagerAdapter(getSupportFragmentManager(), Numboftabs, "Deals");
pager.setAdapter(viewpagerad);
pager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
Try this:
TabLayout tablayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); //your activity layout
tabLayout =(TabLayout)findViewById(R.id.tablayout); //your tab layout id
tabLayout.getTabAt(0).select(); //your tab index;
}
In Kotlin:
With TabLayout and ViewPager2 that works for me:
binding.tablayout.getTabAt(1)!!.select()

Drawer navigation + tab navigation having too many tabs

Im trying to Combine drawer navigation and tab navigation together. I have successfully combined the 2. When i launched the app for first time, everything works fine. However, after I click on the drawer item and back to the tabs fragments, there are too many tabs added. I tried to limit the number and it did not work. Also, when I open the other fragments in the drawer item, the tabs still remains.
here's some pictures to show
when I first open the app
after I open the drawer
When I back to the first fragment again
Here's my code for the tabs fragment's on createview
private ActionBar actionBar;
private String[] tabs={ "1", "2", "3","4" };
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_home, container, false);
mSectionsPagerAdapter = new SectionsPagerAdapter(
getChildFragmentManager());
mViewPager = (ViewPager) v.findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(
new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// When swiping between pages, select the
// corresponding tab.
getActivity().getActionBar().setSelectedNavigationItem(position);
}
});
actionBar=getActivity().getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.TabListener tabListener = new ActionBar.TabListener() {
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
// show the given tab
mViewPager.setCurrentItem(tab.getPosition());
}
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
// hide the given tab
}
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
// probably ignore this event
}
};
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setText(tab_name)
.setTabListener(tabListener));
}
return v;
}
I think its the
actionBar.addTab(actionBar.newTab().setText(tab_name)
.setTabListener(tabListener));
part that makes this happened , can anyone help me how to fix it?
You must call actionBar.removeAllTabs() before adding tabs...because you didn't call actionBar.removeAllTabs() they cummulated (4+4)...
P.S. Please don't use actionbar and navigation modes anymore..Action bar navigation modes are deprecated in Android L
Replace actionBar with toolbar, and replace tabs with the PagerTabStrip or something else...
The onCreateView() method will be called when a frament is attached to an Activity and its view must be created, then the code to add tabs to ActionBar will be called more than once, and this cause your problem.
Since ActionBar is belongs to your Activity, not your Fragment, you'd better add tabs to it in your Activity, move the following code to your Activity should help:
private ActionBar actionBar;
private String[] tabs={ "1", "2", "3","4" };
actionBar=getActivity().getActionBar(); // remove getActivity().
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.TabListener tabListener = new ActionBar.TabListener() {
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
// show the given tab
// This line need to be changed, you can make a public method in
// your fragment which set the current item of ViewPager, and
// call the method in the Activity.
mViewPager.setCurrentItem(tab.getPosition());
}
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
// hide the given tab
}
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
// probably ignore this event
}
};
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setText(tab_name)
.setTabListener(tabListener));
}

TabActivity OnTabChangedListener - how to get the previous selected tab

I have a tab where when the user click on it i want a dialog to appear and keep him on the current tab (without switching to the selected tab).
I have the code of the dialog and the tab listener working but how do i keep the curren tab?
tabHost.setOnTabChangedListener(new OnTabChangeListener(){
#Override
public void onTabChanged(String tabId) {
if(tabId.equals("SomeThing") && !(AppSettings.getIsFullVersion()))
{
callFullVersionDialog("Sorry, SomeThing is only available on full version");
// finish();
}
}});
You can always do this,
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mAppSectionsPagerAdapter);
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in the ViewPager.
// code to show your Dialog box here.
mViewPager.setCurrentItem(position of your current tab here);
}
if each tab is a seperate fragment put your fragment position in there (0,1,2,3...).

How to make actionbarsherlock tabs open listviews instead of fragments

I want to create a feed like the one in the facebook app, and I want to have actionbarsherlock navigation tabs that will be used to filter the feed - a tab for people, a tab for places and a tab for items.
Right now I've set it up so that each tab opens up a fragment. How can I make them open up a list view instead?
ActionBar.Tab itemsFeedTab = actionBar.newTab();
ActionBar.Tab peopleFeedTab = actionBar.newTab();
ActionBar.Tab placesFeedTab = actionBar.newTab();
Fragment itemsFeedFragment = new FeedItems();
Fragment peopleFeedFragment = new FeedPeople();
Fragment placesFeedFragment = new FeedPlaces();
itemsFeedTab.setTabListener(new MyTabsListener(itemsFeedFragment));
peopleFeedTab.setTabListener(new MyTabsListener(peopleFeedFragment));
placesFeedTab.setTabListener(new MyTabsListener(placesFeedFragment));
actionBar.addTab(itemsFeedTab, 0, true);
actionBar.addTab(peopleFeedTab, 1, false);
actionBar.addTab(placesFeedTab, 2, false);
class MyTabsListener implements ActionBar.TabListener {
public Fragment fragment;
public MyTabsListener(Fragment fragment){
this.fragment = fragment;
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
ft.replace(R.id.home, fragment);
}
If your fragments contain only ListViews then its better to use ListFragment
Well the answer is hidden in your question , you are trying to open ListView instead of Fragment.
Why don't you open a ListFragment and you are done.

Categories

Resources