user1500301
user1500301

Reputation: 33

How do I make text in a Bitmap scale properly on different screen densities in Android?

I'm pretty new to android programming, but I've had some people program a widget for me, but they've done things a little differently than what I would've wanted... They set up all of the text in the widget to be displayed as bitmap instead of a textview. This doesn't give me the control I would like though. Let me post up the code for what I have with this and see if anybody can help. Here is the .java code for it:

    String strHourFormat = "hh:mm";
    String strDateFormat = "MM.dd.yy";
    SimpleDateFormat fHour = new SimpleDateFormat(strHourFormat);
    SimpleDateFormat fDate = new SimpleDateFormat(strDateFormat);
    Date date = new Date();
    String am = date.getHours() > 11 ? "PM":"AM";

    setContentView(R.layout.widget_ui);
    TextView day = new TextView(this);
    day = (TextView) findViewById(R.id.day);
    day.setText("" + fDate.format( date));
    day.setTypeface(Typeface.createFromAsset(this.getAssets(), "roboto_thin.ttf"));

    ///////////
    WidgetBiggs.previousState = WidgetBiggs.getWifiState(getApplication());     
    SoundDebug.previousState = SoundDebug.getSoundState(getApplication());
    // Update each requested appWidgetId
    RemoteViews widgetView = WidgetBiggs.buildUpdate(getApplication(), -1);

    for(int wid:widgetIds){
        //final RemoteViews widgetView = new RemoteViews(getPackageName(),R.layout.widget_ui);
        widgetView.setImageViewBitmap( R.id.img_Hour, updateFontText(""+fHour.format(date),40,100,84,100,60)); 
        widgetView.setImageViewBitmap( R.id.img_AM, updateFontText(""+am,25,40,84,40,60)); 
        widgetView.setImageViewBitmap( R.id.img_Day, updateFontText("" + fDate.format( date),38,150,40,150,40)); 
        //widgetView.setImageViewBitmap( R.id.img_Weather, updateFontText(getWeatherGoogle().toString(),25,120,30,120,30));

some other stuff in between....

private Bitmap updateFontText(String time, int size, int width, int height, int widthText, int heightText) 
{
Bitmap myBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444);
Canvas myCanvas = new Canvas(myBitmap);
Paint paint = new Paint();
Typeface clock = Typeface.createFromAsset(this.getAssets(),"roboto_thin.ttf");
paint.setAntiAlias(true);
paint.setSubpixelText(true);
paint.setTypeface(clock);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
paint.setTextSize(size);
paint.setTextAlign(Align.RIGHT );
myCanvas.drawText(time, widthText, heightText, paint);
return myBitmap;

And here is the XML that I've started:

<TextView
    android:id="@+id/day"
    android:visibility="visible"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:gravity="center_horizontal|center_vertical"
    android:textSize="32dp">            
</TextView>

This causes my application to go haywire. If you see anything that stands out please let me know. I would like to take the bitmap text out, and put the textview text in. Thank you!

Upvotes: 2

Views: 1589

Answers (2)

BlackHatSamurai
BlackHatSamurai

Reputation: 23493

The short answer to your question is, use density resources. If you are using a high density screen, but your bitmap in:

res/drawable-hdpi/

The long answer is, that screen density does not have a "silver bullet" so to speak and to have a successful app, you need to make sure your app works across all screens. Getting your image to render on one screen is easy, keeping that the same across multiple resolutions is a little trickier.

This article does a great job of talking about some of the different methods and techniques you can use to make sure that your bitmap displays properly across all screens, and not just one. This article has some best practices and other information that you should be aware of, and that will make things easier for you:

http://developer.android.com/guide/practices/screens_support.html

Best of luck!

Upvotes: 0

Thomas Dignan
Thomas Dignan

Reputation: 7102

There is nothing wrong with their bitmap strategy. Just change the 'size' parameter based on the screen density.

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

Now muliply your size, width, height, widthText, and heightText values by metrics.density.

That will treat them as dp values to produce the correct px value for the screen you are on.

From the docs:

The DisplayMetrics.density field specifies the scale factor you must use to convert dp units to pixels, according to the current screen density. On a medium-density screen, DisplayMetrics.density equals 1.0; on a high-density screen it equals 1.5; on an extra high-density screen, it equals 2.0; and on a low-density screen, it equals 0.75. This figure is the factor by which you should multiply the dp units on order to get the actual pixel count for the current screen.

You'll have more control over the font rendering if you stick with the bitmaps.

Upvotes: 1

Related Questions