Reputation: 275
I wanna know how to make the button text size fill the height of a button. When using sp or dp size of text it is good for small screen resolution(4" screen for example), but on tablet screens(10") the button size is bigger, and button text looks very small) how can I solve this?
Upvotes: 0
Views: 7802
Reputation: 31
You can try setting the button text size relative to the button height.
For example: In XML use weights for buttons to fill all the screen (regardless of screen size):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<Button
android:id="@+id/button1"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<Button
android:id="@+id/button2"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
You set height of the button text (for example 1/3 of the button height) after the layout is drawn by overriding onwindowfocuschanged:
@Override
public void onWindowFocusChanged (boolean hasFocus) { // the layout is set
button1 = (Button)findViewById(R.id.button1);
int text_height = button1.getHeight()/3; // define text_height as 1/3 of button height in px
button1.setTextSize(TypedValue.COMPLEX_UNIT_PX, text_height); // set text height in px
button2 = (Button)findViewById(R.id.button2);
int text_height = button2.getHeight()/3;
button2.setTextSize(TypedValue.COMPLEX_UNIT_PX, text_height);
}
Upvotes: 1
Reputation: 275
I figure it out!
I created folders: values-ldpi
values-small
values-normal
values-large
values-xlarge
In each folder I created dimens.xml file.
For example dimens.xml file in values-small looks like this:
<resources>
<dimen name="text_button">10sp</dimen>
</resources>
dimens.xml file in values-normal like this:
<resources>
<dimen name="text_button">12sp</dimen>
</resources>
Then instead of using button text size with unit(10sp,10px,10dp) you just point it to text_button.
Upvotes: 0
Reputation: 31466
You could overload the onDraw()
method in a child of Button.This example shows how to use getTextBounds()
from the android Paint class to determine the size text will be when drawn. With this information you can calculate a textSize and textScaleX to use to get your text the size you want.
The goal is to find values for the textSize
and textScaleX
that will adjust our text size to fill our View. Instead of calculating this every time onDraw is called, we will watch for size changes and calculate the values up front. To do this we override onSizeChanged to get the new view width and height.
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// save view size
mViewWidth = w;
mViewHeight = h;
// first determine font point size
adjustTextSize();
// then determine width scaling
// this is done in two steps in case the
// point size change affects the width boundary
adjustTextScale();
}
From onSizeChanged
you have to call two methods. First one to determine the textSize we use the getTextBounds()
method of the Paint object to determine a size for the text at a known textSize. From there we do a simple calculation to determine what textSize would be used to result in the text bounds that we want.
void adjustTextSize() {
mTextPaint.setTextSize(100);
mTextPaint.setTextScaleX(1.0f);
Rect bounds = new Rect();
// ask the paint for the bounding rect if it were to draw this
// text
mTextPaint.getTextBounds(mText, 0, mText.length(), bounds);
// get the height that would have been produced
int h = bounds.bottom - bounds.top;
// make the text text up 70% of the height
float target = (float)mViewHeight*.7f;
// figure out what textSize setting would create that height
// of text
float size = ((target/h)*100f);
// and set it into the paint
mTextPaint.setTextSize(size);
}
The second method determines the textScaleX value in the same way. We find what the size would be with a textScaleX
of 1.0, then do some simple math to determine what scale would result in the width of bounds that we want. This is done in a separate call call from the text size calculation just in case setting the textSize affects the result for scale. Changing textScaleX
will definitely not change the height of the text drawn.
void adjustTextScale() {
// do calculation with scale of 1.0 (no scale)
mTextPaint.setTextScaleX(1.0f);
Rect bounds = new Rect();
// ask the paint for the bounding rect if it were to draw this
// text.
mTextPaint.getTextBounds(mText, 0, mText.length(), bounds);
// determine the width
int w = bounds.right - bounds.left;
// calculate the baseline to use so that the
// entire text is visible including the descenders
int text_h = bounds.bottom-bounds.top;
mTextBaseline=bounds.bottom+((mViewHeight-text_h)/2);
// determine how much to scale the width to fit the view
float xscale = ((float) (mViewWidth-getPaddingLeft()-getPaddingRight())) / w;
// set the scale for the text paint
mTextPaint.setTextScaleX(xscale);
}
The final detail is to determine where vertically in the view to paint the text. The boundary rect returned by getTextBounds can help with this. The bounds.top value will actually be a negative value, and it represents the size of the text not including the size of any descenders (parts of letters that extend below the base line). The bounds.bottom value is the size of the descenders. Using this information, we can decide how to position the text in the view. The y value in the call to drawText represents the baseline. Descenders will be drawn below this line. For this example, we adjust the y value so that we are showing the full descenders. This value is saved off as mTextBaseline
and is used in onDraw.
@Override
protected void onDraw(Canvas canvas) {
// let the ImageButton paint background as normal
super.onDraw(canvas);
// draw the text
// position is centered on width
// and the baseline is calculated to be positioned from the
// view bottom
canvas.drawText(mText, mViewWidth/2, mViewHeight-mTextBaseline, mTextPaint);
}
Upvotes: 1
Reputation: 94
Use the wrap_content in layout_height for a good things in comparison of sp and dp
Upvotes: 0