I have a ListView with an adapter attached. The data behind it is a couple of articles. The articles have a title and a subtitle, the length of both varies.
Sometimes the text of either one is so long that the TextView doesn't fit the View created by the adapter which has a fixed height.
Is there a possibility to find out if both TextViews are completely visible within the View?
I know I would have to wait for the layout to be drawn, would do it with getViewTreeObserver().addOnGlobalLayoutListener(...)
It seems like you can only completely fit two lines per title and subtitle. If I were you, I'd measure the length of the text with the paint that's used to draw it and see if it's less than (width of line) * (number of lines).
For example, consider the following:
boolean doesTitleFitBounds = titleTextView.getPaint().measureText(titleText) < (TITLE_LINE_WIDTH * TITLE_NUM_ROWS);
where TITLE_LINE_WIDTH is the available width for your text in pixels (accounting for paddings/margins etc) and TITLE_NUM_ROWS is the number of rows you have per title.
Similarly, you can do a check for the subtitle to see if it fits its own bounds.
Related
I have a textview where I want to show text in vertical (just like rotated 90º). With android:rotation="-90" you can get this.
If the text would have no rotation, and you would like to fit a sentence, you would first look at the width of the textview, since text will try to be in 1 line. Since I rotate the text, here I expect to see the height of the object. However, Android is still considering the width. I need to fix the size of the width, but this causes me a problem for the text: Although the textview has a big vertical dimension and text would fit, Android thinks it needs to use the width to calculate the available space. At the end this causes me overflow of the text, appearing for example, just one word as multiple lines of 1 char.
How can I make android to understand that the space for the lenght to fit the text is now the vertical, instead of the horizontal?
We have horizontal recycler view. Each item view of recycler view contains a textView.
Width of each item view is constant, 100dp. Height is dynamic & we have to set it as per the max data.
List of string is coming from server & hence any data can come. So, e.g. 1st cell can have text of 1 line whereas 2nd cell can have text of 4 lines.
Requirement:
We have to calculate maximum height of the cell (i.e cell consuming max height due to biggest text) and set that maximum height to all cells of recycler view.
This is required because we want height of all item views to be same & also making biggest text visible to user without getting cut (ellipse).
One of the ways that I know:
Before setting adapter, we can iterate the list containing Strings. We can create a dummy textview (invisible to user & width 100 dp). We can set each of the text in the textview & then get height of the textview. We will save the maximum height to adapter while calling setAdapter.
Is this good approach?
Please help.
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 am using ListView to implement a timeline. I enabled FastScroll and used SectionIndexer so that user could drag the scrollbar and see the section text displayed.
The problem is all these are built-in UI. The textview that displays the section text is too small for me, I am trying to display 05pm and it's too long for the textview(or other UI?).
Any easier way to resolve this? For instance, a method I can set the font size of the section text or the textview layout?
Thanks!
Looking through the source code for AbsListView, you can find the class that handles the fast scrolling mechanism which ends up being FastScroller. FastScroller actually draws the image drawable and text on the canvas that was provided to the AbsListView like so...
canvas.drawText(mSectionText, (int) (rectF.left + rectF.right) / 2 - hOff, (int) (rectF.bottom + rectF.top) / 2 + mOverlaySize / 4 - descent - vOff, paint);
The code above actually draws the text on top of the bottom image drawable so it does not respect the bounds of the bottom drawable, which is why the text is actually overflowing and not being cut off. As to why this is designed this way? My guess is that the intention of the index feature was to be mainly used for single characters such as A, B, C, etc... and therefore the fast scroll index feature was designed to fit that.
So, to give a definite answer to your question, there's really no way to change the text size or change how the text is being drawn unless you modify AbsListView and FastScroller to suit your need.
I have built a ListView and my items - at least in part - contain titles of various (text) lengths.
In order to enable the user to read as much of the title as possible, I'm trying to change my adapter to auto-pick a feasible font size for my texts.
So I'm working with the TextView's paint object to measure the text in a basline font size (14dp) and try to compare against the available space. If the text is too big, I reduce the font size to 12dp (later I might think about reducing it even further).
// Note: vh.filmTitleTextView is my TextView, filmText contains the title I want to display
filmTitleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
float textWidth = vh.filmTitleTextView.getPaint().measureText(filmText);
if (textWidth > vh.filmTitleTextView.getWidth())
vh.filmTitleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12);
The issue is that on first run, vh.filmTitleTextView.getWidth() always returns zero. I guess this is because the layout has not been rendered before and the size is not yet known.
I can't just go with the full size of the ListView because the textView doesn't have the same width (despite the fact that it is set to layout_width="fill_parent") - there are some elements around it.
Any ideas?
Had a similar problem that was my bane for a long time - this might help ya: Auto Scale TextView Text to Fit within Bounds