Android - fix TextView width by string - android

I think the answer to this question is probably so simple, but I'm struggling....
I have a TableLayout with multiple columns. I want the last column to be of a fixed width, but I want to define that width to just be able to hold the widest possible string from my program. i.e. it is always wide enough to contain "THIS STRING" without wrapping, or wasting any space.
I would like to do this as I have these TableLayouts within a ListView, so it looks very poor when the last column is of variable widths.
I have tried obtaining the string width, even going so far as to put it into a TextView, call getTextSize() then setWidth() on all appropriate TextViews. The problem I hit there is that gettextSize() returns pixels, but setWidth uses ScaledPixels.
I'm sure there is a really simple solution. Can anyone help?

Are you using android:width="wrap_content" in your XML layout to define the width of that last column?
Edit: I think I just understood, you have a list view, that holds a table and you want all rows of the list view to have the same length for the last row of the table. Right?
I can only think of one, very unelegant solution right now and it involves going over all strings before building the list view.
The general logic would be as follows:
Im going to suppose you are getting al strings from an array, lets call it data.
Establish a global float variable to represent the longest string you have, lets call it maxLength.
Create a textview (lets call it invisibleText) in your layout that wont be visible, you can do this by setting
android:visibility="gone"
Then:
int size = data.length;
maxLength = 0.0f;
for(int i = 0;i<size;i++){
invisibleText.setText(data[i]);
float thisLength = invisibleText.getTextSize();
if(thisLength>maxLength) maxLength = thisLength;
}
In you list view constructor:
TextView text = (TextView)findViewById(R.id.the_text_view_you_want);
text.setText(data[position]);
text.setWidth(maxLength)
The table columns should use android:width="wrap_content"
I didnt test this code, but it should work, i've done similar stuff before.

Related

Android text is cut off on a fixed height TextView

Consider this layout:
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="160dp"
android:textSize="20sp"
android:text="Apple Inc. is an American multinational technology company headquartered in Cupertino, California, that designs, develops, and sells consumer electronics, computer software, and online services."
android:ellipsize="end"
android:gravity="top"/>
What I want the TextView to do is to figure out how many lines it can fit in 160dp and places three dots if room is not enough. However the text is cut off instead:
How can I achieve the above behavior? I assume I can do it by just specifying some attribute on the layout resource file. Thanks.
There's no way to achieve this by simply specifying attributes on the layout resource file.
If you look at the setEllipsize() method in TextView, you'll see that it says:
Causes words in the text that are longer than the view's width to be ellipsized instead of broken in the middle. You may also want to setSingleLine() or setHorizontallyScrolling(boolean) to constrain the text to a single line. Use null to turn off ellipsizing. If setMaxLines(int) has been used to set two or more lines, only TextUtils.TruncateAt.END and TextUtils.TruncateAt.MARQUEE are supported (other ellipsizing types will not do anything).
From that documentation, you can see that ellipsis in TextView is actually highly dependent on two factors: view width and number of lines.
As such, I recall that an ellipsis might not show up for a TextView if it doesn't know the maximum number of lines that your TextView can have.
So for your intended behavior, this isn't possible because you're depending on the View's height instead. You want to use a specific height then have a TextView calculate the amount of lines that can be shown within that height. Finally, if the amount of lines needed is greater than the amount shown, you want to show ellipses.
That's... not possible with how the ellipses in TextView is coded. It simply wasn't meant for that.
Therefore, if you want this behavior, you need to either:
Create a custom TextView for your specific ellipses implementation
Manually calculate the amount of lines visible, then use setMaxLines() on that TextView
For the second option, you can calculate this by using the TextView methods getHeight() and getLineHeight().
For example:
textview = (TextView) findViewById(R.id.exampleTextView);
textview.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
final int maxLines = textview.getHeight() / textview.getLineHeight();
textview.setMaxLines(maxLines);
}
});
In my example, I'm doing this inside a ViewTreeObserver to avoid getHeight() calling a size of 0.
The second option should be able to get the behavior you want, but if you want this for every TextView, you should consider creating a custom TextView instead.
Set the layout_gravity on the TextView to fill

How to match column/view width when using ListViews on Android

I have a collection of models that need to be displayed vertically.
Each models has 4 values like strings, that all have a fixed width except the first values.
Can't figure out how to make the first views/columns wrap_content and equal in width compared to each other.
I tried a TableLayout, but that does not keep the widths in different columns for the rows.
I tried to use a MvxLinearLayout with a custom adapter that picks the largest width and sets all other matching views/columns..
Both solutions didn't work, and ended up with to much hacking.
Anyone idea's how to display Android vertical collections with equal/matching column widths?
edit: Collection I'm using has structure like
List<Person>
where Person has { string Name, int Age, string Gender }
The Collection View I'm looking for:
(where all first views in row must be all same size)

