android dynamically change text size - android

My button layout is as follows
<Button
android:id="#+id/Button01"
android:layout_width="420px"
android:layout_height="120px"
android:background="#drawable/butt1"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp"
android:onClick="clk_fault"
android:text="Enter Fault"
android:textColor="#FFFF00"
android:layout_marginTop="100px"
android:textSize="50px" />
When the activity starts i run code that gets the display width and then adjusts the button size according to the resolution of the device
this all works fine but the text size always stays the same
is there a way of increasing the textsize depending on the size of the button containg the text?
50px is great when button width is 420px but if button width is only 200px i need to be able to reduce the text size so it looks the same whatever the size
any help appreciated
Mark
EDIT
Activity code as requested
public void onCreate(Bundle savedInstanceState) {
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
getWindow().setFormat(PixelFormat.RGBA_8888);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DITHER);
setContentView(R.layout.activity_activity1);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int h = metrics.heightPixels;
int w = metrics.widthPixels;
int w1 = (w/2);
Button txt1 = (Button) findViewById(R.id.Button01);
txt1.setLayoutParams(new LinearLayout.LayoutParams(w1, 100));
setMargins(txt1, 0, 100, 0, 0);
}
public static void setMargins (View v, int left, int top, int right, int bottom) {
if (v.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
p.setMargins(left, top, right, bottom);
v.requestLayout();
}
}

Please, don't use px. Use dp for widget sizes and sp for font sizes.
This way you will be granted a perfect scalability.
sp ~ dp (almost equals).
At mdpi resolution, 1px = 1dp.
At ldpi resolution, the scale multiplier is 0.75
At mdpi resolution, the scale multiplier is 1.0
At hdpi resolution, the scale multiplier is 1.5
At xhdpi resolution, the scale multiplier is 2.0
At xxhdpi resolution, the scale multiplier is 3.0
At xxxhdpi resolution, the scale multiplier is 4.0
mdpi is to be considered the reference resolution
While working in Java code, you are using pixels.
This means you have to:
1 - find the scaling factor to "transform them to dp".
2 - multiply your values by this factor.
To find the multiplier, I use this code:
final DisplayMetrics metrics =
Resources.getSystem().getDisplayMetrics();
final float scale = metrics.density;
Now, you can multiply your values by scale and have your pixels scaled accordingly

Firstly text sizes should be in sp and widget & component sizes in dp.
Secondly dynamics size change based on viewport size change like on different devices needs you to create different layout files for them not do dynamics expansion or contraction based on view sizes.

Related

TextView is on different heights on different resolutions. DIP doesn't work

The bottom property of below textView scales wrong, the TextView is on a different height on every Android device: See attached pictures.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.bars_layout);
RelativeLayout relativeLayout = (RelativeLayout)findViewById(R.id.bar_holder);
BarView view = new BarView(getApplicationContext());
int width = (int) getApplicationContext().getResources().getDimension(R.dimen.bar_width_compare);
int height = 200;
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(width, height);
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
int left = (int) getApplicationContext().getResources().getDimension(R.dimen.bar_margin_left_right);
int right = 0;
int bottom = (int) getApplicationContext().getResources().getDimension(R.dimen.graph_margin_bar_compare_bottom);
params.setMargins(left, 0, right, bottom);
view.setBackgroundColor(getApplicationContext().getResources().getColor(R.color.bar_dark_blue));
view.setLayoutParams(params);
relativeLayout.addView(view);
TextView textView = new TextView(getApplicationContext());
textView.setText(" 20 ");
textView.setTextSize(20);
textView.setTextColor(getApplicationContext().getResources().getColor(R.color.black_text));
width = (int) getApplicationContext().getResources().getDimension(R.dimen.bar_width);
height = 100;
bottom = (int) getApplicationContext().getResources().getDimension(R.dimen.graph_margin_bar_bottom);
int offset = getApplicationContext().getResources().getDimensionPixelOffset(R.dimen.graph_margin_bar_bottom);
int pxSize = getApplicationContext().getResources().getDimensionPixelSize(R.dimen.graph_margin_bar_bottom);
RelativeLayout.LayoutParams params2 = new RelativeLayout.LayoutParams(width, height);
params2.setMargins(0, 0, 0, bottom);
params2.addRule(Gravity.CENTER_HORIZONTAL);
params2.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
params2.addRule(RelativeLayout.ALIGN_LEFT, view.getId());
textView.setLayoutParams(params2);
relativeLayout.addView(textView);
}
}
bars_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_marginTop="40dp" >
<RelativeLayout
android:id="#+id/bar_holder"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="20dp"
android:layout_marginBottom="10dp" >
</RelativeLayout>
</LinearLayout>
dimens.xml
<resources>
<dimen name="graph_margin_bar_bottom">40dp</dimen>
<dimen name="bar_width_compare">25dp</dimen>
<dimen name="bar_margin_left_right">10dp</dimen>
<dimen name="graph_margin_bar_compare_bottom">50dp</dimen>
<dimen name="bar_width">50dp</dimen>
</resources>
Here are 2 examples of phones, but it looks different on every phone...
Samsung Galaxy Tab 3 Lite (density1.0)
Samsung Galaxy S4 (density3.0)
Android groups all actual screen sizes into four generalized sizes: small, normal, large, and extra-large.
Create three floder for "layout" for normal,small screen
layout-large for large screen
layout-xlarge for extra-large screen
Add same bars_layout.xml into all floder and increase size as per screen size(For example if your keep size in layout floder 10 dp then for layout-large increase that size to 30 dp and for layout-xlarge make 60dp)
For dimens.xml small and normal screen add it to "values" floder
For large screen add to values-large floder
For extra-large add to values-xlarge
setMargins(int,int,int,int) is using pixels, not DIP, so on every device same size in pixels looks different, you need to convert DIP into pixels and then setMargins() with that value
multiply text height with densityDpi and textsize with scaledDensity values. So it will support different resolutions.
DisplayMetrics dm = context.getResources().getDisplayMetrics();
int densityDpi = dm.densityDpi;
float spi = dm.scaledDensity;
textheight = 100 * densityDpi;
textSize = 20 * spi;

