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);
}
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 have a fragment which I am using as a navigational menu between my activities.
Each of the icons is in a seperate linearlayout with its own ID. I'm trying to implement an onclick listener in the fragment for each linearlayout so that when it is clicked the appropriate activity is opened and the background of the linear layout as well as the image in the imageview are changed to signify the click. However when I click on the linearlayout nothing happens. I already set the clickable attribute to true so that is not the issue. This is my code:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_menu, container, false);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
LinearLayout betslayout = (LinearLayout) this.getView().findViewById(R.id.betnowlayout);
betslayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
LinearLayout layout = (LinearLayout) v;
layout.setBackgroundResource(R.drawable.selected);
ImageView image = (ImageView) layout.findViewById(R.id.betnowimageview);
image.setImageResource(R.drawable.footballsell);
LinearLayout parent = (LinearLayout) v.getParent();
LinearLayout mybetslayout = (LinearLayout) parent.findViewById(R.id.viewbetslayout);
LinearLayout rankingslayout = (LinearLayout) parent.findViewById(R.id.rankingslayout);
LinearLayout coinfrenzylayout = (LinearLayout) parent.findViewById(R.id.coinfrenzylayout);
LinearLayout shoplayout = (LinearLayout) parent.findViewById(R.id.shoplayout);
mybetslayout.setBackgroundResource(R.drawable.notselected);
rankingslayout.setBackgroundResource(R.drawable.notselected);
coinfrenzylayout.setBackgroundResource(R.drawable.notselected);
shoplayout.setBackgroundResource(R.drawable.notselected);
ImageView mybetsimage = (ImageView) mybetslayout.findViewById(R.id.betnowimageview);
ImageView rankingsimage = (ImageView) rankingslayout.findViewById(R.id.rankingsimageview);
ImageView coinfrenzyimage = (ImageView) coinfrenzylayout.findViewById(R.id.coinfrenzyimageview);
ImageView shopimage = (ImageView) shoplayout.findViewById(R.id.shopimageview);
mybetsimage.setImageResource(R.drawable.chipp);
rankingsimage.setImageResource(R.drawable.medal);
coinfrenzyimage.setImageResource(R.drawable.clover);
shopimage.setImageResource(R.drawable.moneybag);
Intent i = new Intent(getActivity(),AllGameslistActivity.class);
startActivity(i);
getActivity().finish();
}
});
}
First Off All You Should Create Custom Buttons. See this.
and set onClickListener for the Icons.
The problem was in this line of code
return inflater.inflate(R.layout.fragment_menu, container, false);
It should instead be : return myfragment;
This is the proper way to do this:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View myfragment = inflater.inflate(R.layout.fragment_menu, container, false);
// TODO: Rename method, update argument and hook method into UI event
LinearLayout betslayout = (LinearLayout) myfragment.findViewById(R.id.betnowlayout);
betslayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("isitworkign", "yesyes");
LinearLayout layout = (LinearLayout) v;
layout.setBackgroundResource(R.drawable.selected);
ImageView image = (ImageView) layout.findViewById(R.id.betnowimageview);
image.setImageResource(R.drawable.footballsell);
LinearLayout parent = (LinearLayout) v.getParent();
LinearLayout mybetslayout = (LinearLayout) parent.findViewById(R.id.viewbetslayout);
LinearLayout rankingslayout = (LinearLayout) parent.findViewById(R.id.rankingslayout);
LinearLayout coinfrenzylayout = (LinearLayout) parent.findViewById(R.id.coinfrenzylayout);
LinearLayout shoplayout = (LinearLayout) parent.findViewById(R.id.shoplayout);
mybetslayout.setBackgroundResource(R.drawable.notselected);
rankingslayout.setBackgroundResource(R.drawable.notselected);
coinfrenzylayout.setBackgroundResource(R.drawable.notselected);
shoplayout.setBackgroundResource(R.drawable.notselected);
ImageView mybetsimage = (ImageView) parent.findViewById(R.id.viewbetsimageview);
ImageView rankingsimage = (ImageView) parent.findViewById(R.id.rankingsimageview);
ImageView coinfrenzyimage = (ImageView) parent.findViewById(R.id.coinfrenzyimageview);
ImageView shopimage = (ImageView) parent.findViewById(R.id.shopimageview);
mybetsimage.setImageResource(R.drawable.chipp);
rankingsimage.setImageResource(R.drawable.medal);
coinfrenzyimage.setImageResource(R.drawable.clover);
shopimage.setImageResource(R.drawable.moneybag);
Intent i = new Intent(getActivity(), AllGameslistActivity.class);
startActivity(i);
getActivity().finish();
}
});
return myfragment;
}
I have one fragment in which I am setting tabhost widget with three tabs each have fragment.
When ever first time I come to this fragment first tab not loading first child fragment but after click on another tab and return on first tab then it is loading first child fragment.
Also I have little confusion that what will be the third parameter in tabhost.setup() method.It should be the layout of parent fragment which handles tabs or the layout of first child fragment.
Here is my code for parent fragment
public class MyStoreFragment extends Fragment implements TabHost.OnTabChangeListener {
private FragmentTabHost mTabHost;
View rootView;
public MyStoreFragment() {
// Empty constructor required for fragment subclasses
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// rootView = inflater.inflate(R.layout.fragment_my_store,container, false);
// mTabHost = (FragmentTabHost)rootView.findViewById(android.R.id.tabhost);
mTabHost = new FragmentTabHost(getActivity());
// mTabHost.setup(getActivity(), getChildFragmentManager(), android.R.id.tabcontent);
mTabHost.setup(getActivity(), getChildFragmentManager(),R.layout.fragment_my_store);
mTabHost.addTab(mTabHost.newTabSpec("new").setIndicator("NEW"), NewBookFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("trending").setIndicator("TRENDING"),FragmentTab.class, null);
mTabHost.addTab(mTabHost.newTabSpec("explore").setIndicator("EXPLORE"),FragmentTab.class, null);
mTabHost.setCurrentTab(0);
mTabHost.setOnTabChangedListener(this);
mTabHost.getTabWidget().getChildAt(0).setBackgroundColor(Color.WHITE);
mTabHost.getTabWidget().getChildAt(1).setBackgroundColor(Color.parseColor("#FCF4E7"));
mTabHost.getTabWidget().getChildAt(2).setBackgroundColor(Color.parseColor("#FCF4E7"));
mTabHost.getTabWidget().getChildAt(0)
.setBackgroundColor(Color.parseColor("#DF4426"));
TextView tv1 = (TextView) mTabHost.getTabWidget().getChildAt(0).findViewById(android.R.id.title);
tv1.setTextColor(Color.parseColor("#F6CFC2"));
TextView tv2 = (TextView) mTabHost.getTabWidget().getChildAt(1).findViewById(android.R.id.title);
tv2.setTextColor(Color.parseColor("#E03C20"));
TextView tv3 = (TextView) mTabHost.getTabWidget().getChildAt(2).findViewById(android.R.id.title);
tv3.setTextColor(Color.parseColor("#E03C20"));
// TODO To set height and width properly of tab widget
ViewGroup.LayoutParams params = mTabHost.getTabWidget().getChildAt(0).getLayoutParams();
// params.width = 128;
params.height = 50;
mTabHost.getTabWidget().getChildAt(0).setLayoutParams(params );
mTabHost.getTabWidget().getChildAt(1).setLayoutParams(params );
mTabHost.getTabWidget().getChildAt(2).setLayoutParams(params );
// for (int i = 0; i < mTabHost.getTabWidget().getChildCount(); i++) {
// TextView tv = (TextView) mTabHost.getTabWidget().getChildAt(i).findViewById(android.R.id.title);
// tv.setTextColor(Color.parseColor("#DA4426"));
// }
return mTabHost;
}
I need some help in setting the background colour using code for my current fragment. The fragment is created on selecting a particular tab.
Below is my main activity code
public class TabActionBarActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set the text and background colour
setTheme(R.style.MyTheme);
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
String label6 = getResources().getString(R.string.label6);
tab = actionBar.newTab();
tab.setText(label6);
TabListener<Tab6Fragment> tl6 = new TabListener<Tab6Fragment>(this,
label6, Tab6Fragment.class);
tab.setTabListener(tl6);
actionBar.addTab(tab);
String label7 = getResources().getString(R.string.label7);
tab = actionBar.newTab();
tab.setText(label7);
TabListener<Tab7Fragment> tl7 = new TabListener<Tab7Fragment>(this,
label7, Tab7Fragment.class);
tab.setTabListener(tl7);
actionBar.addTab(tab);
}
Now the code for the Tab7Fragment class looks like this
public class Tab7Fragment extends Fragment {
TextView tv1;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ScrollView sv = new ScrollView(this.getActivity());
LinearLayout ll = new LinearLayout(this.getActivity());
ll.setOrientation(LinearLayout.VERTICAL);
sv.addView(ll);
TextView tv = new TextView(this.getActivity());
tv.setText("Dynamic layouts ftw!");
ll.addView(tv);
EditText et = new EditText(this.getActivity());
et.setText("weeeeeeeeeee~!");
ll.addView(et);
Button b = new Button(this.getActivity());
b.setText("I don't do anything, but I was added dynamically. :)");
ll.addView(b);
for(int i = 0; i < 20; i++) {
CheckBox cb = new CheckBox(this.getActivity());
cb.setText("I'm dynamic!");
ll.addView(cb);
}
return this.getView();
}
}
Now how can i set the view for this fragment?
this.getActivity().setContentView(sv);
I know the above method is incorrect. But i need to set the content view with the scrollview layout. and another question is how do i set the background colour for this view?(using setBackgroundColor()?
Try this code in your onCreateView():
View view = inflater.inflate(R.layout.your_fragment_layout, container, false);
Then dont forget to return the view that you just inflated to the android runtime.
Remove return this.getView(); and add return view;
To set background color :
sv.setBackgroundColor(getRessources().getColors(R.color.yourcolor));
To inflate layout into a fragment, you need to return a View from onCreateView :
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.your layout, container, false);
}
I have the following FragmentActivity:
public class TabsActivity extends FragmentActivity {
private FragmentTabHost mTabHost;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tabs);
mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
mTabHost.addTab(mTabHost.newTabSpec("Home").setIndicator("Home", getResources().getDrawable(R.drawable.hometab)),HomeTab.class, null);
mTabHost.addTab(mTabHost.newTabSpec("Explore").setIndicator("Explore", getResources().getDrawable(R.drawable.exploretab)),ExploreTab.class, null);
mTabHost.addTab(mTabHost.newTabSpec("Info").setIndicator("Info", getResources().getDrawable(R.drawable.infotab)),InfoTab.class, null);
mTabHost.addTab(mTabHost.newTabSpec("Social").setIndicator("Social", getResources().getDrawable(R.drawable.socialtab)),SocialTab.class, null);
mTabHost.addTab(mTabHost.newTabSpec("Contact").setIndicator("Contact", getResources().getDrawable(R.drawable.contacttab)),ContactTab.class, null);
TabWidget tabWidget = mTabHost.getTabWidget();
tabWidget.setStripEnabled(false);
for(int i=0; i < tabWidget.getChildCount(); i++){
tabWidget.getChildAt(i).setBackgroundResource(R.drawable.tab_bg);
TextView tv = (TextView)tabWidget.getChildAt(i).findViewById(android.R.id.title);
tv.setTextColor(this.getResources().getColor(R.color.white));
}
mTabHost.setOnTabChangedListener(new OnTabChangeListener() {
#Override
public void onTabChanged(String tabId) {
Log.d("PAUL",tabId);
if(tabId=="Home"){
finish();
}
TabWidget tw = mTabHost.getTabWidget();
for(int i=0; i < tw.getChildCount(); i++){
TextView tabText = (TextView)tw.getChildAt(i).findViewById(android.R.id.title);
if(tabText.getText()==tabId){
tabText.setTextColor(TabsActivity.this.getResources().getColor(R.color.tcmgreen));
} else {
tabText.setTextColor(TabsActivity.this.getResources().getColor(R.color.white));
}
}
}
});
Intent intent = getIntent();
String tag = intent.getStringExtra("tab");
Log.d("DEBUG",tag);
mTabHost.setCurrentTabByTag(tag);
}
}
When the user taps the 'Explore' tab I get the following error: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. Here is my ExploreTab class:
public class ExploreTab extends Fragment {
private ArrayList<Level> levels;
private TCMSQLiteHelper sqliteHelper;
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
sqliteHelper = new TCMSQLiteHelper(this.getActivity());
levels = sqliteHelper.getAllLevels();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d("DEBUG","Explore Created");
View v = inflater.inflate(R.layout.explorelist, container);
return v;
}
}
This doesn't make any sense to me because I don't see where there could be a problem of a view already being loaded. What am I missing here?
In onCreateView(), you should be passing in a third parameter, false. This third parameter specifies whether the layout should attached itself to the ViewGroup container.
From the Fragments documentation:
In this case, this is false because the system is already inserting the inflated layout into the container—passing true would create a redundant view group in the final layout.
Thus your code should be:
View v = inflater.inflate(R.layout.explorelist, container, false);