Dynamic tab in Android with dynamic tab content - android

I want to create a tab dynamically in Android and under each tab I have one listview. So I want the content of the listview to also change dynamically. How can I do this ?

I saw a code on another forum and cleaned it up a little. To do what you need you'll have to change the stuff inside of ts1.setContent and ts2.setContent
Main_screen.java
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;
public class Main_screen extends Activity{
private ListView ls1;
private ListView ls2;
private TabHost myTabHost;
#Override
public void onCreate(Bundle icicle)
{
super.onCreate(icicle);
setContentView(R.layout.main);
myTabHost = (TabHost)this.findViewById(R.id.th_set_menu_tabhost);
myTabHost.setup();
ls1 = new ListView(Main_screen.this);
TabSpec ts1 = myTabHost.newTabSpec("TAB_TAG_1");
ts1.setIndicator("Tab1");
ts1.setContent(new TabHost.TabContentFactory(){
public View createTabContent(String tag)
{
ArrayAdapter<String> adapter = new ArrayAdapter<String>(Main_screen.this,android.R.layout.simple_list_item_1,new String[]{"item1","item2","item3"});
ls1.setAdapter(adapter);
return ls1;
}
});
myTabHost.addTab(ts1);
ls2 = new ListView(Main_screen.this);
TabSpec ts2 = myTabHost.newTabSpec("TAB_TAG_2");
ts2.setIndicator("Tab2");
ts2.setContent(new TabHost.TabContentFactory(){
public View createTabContent(String tag)
{
ArrayAdapter<String> adapter = new ArrayAdapter<String>(Main_screen.this,android.R.layout.simple_list_item_1,new String[]{"item4","item5","item6"});
ls2.setAdapter(adapter);
return ls2;
}
});
myTabHost.addTab(ts2);
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/th_set_menu_tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="64dip" />
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingTop="75dip">
<ListView
android:id = "#+id/danhsach"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</FrameLayout>
</TabHost>

for(int i=0; i<5; i++ )
{
final TabSpec x=tabHost2.newTabSpec("x");
View row = inflater.inflate(R.layout.indicator1,null);
final TextView indicator1 =(TextView) row.findViewById(R.id.textView_indicator1);
indicator1.setText(indicator_list[i]);
// indicator1.setShadowLayer(1, 0, 1, 0xFF013201);
x.setIndicator(row);
x.setContent(new TabContentFactory() {
public View createTabContent(String arg) {
return gallery2;
}
});
tabHost2.addTab(x);
}
you can do like this.

Related

Fragment with ListView: NullPointerException on setAdapter

I have the Problem, that I get a NullPointExeption when I want to set a adapter on my ListView.
Before I had the Fragment extended with ListFragment and a simple Adapter, that works but the problem was, that I have 3 Fragments in this activity all with ListViews and I got display errors (shows the wrong list in a fragment). So I decided to set for every Fragment own ids on the Listview but now it doesnt work.
Error listview.setAdapter(adapter):
java.lang.NullPointerException at
de.resper.e2cast.MainFragmentLive.onCreateView(MainFragmentLive.java:46)
Fragment:
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
import de.resper.e2cast.classes.globalBox;
import de.resper.e2cast.helper.getXml;
import de.resper.e2cast.helper.parseXml;
public class MainFragmentLive extends android.support.v4.app.Fragment {
private List<String> bouquetListString;
private ArrayAdapter<String> adapter;
private globalBox activeBox;
private ListView listview;
#Override
public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main_live, container, false);
activeBox = ((globalBox) getActivity().getApplicationContext());
bouquetListString = new ArrayList<String>();
bouquetListString.add("loading...");
if(activeBox.isInit()){
if(activeBox.getBouquets().size() > 0 && activeBox.getBouquets().get(2).size() > 0){
bouquetListString = activeBox.getBouquets().get(2);
}else{
Log.d("Load Bouquet", "XML");
getBouquetBox();
}
}
listview = (ListView) getActivity().findViewById(R.id.listLive);
adapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1, bouquetListString);
listview.setAdapter(adapter);
ImageButton reloadBouquet = (ImageButton) view.findViewById(R.id.reloadBouquet);
reloadBouquet.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View arg0) {
getBouquetBox();
}
});
setHasOptionsMenu(true);
return view;
}
public void getBouquetBox(){
getXml.DownloadCompleteListener dcl = new getXml.DownloadCompleteListener() {
#Override
public void onDownloadComplete(String result) {
bouquetListString.clear();
String [] tags = {"e2servicereference", "e2servicename"};
List<List<String>> bouquetsList = parseXml.parseXmlByTag(result, tags);
activeBox.addBouquets(bouquetsList);
bouquetListString.addAll(activeBox.getBouquets().get(2));
adapter.notifyDataSetChanged();
}
};
Log.d("MyLogger", "XML Request GET BOUQUET");
getXml downloader = new getXml(dcl);
downloader.execute("http://" + activeBox.getIpPort() + "/web/getservices");
}
}
Fragment XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="8dp">
<TextView
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:text="#string/selectBouquet"
style="#style/header1"/>
<ImageButton
android:layout_width="0dip"
android:layout_height="wrap_content"
android:id="#+id/reloadBouquet"
android:src="#drawable/ic_action_refresh"
android:contentDescription="#string/search"
android:layout_weight=".20"
android:layout_gravity="bottom"/>
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="1dp"
android:background="#android:color/darker_gray"/>
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/listLive" />
</LinearLayout>
Use view instead of getActivity() to initializing ListView because ListView is inside Fragment layout instead of Activity :
listview = (ListView) view.findViewById(R.id.listLive);

