Is possible to use TabWidget without TabHost? I wanna something like Tabs navigation for ActionBar failback for older phones.
So I only want to show user tabs and listen on click actions, where I get active tab ID. Nothing more.
I know in common situations TabsNavigatin for actionBar is just for navigate through Fragments. But I easily avoid Fragments. :
class mTabListener implements ActionBar.TabListener {
private Screen screen;
public mTabListener(Screen screen) {
this.screen = screen;
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
screen.onTabReselected(tab, ft);
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
screen.onTabSelected(tab, ft);
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
screen.onTabUnselected(tab, ft);
}
}
public abstract class Screen extends Activity {
protected void addTab(String title, int what, boolean selected) {
if (Global.API < 11)
return;
ActionBar bar = getActionBar();
Tab tab = bar.newTab()
.setTag(new Integer(what))
.setTabListener(new mTabListener(this))
.setText(title);
bar.addTab(tab, selected);
}
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
Integer what = (Integer)tab.getTag();
tabSelected(what);
}
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
public void tabSelected(int what) {
}
}
But I can't find how to add tab buttons to TabWidget;
No. Tab widget without tab host is like using pushbutton for the tabs. You will have do the manipulation of tab navigation.
Here is the solution, TabWidget without tabHost
https://github.com/muratonnet/android-SingleTabWidget
Related
I am implementing tabs in my activity.
I have 5 tabs and every tab contains a listview (i get the content of the listview through asynctask)
That's the image:
Now Codes:
mViewPager
.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
ab.setSelectedNavigationItem(position);
}
});
this.getSherlockActivity().getSupportActionBar().removeAllTabs();
ab.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
com.actionbarsherlock.app.ActionBar.Tab tab1 = ab
.newTab()
.setText("Samsung")
.setTabListener(
new TabListener<SamsungLB>(this.getSherlockActivity(),
"tabone", SamsungLB.class));
com.actionbarsherlock.app.ActionBar.Tab tab2 = ab
.newTab()
.setText("HTC")
.setTabListener(
new TabListener<HTCLB>(this.getSherlockActivity(),
"tabtwo", HTCLB.class));
com.actionbarsherlock.app.ActionBar.Tab tab3 = ab
.newTab()
.setText("LG")
.setTabListener(
new TabListener<LGLB>(this.getSherlockActivity(),
"tabthree", LGLB.class));
com.actionbarsherlock.app.ActionBar.Tab tab4 = ab
.newTab()
.setText("Sony")
.setTabListener(
new TabListener<SonyLB>(this.getSherlockActivity(),
"tabfour", SonyLB.class));
com.actionbarsherlock.app.ActionBar.Tab tab5 = ab
.newTab()
.setText("Search")
.setTabListener(
new TabListener<SearchLB>(this.getSherlockActivity(),
"tabfive", SearchLB.class));
ab.addTab(tab1);
ab.addTab(tab2);
ab.addTab(tab3);
ab.addTab(tab4);
ab.addTab(tab5);
return rootView;
}
#SuppressLint("NewApi")
public static class TabListener<T extends SherlockFragment> implements
ActionBar.TabListener {
private Fragment mFragment;
private final Activity mActivity;
private final String mTag;
private final Class<T> mClass;
public TabListener(Activity activity, String tag, Class<T> clz) {
mActivity = activity;
mTag = tag;
mClass = clz;
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if (mFragment == null) {
mFragment = Fragment.instantiate(mActivity, mClass.getName());
ft.add(android.R.id.content, mFragment, mTag);
} else {
ft.attach(mFragment);
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
if (mFragment != null) {
ft.detach(mFragment);
}
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
public void onTabReselected(Tab arg0,
android.app.FragmentTransaction arg1) {
}
#SuppressLint("NewApi")
public void onTabSelected(Tab arg0, android.app.FragmentTransaction arg1) {
mViewPager.setCurrentItem(arg0.getPosition());
}
public void onTabUnselected(Tab arg0,
android.app.FragmentTransaction arg1) {
}
#Override
public void onTabSelected(com.actionbarsherlock.app.ActionBar.Tab tab,
FragmentTransaction ft) {
// TODO Auto-generated method stub
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(
com.actionbarsherlock.app.ActionBar.Tab tab,
FragmentTransaction ft) {
// TODO Auto-generated method stub
}
#Override
public void onTabReselected(
com.actionbarsherlock.app.ActionBar.Tab tab,
FragmentTransaction ft) {
// TODO Auto-generated method stub
}
}
Basically, every tab have a listview that fills through AsyncTask. i get the results through JSON And parse them. later on i parse the images through imageloader.
Why it's lagging???
Specially when i change from LG TO HTC. (Even there the application closes sometimes!).
thanks your help will be appreciated :)
UPDATE: All tabs are using the same layout file.
CODES:
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/listview1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawSelectorOnTop="false" />
Kindly help.
As you are using many listviews, there are multiple causes that can slow down your performance..
How are you using adapter, eg: inflating a new view without using recycled convert view.
Improper layout XML declaration on list item, eg: using very complicated layout.
If you are doing a refresh every time you swipe a page, ViewPager.setOffscreenPageLimit(int limit) can prevent a reload while consuming more memory.
And if you're saying your application closes, you should have some stack trace available, posting it up helps us to identify the error.
I have a tabbed application built with fragments and ActionBarSherlock. I have 3 tabs, with 3 ListFragment's Here's what's happening.
When I select any tab, the onCreate method for the associated fragment is called as expected at first time but not at second. The problem is that the onCreate method is called for the next adjacent tab but not selected tab.
Click on tab2 and onCreate of tab3 is called but not tab2.
Actually my requirement is, when i change some data in tab1 means fragment1. those changes are not effected in fragment2, when i select tab2 (fragment2) it means fragment2 onCreate() was not calling. why it's not refreshing the fragment properly. this is the adapter i am using.
private class TabsAdapter extends FragmentPagerAdapter implements ViewPager.OnPageChangeListener, ActionBar.TabListener {
public TabsAdapter(FragmentActivity activity, ActionBar actionBar, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = actionBar;
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, int tabId) {
mTabs.add(clss.getName());
mTabsId.add(tabId);
mActionBar.addTab(tab.setTabListener(this));
notifyDataSetChanged();
}
public Integer getIdForPosition(int position) {
if (position >= 0 && position < mTabsId.size()) {
return mTabsId.get(position);
}
return null;
}
#Override
public int getCount() {
return mTabs.size();
}
#Override
public Fragment getItem(int position) {
//TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, mTabs.get(position), new Bundle());
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Log.i(TAG, "*******tab selected*******" +tab);
clearDetails();
if (mViewPager.getCurrentItem() != tab.getPosition()) {
mViewPager.setCurrentItem(tab.getPosition(), true);
}
}
#Override
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
if (mCurrentPosition == position) {
}
mNextPosition = position;
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
From this page:
The fragment of each page the user visits will be kept in memory,
though its view hierarchy may be destroyed when not visible.
This means that your fragments that are not visible to the user are still being kept in memory, so their onCreate methods won't be called when they're redisplayed. You can force them to be kicked out of memory when you switch pages by setting the ViewPager's offscreen page limit to 0.
A better way might be to use some sort of external data model shared between your Fragments and then use your onPageSelected method to tell the Fragment to update itself based on the data model when brought into view.
when you are on a Tab:(n), only Tab:(n-1) and Tab:(n+1) will be alive in the memory, for memory usage optimization. Rest all Tabs will be destroyed, thats the reason why when you come back to the first Tab, its onCreateView is being called again.
Actually Tab:1's onCreateView will be called even if you click Tab:2 because its the neighbourhood Tab.
One solution i got is:
change the OffscreenPageLimit of the ViewPager. Its default value is 1
Try changing it to 0. Should work.But in case if it didn't
Use the Call backs
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
class MyTabsListener implements ActionBar.TabListener {
public Fragment fragment;
public MyTabsListener(Fragment fragment) {
this.fragment = fragment;
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
Toast.makeText(DashboardFragmentActivity.appContext, "Reselected!", Toast.LENGTH_LONG).show();
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.replace(R.id.fragment_container, fragment);
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.remove(fragment);
}
Is it possible instead to change Fragment to FragmentActivity? How would you implement this, I'm confuse about those two.
Fragments are always used in FragmentActivities, so you cannot replace a Fragment with a FragmentActivity, because nested activities are deprecated.
And you always have an option to use getActivity(); in the Fragments to get the parent Activity, so for whatever reason you wanted to replace Fragment with FragmentActivity it can be achieved with just Fragment.
I have an example with 3 tabs and one button.
public class MainActivity extends SherlockActivity implements TabListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
setContentView(R.layout.activity_main);
addTab("1", 0, false);
addTab("2", 1, false);
addTab("3", 2, false);
Button cmdClick = (Button) findViewById(R.id.cmdClick);
cmdClick.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
getSupportActionBar().setSelectedNavigationItem(0);
}
});
}
private void addTab(String tabTitle, int position, boolean setSelected) {
ActionBar.Tab tab = getSupportActionBar().newTab();
tab.setText(tabTitle);
tab.setTabListener(this);
getSupportActionBar().addTab(tab, position, setSelected);
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Log.d("example", "Selected " + tab.getPosition());
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
Log.d("example", "Unselected " + tab.getPosition());
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
Log.d("example", "Reselected " + tab.getPosition());
}
}
When I click on the button it automatically selects first tab. I would like to automatically select first tab whenever I click on the second or on the third tab. I tried like this
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Log.d("example", "Selected " + tab.getPosition());
getSupportActionBar().setSelectedNavigationItem(0);
}
but it doesn't work. Any ideas?
Thanks.
Edit:
Maybe this example doesn't have any sense but this is just a simplified example of what I'm trying to do. I would like to have 2 tabs by default, one with title "1" and second one with title "+". When user selects "+" tab I would like to create new tab with title "2" (between tabs "1" and "+") and to automatically select tab "2".
First of all I'd like to discourage this kind of behavior. This will be VERY confusing for your users and frankly doesn't make any sense.
That said I tried hacking it but it doesn't seem like it's that easy to do. I did following:
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if(tab.getPosition() == 0) {
int tabs = mActivity.getSupportActionBar().getTabCount();
if(tabs > 3) {
ActionBar.Tab test = mActivity.getSupportActionBar().getTabAt(2);
test.select();
return;
}
}
Edit:
For the behavior your describing I think it would be much easier to implement it by creating your own tabs. You could use radio buttons and/or buttons to implement it easily.
Now this causes the tab indicator to still point at the old tab but the fragment inside is updated to the selected one =/ so not quite there...
In my Android app I'm using an Action Bar with tabs to switch between fragments that display the content of the tabs. Everything is working fine until an orientation change: Then Android starts to draw the widgets on top of each other so that the contents of the fragments get mixed up. My TabListener:
private class TabListener implements ActionBar.TabListener {
private final Activity mActivity;
private final String mTag;
public TabListener(Activity activity, String tag) {
mActivity = activity;
mTag = tag;
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
Fragment mFragment = MyActivity.this.getSupportFragmentManager().findFragmentByTag(mTag);
if (mFragment == null) {
mFragment = new MyFragment();
ft.add(android.R.id.content, mFragment, mTag);
} else {
ft.attach(mFragment);
}
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
Fragment mFragment = MyActivity.this.getSupportFragmentManager().findFragmentByTag(mTag);
if (mFragment != null) {
ft.detach(mFragment);
}
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
// Do nothing
}
}
The only thing I noticed was that on every orientation change, onTabUnselected() won't be called, but still onTabSelected() is called (so the current tab will be attached twice without being detached in between). If that's the problem, I do not know how to fix it. If that's not the problem, I do not know where to look. I would be glad if someone has a suggestion.
Sidenote: I'm using the Action Bar from ActionBarSherlock. The problem appears on all Android versions I tested with (2.3, 4.0, 4.1).
I am not sure but here are some steps you can follow
Take Bundle reference before your Activity onCreate() method.
Bundle b1;
In your onCreate() method , put the Bundle value in b1
#Override
public void onCreate(Bundle savedInstanceState) {b1=savedInstanceState;
............................
}
Use this b1 in your onTabSelected method as
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
Fragment mFragment = MyActivity.this.getSupportFragmentManager().findFragmentByTag(mTag);
if (b1!=null){
ft.detach(mFragment);
//and the rest code
................}
}
Its an conclusion , which I have concluded with my working with fragments, but I have not done it with TabListener. So tell me when you are done , or any other solution.