In my Android application, I am using FragmentTabHost. I have added 3 tabs in the tabhost now my problem is I could not change the tab icon dynamically when choose each tab.
My requirement is if I select a tab other tabs icon should be changed, I got null pointer exception when try to change the tab icon. This is the line I got null pointer exception. the following code under onTabChanged method
ImageView v1 = (ImageView) mTabHost.getTabWidget().getChildAt(0)
.findViewById(android.R.id.icon);
v1 is return null (checked by if condition)
public class MainActivity extends FragmentActivity implements
OnTabChangeListener {
private static final String TAB_1_TAG = "FindTab";
private static final String TAB_2_TAG = "AddPopUpTab";
private static final String TAB_3_TAG = "MyAccoutTab";
private FragmentTabHost mTabHost;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
InitView();
}
private void InitView() {
mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
mTabHost.addTab(
setIndicator1(MainActivity.this,
mTabHost.newTabSpec(TAB_1_TAG), R.drawable.tab1),
Tab1Container.class, null);
mTabHost.addTab(
setIndicator1(MainActivity.this,
mTabHost.newTabSpec(TAB_2_TAG), R.drawable.tab2),
Tab2Container.class, null);
mTabHost.addTab(
setIndicator1(MainActivity.this,
mTabHost.newTabSpec(TAB_3_TAG), R.drawable.tab3),
Tab3Container.class, null);
mTabHost.getTabWidget().setDividerDrawable(null);
mTabHost.setOnTabChangedListener(MainActivity.this);
}
private TabSpec setIndicator1(Context ctx, TabSpec spec, int genresIcon) {
View v = LayoutInflater.from(ctx).inflate(R.layout.tab_item, null);
ImageView img = (ImageView) v.findViewById(R.id.img_tabtxt);
img.setBackgroundResource(genresIcon);
return spec.setIndicator(v);
}
#Override
public void onTabChanged(String arg0) {
Log.e("tab change string", arg0);
ImageView v1 = (ImageView) mTabHost.getTabWidget().getChildAt(0)
.findViewById(android.R.id.icon);
if (v1 == null) {
Log.e("v1", "null"); // Line
} else {
Log.e("v1", " Not null");
}
if (getResources().getDrawable(R.drawable.tab3) == null) {
Log.e("resource", "null");
} else {
Log.e("resource", "not null");
}
v1.setImageDrawable(getResources().getDrawable(R.drawable.tab3));
ImageView v2 = (ImageView) mTabHost.getTabWidget().getChildAt(1)
.findViewById(android.R.id.icon);
v2.setImageDrawable(getResources().getDrawable(R.drawable.tab1));
ImageView v3 = (ImageView) mTabHost.getTabWidget().getChildAt(2)
.findViewById(android.R.id.icon);
v3.setImageDrawable(getResources().getDrawable(R.drawable.tab2));
}
}
Layout for tab item:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ImageView
android:id="#+id/img_tabtxt"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:layout_centerHorizontal="true" />
</RelativeLayout>
I think you need to you Actionbar is good.
If you want using Action bar then.
You need to try this
Change Tab icon in Action bar
Related
I want to create a custom tabhost, which contains an icon also. For the purpose I need to use a method. This method works fine, but the tab indicator is disappeared from the tab.
The code for the tab indicator is:
private View getTabIndicator(Context context, String title, int icon) {
View view = LayoutInflater.from(context).inflate(R.layout.tab_layout, null);
ImageView iv = (ImageView) view.findViewById(R.id.imageView);
iv.setImageResource(icon);
TextView tv = (TextView) view.findViewById(R.id.textView);
tv.setText(title);
return view;
}
Main Activity is :
public class MainActivity extends AppCompatActivity {
private FragmentTabHost mTabHost;
Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Setting up a toolbar for the navigation purpose.
toolbar = (Toolbar)findViewById(R.id.app_bar);
toolbar.setTitle(" Call History Control");
toolbar.setLogo(R.mipmap.ic_launcher);
setSupportActionBar(toolbar);
// The fragments management is done here
// mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);
// mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
//
// mTabHost.addTab(
// mTabHost.newTabSpec("home").setIndicator(" HOME"),
// Home.class, null);
// mTabHost.addTab(mTabHost.newTabSpec("settings").setIndicator(" SETTINGS"),
// Settings.class, null);
//
// mTabHost.addTab(mTabHost.newTabSpec("about").setIndicator(" ABOUT"),
// About.class, null);
mTabHost.addTab(
mTabHost.newTabSpec("home").setIndicator(getTabIndicator(getApplicationContext(),"HOME",R.drawable.ic_home)),
Home.class, null);
mTabHost.addTab(mTabHost.newTabSpec("settings").setIndicator(getTabIndicator(getApplicationContext(),"SETTINGS",R.drawable.ic_settings)),
Settings.class, null);
mTabHost.addTab(mTabHost.newTabSpec("about").setIndicator(getTabIndicator(getApplicationContext(),"ABOUT",R.drawable.ic_account)),
About.class, null);
}
The screeen shot is:
i want to change color of tabwidget background. How can i change color of blue line??
My code is:
public class MainActivityNew extends ActionBarActivity implements
ActionBar.TabListener {
private FragmentTabHost mTabHost;
private int oldButtonId = 1;
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
private Database db;
private FrameLayout frame;
// Tab titles
private String[] tabs = {"Новости", "Мои купоны"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
}
private void initialization() {
frame = (FrameLayout) findViewById(R.id.content_frame);
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getSupportActionBar();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager(), actionBar, frame, viewPager);
mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.content_frame);
///////////////Add now 16/01/2014
Bundle b = new Bundle();
mTabHost.getTabWidget().setDividerDrawable(R.color.tabTransparent);
View tabIndicator = LayoutInflater.from(this).inflate(R.layout.tab_indicator_new,mTabHost.getTabWidget(), false);
ImageView icon = (ImageView) tabIndicator.findViewById(R.id.icon);
icon.setImageDrawable(getResources().getDrawable(R.drawable.news_icon_selector));
mTabHost.addTab(mTabHost.newTabSpec("1")
.setIndicator(tabIndicator),
FragmentNews.class, b);
tabIndicator = LayoutInflater.from(this).inflate(R.layout.tab_indicator_new,mTabHost.getTabWidget(), false);
icon = (ImageView) tabIndicator.findViewById(R.id.icon);
icon.setImageDrawable(getResources().getDrawable(R.drawable.catalog_icon_selector));
mTabHost.addTab(mTabHost.newTabSpec("2")
.setIndicator(tabIndicator), FragmentCatalog.class, b);
tabIndicator = LayoutInflater.from(this).inflate(R.layout.tab_indicator_center,mTabHost.getTabWidget(), false);
icon = (ImageView) tabIndicator.findViewById(R.id.icon);
icon.setImageDrawable(getResources().getDrawable(R.drawable.my_cards_icon_selector));
mTabHost.addTab(mTabHost.newTabSpec("3").
setIndicator(tabIndicator),FragmentMyCards.class, b);
tabIndicator = LayoutInflater.from(this).inflate(R.layout.tab_indicator_new,mTabHost.getTabWidget(), false);
icon = (ImageView) tabIndicator.findViewById(R.id.icon);
icon.setImageDrawable(getResources().getDrawable(R.drawable.near_icon_selector));
mTabHost.addTab(mTabHost.newTabSpec("4").
setIndicator(tabIndicator),FragmentNear.class, b);
tabIndicator = LayoutInflater.from(this).inflate(R.layout.tab_indicator_new,mTabHost.getTabWidget(), false);
icon = (ImageView) tabIndicator.findViewById(R.id.icon);
icon.setImageDrawable(getResources().getDrawable(R.drawable.settings_icon_selector));
mTabHost.addTab(mTabHost.newTabSpec("5").
setIndicator(tabIndicator), FragmentSettingsPartOne.class, b);
mTabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
#Override
public void onTabChanged(String tabId) {
setActivityView(Integer.valueOf(tabId));
Log.d("tabs", "tabID=" + tabId);
}
});
////////////////////end of adding
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Adding Tabs
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setText(tab_name)
.setTabListener(this));
}
setButtonsColor(1, 3);
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
viewPager.setCurrentItem(tab.getPosition());
}
public void setActivityView(int newButtonId) {
switch (newButtonId) {
case 1:
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.show();
viewPager.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, 0, 8.0f));
frame.setLayoutParams(new LinearLayout.LayoutParams(0, 0, 0f));
break;
default:
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.hide();
frame.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, 0, 8.0f));
viewPager.setLayoutParams(new LinearLayout.LayoutParams(0, 0, 0f));
break;
}
}
#Override
protected void onResume() {
initialization();
db = Database.getInstance(this);
/**
* on swiping the viewpager make respective tab selected
* */
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
super.onResume(); /
}
}
I have read this i try next
TabWidget widget = mTabHost.getTabWidget();
for(int i = 0; i < widget.getChildCount(); i++) {
View v = widget.getChildAt(i);
// Look for the title view to ensure this is an indicator and not a divider.
TextView tv = (TextView)v.findViewById(android.R.id.title);
if(tv == null) {
continue;
}
// v.setBackgroundResource(R.drawable.your_tab_selector_drawable);
v.setBackgroundColor(Color.RED);
}
But it only change background color of bottom tabs.
Use android.support.design.widget.TabLayout instead
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/actionbar"
app:tabIndicatorColor="#color/tab_indicator_color" // this is what you want
app:tabIndicatorHeight="3dp" // tab indicator height
app:tabSelectedTextColor="#color/white"
app:tabTextColor="#color/font_color_white70"/>
This has backward compatibility also
I really need to access the images of a tab at runtime for scaling.
Therefore I made a custom tab layout with an imageview and a textview.
But if i want to add the custom tab to my tabhost I a "did you forget to call 'public void setup(localactivitymanager activitygroup)'" exception.
Thx in advance for any solutions ;D
Ps. I cannot use
spec = tabHost.newTabSpec("2").setIndicator(res.getString(R.string.tabname2),
res.getDrawable(R.drawable.tabimage2));
tabHost.addTab(spec, FragmentTwo.class, null);
because i need to scale the image before adding.
Here is my class:
public class MyTabActivity extends FragmentActivity {
private FragmentTabHost mTabHost;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tabmanager_layout);
mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
addCustomTab(getApplicationContext(),"Meldungen", getResources().getDrawable(R.drawable.messagewhite), NewsFragment.class, mTabHost);
addCustomTab(getApplicationContext(),"Meldungen", getResources().getDrawable(R.drawable.messagewhite), NewsFragment.class, mTabHost);
addCustomTab(getApplicationContext(),"Meldungen", getResources().getDrawable(R.drawable.messagewhite), NewsFragment.class, mTabHost);
addCustomTab(getApplicationContext(),"Meldungen", getResources().getDrawable(R.drawable.messagewhite), NewsFragment.class, mTabHost);
for(int i=0;i<mTabHost.getTabWidget().getChildCount();i++)
{
mTabHost.getTabWidget().getChildAt(i).setBackgroundColor(Color.parseColor("#3b6c8d")); //unselected
}
}
private void addCustomTab(Context context,String labelId, Drawable drawable, Class<?> c, FragmentTabHost fth ) {
View view = LayoutInflater.from(context).inflate(R.layout.tab_customtab, null);
ImageView image = (ImageView) view.findViewById(R.id.icon);
TextView text = (TextView) view.findViewById(R.id.tabtitle);
image.setImageDrawable(drawable);
text.setText(labelId);
TabHost.TabSpec spec = fth.newTabSpec(labelId);
Intent i = new Intent(this,c);
spec.setContent(i);
spec.setIndicator(view);
fth.addTab(spec);
}
You need to use FragmentTabHost's custom addTab() which will also take your Fragment class as parameter.
Replace
TabHost.TabSpec spec = fth.newTabSpec(labelId);
Intent i = new Intent(this,c);
spec.setContent(i);
spec.setIndicator(view);
with
TabHost.TabSpec spec = fth.newTabSpec(labelId);
spec.setIndicator(view);
fth.addTab(spec, c, null);
I am having an issue getting the view to change on a tabhost - when I select a tab the content stays blank.
From what I can tell, onCreateView is not being called on the child Fragments. onMenuCreate runs fine because the menu changes like it is supposed to.
public class PatientTabFragment extends Fragment {
private FragmentTabHost mTabHost;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mTabHost = new FragmentTabHost(getActivity());
mTabHost.setup(getActivity(), getChildFragmentManager());
mTabHost.addTab(mTabHost.newTabSpec("simple").setIndicator("Info"),
NewPatientFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("contacts").setIndicator("Notes"),
NoteListFragment.class, null);
return mTabHost;
}
#Override
public void onDestroyView() {
super.onDestroyView();
mTabHost = null;
}
}
according to the docs:
Special TabHost that allows the use of Fragment objects for its tab
content. When placing this in a view hierarchy, after inflating the
hierarchy you must call setup(Context, FragmentManager, int) to
complete the initialization of the tab host.
(emphasis mine)
So I suggest somethong like this:
public class PatientTabFragment extends Fragment {
private FragmentTabHost mTabHost;
private boolean createdTab = false;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mTabHost = new FragmentTabHost(getActivity());
mTabHost.setup(getActivity(), getChildFragmentManager());
mTabHost.addTab(mTabHost.newTabSpec("simple").setIndicator("Info"),
NewPatientFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("contacts").setIndicator("Notes"),
NoteListFragment.class, null);
return mTabHost;
}
public void onResume(){
if (!createdTab){
createdTab = true;
mTabHost.setup(getActivity(), getActivity().
getSupportedFragmentManager());
}
}
#Override
public void onDestroyView() {
super.onDestroyView();
mTabHost = null;
}
}
Now we can use TabLayout and ViewPager do those things.This is a good guide to use it.Here is my code:
viewPager=(NonSwipeableViewPager)view.findViewById(R.id.circleresdyn_viewpager);
tabLayout=(TabLayout)view.findViewById(R.id.circleresdyn_tablayout);
if (viewPager != null) {
Adapter adapter = new Adapter(((AppCompatActivity)activity).getSupportFragmentManager());
ContentFragment con=new ContentFragment();
con.setArguments(bundleForFramgnet);
MemberFragment memberFragment=new MemberFragment();
memberFragment.setArguments(bundleForFramgnet);
CirResDynTileFragment cirResDynTileFragment=new CirResDynTileFragment();
cirResDynTileFragment.setArguments(bundleForFramgnet);
adapter.addFragment(cirResDynTileFragment, "Tab1");
adapter.addFragment(con, "Tab2");
adapter.addFragment(memberFragment, "Tab3");
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(3);
tabLayout.setTabGravity(TabLayout.GRAVITY_CENTER);
tabLayout.setupWithViewPager(viewPager);
tabLayout.getTabAt(0).select();
}
Check this peace of code. It may help you:
import android.app.Fragment;
public class Change_password extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.change_password, container,false);
setTabs();
return rootView;
}
private void setTabs() {
try {
addTab("Airlines", R.drawable.tab_home, HomeActivity_bkp.class);
addTab("Advance Search", R.drawable.tab_search,
AdvanceSearchAcitivty.class);
addTab("Booking", R.drawable.tab_home, Booking.class);
addTab("Settings", R.drawable.tab_search, SettingAcitivty.class);
} catch (Exception e) {
Toast.makeText(getApplicationContext(), e.toString(),
Toast.LENGTH_LONG).show();
// TODO: handle exception
}
}
private void addTab(String labelId, int drawableId, Class<?> c) {
TabHost tabHost = getTabHost();
Intent intent = new Intent(this, c);
TabHost.TabSpec spec = tabHost.newTabSpec("tab" + labelId);
View tabIndicator = LayoutInflater.from(this).inflate(
R.layout.tab_indicator, getTabWidget(), false);
TextView title = (TextView) tabIndicator.findViewById(R.id.title);
title.setText(labelId);
ImageView icon = (ImageView) tabIndicator.findViewById(R.id.icon);
icon.setImageResource(drawableId);
spec.setIndicator(tabIndicator);
spec.setContent(intent);
tabHost.addTab(spec);
}
Is it possible to update the TabWidget icons/indicators? If so, how, when you are creating TabContent through intents?
Edits below with answer thanks to #Bart
Generic code:
MainActivity:
public class TestActivity extends TabActivity {
public int i;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//TabHost mTabHost = (TabHost) findViewById(android.R.id.tabhost);
TabHost mTabHost = getTabHost();
mTabHost.addTab(mTabHost.newTabSpec("tab1").setContent(
new Intent(this, OneActivity.class)).setIndicator("One"));
mTabHost.addTab(mTabHost.newTabSpec("tab2").setContent(
new Intent(this, TwoActivity.class)).setIndicator("Two"));
changeTitle(0, 20);
}
public void changeTitle(int cnt, int i){
View v = getTabWidget().getChildAt(cnt);
TextView tv = (TextView) v.findViewById(android.R.id.title);
tv.setText("One ("+i+")");
}
}
OneActivity (ChildActivity):
public class OneActivity extends Activity {
TextView tv;
Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.one);
tv = (TextView) findViewById(R.id.tv);
btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
int i = Integer.parseInt((String) tv.getText());
i++;
tv.setText(""+i);
TestActivity parent = OneActivity.this.getParent();
parent.changeTitle(0,i);
}
});
}
}
I'd like to show the number in the Tab's title
It is possible but it is a bit of tricky:
ViewGroup vg = (ViewGroup) getTabHost().getTabWidget().getChildAt(0);
TextView tv = (TextView) vg.getChildAt(1);
You should pay attention to indices while calling getChildAt(). The best way is always to debug and check.
Since 1.6 TabWidget has a method getChildTabViewAt thanks to which you could skip the first line and write:
ViewGroup vg = (ViewGroup) getTabHost().getTabWidget().getChildTabViewAt(0);
I attach also source code of Android SDK to show how TabWidget icons are built:
View tabIndicator = inflater.inflate(R.layout.tab_indicator,
mTabWidget, // tab widget is the parent
false); // no inflate params
final TextView tv = (TextView) tabIndicator.findViewById(R.id.title);
tv.setText(mLabel);
final ImageView iconView = (ImageView) tabIndicator.findViewById(R.id.icon);
iconView.setImageDrawable(mIcon);
As you can see, it contains a TextView and ImageView.
Try get the imageView like this
ImageView v = (ImageView)tabActivity.getTabHost().getTabWidget().getChildTabViewAt(i).findViewById(android.R.id.icon);
v.setImageDrawable(getResources().getDrawable(R.drawable.newIcon));
Given a arrays for titles and icons
for (int i = 0; i < numTabs; i++ ) {
TabSpec spec = host.newTabSpec(String.valueOf(i)); //sets tab index
Drawable icon = res.getDrawable(icons[i]); //sets the icon
// set tab text and icon
spec.setIndicator(titles[i], icon); //sets the title
host.addTab(spec);
}