How to add ListView and tab bar in android

I want the list view and tab bar both at the same time and my code is below:
Please check my Main Activity and Custom Adapter and tell me what changes I need to do.
Because list is working but tabs are not being displayed.
Two XML files I have included.
1.tab_bar
2.final_tab_item
Please let me know where I am going wrong...
MainActivity.java
package com.example.tabwithlist;
import java.util.ArrayList;
import com.example.customlist.CustomAdapter;
import com.example.customlist.ListModel;
import android.app.TabActivity;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;
import android.widget.TabHost;
import android.widget.TabHost.OnTabChangeListener;
public class MainActivity extends TabActivity implements OnTabChangeListener
{
ListView list;
CustomAdapter adapter;
public ArrayList<ListModel> CustomListViewValuesArr = new ArrayList<ListModel>();
/** Called when the activity is first created. */
TabHost tabHost;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tab_bar);
// setContentView(R.layout.custom_list_view);
setListData();
Resources res =getResources();
list=(ListView)findViewById(R.id.listnew);
//**************** Create Custom Adapter *********//*
adapter=new CustomAdapter(this, CustomListViewValuesArr,res);
list.setAdapter(adapter);
for (int i = 0; i < 11; i++) {
final ListModel sched = new ListModel();
//******* Firstly take data in model object ******//*
sched.setCompanyName("Company "+i);
sched.setImage("image"+i);
sched.setUrl("http:\\\\www."+i+".com");
//******** Take Model Object in ArrayList **********//*
CustomListViewValuesArr.add(sched);
}
// Get TabHost Refference
tabHost = getTabHost();
// Set TabChangeListener called when tab changed
tabHost.setOnTabChangedListener(this);
TabHost.TabSpec spec;
Intent intent;
//************* TAB1 ************//*
// Create Intents to launch an Activity for the tab (to be reused)
intent = new Intent().setClass(this, Tab1.class);
spec = tabHost.newTabSpec("First").setIndicator("")
.setContent(intent);
//Add intent to tab
tabHost.addTab(spec);
//************* TAB2 ************//*
intent = new Intent().setClass(this, Tab2.class);
spec = tabHost.newTabSpec("Second").setIndicator("")
.setContent(intent);
tabHost.addTab(spec);
/************* TAB3 ************/
intent = new Intent().setClass(this, Tab3.class);
spec = tabHost.newTabSpec("Third").setIndicator("")
.setContent(intent);
tabHost.addTab(spec);
// Set drawable images to tab
tabHost.getTabWidget().getChildAt(1).setBackgroundResource(R.drawable.tab2);
tabHost.getTabWidget().getChildAt(2).setBackgroundResource(R.drawable.tab3);
// Set Tab1 as Default tab and change image
tabHost.getTabWidget().setCurrentTab(0);
tabHost.getTabWidget().getChildAt(0).setBackgroundResource(R.drawable.tab1_over);
}
private void setListData() {
for (int i = 0; i < 11; i++) {
final ListModel sched = new ListModel();
/******* Firstly take data in model object ******/
sched.setCompanyName("Company "+i);
sched.setImage("image"+i);
sched.setUrl("http:\\\\www."+i+".com");
/******** Take Model Object in ArrayList **********/
CustomListViewValuesArr.add(sched);
}
}
#Override
public void onTabChanged(String tabId) {
/************ Called when tab changed *************/
//********* Check current selected tab and change according images *******/
for(int i=0;i<tabHost.getTabWidget().getChildCount();i++)
{
if(i==0)
tabHost.getTabWidget().getChildAt(i).setBackgroundResource(R.drawable.tab1);
else if(i==1)
tabHost.getTabWidget().getChildAt(i).setBackgroundResource(R.drawable.tab2);
else if(i==2)
tabHost.getTabWidget().getChildAt(i).setBackgroundResource(R.drawable.tab3);
}
Log.i("tabs", "CurrentTab: "+tabHost.getCurrentTab());
if(tabHost.getCurrentTab()==0)
tabHost.getTabWidget().getChildAt(tabHost.getCurrentTab()).setBackgroundResource(R.drawable.tab1_over);
else if(tabHost.getCurrentTab()==1)
tabHost.getTabWidget().getChildAt(tabHost.getCurrentTab()).setBackgroundResource(R.drawable.tab2_over);
else if(tabHost.getCurrentTab()==2)
tabHost.getTabWidget().getChildAt(tabHost.getCurrentTab()).setBackgroundResource(R.drawable.tab3_over);
}
}
CustomAdapter.java(Here I am inflating my final_tab_item.xml file which displays how list view will look like.)
package com.example.customlist;
import java.util.ArrayList;
import android.R;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.view.LayoutInflater;
//import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class CustomAdapter extends BaseAdapter {
/*********** Declare Used Variables *********/
private Activity activity;
private ArrayList data;
private static LayoutInflater inflater=null;
public Resources res;
ListModel tempValues=null;
int i=0;
/************* CustomAdapter Constructor *****************/
public CustomAdapter(Activity a, ArrayList d,Resources resLocal) {
/********** Take passed values **********/
activity = a;
data=d;
res = resLocal;
/*********** Layout inflator to call external xml layout () **********************/
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
/******** What is the size of Passed Arraylist Size ************/
public int getCount() {
if(data.size()<=0)
return 1;
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
/********* Create a holder to contain inflated xml file elements ***********/
public static class ViewHolder{
public TextView text;
public TextView text1;
public TextView textWide;
public ImageView image;
}
/*********** Depends upon data size called for each row , Create each ListView row ***********/
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
ViewHolder holder;
if(convertView==null){
/********** Inflate tabitem.xml file for each row ( Defined below ) ************/
//vi = inflater.inflate(R.layout., null);
vi=inflater.inflate(com.example.tabwithlist.R.layout.final_tab_item,null);
/******** View Holder Object to contain tabitem.xml file elements ************/
holder=new ViewHolder();
holder.text=(TextView)vi.findViewById(com.example.tabwithlist.R.id.text);
holder.text1=(TextView)vi.findViewById(com.example.tabwithlist.R.id.text1);
holder.image=(ImageView)vi.findViewById(com.example.tabwithlist.R.id.image);
/************ Set holder with LayoutInflater ************/
vi.setTag(holder);
}
else
holder=(ViewHolder)vi.getTag();
if(data.size()<=0)
{
holder.text.setText("No Data");
}
else
{
/***** Get each Model object from Arraylist ********/
tempValues=null;
tempValues = (ListModel) data.get(position);
/************ Set Model values in Holder elements ***********/
holder.text.setText(tempValues.getCompanyName());
holder.text1.setText(tempValues.getUrl());
holder.image.setImageResource(res.getIdentifier("com.example.tabwithlist:drawable/"+tempValues.getImage(),null,null));
/******** Set Item Click Listner for LayoutInflater for each row ***********/
// vi.setOnClickListener(new OnItemClickListener(position));
}
return vi;
}
}
tab_bar.xml(In this file I am declaring list view and tab bar)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TabHost
android:id="#android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RelativeLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"/>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</RelativeLayout>
</TabHost>
<ListView
android:id="#+id/listnew"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</RelativeLayout>
Ur MainActivity loads the tabs only, put our listview code in first tab (Tab1.class)
Changes:
tab_bar.xml with
<TabHost
android:id="#android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RelativeLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"/>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</RelativeLayout>
</TabHost>
remove all the listview code from ur MainActivity.
Create Tab1, Tab2 and Tab3 activities.
Create new xml add
<ListView
android:id="#+id/listnew"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
Move all the listview code to Tab1.java

