I am using Html.fromHtml() to get content and display it on my activity. To do this I am using an ImageGetter. I was having a problem that if the phone could not connect to the internet the app crashed as the pictures could not load. Instead I wanted to have a placeholder image saved in my ldpi/mdpi/...etc folders that would be inserted whenever a picture could not be loaded.
My ImageGetter uses URLImageParser which has the following onPostExecute() method:
#Override
protected void onPostExecute(Drawable result) {
//check to see if an image was found (if not could
//be due to no internet)
if(result ==null){
//the drawable wasn't found so use the image not found
//png
Drawable imageNotFound = a.getResources().getDrawable(R.drawable.image_not_found);
result = imageNotFound;
}
intrinsicHeight = result.getIntrinsicHeight();
intrinsicWidth = result.getIntrinsicWidth();
DisplayMetrics dm = new DisplayMetrics();
((WindowManager) c.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels -50;
int height = width * intrinsicHeight / intrinsicWidth;
result.setBounds(0, 0, 0 + width, 0
+ height);
urlDrawable.setBounds(0, 0, 0+width, 0+height);
// change the reference of the current drawable to the result
// from the HTTP call
urlDrawable.drawable = result;
// redraw the image by invalidating the container
URLImageParser.this.container.invalidate();
// For ICS
URLImageParser.this.container.setHeight((URLImageParser.this.container.getHeight()
+ height));
// Pre ICS
URLImageParser.this.container.setEllipsize(null);
}
I have simply inserted the if(result==null) statement at the top of this method. But now if the pictures can be loaded the app works perfectly. If the images cannot be loaded and the placeholders are used instead I get some odd behavior.
The scrollview never scrolls to the bottom of the screen, and I have no idea why this is. In theory there should be no difference between my imageNotFound drawable (which is a png file) and the files downloaded off the internet. The scrollview will only move slightly.
I have no idea what is causing this. When searching online most people seem to be having problems with RelativeLayouts. I couldn't find anyone having trouble with drawables or TableLayouts.
My xml for the layout is as follows:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:paddingBottom = "0dip"
android:orientation = "vertical" >
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stretchColumns="0,1"
android:shrinkColumns="0,1"
android:id = "#+id/SharedTableLayout"
android:paddingBottom = "0dip" >
<TableRow
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:paddingBottom = "0dip">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id = "#+id/SharedTableContent"
android:layout_span="2"
android:gravity = "left"
android:paddingLeft = "10dip"
android:paddingRight = "10dip"
android:paddingTop = "20dip"
android:paddingBottom = "0dip"/>
</TableRow>
</TableLayout>
</ScrollView>
I would really appreciate any suggestions on this, I've been stuck on it for weeks.
Thanks for your time
The TextView with id SharedTableContent displays a string that was converted from html using Html.fromHtml() so the images may be surrounded by text which means I cannot hard code a solution into xml as there is no way of telling how many images there will be to download in advance, thats all done programmatically.
Try changing the layout width of the scrollview to match_parent.
android:layout_width="match_parent"
android:layout_height="match_parent"
Or try this
<?xml version="1.0" encoding="utf-8"?>
<ScrollView android:id="#+id/ScrollView02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android">
<HorizontalScrollView android:id="#+id/HorizontalScrollView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView android:id="#+id/ImageView01"
android:src="#drawable/pic"
android:isScrollContainer="true"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:adjustViewBounds="true">
</ImageView>
</HorizontalScrollView>
</ScrollView>
Related
Background
Suppose I want to show an image of the something using an ImageView, and I want to put new views on top of it (animated ImageViews that show pins on a world map image, for example, or a Switch view on top of a smartphone image).
This means that no matter how the ImageView shows the image, the views should be in it, inside correct spot, with the same size as specified, or in a size related to the imageView itself
The problem
As opposed to other views, the ImageView can have a certain size, but its content is something else (to keep aspect ratio).
What I tried
I tried to use ConstraintLayout, but this can't really help, because the ImageView can change its size (for example when changing orientation), and thus ruining the position I've given the views compared to the ImageView.
I've found some libraries that can handle a similar thing (like here) and I even asked a similar question before (here), but all those solutions are for a static image within the ImageView, yet what I search for is adding a view on top of an ImageView.
The question
How do I put the views on top of the ImageView's content correctly?
How do I also scale the views down/up compared to the size of the ImageView's content ?
Can ConstraintLayout be used to change the scale of the views according to the ImageView's size ?
Make FrameLayout with wrap_content around ImageView. Then you could set SwitchView on top of ImageView. You could align it to center, side or corners and using margins to get some fine position.
It still won't scale with image, but you can get pretty good results. If that doesn't fit you, you can programatically get width/height of ImageView and alter position (or margins) of SwitchView accordingly.
With below you can manage width of switch or any other view as per image view width
android:layout_alignLeft="#+id/imageView"
android:layout_alignRight="#+id/imageView"
<Switch
android:id="#+id/swi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/imageView"
android:layout_alignRight="#+id/imageView" />
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/swi"
android:src="#drawable/download" />
In Java,
ImageView imgView = (ImageView) findViewById(R.id.imageView);
imageView.setBackgroundResource(R.drawable.yourDrawable);
int width = imgView.getDrawable().getIntrinsicWidth();
Switch switchKey = (Switch) findViewById(R.id.switchKey);
switchKey.setMinimumWidth(width);
And in XML, align it with alignLeft and alignRight with ImageView.
As far as i get it, you need the image size displayed inside the image view and set that as the max width of your switch view right?
You need both Java and XML for this,
The XML file is basically as RelativeLayout with the view stacked as needed.
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:src="#drawable/nonet_icon"
android:id="#+id/iconView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<android.support.v7.widget.SwitchCompat
android:layout_width="wrap_content"
android:visibility="gone"
android:layout_centerInParent="true"
android:layout_height="wrap_content"
android:id="#+id/switchView"/>
</RelativeLayout>
And the Java Code gets the imageWidth and sets it to the SwitchView.
mSwitchCompat.setVisibility(View.VISIBLE);
// 20% x 25% of Content in ImageView
final float x = mImageView.getDrawable().getIntrinsicWidth()*.2f;
final float y = mImageView.getDrawable().getIntrinsicHeight()*.25f;
// waiting for the view to be drawn
mSwitchCompat.post(new Runnable() {
#Override
public void run() {
// scale current view W.r.t. x and y values
mSwitchCompat.setScaleX((float)mSwitchCompat.getWidth()/x);
mSwitchCompat.setScaleY((float)mSwitchCompat.getHeight()/y);
}
});
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT);
// 30% x 35% of content, for location
int xMargin = Math.round(mImageView.getDrawable().getIntrinsicWidth()*.3f);
int yMargin = Math.round(mImageView.getDrawable().getIntrinsicHeight()*.35f);
// set margin values, can optionally add for top and bottom
layoutParams.setMargins(xMargin,0,yMargin,0);
mSwitchCompat.setLayoutParams(layoutParams);
Ref: Getting Displayed image size of an ImageView
Trying to get the display size of an image in an ImageView
Ref: Dynamic size values
Do comment if you need a detailed explaination.
Example: Check this image!
Scaled View on Image: Scaled View on Image!
You can use MarginLayoutParams with Relative Layout to set left and top position in ImageView.
image = (ImageView) findViewById(R.id.imageID);
MarginLayoutParams marginParams = new MarginLayoutParams(image.getLayoutParams());
marginParams.setMargins(left_margin, top_margin, right_margin, bottom_margin);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(marginParams);
image.setLayoutParams(layoutParams);
find complete information for this in below link :
MarginLayoutParams
Try this, may be it will help you.
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/img_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/semi_transparent"
android:layout_margin="#dimen/spacing_small"
android:layout_alignTop="#+id/img_background"
android:layout_alignBottom="#id/img_background">
//this layout will expand according to your image size
</RelativeLayout>
</RelativeLayout>
Do you want to show switch that lay on imageview ?
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ll_download"
android:layout_width="100dp"
android:layout_height="60dp"
android:layout_centerInParent="true"
android:orientation="vertical">
<ImageView
android:src="#android:drawable/btn_star_big_on"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Switch
android:id="#+id/mySwitch"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Switch" />
</RelativeLayout>
I have an ImageView. Below it, I want to have a GridView containing lots of smaller images. I want it to look neat... 4 per line, with even spacing top and bottom.
Currently, the spacing is not too bad (even though to my eye the left-to-right-spacing looks a little thinner than the top-to-bottom-spacing) but the thing that I'm really struggling with is the extra margin on the far right.
I want the right edge of the images in the grid view to align perfectly with the right edge of the big image. What am I doing wrong?
Here is an image of what I currently have:
Here is my layout:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/items_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/placeholder"
android:scaleType="fitStart"
android:adjustViewBounds="true"
style="#style/ItemsImage" />
<GridView
android:id="#+id/items_all_images"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numColumns="4"
android:stretchMode="columnWidth"
android:clipToPadding="false"
android:scrollbarStyle="outsideOverlay"
android:verticalSpacing="20dp"
style="#style/ItemsImage"
/>
</LinearLayout>
</LinearLayout>
The ItemsImage style is this:
<style name="ItemsImage">
<item name="android:gravity">top|left</item>
<item name="android:layout_gravity">top|left</item>
<item name="android:paddingRight">25dp</item>
</style>
I don't know this is the best way to do this but it can solve the problem.
Add these lines to your activity's onCreate method :
YOUR_GRIDVIEW.post(new Runnable()
{
#Override
public void run(){
YOUR_GRIDVIEW.setWidth(YOUR_IMAGE.getWidth());
}
});
Define fix width and height for grids and also for image in gridView. In code after grid instance initialized, you can set spacing as follow.
GridView gridView;
int gridWidth = 1280;
int gridHeight = 500;
int gridItemWidth = 60;
int gridItemHeight = 50;
int gridRows = 3, gridColumns = 4;
int vSpacing = (gridHeight - (gridItemHeight * gridRows))/gridRows;
int hSpacing = (gridWidth - (gridItemWidth * gridColumns))/gridColumns;
gridView.setLayoutParams(new LayoutParams(gridWidth, gridHeight));
gridView.setColumnWidth(gridItemWidth);
gridView.setNumColumns(gridColumns);
gridView.setHorizontalSpacing(hSpacing);
gridView.setVerticalSpacing(vSpacing);
Set grid width equal to the size of large image above GridView.
Hope it helps you.
I had saw many ways to align a textview with an imageview, but I didnĀ“t find how to make when the text is bigger than the image, and when you want that text occupy all the parent layout. My layout is this:
<RelativeLayout
android:id="#+id/accordion_toogle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone">
<ImageView
android:id="#+id/accordion_image"
android:layout_width="#dimen/accor_img_wid"
android:layout_height="#dimen/accor_img_hei" />
<TextView
android:id="#+id/accordion_msg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/accordion_image"
android:paddingLeft="5dp"/>
</RelativeLayout>
In this case, assuming that the image occupy the half of the RelativeLayout, the accordion_msg continues to occupy the half of the relativeLayout once the imageView finish.
Do you understand me?? Have I expressed well?? Any suggestion??
Thank you.
EDIT
A picture to help what I try to do:
The pink square is the picture, the purple and white rectangles are where the text must to be, but until now, the purple is empty. The text only occupy the white square.
EDIT 2
I am trying what #Elltz says... but I cannot make what I want, I have this code:
draw.setBounds(0, 0, width, height); //width: 128 height: 172 in this case
textview.setCompoundDrawablesRelative(draw, null, null, null);
But no image is shown, I try other many things, like:
textview.setCompoundDrawablesRelative(null, draw, null, null);
And the image stays on the top of the text. Other diferent this I tried was:
textview.setCompoundDrawables(draw, null, null, null);
And the image is on the left... but it is vertically align at center, and top and bottom of image are blank (no text, no picture... no nothing). I try changing the parent to LinearLayout, using gravity left, gravity top, RelativeLayout...
Oooppsss!!! now the layout is this:
<RelativeLayout
android:id="#+id/accordion_toogle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone">
<TextView
android:id="#+id/accordion_msg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/accordion_image"
android:paddingLeft="5dp"/>
</RelativeLayout>
*The visibility gone on the parent is not important, I change it programmatically.
Thank you.
Ok... after a hard job of experimentation, searching-> attempting-> failing-> searching-> attempting-> failing-> searching-> attempting-> success ;)
In this stack question #K_Anas gives the solution... I will type what I do for the next case on this situation (Furthermore, it is possible process a link on the text, resolving it with Html.fromHtml and preserving the link property after the SpannableString):
The Layout
<RelativeLayout
android:id="#+id/accordion_toogle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="6dp"
android:visibility="gone"
android:gravity="top">
<ImageView
android:id="#+id/accordion_image"
android:layout_width="#dimen/img_width"
android:layout_height="#dimen/img_height"
android:src="#drawable/default_image"/>
<TextView
android:id="#+id/accordion_msg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="5dp"/>
</RelativeLayout>
The Java code
final TextView msgView = (TextView)view_aux.findViewById(R.id.accordion_msg);
String msg_text = dbStructure.getMsg();
if(msg_text.contains("href=\"")) {
String[] msg_aux = msg_text.split("href=\"");
if (!msg_aux[1].toLowerCase().startsWith("http"))
msg_aux[1] = "http://" + msg_aux[1];
msg_text = msg_aux[0] + "\"href=\"" + msg_aux[1];
}
msgView.setText(Html.fromHtml(msg_text));
msgView.setMovementMethod(LinkMovementMethod.getInstance());
int lines = (int)Math.round(height / msgView.getLineHeight());
SpannableString ss = new SpannableString(msgView.getText());
ss.setSpan(new MyLeadingMarginSpan2(lines, width+10), 0, ss.length(), 0);
msgView.setText(ss);
In this case the width and height are the meassures of the ImageView.
First let's introduce me, I'm new in Android and mobile device programming, I previously worked on embedded systems running on QNX.
I hope I will respect the rules of this forum which seem to be quite stricts ;-).
I'm wrinting an application where I declare a layout for a welcome screen populated, between other things with a image view.
There is a first image placed in this image view in the xml file, but I will replace it by an other one later in the application's code and this second image will be potentially of a different size.
My problem is to resize and center my second image. According to my tests, it's quite automatic by using resources in Lint but it seems not so obvious by program, even if I read in the docs that it should be similar.
After reading several posts on the subject, I finally have a doubt; Can I center an image in an ImageView, or do I have to center the ImageView in the available space?
I tried the first solution without success.
So my layout is:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/fragmentInit"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.cabbonline.ndguidelt.MainActivity" >
<TextView
android:id="#+id/textViewAppName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/textViewAppVersion"
android:layout_centerHorizontal="true"
android:text="#string/app_name" />
<TextView
android:id="#+id/textViewAppVersion"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/TextViewDevelopCabb"
android:layout_centerHorizontal="true"
android:text="#string/app_version" />
<TextView
android:id="#+id/TextViewDevelopCabb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/imagecaBB"
android:layout_centerHorizontal="true"
android:text="#string/develop_cabb" />
<ImageView
android:id="#+id/imagecaBB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/textViewCabbUrl"
android:layout_centerHorizontal="true"
android:contentDescription="#string/logo_caBB"
android:maxHeight="150dp"
android:src="#drawable/logo_cabb_100x51_or" />
<TextView
android:id="#+id/textViewCabbUrl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="#string/cabb_url" />
<ImageView
android:id="#+id/imageSite"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/textViewAppName"
android:contentDescription="#string/logo_Site"
android:scaleType="centerInside"
android:src="#drawable/image_guide_320x400" />
</RelativeLayout>
Here I can say tht the "imageSite" ImageView is well displayed, centered and occupies the whole area. Right.
Now I have a piece of code to replace this image in this same ImageView:
Bitmap imageSite = site.getSitePictureBitmap();
if (imageSite != null) {
imageGuide.setImageBitmap(imageSite);
}
If I only do that, despite en center_inside flag, the new bitmap, smaller and rectangular horizontally compare to the first one which is almost sqaure, the image is displayed very small on the bottom right corner of the ImageView, or the area taken by the ImageView, Idon't really know.
So I add this piece of code to resize it:
imageSite = site.getSitePictureBitmap(); // here I read the bitmap in a file.
if (imageSite != null) {
float maxWidth = imageGuide.getWidth();
float maxHeight = imageGuide.getHeight();
float width = imageSite.getWidth();
float height= imageSite.getHeight();
float hRatio = width / maxWidth;
float vRatio = height / maxHeight;
if (Math.abs(1 - hRatio) < Math.abs(1 - vRatio)) {
// We match horizontal available size
width = width / hRatio;
height = height / hRatio;
} else {
width = width / vRatio;
height = height / vRatio;
}
Bitmap reSizedBitmap = Bitmap.createScaledBitmap(imageSite, (int)width, (int)height, true);
imageGuide.setImageBitmap(reSizedBitmap);
So the image is now of the good width but as its vertical dimension is lower than the first picture, it's close to the textViewAppName. So as it's a rule for the ImageView in the layout description, I wonder if my image is not in the center of the ImageView in fact and my problem would come from the fact that the ImageView is now of a smaller height and doesn't fill up the whole space available at the top of the layout.
I also wondered if setting a new image doesn't reset the positionning flags. I didn't see that in the doc AFAIR but...
So I add this line after setImagebitmap() without success:
imageGuide.setScaleType(ScaleType.CENTER_INSIDE);
Can you tell me a bit more about ImageView behavior in this case and how to get my image vertically in the center of the available space. Do I have to calculate padding?
Regards,
Al
tl;dr: How do I get the DIP height of the FrameLayout?
Full: I am trying to design a layout that is consistent across the general resolutions available. I've gone through the developer best practices on Google and that helped my understanding a bit. I've converted icons to 9-patch and am using DIP heights which improved things a lot.
However where I'm stuck is trying to play three rows of buttons that will take up the remainder of the screen, regardless of the resolution. I'll need to make something different for small screens and tablets, but I am only currently worried about the normal screens on most phones.
I have a layout that has a TabWidget as the #android:id/tabs role and a FrameLayout for the #android:id/tabcontent
One of the Tab Activities is simply 3 rows of buttons which I want to fill the entire FrameLayout which I suspect I must calculate the height of the button based on the height of the FrameLayout.
My question then is, how do I get the DIP height of the FrameLayout?
I've tried a GlobalLayoutListener and that just returns 0. I've tried pulling the LayoutParams and that just returned -1 for FILL_PARENT. I need the actual DIP height of the FrameLayout to properly set the height of the area available.
How can I do that, or am I looking at it incorrectly?
Any help is appreciated.
I figured out a way to get the result I wanted, just not the exact way I was trying and never managed to get the height of the tabcontent directly but indirectly.
I found two methods to do this and I'll post them below.
First I did Method 2 but then discovered I preferred Method 1 and decided to go with that since it's more extendable.
Method 1
This way I found from How to size an Android view based on its parent's dimensions and is the most customizable and readable method. In a nut shell, you need to extend FrameLayout and override the onMeasure method.
<?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"
android:padding="0dip"
android:layout_margin="0dip">
<LinearLayout
android:id="#+id/topLayout"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="0dip"
android:layout_margin="0dip">
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:padding="0dip"
android:layout_margin="0dip" />
<view
class="com.tmcaz.patch.TabContentFrameLayout"
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="0dip"
android:layout_margin="0dip" />
</LinearLayout>
</TabHost>
The major difference is using a custom class for this where you can handle the sizing from the event itself, similar to Method 2 but no need to do any calculations to get the content height.
I did this to give myself access to the event and handle all of the sizing in the content. Someone reading this may very well need to override something else and deal with the onMeasure event totally differently.
The code is below
public class TabContentFrameLayout extends FrameLayout {
// add constructors, etc
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
// Should turn these in to member variables and reference it throughout.
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
this.setMeasuredDimension(parentWidth, parentHeight);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
Method 2
I assigned an id to the LinearLayout that held the TabWidget and FrameLayout. Here is my main.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"
android:padding="0dip"
android:layout_margin="0dip">
<LinearLayout
android:id="#+id/topLayout"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="0dip"
android:layout_margin="0dip">
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="50dip"
android:padding="0dip"
android:layout_margin="0dip" />
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="0dip"
android:layout_margin="0dip" />
</LinearLayout>
</TabHost>
I assigned a DIP height to the tabs and then grabbed the LayoutParams for the LinearLayout which I simply subtract the height of the tabs from the result. I've added code here for basic illustrative purposes only and can do it a bit more efficiently, it's not my production code :)
One thing to note is that you can't appear to directly pull the height of the layout during the onCreate event where it's most useful. You need to create a GlobalLayoutListener to capture the change in the layout and get the size.
public class MyTabActivity extends TabActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout ll = (LinearLayout)findViewById(R.id.topLayout);
ll.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
DisplayLayoutDimensions();
}
}
);
// Code here to add activities to the tabs, etc
}
.
public void DisplayLayoutDimensions()
{
// Put code to calculate the heights you need instead of printing
// out the values obviously.
Resources r = getResources();
LinearLayout topLayout = (LinearLayout)findViewById(R.id.topLayout);
LayoutParams tabWidgetParams = getTabHost().getTabWidget().getLayoutParams();
float scale = r.getDisplayMetrics().density;
float pxTabContent = topLayout.getHeight() - tabWidgetParams.height;
/*** The commented out DIP calculations didn't work for me in any AVD so
manually I calculated them with the scale which worked fine ***/
//float dipTopLayout = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, topLayout.getHeight(), r.getDisplayMetrics());
//float dipTabWidget = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, tabWidgetParams.height, r.getDisplayMetrics());
//float dipTabContent = dipTopLayout - dipTabWidget;
Log.d("MyTabActivity", "LinearLayout (topLayout) Height: " + topLayout.getHeight() + "px / " + (topLayout.getHeight() / scale) + "dp");
Log.d("MyTabActivity", "TabWidget Height: " + tabWidgetParams.height + "px / " + (tabWidgetParams.height / scale) + "dp");
Log.d("MyTabActivity", "Calculated (tabcontent) Height: " + pxTabContent + "px / " + (pxTabContent / scale) + "dp");
}
Hope this helps someone at some point. If someone has a better way to do this, please speak up.