Android TextView: can I stop text that is partially displayed from appearing - android

In my app I display several text views containing text of various length that is loaded in at run time. I do not know the dimensions of the text view or the length of the text until run time. Sometimes, when the text is long and the textview small some of the text is partially visible, for example:
I want to remove the partially visible text as it looks a bit naff, but I can't find a way to do this. Any help would be appreciated!
Thanks,
Dave

You can hard code the TextView height in a way that the second row of text will not be visible.
Or use:
android:maxLines , Makes the TextView be at most this many lines tall.
as suggested above.

Put your textviews in a scrollview layout.And specify a specific width to your textview and make the height wrap content.So that your text doesn't get cut.

This is how I did it. I ran this code after the activity had loaded by posting the method CheckTextIsVisible to the parent relativelayout's handler queue, otherwise the height of the textviews will not be known:
m_eventsLayout.Post(new Action(CheckTextIsVisible));
Then the method CheckTextIsVisible finds each textview with text in it, calculates the height of the font, works out how many lines can fit in the textview, and sets the number of maximum lines accordingly:
private void CheckTextIsVisible()
{
View view;
TextView tView;
Android.Text.TextPaint tPaint;
float height;
int heightOfTextView;
int noLinesInTextView;
for (int i = 0; i < m_eventsLayout.ChildCount; i++)
{
view = m_eventsLayout.GetChildAt(i);
if (view is TextView)
{
tView = (TextView)view;
if (tView.Text != "")
{
//calculate font height
tPaint = tView.Paint;
height = CalculateTextHeight(tPaint.GetFontMetrics());
//calculate the no of lines that will fit in the text box based on this height
heightOfTextView = tView.Height;
noLinesInTextView = (int)(heightOfTextView / height);
//set max lines to this
tView.SetMaxLines(noLinesInTextView);
}
}
}
}
private float CalculateTextHeight(Android.Graphics.Paint.FontMetrics fm)
{
return fm.Bottom - fm.Top;
}
This results in no partially visible text!

Related

how to change text if is Ellipsized in android textView

I saw this post on how to check if text is ellipsized.
I want to programatically change the text if it's ellipsized.
however, if I use callback in textView.post() the text change will be seen in the UI for the user or cause performance issues.
side comment:
I have tried to measure text width and view width in treeObserver.preDraw() but there is a case I see when debugging that both width are equal and nevertheless the text is replaced when it's not truncated.
replacing the condition to textWidth < viewWidth makes few cases of non-ellipsized text to still be replaced by shorter one.
final ViewTreeObserver[] viewTreeObserver = {myAccountView.getViewTreeObserver()};
viewTreeObserver[0].addOnPreDrawListener(
new OnPreDrawListener() {
#Override
public boolean onPreDraw() {
int chipWidth =
myAccountView.getMeasuredWidth()
- myAccountView.getPaddingLeft()
- myAccountView.getPaddingRight();
if (chipWidth > 0) {
myAccountView.setText(
setChipTextWithCorrectLength(
getContext().getString(R.string.desc_long_length),
getContext().getString(R.string.desc_meduim_length),
getContext().getString(R.string.short_length),
chipWidth));
viewTreeObserver[0] = myAccountView.getViewTreeObserver();
if (viewTreeObserver[0].isAlive()) {
viewTreeObserver[0].removeOnPreDrawListener(this);
}
}
return true;
}
});

How to check programatically if all the Views fit inside the screen