Creating an Android app using TabHost and multiple fragments

I have been trying to create a basic Android app that contains tabs, which when clicked will load a new fragment - each fragment being a separate xml file. I would like to use TabHost and not the Activity Bar tabs. I have been looking through many tutorials on the web and posts here on stackoverflow, but to no avail. Most questions and tutorials are discussing either fragments OR tabs, but not both subjects. Thank you in advance for the suggestions.
I would like to try a very basic app that contains:
one fragment to input a number - xml file_1 (1st tab)
one fragment to display the number in a TextView - xml file_2 (2nd tab)
try like this
your xml file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TabHost
android:id="#android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1" >
<FrameLayout
android:id="#+id/tab_1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</FrameLayout>
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="0dip"
android:layout_marginRight="0dip"
android:layout_weight="0" />
</LinearLayout>
</TabHost>
</LinearLayout>
In your activity onCreate
mTabHost = (TabHost)findViewById(android.R.id.tabhost);
mTabHost.setOnTabChangedListener(this);
mTabHost.setCurrentTab(0);
setupTabs();
setupTabs() method
private void setupTabs() {
mTabHost.setup();
setupTab(new TextView(this), "Tab1");
setupTab(new TextView(this), "Tab2");
setupTab(new TextView(this), "Tab3");
mTabHost.getTabWidget().setDividerDrawable(R.drawable.empty);//not necessery
}
setupTab() method //setup a single tab
private void setupTab(final View view, final String tag) {
View tabview = createTabView(mTabHost.getContext(), tag);
TabSpec setContent = mTabHost.newTabSpec(tag).setIndicator(tabview).setContent(new TabContentFactory() {
public View createTabContent(String tag) {
return view;
}
});
mTabHost.addTab(setContent);
}
createTabView method
private static View createTabView(final Context context, final String text) {
int resouceId = R.layout.tabs_bg;
if(text.equals("Tab1")) {
resouceId = R.layout.tab_1_layout;
} else if(text.equals("Tab2")) {
resouceId = R.layout.tab_2_layout;
}
View view = LayoutInflater.from(context).inflate(resouceId, null);
return view;
}
onTabChanged method
#Override
public void onTabChanged(String tabId) {
Log.d("TAB_CHANGE","onTabChanged(): tabId=" + tabId);
updateTab(tabId, R.id.tab_1,new YourFragment());
}
public void updateTab(String tabId, int placeholder,Fragment fragment) {
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction()
.replace(placeholder,fragment, tabId)
.commit();
}
First off, thanks to deniz for getting me close enough to the right solution I could eke out a working project. Now, this should be closer to functional. I changed names to be generic, but hopefully everything will work as intended and be enough to help you understand what's happening.
TabHostActivity (your main Activity):
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TabHost;
import android.widget.TextView;
public class TabHostActivity extends FragmentActivity implements TabHost.OnTabChangeListener
{
private static final String TAG = "TabHostActivity";
private TabHost tabHost;
#Override
protected void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabhost);
tabHost = (TabHost) findViewById(android.R.id.tabhost);
tabHost.setOnTabChangedListener(this);
tabHost.setCurrentTab(0);
setupTabs();
}
private void setupTabs()
{
tabHost.setup();
setupTab(new TextView(this), "tab1");
setupTab(new TextView(this), "tab2");
setupTab(new TextView(this), "tab3");
setupTab(new TextView(this), "tab4");
}
private void setupTab(final View view, final String tag)
{
View tabview = createTabView(tabHost.getContext(), tag);
TabHost.TabSpec setContent = tabHost.newTabSpec(tag)
.setIndicator(tabview)
.setContent(new TabHost.TabContentFactory()
{
public View createTabContent(String tag)
{
return view;
}
});
tabHost.addTab(setContent);
}
/**
* Return the view for the individual tabs, the tab view being set is identified by tabId.
*
* #param context
* #param tabId
* #return
*/
private static View createTabView(final Context context, final String tabId)
{
int resourceId;
if (tabId.equals("tab1"))
{
resourceId = R.layout.tab1;
}
else if (tabId.equals("tab2"))
{
resourceId = R.layout.tab2;
}
else if (tabId.equals("tab3"))
{
resourceId = R.layout.tab3;
}
else
{
resourceId = R.layout.tab4;
}
return LayoutInflater.from(context).inflate(resourceId, null);
}
#Override
public void onTabChanged(String tabId)
{
Log.d(TAG, "onTabChanged(): tabId=" + tabId);
if (tabId.equalsIgnoreCase("tab1"))
{
updateTab(android.R.id.tabcontent, new tab1(), tabId);
}
else if (tabId.equalsIgnoreCase("tab2"))
{
updateTab(android.R.id.tabcontent, new tab2(), tabId);
}
else if (tabId.equalsIgnoreCase("tab3"))
{
updateTab(android.R.id.tabcontent, new tab3(), tabId);
}
else
{
updateTab(android.R.id.tabcontent, new tab4(), tabId);
}
}
public void updateTab(int placeholder, Fragment fragment, String tabId)
{
getSupportFragmentManager().beginTransaction()
.replace(placeholder, fragment, tabId)
.commit();
}
}
activity_tabhost.xml:
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1" >
<FrameLayout
android:id="#+id/tab_1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<FrameLayout
android:id="#+id/tab_2"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<FrameLayout
android:id="#+id/tab_3"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<FrameLayout
android:id="#+id/tab_4"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</FrameLayout >
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout >
</TabHost >
tab1.xml, tab2.xml, tab3.xml, tab4.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</LinearLayout>
tab1.java, tab2.java, tab3.java, tab4.java:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class tab1 extends Fragment
{
private static final String TAG = "tab1";
#Override
public void onActivityCreated(final Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
Log.i(TAG, "onActivityCreated");
}
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState)
{
Log.i(TAG, "onCreateView");
return inflater.inflate(R.layout.tab1, container, false);
}
}
AndroidManifest.xml:
<activity android:name="<YOUR_PACKAGE_NAME>.TabHostActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
This was done using v19 of the API as target, and with a minimum of v10 using the android.support.v4.app library.
So again, thank you deniz for getting me to this point, I had spent 10 hours trying things and everything I found was out of date. Hopefully this can help other people who are in my ex-state of limbo. You should now have a working state and can see where you can design the tabs as well as where you put the contents of the Fragments.
PS - yes, in my generalization pass it did result in the xml content and the tabs being called "tab1.whatever", hopefully this isn't too confusing, which is which can be deduced with a little context.

