If I know the text for a Button, is there any way to calculate the button dimensions (width and height) before creating the button?
Buttons have the same chrome, paddings, margins, and font. They just vary system by system. So, in theory, button dimensions can be determined by its text.
In case you wonder why I would want to do that, I want to create a dynamic array of horizontal buttons, and if there is not enough space I would to create a menu instead of the excess buttons.
You can try something like this:
Button button = new Button(context);
button.setText("Testing");
button.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
int width = button.getMeasuredWidth();
int height = button.getMeasuredHeight();
As far as I know, if you are creating it from java, it'll give you proper values always.
Related
I am using a relative layout with 4 buttons (in the center, one below the other).
My problem is to adjust the gap between all buttons so it will be the same between all buttons.
I want to do it dynamically according to the height of the screen (i use Display class to get the actual height).
what is the best way to do it?
Thanks,
Amigal
You can do this via modifying the LayoutParams of your View
Button b;// your button
RelativeLayout.LayoutParams lp=(RelativeLayout.LayoutParams)b.getLayoutParams();
lp.leftMargin=10;//your left margin here
lp.topMargin=10;//your top margin here and do this for other 2 margins if you need to
sometimes you need to call
b.setLayoutParams(lp);
to have the changes applied
also i dont know how you get the screen dimensions, but this works at every API:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
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.
TableLayout relativeLayout = (TableLayout)findViewById(R.id.ll1);
TableRow row =new TableRow(this);
Button button ;
int counter = 0;
for(int i = 0;i<=13;i++){
counter++;
button = new Button(this);
button.setText(counter);
row.addView(button);
}
relativeLayout.addView(row,new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
relativeLayout.computeScroll();
XML File
<TableLayout android:id="#+id/ll1" android:shrinkColumns="true"
android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="#id/button1"
xmlns:android="http://schemas.android.com/apk/res/android"></TableLayout>
But whenever i execute my application it just move my buttons in a single row and after 5 buttons all the buttons move out from the screen. i dont' want to add more rows as i don't want to hard-code anything in my code like placing some code if (counter%5==0) then do this and that.
Is there any other way to calculate the width that if the buttons are equivalent to the width of screen then do this or that or any other way like any property in table Layout which simply wrap content of a row?
Yes there is a way to get the exact width of any component in your app. Look at my answer to my question asked a while ago here. As you can see, I instantiate a Paint object, but that's not necessary unless you wish to get the width of the text itself. However you must use the density multiplier:
float scale = getContext().getResources().getDisplayMetrics().density;
That will convert any function that gets the width of a component (in this case, your button) to the actual pixel width on any given devices. So you would get the button width (via invoking the getWidth() function on your Button object) and then multiply by that scaling factor.
Use FlowLayout instead:
http://nishantvnair.wordpress.com/2010/09/28/flowlayout-in-android/
GIT project:
https://gist.github.com/1073863
Using Contex's method getResources() you can access all the resources for your application's package. The method returns Resources and you can see here all properties that are available.
I'm probably just being daft but my Google searches are not working out well.
I have a bunch of buttons i add in code that all have dynamic text. I've set a background image for each of these buttons since the default greybutton doesn't work well for my application.
This works perfectly and when the text size (or content) changes, the button automatically grows to accommodate the expanded text. What doesn't work is that I'd like the button to scale proportionally - i.e. if the background image is round, i'd like it to stay round rather than oval as the button gets bigger.
With an imagebutton, there is a property "Adjust view bounds" that does exactly this but I cant put text on an imagebutton. Is there something equivalent for a regular button?
or am I going about this wrong?
i also tried setting the width of the button in code, but I can't seem to determine the new height (button.getHeight() returns 0)
ok i found one way to do it...
I modified the patch-9 to have its expandable area be the maximum on both axis.
then used the DisplayMetrics like this:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
buttonView.setGravity(Gravity.CENTER);
int buttonSize=(int) Math.floor(metrics.density*1.6*fontSize);
buttonView.setWidth(buttonSize);
buttonView.setHeight(buttonSize);
where fontSize is the size of the font in DIP that i'm placing on each button. In this case, since I only have a single letter on each button, i don't need to worry about the text length, but one could obviously tweak this to handle that situation as well.