I am looking to resize an EditText height, based on the height of the text size.
The reason I want to do this is because some users will set their text size to "Large" inside the Android Accessibility Options, and than some of the text will be cut off within my applications EditText views.
What can I do to dynamically adjust the height to match the Text Size? I do not need auto resizing or anything fancy.
Here is some code inside my custom EditText Class
mCurrentTextSize = getTextSize();
LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT,
DisplayUtils.pixel2dp(getContext(), mCurrentTextSize));
setLayoutParams(layoutParams);
Inside a Utility Class
public static int pixel2dp(Context context, float pixel) {
DisplayMetrics metrics = new DisplayMetrics();
float logicalDensity = metrics.density;
return (int) Math.ceil(pixel / logicalDensity);
}
Why not use layout_height=wrap_content? It will automatically re-adjust the EditText so as to contain the text.
Related
I have a code in my app which when you click the FAB, a spinner appears. when I test this on my phone which is quite small in screen size, the spinner shows up right. but when I try it on a bigger phone screen size, the spinner seems to shrink and is hidden partially.
Is it possible to add constraints to my code here so that the size of the spinner will change depending on the size of the screen and it won't be partially cut off/hidden?
code:
SearchableSpinner spinner = (SearchableSpinner) makeSpinner();
mLinearLayout.addView(spinner); //Add another spinner
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams)spinner.getLayoutParams();
layoutParams.setMargins( 5, 130, 10, 0);
layoutParams.height = 80;//pixels
layoutParams.width = 240;//pixels
spinner.setLayoutParams(layoutParams);
To make your spinner have a consistent size/looks on different screen sizes you have to use DP(density independent pixels) instead of simple pixels.
What I would recommend you to do is to set your layout.height/width to specific DP by converting DP to pixels using this:
public static float convertDpToPixel(float dp, Context context){
Resources resources = context.getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
float px = dp * ((float)metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT);
return px;
}
Good luck :)
Part of my app displays a single 5-character word in a TextView which should fill the entire screen. The questions listed below address this same issue:
How to adjust text font size to fit textview
Have TextView scale its font size to fill parent?
Text size and different android screen sizes
Auto-fit TextView for Android
However, since my case requires only one 5-character word to fill the entire screen, is there a simpler way to do this? If not, would it be practical to simply provide drawable resources (assuming that the 5-character word will always be the same)?
Thanks!
I'm going to give you some code which shows the exact opposite of what you requested. The code below shrinks a line of text until it fits within the desired area. But there is the basic idea: Get the paint of the textView and then measure it. Adjust the size and remeasure it e.g. textView.getPaint().measureText("Your text")
public static float calculateTextSizeToFit(TextView textView, String desiredText, int limitSpSize, float desiredTxtPxSize) {
Paint measurePaint = new Paint(textView.getPaint());
measurePaint.setTextSize(desiredTxtPxSize);
float pWidth = measurePaint.measureText(desiredText);
float labelWidth = textView.getWidth();
int maxLines = textView.getMaxLines();
while (labelWidth > 0 && pWidth/maxLines > labelWidth-20) {
float textSize = measurePaint.getTextSize();
measurePaint.setTextSize(textSize-1);
pWidth = measurePaint.measureText(desiredText);
if (textSize < TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, limitSpSize,
textView.getContext().getResources().getDisplayMetrics())) break;
}
return measurePaint.getTextSize();
}
Alright I'm trying to build an activity that has a horizontal scrollview, that the user can swipe through, to view different "pages". My train of thought is these "pages" will be views. The following is a mockup of my idea (to mess around to see if it works)
I've experimented with this as follows:
My content view is set to the the scrollview. (unsure if this is an incorrect approach)
I create the scrollview, and place a view into it as follows:
private void setupScrollView()
{
Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics ();
display.getMetrics(outMetrics);
float density = getResources().getDisplayMetrics().density;
float dpHeight = outMetrics.heightPixels / density;
float dpWidth = outMetrics.widthPixels / density;
int width = (int)MeasureUtils.convertDpToPixel(dpWidth, getApplicationContext());
int height = (int)MeasureUtils.convertDpToPixel(dpHeight, getApplicationContext());
_scrollView = new HorizontalScrollView(getApplicationContext());
_scrollView.setBackgroundColor(Color.CYAN);
_scrollView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
Log.i("DEBUG", "Screen dp width = " + dpWidth + " screen dp height = " + dpHeight);
TextView view = new TextView(getApplicationContext());
view.setBackgroundColor(Color.RED);
view.setText("TEST");
view.setX(0); // Start at the left of the scrollview.
view.setWidth(width); // Size it so that it fills to the right of the scrollview.
TextView view2 = new TextView(getApplicationContext());
view2.setBackgroundColor(Color.GREEN);
view2.setText("TEST2");
view2.setX(width); // Start the second "page/view" offscreen to the right where i can scroll to it
view.setWidth(width); // Fill the screen width
LinearLayout layout = new LinearLayout(getApplicationContext());
layout.setBackgroundColor(Color.MAGENTA);
layout.addView(view);
layout.addView(view2);
_scrollView.addView(layout);
}
The idea above is that I will see a view, that takes up the screen, representing a page. This view should be "RED" in color. I can then scroll horizontally to the right and see the second view (view2) representing the next page. This view should be "GREEN" in color. This does not happen. I end up seeing what looks like 1/3rd or 1/2 of my screen being view1, the linearlayout taking up almost the whole screen (a bit of a gap to the right edge where the CYAN from the scrollview bleeds through).
Am I approaching this the wrong way, and/or is it possible to make this work the way I'm going at it?
You probably do not want to use a horizontalscroll view to create "pages".
Try looking at PageViewer
This automatically builds in all the sywpe and inflating logic for you.
Basically you will get a call to inflate a certain page. There you can then create your view (dynamically if you wish) and then just return the root to be rendered.
Alright I've figured out what I was doing wrong, and it turned out to be something very small...
The complete code is here:
private void setupScrollView()
{
Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics ();
display.getMetrics(outMetrics);
float density = getResources().getDisplayMetrics().density;
float dpHeight = outMetrics.heightPixels / density;
float dpWidth = outMetrics.widthPixels / density;
int width = (int)MeasureUtils.convertDpToPixel(dpWidth, getApplicationContext());
int height = (int)MeasureUtils.convertDpToPixel(dpHeight, getApplicationContext());
_scrollView = new HorizontalScrollView(getApplicationContext());
_scrollView.setBackgroundColor(Color.CYAN);
_scrollView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
Log.i("DEBUG", "Screen dp width = " + dpWidth + " screen dp height = " + dpHeight);
TextView view = new TextView(getApplicationContext());
view.setBackgroundColor(Color.RED);
view.setText("TEST");
view.setX(0);
view.setWidth(width);
view.setHeight(height - 50);
TextView view2 = new TextView(getApplicationContext());
view2.setBackgroundColor(Color.GREEN);
view2.setText("TEST2");
view2.setX(0);
view2.setWidth(width);
view2.setHeight(height - 50);
LinearLayout layout = new LinearLayout(getApplicationContext());
layout.setBackgroundColor(Color.MAGENTA);
layout.addView(view);
layout.addView(view2);
_scrollView.addView(layout);
}
This creates a horizontal scrollview programmatically, as I had, but the problem was that I was setting the second view to be "width" away, when it should be set to "0"as can be seen by:
view2.setX(0);
With that, I get 2 "views" that resemble pages in my scrollview that I can swipe through. Each taking up the whole page.
Hate having the code close and it being a simple fix that I missed :|
Hope this helps anyone else that tries to do it this way. I'm going to look into the PageViewer as Frank suggested.
Is there a way to find out whether the text content to be placed in a TextView will fit in a single row or not?
What i want to achieve is displayed in the attached image (its a section of a listView). The problem relates to textView#3. If it is too big, i want to place it below textView#2, but if content is short enough i want to place it to right of textView#2 (scenario seen in row#3 is what i want to escape from)
So, anyone?.. How can i solve this particular problem?
I'm imagining this can't be achieved with a single layout for my listview's rows..
It is possible. You should measure text size and compare it against TextView size. If text width > textView width than it is too long.
You can learn about text measuring from this post.
also you can use TextView's built-in features and make it single line and set text ellipsize method.
A solution (& not a pretty one) is to do some math on the space occupied in the textView by your strings. In my particular case i've added 2 textViews (3 & 3B) & depending on what my math calculations say - i would use just one & hide the other.
Details:
in the getView method of your adapter find out the width of the parent listView
public View getView(int position, View convertView, ViewGroup parent) {
int listViewWidth = parent.getWidth();
calculate occupied space by other textViews placed in same row (just textView2 in my case);
Paint paint = textViewX.getPaint();
occupiedWidth = (int) (occupiedWidth +paint.measureText("text to be placed in textview"));
compare space occupied by text to be placed in the last textview ( in my screenShot textView3, same formula to calculate width) & compare with space left (listViewWidth - occupiedWidth)
set the text on the correct textView & hide the other
.. improve the code as needed
There is no in-build function to compare this.
After doing to many research and code i have build my own function to do this...
1) copy this code to your project
import android.app.Activity;
import android.content.res.Resources;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.widget.TextView;
public class TextMeasure {
public static boolean isTextCanFitInTextView(TextView textView, String txt , float allowWidthInDp , Activity activity){
String backupText = textView.getText().toString();
textView.setText(txt);
textView.measure(0, 0); //must call measure!
float textViewSize_px = textView.getMeasuredWidth(); //get width in px
// Converts dip into its equivalent px
float dip = allowWidthInDp;
Resources r = activity.getResources();
float allowView_px = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dip,
r.getDisplayMetrics()
);
//restore textView
textView.setText(backupText);
return textViewSize_px <= allowView_px;
}
public static boolean isTextCanFitInTextView_matchParent(TextView textView, String txt , float totalMarginInDp, Activity activity){
String backupText = textView.getText().toString();
textView.setText(txt);
textView.measure(0, 0); //must call measure!
float textViewSize_px = textView.getMeasuredWidth(); //get width in px
// Converts dip into its equivalent px
float dip = totalMarginInDp;
Resources r = activity.getResources();
float totalMarginInDp_px = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dip,
r.getDisplayMetrics()
);
float allowView_px;
float window_length;
window_length = getDisplayWidthInPixel(activity);
allowView_px = window_length - totalMarginInDp_px;
//re store textView
textView.setText(backupText);
return textViewSize_px <= allowView_px;
}
private static float getDisplayWidthInPixel(Activity activity){
DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
return metrics.widthPixels;
}
}
2) Use above class method to do your text and textView comparison , for eg :
1) Know exact width , android:layout_width="300dp"
TextView yourTextView = findViewById(R.id.txt);
float widthOfTextView_inDp = 300f; // width of textView Size in dp (densityPixel) , what you set in xml view
String yourTxt = "your text need to display in single line";
if (TextMeasure.isTextCanFitInTextView(yourTextView,yourTxt,widthOfTextView_inDp,this)){
// text can fit in to text View
yourTextView.setText(yourTxt);
}else {
// text can't fit in to text View
// add your logic
}
2) match_parent used to set width.
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_width="match_parent"
TextView yourTextView = findViewById(R.id.txt);
float totalMargin_inDp = 20f; // width of text view is match_parent and (marginStart = 10dp), (marginEnd = 10dp) = 20dp, note: it is total margin from both end of mobile screen combine.
String yourTxt = "your text need to display in single line";
if (TextMeasure.isTextCanFitInTextView_matchParent(yourTextView,yourTxt,totalMargin_inDp,this)){
// text can fit in to text View
yourTextView.setText(yourTxt);
}else {
// text can't fit in to text View
// add your logic
}
try this property of textview
android:maxLength="number of characters you want to display in textview"
now in Actvity check if string length is > maxLength than change the postion of your view.
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.