how to rename tab android use tabhost and long click

I have designed an app in that I am using Tabhost and I have added two tabs. I want rename tab Device1 when "long click" this tab. I try some way but it is not working. I have implemented following:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/tabHost"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<HorizontalScrollView
android:id="#+id/horScrollView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:scrollbars="none" >
<TabWidget
android:id="#android:id/tabs"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</HorizontalScrollView>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:id="#+id/Device1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:paddingTop="80px" >
</LinearLayout>
<LinearLayout
android:id="#+id/Device2"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:paddingTop="80px" >
</LinearLayout>
</FrameLayout>
MainActivity.java
package com.example.renametab;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.widget.TabHost;
import android.widget.TextView;
import android.widget.TabHost.TabSpec;
public class MainActivity extends Activity {
public static TabHost tabHost;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabHost = (TabHost) findViewById(R.id.tabHost);
tabHost.setup();
TabSpec tabDevice1 = tabHost.newTabSpec("Device1");
tabDevice1.setContent(R.id.Device1);
tabDevice1.setIndicator("Device1");
TabSpec tabDevice2 = tabHost.newTabSpec("Device2");
tabDevice2.setContent(R.id.Device2);
tabDevice2.setIndicator("Device2");
tabHost.addTab(tabDevice1);
tabHost.addTab(tabDevice2);
tabHost.getTabWidget().getChildAt(0).setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
//How to rename tab????
//I try this way but it is false
TextView tv = (TextView) tabHost.getTabWidget().getChildAt(0).findViewById(R.id.Device1);
tv.setText("New Name Tab");
return true;
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
On close inspection using the Android Studio debugger, each tab contained in TabWidget is a LinearLayout with 2 children:
An ImageView with the id android.R.id.icon;
A TextView with the id android.R.id.title.
Knowing this, we can find each tab's title TextView, set an OnLongClickListener on each tab, and then modify the title using TextView.setText().
Here's my Fragment's onCreateView() method, defining 3 tabs, each implementing this functionality:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
mTabHost = (TabHost) rootView.findViewById(android.R.id.tabhost);
mTabHost.setup();
mTabHost.addTab(mTabHost.newTabSpec(TAB_1).setIndicator("Tab 1").setContent(R.id.tab_1));
mTabHost.addTab(mTabHost.newTabSpec(TAB_2).setIndicator("Tab 2").setContent(R.id.tab_2));
mTabHost.addTab(mTabHost.newTabSpec(TAB_3).setIndicator("Tab 3").setContent(R.id.tab_3));
LinearLayout tabOne = (LinearLayout) mTabHost.getTabWidget().getChildTabViewAt(0);
final TextView tabOneTitle = (TextView) tabOne.findViewById(android.R.id.title);
LinearLayout tabTwo = (LinearLayout) mTabHost.getTabWidget().getChildTabViewAt(1);
final TextView tabTwoTitle = (TextView) tabTwo.findViewById(android.R.id.title);
LinearLayout tabThree = (LinearLayout) mTabHost.getTabWidget().getChildTabViewAt(2);
final TextView tabThreeTitle = (TextView) tabThree.findViewById(android.R.id.title);
tabOne.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
tabOneTitle.setText("New Tab 1");
return true;
}
});
tabTwo.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
tabTwoTitle.setText("New Tab 2");
return true;
}
});
tabThree.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
tabThreeTitle.setText("New Tab 3");
return true;
}
});
return rootView;
}
Here are before and after screenshots documenting the results:
Simply use the onTabChanged event:
TabHost th = new findViewById(android.R.id.tabhost);
th.setOnTabChangedListener(new OnTabChangeListener() {
#Override
public void onTabChanged(final String tabId) {
TextView tv = (TextView) th.getCurrentView();
tv.setText("New Name Tab");
}
});
<TextView
android:id="#+id/textView1"
android:layout_width="204dp"
android:layout_height="match_parent"
android:paddingLeft="10dp"
android:text="TAB 1"/>
Add a TextView in both the linear layouts in the xml file and set their text dynamically using Tab Change Listener :-
TabHost tabHost = new findViewById(android.R.id.tabHost1);
tabHost.setOnTabChangedListener(new OnTabChangeListener() {
#Override
public void onTabChanged(final String tabId) {
TextView textView1 = (TextView) tabHost.getCurrentView();
textView1.setText("This Tab is Selected");
}
});

