I was creating Android application. that will dynamically create questions. but based on the mobile screen size view is not coming properly. I don't know how to fix this problem. I have enclosed image that is taken form different mobiles.
Screen size -3.7" , Screen Size -5.0"
All the Element sizes are varied based on the screen size.can any one help to display responsive screen in Android.
My Code is:
lView.setBackgroundColor(Color.parseColor("#FFFFFF"));
lView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
LinearLayout.LayoutParams layoutParams2 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 220);
GradientDrawable gdtitle = new GradientDrawable();
gdtitle.setCornerRadius(5);
ImageView title = new ImageView(Main2Activity.this);
title.setImageResource(R.drawable.logo);
title.setLayoutParams(layoutParams2);
title.setBackgroundDrawable(gdtitle);
lView.setOrientation(LinearLayout.VERTICAL);
lView.addView(title);
GradientDrawable gd3 = new GradientDrawable();
gd3.setCornerRadius(30);
gd3.setColor(Color.parseColor("#003366"));
gd3.setStroke(0, 0xFF000000);
TextView uname1 = new TextView(Main2Activity.this);
uname1.setText("Hello , "+Sessionname);
uname1.setGravity(Gravity.LEFT);
uname1.setTextColor(Color.parseColor("#003366"));
uname1.setTextSize(20);
uname1.setLayoutParams(l2);
et1 = new TextView(Main2Activity.this);
et1.setHeight(100);
et1.setTextColor(Color.WHITE);
et1.setHintTextColor(Color.WHITE);
et1.setGravity(Gravity.CENTER);
et1.setHint("Select Date");
et1.setBackgroundDrawable(gd3);
et1.setTextSize(15);
et1.setLayoutParams(l2);
lView.setOrientation(LinearLayout.HORIZONTAL);
LinearLayout.LayoutParams l4 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
l4.gravity=Gravity.CENTER;
lHorizontalView1.setOrientation(LinearLayout.HORIZONTAL);
lHorizontalView1.setLayoutParams(l4);
lHorizontalView1.addView(uname1);
lHorizontalView1.addView(et1);
lView.addView(lHorizontalView1);
You're hard-coding your values in pixels. For example for your height you call setHeight(100) that means set this View to be 100px tall. However, with different screen densities that's going to look completely different. Given a fix screen size (say 5 inches), one device could have a resolution of 480x800 and another one could be 1440x2560, your setting of 100px will look exactly how you have it now.
Use Display Metrics instead to retrieve the screen density and use device independent pixels (dip or dp) instead of pixels (px) as units. For example you can set your height based on the density of the device like this:
setHeight(100 * getResources().getDisplayMetrics().density);
However, your desired height may have to be smaller as that will become 100dp so you may have to set it to something like 50 instead. Play around until you get your desired results.
then your View will look uniform across devices.
Related
I use the code below for a popup alert box with a EditText in it. I am using margin to align the EditText in the code below. The problem is the margin numbers that I use for the one device or emulator will be off on an other device or emulator. if I align one device correctly, it will look off on the other device. Any help is appreciated.
AlertDialog.Builder aBuilder = new AlertDialog.Builder(ExpenseSheet.this);
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
params.setMargins(85, 0, 50, 0);
// Set up the input
final EditText input = new EditText(ExpenseSheet.this);
//FOCUSING ON POPUP WINDOW TEXT
input.requestFocus();
layout.addView(input, params);
// Specify the type of input expected; this, for example, sets the input as a password, and will mask the text
input.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
//limiting the amount of characters
input.setFilters(new InputFilter[]{new InputFilter.LengthFilter(8)});
aBuilder.setView(layout);
The problem is that you are using hard-coded numbers for margin which represent pixels by default. this pixel count can get converted to a longer or shorter actual length on devices depending upon their screen density.
you should try multiplying these values with screen density in order to make them look constant across devices of various screen densities.
example:
final DisplayMetrics metrics = context.getResources().getDisplayMetrics();
final float screenDensity = metrics.density;
double mWidth = 25 * screenDensity;// constant width across densities
double mHeight = 30 * screenDensity;// constant height across densities
now you can use such variables instead of hard-coded values to get uniform effect across various screen densities.
I'm using the following method which programatically creates a linearlayout and populates it with two textviews, adds text and then turns it into a drawable that I later use a layer above a shape. However, I've noticed that I can't create a small fontsize - it seems stuck at a minimum size which is relatively.. large, and anything that I specify below that value just seems to make it look increasingly blurry (but still the same size). What could be the reason for this?
This behavior occurs whether or not I used TypedValue.COMPLEX_UNIT_SP.
Edit: This size stays the same even if I specify something ridiculous like:
.setTextSize(TypedValue.COMPLEX_UNIT_SP, 60);
it doesn't get any bigger - it just gets "sharper".
Edit 2: If I specify the top textview as having a very large size, then the smaller I set the second textview, the smaller it becomes - as a ratio (for example, if I set the top at 100 and the bottom at 50 it looks exactly the same as the top at 10 and the bottom at 5). However, in no way can I reduce the size of the top textview.
Edit 3: If I remove one of the textviews, and leave only the other one as a single textview in the layout - I can't change the size at all. I can only make it more or less blurry depending how low I set the number but it will always appear the exact same size on screen.
private Drawable createTextLayer() {
LinearLayout newLinearLayout = new LinearLayout(getContext());
newLinearLayout.setOrientation(LinearLayout.VERTICAL);
newLinearLayout.setGravity(Gravity.CENTER);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
newLinearLayout.setBackgroundColor(getColor(R.color.somecolor));
newLinearLayout.setLayoutParams(layoutParams);
TextView headlinetv = new TextView(getContext());
TextView bodytv = new TextView(getContext());
headlinetv.setText(headlineText);
headlinetv.setTextSize(7);
headlinetv.setGravity(Gravity.CENTER);
bodytv.setText(bodyText);
bodytv.setTextSize(6);
bodytv.setGravity(Gravity.CENTER);
newLinearLayout.addView(headlinetv);
newLinearLayout.addView(bodytv);
newLinearLayout.setDrawingCacheEnabled(true);
newLinearLayout.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
newLinearLayout.layout(0, 0, newLinearLayout.getMeasuredWidth(), newLinearLayout.getMeasuredHeight());
newLinearLayout.buildDrawingCache(true);
Bitmap b = Bitmap.createBitmap(newLinearLayout.getDrawingCache());
newLinearLayout.setDrawingCacheEnabled(false);
return new BitmapDrawable(getResources(), b);
}
Change your code to:
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 7);
Change the font size of 7 to any font size as you wish.
This turned out to be quite tricky and took me several hours to solve, but I'm posting the answer for anyone else who ends up in a similar situation.
The cause:
The entire drawable layer was the uppermost layer above a shape, and was therefore stretched to the size of the shape no matter what. In order to stretch it to the size of the shape, the largest view was stretched (essentially, the longest textview) and therefore couldn't be enlarged or reduced in size.
The solution:
I defined two more textviews, gave them the longest string by 1 character, and made the textcolor transparent. I would have preferred to give them blank space as content but android refused to measure a textview containing whitespace, so it had to be actual text. I put one textview at the top and one at the bottom and thus the visible text appears perfectly centered and in the correct font size.
Edit:
There turns out to be a better way of doing this. Define the textview as the same size as the shape on which it sits as a layer and define padding around the textview (play around with it to find the minimal amount of padding needed). If you have several textviews, divide the size of the shape by the number of textviews and give each one a fraction.
I've been having trouble finding a generic way to size UI components so they look good on all devices. I have some ideas but could use any feedback on them or suggestions for better strategies.
Take a simple situation like a dialog with a single EditText which a user will enter a fairly long String into. On smaller devices I would like the EditText to be as wide as possible (because its likely that the maximum size possible on these devices isn't all that large). However, if I set the width of this EditText to FILL_PARENT, the dialog will look silly on tablets, because it will be much, much wider than it needs to be. Also, setting the width to some hard coded DIP value, like 500, isn't great because it doesn't maximize available space on smaller devices, won't expand to take up additional space if the device is rotated, and could be an issue on devices narrowers than 500 DIP.
What I would like to do is approximate the behavior FILL_PARENT by hardcoding the width of the EditText to of the screen's width, but to prevent the EditText from growing to wide on large devices by not allowing the width to be larger than some DIP value, like 500.
I have encountered 2 problems with this strategy:
1: If I set the EditText's width to the screen's width, the EditText doesn't fit on the screen (as shown in the below image). I fixed this by setting the width to 90% of screen width, but this is questionable (what if the device's dialogs have larger margins around them?).
2: My app sets android:configChanges flag in its application manifest such that dialogs don't get dismissed on rotation. But this means that dialogs don't get resized on rotation. So, if the device rotates from landscape to portrait while the dialog is visible, then the EditText will be too wide for the screen; and if it goes the opposite direction, then the EditText will not take up all the available space. I guess this would be fixable by relaying out my dialog on rotate, but it seems painful/ugly for my Activity to have to keep track of the visible Dialog and force it to relayout on rotation (particularly because each dialog would then have re-populate any field values when after relayout).
So, any thoughts on improving my solution, or on alternatives?
class SampleDialog extends Dialog
{
public SampleDialog(Context context)
{
super(context);
setContentView(getContentView());
}
private View getContentView()
{
TextView label = new TextView(getContext());
label.setText("A label:");
int fiveHundredDips = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 500, activity.getResources().getDisplayMetrics());
Display display = getWindowManager().getDefaultDisplay();
float width = .9f * display.getWidth();
Math.min(width, fiveHundredDips);
LinearLayout.LayoutParams linearParams = new LinearLayout.LayoutParams((int) width, LinearLayout.LayoutParams.WRAP_CONTENT);
EditText editText = new EditText(getContext());
editText.setLayoutParams(linearParams);
LinearLayout layout = new LinearLayout(getContext());
layout.addView(label);
layout.addView(editText);
return layout;
}
}
}
You could use different folders in your resources folder, which define different qualifiers for different devices. You can then specify say on a small device you would like a dimension to be 'x' big, and on a tablet to be 'x' big.
Another solution would be to programatically detect if the device is a Tablet, and perform actions based on that.
I would recommend you look into resource qualifiers, which are a very powerful tool in Android.
Take a look at the android:minWidth property. It's available on TextView as well as others. It seems the minWidth (set using dip units) would be a good option for you. You can make the text boxes large enough but not too large.
These values can be set programmatically. You might also find the following code useful in determining what values you want to use for the minWidth:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
Log.d("density", metrics.density);
Log.d("width dip", (int) (metrics.widthPixels / metrics.density));
Log.d("height dip", (int) (metrics.heightPixels / metrics.density));
I am developing for two different devices and need to force pxs on one device's layoutparameter object through code when specifying width and height. How do I do that?
GridView.LayoutParams glp = new GridView.LayoutParams(GridView.LayoutParams.WRAP_CONTENT, GridView.LayoutParams.WRAP_CONTENT);
glp.width = 80; <- need to ensure this is in px or LDPI interprets it .75 of 80
glp.height = 80;
Normally I would use setFontSize(TypedValue.COMPLEX_UNIT_PX, size) and it works. How about Layouts themselves?
You need the params to be fixed? If you want to make sure adding pixels, create dimen resources e.g: 80px in string.xml then load in LayoutParams
new GridView.LayoutParams(pixels, pixels); They are already pixels.
See the docs
http://developer.android.com/reference/android/view/ViewGroup.LayoutParams.html#ViewGroup.LayoutParams(int, int)
How can I set the image size on a widget programmatically? I am using this code to change the image but how can I set the size?
RemoteViews updateViews = new RemoteViews(EditPreferences.this.getPackageName(), R.layout.widgetmain2);
updateViews.setImageViewBitmap(R.id.ImageView00, ((BitmapDrawable)EditPreferences.this.getResources().getDrawable(R.drawable.normal_black_op100)).getBitmap());
ComponentName thisWidget = new ComponentName(EditPreferences.this, HelloWidget.class);
AppWidgetManager manager = AppWidgetManager.getInstance(EditPreferences.this);
manager.updateAppWidget(thisWidget, updateViews);
Thanks in advance
It's a very wide question in fact. There are multiple answers for it:
Usually you do it in layout.xml setting appropriate layout parameters (width, height) and scaleType: http://developer.android.com/reference/android/widget/ImageView.html#attr_android:scaleType. This handles a lot of cases - whenever the image is set its scaling will be recalculated according to it's parameters.
But sometimes you ned to do it programmatically. But it is more complex because it needs to take into account density of the screen and density of the bitmap, screen size independent pixel size and so on. There are two points here:
Getting bitmap in the right size. It depends whether you load bitmap from resources (it seems you do) or whether you load it manually. If you want to fully control the size of the bitmap, then you have to understand how it all works - I recommend reading http://developer.android.com/guide/practices/screens_support.html and especially the chapter Scaling Bitmap Objects created at Runtime.
Setting bitmap's dimensions on screen. If you want to do it on runtime and you already calculated required size in physical pixels. Remember there are also independent pixels and you need to convert physical pixels to another (look at "density independent pixels" definition and algorithms for calculation in http://developer.android.com/guide/practices/screens_support.html . Once you know the physical pixels, you can apply LayoutParameters to the ImageView. It will be something like:
Example:
LinearLayout.LayoutParams layoutParams = new
LinearLayout.LayoutParams(width_physical_pixels, height_physical_pixels);
imageView.setLayoutParams(layoutParams);
IMPORTANT! LinearLayout here is just example. It should be the PARENT class of the ImageView - so layout params are always of the type of the object container rather than of the object they are set on.