How to use the taken width and height in xml file in andorid?

I have identified the width and height of the screen programatically. Now I want to use that width and height in my xml file. Kindly give me a way to achive this.
Here is my Activity class.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DisplayMetrics display = this.getResources().getDisplayMetrics();
float width = display.widthPixels;
float height = display.heightPixels;
Toast.makeText(TestProjectActivity.this, "width and height is: "+width + ": "+height, Toast.LENGTH_LONG).show();
float w = convertPixelsToDp(width, this);
float h = convertPixelsToDp(height, this);
Toast.makeText(TestProjectActivity.this, "DP" +w+": "+h, Toast.LENGTH_LONG).show();
}
public static float convertPixelsToDp(float px,Context context){
Resources resources = context.getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
float dp = px / (metrics.densityDpi / 160f);
return dp;
}
Now I want to send the w and b to the xml for the further work.
Any help would be appricieted?
Thanks.
You cannot pass information back to XML. At most, you can get your widget using findViewById and then programmatically set the widget size.
I am developing the application which runs on any screen device. So the issue with the screen size. If I am setting the width of textview to 200dp, then its ok in my device but on other device,its not getting appear. So I just want a way where I can use this above detected width and height in my XML
You should then use a LinearLayout to give your image a size relative to the available width (like a percentage of the width of the screen
Here is how your XML would look (pseudo code)
LinearLayout (layout_width: match_parent, layout_height: wrap_content)
ImageView (layout_width: 0dip, layout_height: wrap_content, layout_weight: 50)
ImageView (layout_width: 0dip, layout_height: wrap_content, layout_weight: 50)
In the above example, each image view will take 50% of the screen width, no matter the number of pixels.
I think you need to Google a good tutorial about layouts in Android.

Android Programming: How to maintain image size on different displays?

e.g. I want a given Bitmap (100x200px) to always have the following size:
height = 1/10 of the screens height
length = 1/20 of the screens length,
no matter how large the screen is and what resolution it has. How can I do this without creating versions of my bitmap for each of the drawable folders (I've seen examples where all the pictures where only stored in the "drawable" folder, so there must be away without creating 4 instances of each picture used)?
Thanks for the help!
Load your bitmap into an ImageView and set the ScaleType of the ImageView to 'FIT_XY' and it will scale your image to whatever size your ImageView is. You can set the ImageView size to be relative to your screen size by getting the screen dimensions from the WindowManager
For example:-
int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
int screenHeight = getWindowManager().getDefaultDisplay().getHeight();
float newWidth = 0.05f * screenWidth;
float newHeight = 0.10f * screenHeight;
imageview.setScaleType( ImageView.ScaleType.FIT_XY );
imageview.setLayoutParams(new LinearLayout.LayoutParams( (int)newWidth, (int)newHeight ));
final int width = getWindowManager().getDefaultDisplay().getWidth();
final int height = getWindowManager().getDefaultDisplay().getHeight();
then use bitmapfactory to scale the image

Aligning a view to an ImageView in different resolutions

The problem with properly handling multiple screen sizes on Android has been talked all over thousands of times. However I couldn't find a solution to m problem. In a nutshell I need to align my custom progress bar over an imageView. I've got 3 set of drawables for the imageView - ldpi(240x400), mdpi(320x480), hdpi(480x800). I align my custom view in Java with the following code:
//get screen density
float density = getBaseContext().getResources().getDisplayMetrics().density;
//set the progress bar position according to screen density
if ( density == 1.0f)
{
ImageView micImage = ((ImageView) findViewById(R.id.imageViewClk));
Drawable drawing = micImage.getDrawable();
Bitmap bitmap = ((BitmapDrawable)drawing).getBitmap();
// Get current dimensions
int width = bitmap.getWidth();
int height = bitmap.getHeight();
LayoutParams params = new LayoutParams((int)(height/13.94), (int)(height/13.94));
params.setMargins((int)(width/2.30), 0, 0, (int)(height/2.75));
params.addRule(RelativeLayout.ALIGN_LEFT,R.id.imageViewClk);
params.addRule(RelativeLayout.ALIGN_BOTTOM,R.id.imageViewClk);
myCustomTwistedProgressBar.setLayoutParams(params);
}else if ( density == 1.5f ){
ImageView micImage = ((ImageView) findViewById(R.id.imageViewClk));
Drawable drawing = micImage.getDrawable();
Bitmap bitmap = ((BitmapDrawable)drawing).getBitmap();
int width = bitmap.getWidth();
int height = bitmap.getHeight();
LayoutParams params = new LayoutParams((int)Math.round(height/14.13), (int)Math.round(height/14.13));
params.setMargins((int)Math.round( width/2.27), 0, 0, (int)Math.round(height/2.91));
params.addRule(RelativeLayout.ALIGN_LEFT,R.id.imageViewClk);
params.addRule(RelativeLayout.ALIGN_BOTTOM,R.id.imageViewClk);
myCustomTwistedProgressBar.setLayoutParams(params);
}else if ( density == 0.75f ){
ImageView micImage = ((ImageView) findViewById(R.id.imageViewClk));
Drawable drawing = micImage.getDrawable();
Bitmap bitmap = ((BitmapDrawable)drawing).getBitmap();
// Get current dimensions
int width = bitmap.getWidth();
int height = bitmap.getHeight();
LayoutParams params = new LayoutParams((int)(height/14.88), (int)(height/14.88));
params.setMargins((int)(width/2.27), 0, 0, (int)(height/2.69));
params.addRule(RelativeLayout.ALIGN_LEFT,R.id.imageViewClk);
params.addRule(RelativeLayout.ALIGN_BOTTOM,R.id.imageViewClk);
myCustomTwistedProgressBar.setLayoutParams(params);
}
Everything worked fined on different screen sizes however when I tried to check on 480x854 resolution the vertical alignment of the custom view was incorrect. Checked with 480x800 on the same screen size and it again works. I than went for a big jump and checked in GalaxyTab and the horizontal and vertical alignments were wrong. Now my first though was that the bitmap width and height were the one of the image not the actual resized imageview. So I spent a lot of time on trying to get the real size of the imageview and even went for viewTreeObserver but the results were all the same - the correct, unchanged (unscaled?) bitmap size. So being positive that the problem is not here I couldn't get through further. Does anyone have an idea why the alignment is not working correctly?
PS: as for the image view in layout xml file I have 2 configurations for long and notlong but this image has the same description in both:
<ImageView
android:src="#drawable/cloking"
android:id="#+id/imageViewClk"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_centerHorizontal="true"
android:layout_above="#+id/imageViewProcess"
android:adjustViewBounds="true"
android:cropToPadding="false"
android:layout_marginTop="60dp"
android:scaleType="fitXY">
</ImageView>
Android will scale the image but it will maintain aspect ratio for the image. You can't control aspect ratio with layout settings (as far as I know). I would solve that problem by choosing few screen ratios that I want to support and making few more resources (images that would have aspect ratios that you support). Code would look like this:
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
ImageView image = (ImageView) findViewById(R.id.imageViewClk);
if(width/height == aspectRatio1)
{
image.setImageResource(R.id.imageAspect1);
} else if( width/height == aspectRatio2...

Android Scale Image to largest size

Hi i'm working on an application that will be loading images and i'm looking to scale each image to it's largest possible size for instance if the image is a landscape image (if width is larger than height) i would like to stretch the width to fill the width of the phone and scale height to keep it's aspect ratio. If the height is larger than the width i.e. a portrait image the image should be scaled to fit the height of the phone and width should then adjust to keep the aspect ratio i've had a bit of trouble getting this to work here's what i've done so far though any help would be greatly appreciated.
final ImageView i = new ImageView(mContext);
i.setImageResource(mImageIds[position]);
i.setBackgroundResource(android.R.color.black);
//TODO need to get actual size of drawable not view size which is 0
ViewTreeObserver vto = i.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
int w = i.getMeasuredWidth();
int h = i.getMeasuredHeight();
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
if(w <= h){
//TODO need to think about landscape
h = height - convertDpToPixel(50, context);
w = w*(width);
}else{
h = h*(height);
w = width;
}
//TODO set imageview to w and h
return true;
}
});
for get Display width , height
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int wwidth = displaymetrics.widthPixels;
For Resize Imageview
ImageView img=(ImageView)findViewById(R.id.ImageView01);
Bitmap bmp=BitmapFactory.decodeResource(getResources(), R.drawable.sc01);
Bitmap resizedbitmap=Bitmap.createScaledBitmap(bmp, width, height, true);
img.setImageBitmap(resizedbitmap);
Increase either the height or the width to their maximum, depending on which is already greater.
Now, let's say you're working with a landscape image:
You've already expanded the width to it's maximum size, the display's width
The side you expanded is the width of the image, so assuming the display width = width and the image's width = w:
width / w = r
So r would be the ratio between the display width and the image width. Now you need to use this to increase your height.
Simply multiply the height by the ratio, and set the image's new height to the resulting number.
If you end up with a portait image... well, I think you'll be able to figure it out. It's pretty much the same thing.
After all that, I think it would just be a matter of positioning the image in the center of the screen.

Categories

Resources