TabHost with Fragments and FragmentActivity

I'm working on an Android App and I want to use 3 tabs for navigation using Fragments for each tab, but I don't know how to create the structure for doing it.
I want to add each fragment separately because each one is different, but I don't know where to add them in FragmentActivity.
I have these files.
tabs_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_height="match_parent"
android:layout_width="match_parent">
<TabHost android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TabWidget
android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<FrameLayout
android:id="#+id/tabRateAPet"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<FrameLayout
android:id="#+id/tabViewMyRates"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<FrameLayout
android:id="#+id/tabViewGlobalRates"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</FrameLayout>
</LinearLayout>
</TabHost>
</LinearLayout>
TabsMain.java
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
public class MainTabsActivity extends FragmentActivity {
public static final String RATE_A_PET = "Rate a Pet";
public static final String MY_RATES = "My Rates";
public static final String GLOBAL_RATES = "Global Rates";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tabs_layout);
}
}
Tabs.java
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TabHost;
import android.widget.TabHost.OnTabChangeListener;
import android.widget.TabHost.TabSpec;
import android.widget.TextView;
public class Tabs extends Fragment implements OnTabChangeListener {
private static final String TAG = "FragmentTabs";
public static final String RATE_A_PET = "Rate a Pet";
public static final String MY_RATES = "My Rates";
public static final String GLOBAL_RATES = "Global Rates";
private View mRoot;
private TabHost mTabHost;
private int mCurrentTab;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// super.onCreateView(inflater, container, savedInstanceState);
mRoot = inflater.inflate(R.layout.tabs_layout, null);
mTabHost = (TabHost) mRoot.findViewById(android.R.id.tabhost);
setupTabs();
return mRoot;
}
private void setupTabs() {
mTabHost.setup(); // important!
mTabHost.addTab(newTab(RATE_A_PET, R.string.tabRateAPet, R.id.tabRateAPet));
mTabHost.addTab(newTab(MY_RATES, R.string.tabViewMyRates, R.id.tabViewMyRates));
}
private TabSpec newTab(String tag, int labelId, int tabContentId) {
Log.d(TAG, "buildTab(): tag=" + tag);
View indicator = LayoutInflater.from(getActivity()).inflate(
R.layout.tab,
(ViewGroup) mRoot.findViewById(android.R.id.tabs), false);
((TextView) indicator.findViewById(R.id.text)).setText(labelId);
TabSpec tabSpec = mTabHost.newTabSpec(tag);
tabSpec.setIndicator(indicator);
tabSpec.setContent(tabContentId);
return tabSpec;
}
#Override
public void onTabChanged(String tabId) {
Log.d(TAG, "onTabChanged(): tabId=" + tabId);
if (RATE_A_PET.equals(tabId)) {
updateTab(tabId, R.id.tabRateAPet);
mCurrentTab = 0;
return;
}
if (MY_RATES.equals(tabId)) {
updateTab(tabId, R.id.tabViewMyRates);
mCurrentTab = 1;
return;
}
if (GLOBAL_RATES.equals(tabId)) {
updateTab(tabId, R.id.tabViewGlobalRates);
mCurrentTab = 2;
return;
}
}
private void updateTab(String tabId, int placeholder) {
FragmentManager fm = getFragmentManager();
if (fm.findFragmentByTag(tabId) == null) {
fm.beginTransaction()
.replace(placeholder, new RateMyPetActivity(), tabId)
.commit();
}
}
}
I would suggest creating a separate fragment file for each tab. I recently did this as well, so I have outlined my code below:
Layout Files
activity_main.xml
<android.support.v4.app.FragmentTabHost
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TabWidget
android:id="#android:id/tabs"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"/>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0"/>
<FrameLayout
android:id="#+id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
tab1_view.xml //add your respective tab layouts using this format (make sure to change string variables)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".DeviceFragment" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/tab1_fragment_string" />
</LinearLayout>
SRC Files
MainActivity.java //notice that in the .addTab process I only used text. You can also add icons using drawables that you would need to add to your hdpi folder. I also only created three tabs in this example.
package com.example.applicationname;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTabHost;
public class MainActivity extends FragmentActivity {
// Fragment TabHost as mTabHost
private FragmentTabHost mTabHost;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
mTabHost.addTab(mTabHost.newTabSpec("tab1").setIndicator("Tab1"),
Tab1Fragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("tab2").setIndicator("Tab2"),
Tab2Fragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("tab3").setIndicator("Tab3"),
Tab3Fragment.class, null);
}
}
Tab1Fragment.java //once again replicate for desired number of tabs
package com.example.applicationname;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Tab1Fragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View V = inflater.inflate(R.layout.tab1_view, container, false);
return V;
}
}
Make sure that your R.java and strings.xml files are properly set up, and then your tabs should be up and running.
TabHost doesn't retains Fragment's states. So why using TabHost?
So use ViewPager with TabLayout instead.
Prons of Viewpager over Tabhost:
ViewPager retains Fragments states. Mean Fragment will not again recreated if switched.
Inbuilt swiping feature that gives user smoother experience.
Less CPU consumption, because Tabhost recreates Fragment/Activity again and again when Tab is switched.
See the difference :
Using Tablayout + ViewPager (Supports swipe, retains Fragments states
Using TabHost (Doesn't support swipe, doesn't retain states)
Small Code for Tablayout + ViewPager
// find views by id
ViewPager viewPager = findViewById(R.id.viewpager);
TabLayout tabLayout = findViewById(R.id.tablayout);
// attach tablayout with viewpager
tabLayout.setupWithViewPager(viewPager);
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
// add your fragments
adapter.addFrag(new SampleFragment(), "Tab1");
adapter.addFrag(new SampleFragment(), "Tab2");
adapter.addFrag(new SampleFragment(), "Tab3");
// set adapter on viewpager
viewPager.setAdapter(adapter);
XML layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="#+id/tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.viewpager.widget.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
Note If you are not using AndroidX yet, you need to change following in layout.
Change com.google.android.material.tabs.TabLayout to android.support.design.widget.TabLayout
Chagne androidx.viewpager.widget.ViewPager to android.support.v4.view.ViewPager
But I'll strongly recommend to migrate to AndroidX, see #this answer to understand why.
And this is common ViewPagerAdapter for all your Viewpager in app.
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = 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();
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
public void addFrag(Fragment fragment) {
mFragmentList.add(fragment);
mFragmentTitleList.add("");
}
public void addFrag(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
}
Important Related Links
Difference between getSupportFragmentManager() and getChildFragmentManager()?
getSupportFragmentManager() versus getFragmentManager() in android 3.0+
Difference between FragmentPagerAdapter and FragmentStatePagerAdapter

Categories

Resources