0

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?

asked Dec 14, 2012 at 18:50
1

4 Answers 4

1

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);
}
answered Dec 15, 2012 at 0:17
Sign up to request clarification or add additional context in comments.

Comments

1

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); 
 }
answered Nov 3, 2013 at 7:43

Comments

0

Use the wrap_content in layout_height for a good things in comparison of sp and dp

answered Dec 14, 2012 at 19:27

Comments

0

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.

answered Dec 20, 2012 at 20:39

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.