I have a layout which is something like this:
LinearLayout (linearLayout)
'--TextView (textView1)
'--ImageView (imageView)
'--TextView (textView2)
textView1 changes its text sometimes and it can be long, so it leaves part of textView2 out of the screen. I want to prevent that, so I want to remove imageView from the layout whenever this happens. imageView may or may not be visible at the time when this is computed (maybe it was removed before when textView1 was edited previously).
This is what I have coded:
void changeText(String veryLongString){
textView1.setText(veryLongString);
int [] loc = new int [2];
textView2.getLocationOnScreen(loc);
int bottom = textView2.getMeasuredHeight() + loc[1];
if (imageView.getVisibility() == View.GONE)
bottom += imageView.getHeight();
if (bottom > linearLayout.getMeasuredHeight()){
imageView.setVisibility(View.GONE);
} else {
imageView.setVisibility(View.VISIBLE);
}
}
But for some reason this doesn't work as expected, because it seems as if changes in the position and height of the Views don't take place immediately. When I call getMeasuredHeight() and getLocationOnScreen() I get the values BEFORE the changes I have just made. The result that I get is that if I set a very large text imageView is not removed, but if I then set a short text, it is removed.
If there any other way to face this problem?
Even though I think that this is not the right approach (you can do all kinds of stuff in your XML so you don't have to meddle with Java code), here is a quick example of what you can do from Java (for example, in your onStart() method)
ViewGroup group = (ViewGroup) findViewById(R.id.myLayout);
int groupHeight = group.getHeight();
for (int i = 0; i < group.getChildCount(); i++) {
groupHeight -= group.getChildAt(i).getHeight();
if (groupHeight < 0) {
// they don't fit in the layout
myImageView.setVisibility(View.GONE);
}
}

Android TextView baseline related margin

I need to position a TextView the way its baseline is 20dp from the bottom of the container.
How can I achieve this?
The layout with bottom margin or padding produces the same result.
I would like to make the text 'sit' on the purple line.
When I write 'sit' I mean, the 'wert' should touch the line, not 'q...y'.
The padding / margin is equal to the purple square size:
If you still need it, I wrote custom method, to not create lots of custom views. It works for me with TextView:
public static void applyExistingBotMarginFromBaseline(View view) {
final int baseline = view.getBaseline();
final int height = view.getHeight();
final ViewGroup.MarginLayoutParams marginLayoutParams;
try {
marginLayoutParams = ((ViewGroup.MarginLayoutParams) view.getLayoutParams());
} catch (ClassCastException e) {
throw new IllegalArgumentException("Applying margins on a view with wrong layout params.");
}
final int baselineMarginValue = baseline + marginLayoutParams.bottomMargin;
marginLayoutParams.bottomMargin = baselineMarginValue - height;
view.setLayoutParams(marginLayoutParams);
}
You can apply it when view is measured already, so like this:
final TextView title = (TextView) findViewById(R.id.title);
title.post(new Runnable() {
#Override public void run() {
Utils.applyExistingBotMarginFromBaseline(title);
}
});
Also you can use databinding framework and write your own custom BindingAdapter with a bit customized method, to use it from xml.
Your problem is not the padding/margin referenced to the parent, I think is about your font, I recommend you to change the fontFamily:"yourStyle"
even worst you have to re-difine your own font style which is explained here Custom fonts and XML layouts (Android) or Set specific font in a styles.xml

Set ScollView Size (Height) in Code (Sum of All Controls Heights)

I would like to set the Height of my ScrollView per Code dynamically cause my ScrollView is actually higher then it shall be (empty space at bottom).
My thoughts were, that I could get the Heights of all Controls within the the ScrollView, sum-up them and then I could set that Height to my ScrollView.
What I tried is following code:
protected override void OnStart()
{
base.OnStart();
SetScrollViewSize();
}
private void SetScrollViewSize()
{
var root = FindViewById<ScrollView>(Resource.Id.root);
if (root != null)
{
var controls = GetSelfAndChildrenRecursive(root); //Gives me all Controls in the root (The ScrollView)
int heightOfAllControlsTogether = 0;
foreach (ViewGroup control in controls)
{
heightOfAllControlsTogether += control.Height;
}
ViewGroup.LayoutParams parameters = new ViewGroup.LayoutParams(root.Width, heightOfAllControlsTogether);
root.LayoutParameters = parameters;
}
}
The Heights and MeasuredHeights are always 0 (zero) - (I know it needs to be rendered first, but what would be the right place then?) and I'm not even sure if my approach would work.
Any Help would be appreciated!
Well I found out why.
The Background-Graphic was too high. That was creating the empty space at the bottom.
THis is an example to set scrollview height based on total height of Children:
private void setScrollViewHeightBasedOnChildren() {
int size = layoutRoot.getChildCount();
LinearLayout item = (LinearLayout) layoutRoot.getChildAt(0);
item.measure(0, 0);
int height = item.getMeasuredHeight();
//Reset size of ScrollView
scroll.setMinimumHeight(height / size);
scroll.invalidate();
}
See details: Set the height of ScrollView equal total height of children

TextSwitcher bug

i have a problem with the TextSwitcher.
In my app i have 3 Textswitcher with wrap_content (width and higth) inside an LinearLayout!
Each TextSwitcher is declared with an in and outAnimation.
My problem:
When the text is switch the first time, i have spaces between the elements!
like: 1.23 45 678
but it has to: 1.2345678 without spaces
when the text switches the second or 3. time the spaces are gone.
I cant imagine why there are spaces?? There is no other Element, no padding, no margin.
maybie the reason is the ViewFactory:
ViewFactory for the middle part switche:
public View makeView() {
TextView t = new TextView(SmartTraderFxTrading.this);
t.setTextColor(Color.BLACK);
t.setTypeface(null, Typeface.BOLD);
t.setTextSize(26f);
return t;
}
an for the switcher left and right from the middle part:
public View makeView() {
TextView t = new TextView(this);
t.setTextColor(Color.DKGRAY);
t.setTextSize(20f);
return t;
}
but i can change everything, the spaces are always there after the first switch, and also maybie after the second.
Is it a bug? Please help!
EDIT:
Problem solved!
The problem is that the Text befor has more digits as after! So the TextSwitcher has a larger width and after redraw of the activitie it wraps the TS.

Categories

Resources