I am having a problem with a list view that will only show one row at a time even though there are many rows.
The list view is included within a tab so the problem could be there rather than in the list view.
I first tried defining the list view in a separate layout file and using that when creating the tab. When that didn't work I put it into the FrameLayout with the tab definition.
Same result.
<?xml version="1.0" encoding="utf-8"?>
<TabHost android:layout_width="fill_parent"
android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost">
<LinearLayout android:id="#+id/LinearLayout01"
android:orientation="vertical" android:layout_height="fill_parent"
android:layout_width="fill_parent">
<TabWidget android:id="#android:id/tabs"
android:layout_height="fill_parent" android:layout_width="wrap_content"></TabWidget>
<FrameLayout android:id="#android:id/tabcontent"
android:layout_height="fill_parent" android:layout_width="fill_parent">
<ListView android:id="#+id/list1" android:layout_width="fill_parent"
android:layout_height="fill_parent">
</ListView></FrameLayout>
</LinearLayout>
</TabHost>
This is the code I use to create and add the tab:
protected void addTab(String tabName, TabHost.TabContentFactory tabFactory){
TabSpec tabSpec = tabHost.newTabSpec(tabName);
tabSpec.setIndicator(tabName);
tabSpec.setContent(tabFactory);
tabHost.addTab(tabSpec);
tabs.add(new TabDetails(tabName,tabFactory));
}
I call it with:
addTab("Medical Center Tests",this);
and include this code for creating the tab contents:
#Override
public View createTabContent(String tag) {
// Get the data returned from the servelet and display it in the ListView
data = getDataArray(this.getIntent().getExtras());
ListView lv = (ListView) contentView.findViewById(R.id.list1);
lv.setAdapter(new MyMedicalCentersTestsScreenAdapter(this,lv,data));
return lv;
}
The data is all there. It's just the the height of the list view is equal to the height of one row.
EDIT:
I added some debug commands to see what position the getView requests. It only requests the first row and then requests them one at a time as I scroll.
So, it is definitely seeing it as a small listview and scrolling them accordingly.
Edit 2:
Decided to try an experiment.
Returned a simple list for the list view.
ListView lv = (ListView) contentView.findViewById(R.id.list1);
// create some dummy strings to add to the list
List<String> list1Strings = new ArrayList<String>();
list1Strings.add("Item 1");
list1Strings.add("Item 2");
list1Strings.add("Item 3");
list1Strings.add("Item 4");
lv.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, list1Strings));
Still the same. Only one row at a time.
you define height of layout rather than using fill_parent...
code:
layout_height ="150dp"
try doing this
<TabWidget android:id="#android:id/tabs"
android:layout_height="fill_parent" android:layout_width="fill_parent"></TabWidget>
instead of
<TabWidget android:id="#android:id/tabs"
android:layout_height="fill_parent" android:layout_width="wrap_content"></TabWidget>
android:layout_height="wrap_content" or android:layout_height="100dp"
instead of this
android:layout_height="fill_parent"
Your layout is a little weird cause the tabWidget (it displays a list of tab labels representing each page in the parent's tab collection) height is set to fill_parent. How about something like this?
<?xml version="1.0" encoding="utf-8"?>
<TabHost android:layout_width="fill_parent"
android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost">
<LinearLayout
android:id="#+id/LinearLayout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TabWidget
android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="84dp" >
</TabWidget>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:id="#+id/tab1"
android:layout_width="match_parent"
android:layout_height="fill_parent">
<ListView
android:id="#+id/list1"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
<LinearLayout
android:id="#+id/tab2"
android:layout_width="match_parent"
android:layout_height="fill_parent" >
</LinearLayout>
</FrameLayout>
</LinearLayout>
</TabHost>
For tabs:
tabhost = (TabHost) findViewById(android.R.id.tabhost);
tabhost.setup();
TabSpec ts = tabhost.newTabSpec("tag1");
ts.setContent(R.id.tab1);
ts.setIndicator("TAB1");
tabhost.addTab(ts);
ts = tabhost.newTabSpec("tag2");
ts.setContent(R.id.tab2);
ts.setIndicator("TAB2");
tabhost.addTab(ts);
You add tabs in that way 'cause you add them dynamically?
Related
i'm using Listview on Tab Layout in my android app to load data from network. Tha tabs are working properly and i can switch between my tabs easily without any error but when the listview is populated with data from server the tabs go away and i've a simple listview with data. I can't see my other tabs anymore.
PS The data is loading just fine without any problem.
Here is the Home java code for home_layout
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home_layout);
TabHost tabHost = getTabHost();
TabHost.TabSpec myprofiletab = tabHost.newTabSpec("Profile");
myprofiletab.setIndicator("Profile",getResources().getDrawable(R.drawable.myprofile_icon));
Intent myprofileintent = new Intent(this,MyProfile.class);
myprofiletab.setContent(myprofileintent);
TabHost.TabSpec newsfeedtab = tabHost.newTabSpec("NewsFeed");
newsfeedtab.setIndicator("Feed",getResources().getDrawable(R.drawable.newsfeed_icon));
Intent feed = new Intent(this,NewsFeed.class);
newsfeedtab.setContent(feed);
tabHost.addTab(newsfeedtab);
tabHost.addTab(myprofiletab);
}
Here is the home_layout
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="fill_parent"
android:layout_alignParentBottom="true"
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>
Solved my problem by adding one line to my FrameLayout
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#android:id/tabs" />
I have a little problem using Tabs with Views.
First I just copied the sample code where Tabs are used with activitys:
My LayoutFile looks like this:
<?xml version="1.0" encoding="utf-8"?>
<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:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp">
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp" />
</LinearLayout>
</TabHost>
And this is my Java-code:
public class MyActivity extends TabActivity{
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState)
setContentView(R.layout.main);
TabHost tH = getTabHost();
Indent intent = new Intent().setClass(this, AnotherActivity.class);
// Initialize a TabSpec for each tab and add it to the TabHost
//TextView Test = new TextView(this);
//Test.setText("test");
tH.addTab(tH.newTabSpec("t1").setIndicator("Tab1").setContent(intent));
tH.setCurrentTab(0);
}
}
And this works as expected.
But when I uncomment the TextView-lines and call setContent(Test.getId()) instead of setContent(intent), the app crashes.
I also tried to create a textview in the layoutfile, and call setContent(R.id.test),
that also makes it crash.
So this is one problem.
The seccond point is. I do not want to use activitys, because i want to be able to call methods on those classes, which shall represent the Tab-content.
So my original idea is, to derive some classes from view. 1 for each tab, and pass their ids. But therefor the codesample above needs to work first.
greetings Uzaku
I know you said you tried a TextView in the layout file but this should work...
Change the FrameLayout section as follows...
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp" >
<TextView
android:id="#+id/test"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="TEST" />
</FrameLayout>
Then in your code do the following...
tH.addTab(tH.newTabSpec("t1").setIndicator("Tab1").setContent(R.id.test));
I'm trying to insert a ListView as one of the tabs in a tabhost. I've scoured the web and found several implementations that say they work, but don't for me (either in their own projects or when incorporated into mine).
I've settled on the following, which works (as far as not crashing) and I'm not getting any errors in LogCat, but the tab appears empty.
I've checked the array supplying the list (tooldisplay) and it is populated.
I would rather not have to fire another activity to populate the tab.
setupdetail.xml:
<?xml version="1.0" encoding="utf-8"?>
<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"
android:padding="5dp" >
<TextView
android:id="#+id/setupheader"
android:layout_width="fill_parent"
android:layout_height="20dp"
android:text="This will be the setup header"
android:textSize="15dp" />
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="30dp"
android:gravity="bottom" />
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp" >
<!-- General Info Tab -->
<LinearLayout
android:id="#+id/general_tab"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
<!-- Tool Tab -->
<ListView
android:id="#+id/list1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:drawSelectorOnTop="false" />
</FrameLayout>
</LinearLayout>
</TabHost>
activity for tabhost (edited to remove non-relevant code):
public class SetupDisplay extends TabActivity {
private String[] tooldisplay = new String[20];
private ListView mListView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.setupdetailmain);
// Set up tabs
TabHost tabHost = getTabHost();
TabHost.TabSpec spec;
spec = tabHost.newTabSpec("general").setIndicator("General")
.setContent(R.id.general_tab);
tabHost.addTab(spec);
spec = tabHost.newTabSpec("tools").setIndicator("Tools")
.setContent(R.id.list1);
tabHost.addTab(spec);
// Load data into tooldisplay[]
// get view & set adapter
mListView = (ListView)findViewById(R.id.list1);
mListView.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, tooldisplay));
}
}
I found the source of my problem after much more googling. Posting an answer for anyone who might come later with the same issue.
I was using the wrong contructor.
Since I have more than a textview in the layout, I need to specify the layout AND the textview for the adapter (Note my code for the fix is a little different from originally posted as I switched to a custom list layout, but the issue was still there until I came upon the constructor fix).
mListView.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, tooldisplay));
should be:
ListView mListView = (ListView)findViewById(R.id.list1);
mListView.setAdapter(new ArrayAdapter<String>(this,
R.layout.listlayout, R.id.ListItem1, tooldisplay));
can anybody tell how to reduce the height of tab bar and display tab bar in bottom
Thanks
use the following line of code to change the height, this is the last line in my onCreate method
tabHost.getTabWidget().getChildAt(0).getLayoutParams().height =35;
Add the following method to your class that extends TabActivity
public void addNewTab(Context context, String title, int height){
TabHost tabHost = getTabHost(); // The activity TabHost
Intent intent = new Intent().setClass(context, HelloTabsActivity.class);
TabHost.TabSpec spec = tabHost.newTabSpec(title.toLowerCase()).setIndicator(title).setContent(intent);
tabHost.addTab(spec);
int totalTabs = tabHost.getTabWidget().getChildCount();
((RelativeLayout)tabHost.getTabWidget().getChildTabViewAt(totalTabs-1)).removeViewAt(0);
((TextView)((RelativeLayout)tabHost.getTabWidget().getChildTabViewAt(totalTabs-1)).getChildAt(0)).setHeight(30);
tabHost.getTabWidget().getChildAt(totalTabs-1).getLayoutParams().height = height;
}
then call it like this addNewTab(this, "tab title", 30);
Note that you have to change the height of each tab. For two tabs:
#Override
public void onCreate(Bundle savedInstanceState) {
... // other code
final int height = 45;
mTabHost.getTabWidget().getChildAt(0).getLayoutParams().height = height;
mTabHost.getTabWidget().getChildAt(1).getLayoutParams().height = height;
}
You could either
Build your own tab using a TableLayout at the bottom of the screen - which gives you quite a lot of flexibility
or
Modify use the existing TabHost/TabWidget - works in principle but I don't know how to reduce the tab bar height. Works like that:
Layout file main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TabHost android:id="#+id/tab_host"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<TabWidget android:layout_width="fill_parent"
android:layout_height="wrap_content" android:id="#android:id/tabs"
android:layout_gravity="bottom" />
<FrameLayout android:id="#android:id/tabcontent"
android:layout_width="fill_parent" android:layout_height="fill_parent" >
<LinearLayout android:id="#+id/first_tab"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView android:layout_width="fill_parent"
android:layout_height="fill_parent" android:text="First Tab" />
<!-- Replace TextView with your layout content for this tab -->
</LinearLayout>
<LinearLayout android:id="#+id/second_tab"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView android:layout_width="fill_parent"
android:layout_height="fill_parent" android:text="Second Tab" />
<!-- Replace TextView with your layout content for this tab -->
</LinearLayout>
<LinearLayout android:id="#+id/third_tab"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView android:layout_width="fill_parent"
android:layout_height="fill_parent" android:text="One More Tab" />
<!-- Replace TextView with your layout content for this tab -->
</LinearLayout>
<LinearLayout android:id="#+id/edit_item_text_tab"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</FrameLayout>
</TabHost>
</LinearLayout>
Source code of your activity, in this case StartActivity.java
import android.app.Activity;
import android.os.Bundle;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;
public class StartActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabHost tab_host = (TabHost) findViewById(R.id.tab_host);
tab_host.setup();
TabSpec tabspec1 = tab_host.newTabSpec("TAB_1");
tabspec1.setIndicator("Tab 1");
tabspec1.setContent(R.id.first_tab);
tab_host.addTab(tabspec1);
TabSpec tabspec2 = tab_host.newTabSpec("TAB_2");
tabspec2.setIndicator("Tab 2");
tabspec2.setContent(R.id.second_tab);
tab_host.addTab(tabspec2);
TabSpec tabspec3 = tab_host.newTabSpec("TAB_3");
tabspec3.setIndicator("Tab 3");
tabspec3.setContent(R.id.third_tab);
tab_host.addTab(tabspec3);
tab_host.setCurrentTab(0);
}
}
Turns out to look like:
<?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="wrap_content" android:padding="1dp">
<RelativeLayout android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TabWidget android:id="#android:id/tabs"
android:layout_width="fill_parent" android:layout_height="60dp"
android:layout_alignParentBottom="true" />
<FrameLayout android:id="#android:id/tabcontent"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:padding="1dp">
</FrameLayout>
</RelativeLayout>
Most likely you'll have to implement tabs by your own. As far as I know that's impossible with regular android tabs.
<TabWidget android:id="#android:id/tabs"
android:tabStripEnabled="false"
android:padding="0dip"
android:layout_width="wrap_content"
android:layout_height="fill_parent"/>
Working with tabs in the Eclipse "graphical layout" mode is not quite intuitive.
NOTE - Currently I am not able to attach pictures to this answer as my reputation is
below 10. Maybe in the future I will edit it and add them.
1) To change tab bar height:- Select "tabs (TabWidget)" in the Outline view. A selection/resize box should appear around the tab bar and its height can now be modified. I have made it thinner in picture1.
2) To move the tab bar to bottom:- Select "tabs (TabWidget)" in the Outline view and drop it into the LinearLayout above it (as marked in the picture 1). This will send the "tabs (TabWidget)" to the bottom of the list (see picture2). Tabs Bar might disappear at this stage. So adjust the weights of "tabcontent" & "tabs (TabWidget)" till it looks ok. I have used 10 & 1 respectively.
3) To bring tab2 to the top:- After design/layout of tab1 is complete, we want to work on the next tab. But Eclipse does not allow selecting it. To bring tab2 to the top select tab1 and drop it into tabcontent. This will send tab1 to the bottom of the list and tab2 to the top.
Later when work on tab2 is complete, tab3 can be brought up.
This pretty roundabout way of working in graphical layout mode but maybe better than typing xml code.
Cheers
I never designed UIs (more of a middleware guy) before so I apologize if the question is stupid. I am designing a UI to look something like the following:
ImageView ImageView
TabHost
Tab 0 ------ Tab 1 ------ Tab 2
-----INSIDE EACH TAB-----
TextView
ListView
- Consists of ImageView TextView
The problem is I think I am following a very inefficient way of doing the whole stuff. The onCreate method is as follows:
CODE:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabHost mTabHost = getTabHost();
Drawable Tab1Icon = getResources().getDrawable(R.drawable.tab1_icon);
Drawable Tab2Icon = getResources().getDrawable(R.drawable.tab2_icon);
Drawable Tab3Icon = getResources().getDrawable(R.drawable.tab3_icon);
mTabHost.addTab(mTabHost.newTabSpec("Tab1").setIndicator("Tab 1", Tab1Icon).setContent(new Intent(this, Tab1.class)));
mTabHost.addTab(mTabHost.newTabSpec("Tab2").setIndicator("Tab 2", Tab1Icon).setContent(new Intent(this, Tab2.class)));
mTabHost.addTab(mTabHost.newTabSpec("Tab3").setIndicator("Tab 3", Tab1Icon).setContent(new Intent(this, Tab3.class)));
mTabHost.setCurrentTab(0);
}
This program crashes on CupCake (v1.5) complaining about StackOverflowException but runs well on Donut (v1.6). This is my main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/application_background"
>
<TableLayout
android:id="#+id/TableLayout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stretchColumns="0"
android:background="#color/application_background">
<TableRow>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView id="#+id/picview1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/leftlogo"
android:paddingRight="105sp"
/>
<Button
android:id="#+id/picview2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/rightlogo"
/>
</LinearLayout>
</TableRow>
<TableRow>
<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: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" />
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</FrameLayout>
</LinearLayout>
</TabHost>
</TableRow>
</TableLayout>
</LinearLayout>
Any suggestions regarding the design please?
Thanks
If you are getting StackOverflowExceptions, your UI is too complex. Fire up hierarchyviewer and find ways to remove some layers.
One way to simplify everything and remove layers is to supply the tab contents as Views, not Intents pointing to Activities.
You can just pass the R.drawable ID of the icon to setIndicator().
You should not have the TableLayout inside a LinearLayout (why bother with the LinearLayout?) or a LinearLayout inside of a TableRow (TableRow is a LinearLayout, for all intents and purposes). Please consider dumping the entire TableLayout/TableRow/LinearLayout stuff and just use a single RelativeLayout.