TableLayout not skipping column 0 when setting android:layout_column = "1"

The xml code on this site: http://www.learn-android.com/2010/01/05/android-layout-tutorial/6/
Gives the table layout shown in the image.
http://www.learn-android.com/wp-content/uploads/2010/01/TableLayout.png
But if you remove the first table row, then the First Name textview appears in column 0 even though its android:column_layout is set to "1"
But on this site: http://developer.android.com/reference/android/widget/TableLayout.html it says "If you skip a column number, it will be considered an empty cell in that row."
IF you want a empty cell in the row, do you have to fill it in with something or set its width?
Is there a better way to get things spaced in the middle of the screen like in the table row?
Thanks
So, the empty cell is there, it just has no width. If there is nothing with a nonzero width, it will look like there is no column 0. To get it to take up some space, there needs to be something there, even if its just an empty View with a width set.
If you want things centered, it might make sense to use a RelativeLayout and use either android:layout_gravity="center" or android:layout_gravity="center_horizontal" to align things in the center of the screen.

Layouts and Button

TableLayout relativeLayout = (TableLayout)findViewById(R.id.ll1);
TableRow row =new TableRow(this);
Button button ;
int counter = 0;
for(int i = 0;i<=13;i++){
counter++;
button = new Button(this);
button.setText(counter);
row.addView(button);
}
relativeLayout.addView(row,new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
relativeLayout.computeScroll();
XML File
<TableLayout android:id="#+id/ll1" android:shrinkColumns="true"
android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="#id/button1"
xmlns:android="http://schemas.android.com/apk/res/android"></TableLayout>
But whenever i execute my application it just move my buttons in a single row and after 5 buttons all the buttons move out from the screen. i dont' want to add more rows as i don't want to hard-code anything in my code like placing some code if (counter%5==0) then do this and that.
Is there any other way to calculate the width that if the buttons are equivalent to the width of screen then do this or that or any other way like any property in table Layout which simply wrap content of a row?
Yes there is a way to get the exact width of any component in your app. Look at my answer to my question asked a while ago here. As you can see, I instantiate a Paint object, but that's not necessary unless you wish to get the width of the text itself. However you must use the density multiplier:
float scale = getContext().getResources().getDisplayMetrics().density;
That will convert any function that gets the width of a component (in this case, your button) to the actual pixel width on any given devices. So you would get the button width (via invoking the getWidth() function on your Button object) and then multiply by that scaling factor.
Use FlowLayout instead:
http://nishantvnair.wordpress.com/2010/09/28/flowlayout-in-android/
GIT project:
https://gist.github.com/1073863
Using Contex's method getResources() you can access all the resources for your application's package. The method returns Resources and you can see here all properties that are available.

Programmatically getting the width of a TextView

I'm attempting to build a layout programmatically.
This layout is dynamic. Based on the data read from a database, it could look different every time.
I have a LinearLayout with its orientation set to vertical.
I want to fit as many TextViews with text (the data from database) as I can on a "row".
What I'm doing is building LinearLayouts that are the rows. These LinearLayouts are populated with TextViews. I build the TextView, set the text, and then check the width to see if it will fit on this row (by subtracting the sum of all TextView widths from the screen width and see if the new TextView will fit). If not, I create a new LinearLayout and start adding TextViews to that one.
The problem is myTextView.getWidth() and myTextView.getMeasuredWidth() both return 0.
Why? How can I get the width of the TextView?
Well first of all, please post your code. Second the getWidth/getHeight returning zero question gets asked A LOT so you could search SO for more answers.
Assuming your calling these methods during onCreate (which is probably the case), the UI hasn't been drawn yet so the returned value is zero. You can't get the width or height of the view until it has been drawn.
You can use this library to schedule the task of perform calculation on the width to the correct time after the view had been completely drawn
You can call it on onCreate() and from any Thread
https://github.com/Mohamed-Fadel/MainThreadScheduler
Sample of use:
MainThreadScheduler.scheduleWhenIdle(new Runnable() {
#Override
public void run() {
int width = textview.getWidth();
int height = textview.getHeight();
textview.setText( String.valueOf( width +","+ height ));
}
});

Categories

Resources