I'm wondering whether there is a way to find out the space available for Views within a layout.
To be a little more precise: in the activity two TextViews are displayed side by side. As the second one contains pretty much text, I'd like to check, whether this text can be displayed on the screen or whether it's too large. If that's the case I'll display a smaller version of the text instead (as Android doesn't display this text on multiple lines by default).
Currently I'm using some code like this:
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
Point screenSize = new Point();
display.getSize(screenSize);
int screenWidth = screenSize.x;
if (tvTitle.getWidth() + tvDescription.getWidth() > screenWidth) {
tvDescrition.setText(getString(R.string.descritption_short));
}
But this doesn't work: the widths normally are smaller than the screen, so the long version is used. But: the text isn't displayed completely, the last words are always missing.
I guess the problem is, that the layout is using a padding and is therefore reducing the space really available.
So how to fix this? Any ideas are extremely welcome :-)
You can measure the width of a text(String) in pixels. Using this method:
Paint.measureText(titleString + descriptionString);
If that exceeds the total screen width - horizontal margin - horizontal padding then you can go for the short description.
Related
I am developing an application in android studio which is displayed correctly on 1080x1920 phones(and lower) but for phones like mine(s8) the app gets messed up and i can't find a way to fix the app's ui for every screen size. So, i was wondering if there is a way to restrict the app's screen size to 1080x1920(with let's say black bars at the top & bottom of the screen) even if a phone's dimensions are bigger than that(this is automatically done in games that are not compatible with s8). Do you guys know a way of achieving this effect?
It's possible, you can set your parent View to exact size given the aspect ratio you want (1080x1920 scales down to 9x16). For this you'd have to programmatically call the View (or create it in code) and set width and height in pixels with LayoutParams:
yourView.setLayoutParams(new LayoutParams(width, height));
for the weight and height you'd want the actual screen dimensions, which you can get from the WindowManager:
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
Point point = new Point();
display.getSize(point);
int x = point.x;
int y = point.y;
Here you get the x and y, which hold your actual screen size (in pixels). Then, you decide on which one should be reduced (in order to maintain 9x16 aspect ratio) and set your parent View's LayoutParams as mentioned above.
Finally, your set your content View as your parent View:
setContentView(yourView);
That's about it. Hope that helps.
EDIT: Since you've mentioned games, I can tell you that there (if your use Android SDK) you have your SurfaceView as a parent View, the procedure is same.
First, my apologies for the title. I thought long and hard to choose a more descriptive title but couldn't really find one.
I have a screen with a header (variable length - using sliding action bar), a middle part (scrollview) and a bottom part for showing ads (fixed length). I am able to write the screen using RelativeLayout but what I would really like to do is this:
If the scrollview's content (the middle part) is not long enough to fill the screen (including header), I would like to show the ad at the bottom of the screen
If the scrollview's content + header is longer than the screen, I would like to show the ad BELOW the scroll view's contents, meaning it's not visible unless the user scrolls to the bottom of the fragment.
Imagine the scroll view's content as a short text or an image + a long text. For the first case, the scroll view content will be short and therefore I'd ideally show the ad at the bottom of the screen since I have enough space but if it's image + text, it will be larger than the screen height and as such, I would like to show the ad after the user has scrolled to the bottom.
The reason I want to do this is so that the ad doesn't necessarily take space if there's useful content on the screen (user experience).
Is there anyway to achieve this in android without writing my own custom layout? If so, which view would you recommend?
Many thanks in advance,
I don't think there is such a layout. You can do this programmatically. The ScrollView always has a single child so you can get the content height this way:
int contentHeight = scrollView.getChildAt(0).getHeight();
You can get window height this way
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int windowHeight = size.y;
The height of the header and footer is fixed so you can do the maths decide where to put the footer.
int totalHeight = heaederHeight + contentHeight + footerHeight
if(totalHeight < windowHeight) {
// add the footer to the scrollview
} else {
// add the footer below the scrollview
}
The cons of this approach is that you have to do all the magic manually.
I hope this helped you :)
Currently, My goal is to place some images in an arrangement relative to the center of the screen. There is a varying number of images and locations, so I'd like to do this programmatically.
I am having trouble finding the center of the correct center of screen in terms of px. To test, I have tried placing an image at the center.
ImageView image = (ImageView)findViewById(R.id.imageView1);
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
image.setPadding(width/2,height/2,0,0);
I understand that there is an offset since setting the padding should place the image's top left corner in the center. Even so, the image comes out as too low and too far right. What kind of issue could be causing this?
Padding set just the inner space between element's border and content. If element have also margins, they summarized. You can use only margins (paddings equals to 0) or only paddings (margins equals to 0). Also if you not interested in supporting android 2.3 and less, you can use setX() and setY() methods of View class.
I hope this help you.
Is there any simple way of changing the text of a TextView in order to make it fit the view's size? Note that I do not want to truncate the text or to put an ellipsis, I want to set a different text.
For example instead of Experience: I want to use Exp: if the view is too small(where both those strings are resources).
I know that I could "avoid" this writing a custom .xml layout file for every possible screen size, but I'd like to avoid this if possible. I'm already using some different layout files, but only for situations where the layout needs some radical change to fit the size of the screen. Also in some circumstances I'd like to be able to dynamically set the text of a TextView and this can't be done via xml layout files.
I'm interested only in single-line TextViews and width.
The only way I could think of is to use a custom TextView subclass that uses a fallback text if the original text doesn't fit, but I wonder whether there is a simpler solution and, eventually, how can I reliably compute whether some text fits the TextView size or not.
You can try something like this:
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int screenWidth = size.x;
if( textView.getWidth() > screenWidth ) {
textView.setText("Exp:");
} else {
textView.setText("Experience:");
}
I'm not sure if you need to use getWidth() or getMeasuredWidth() so if it will not work, try second option.
I am making an android component which allows user to pick date from it. It can be helpful for developer who wants user to select date in his app. In my basic view, I have TextView where date from pop up will be populated into it and I have a button beside TextView. When a User clicks on the button, my component gets popped out and displays Dates. The component gets pops out in a Popup window and shows dates as month view and user also can switch from next-previous months, next-previous years just like we do in Calendar. Check the Image.
http://s15.postimage.org/ujw8py60b/stackoverflow.jpg (Sorry, I couldn't upload an image here because I am not allowed as I am new User here)
Each date is a TextView with the width of 35 and height as 30 set by me. DaysDisplayBar is also of some size set by me. So this component's whole width is 245 and height is around 200. Which is for mobile screen size.
I want to make this component as size dependent for various screen display sizes. For e.g. If it is being viewed on Tablet or Pad, it should be bigger in size than what its size on mobile phone screen. That is, For various displays its size should be changed to some value like max 1/3 of display size or like that something.
What can be the solution for this? According to me, some mathematics is needed here, some formula, equations etc. how about Parabola? Please help, I am dumb in maths totally. Thanks! :D
"Each date is a TextView with the width of 35 and height as 30 set by me. DaysDisplayBar is also of some size set by me. So this component's whole width is 245 and height is around 200. Which is for mobile screen size."
^^ is the problem. Sizes should be defined relative to the layout, not absolute. For example, the calendar has 7 columns (one for each day). Instead of making each one 35px, make each 1/7th of the screen.
SO:
I am assuming a DaysDisplayBar is a row containing 7 TextViews (one for each day). If that is true, why not call it a Week? Either way, The trick is in layout_wieght. Make all elements fill_parent, and all with the same weight of 1. This will evenly distrubate all elements in the parent. In your case, the parent is a DaysDisplayBar.
SO:
set DaysDisplayBar attribute `layout_width="fill_parent"
For each TextViewset attribute layout_width="fill_parent" ANDlayout_weight="1"`
hope that helps!
First of all, make sure you use density pixels (dip) instead of pixels.
Second, you can get the screen width and height, and from there, calculate your component size.
You can get the screen dimensions using the Display class getSize() method:
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point screenSize = new Point();
display.getSize(screenSize);
int screenWith = screenSize.x;
Or you can get the parent view dimensions:
MarginLayoutParams params = (MarginLayoutParams)parentView.getLayoutParams();
int padding = parentView.getPaddingLeft() + parentView.getPaddingRight();
int margin = params.leftMargin + params.rightMargin;
int measuredWidth = parentView.getMeasuredWidth() - padding - margin;
That way you know how much space you have inside the parent view element for your component.
Remember to convert any hard coded value to dip, you can do it this way:
public static int getDensitySize(float size) {
float density = getResources().getDisplayMetrics().density;
return (int)(density * size);
}
You do all of this from your onMeasure method to set your view size, and later on the onDraw you'll use this measure to draw your component.