TextView with ImageSpans inside RecyclerView = wrong layout - android

I'm inserting ImageSpans inside TextViews, which are part of a RecyclerView. Most of the time it works fine, but as you scroll up and down sometimes the TextView height is wrong for no obvious reason - there's too much vertical whitespace.
In this layout on a specific device, the correct height for a TextView with 1 line of text is 48, and the wrong height is 80 (I got these values from HierarchyViewer). The interesting thing is that the correct height for a TextView with 1 line of text including an ImageSpan is 80. So what seems to be happening is as the TextView gets recycled by RecyclerView, it sometimes keeps the height representing its old content (which included an ImageSpan).
This screenshot shows the "Anore" and "Halal blahs" TextViews as being 80 pixels high, which is wrong. The "Hello" TextView is correct at 48 pixels.
While investigating this I opened DDMS and ran "Dump UI hierarchy" and something interesting happened: the TextView heights corrected themselves on the fly:
That's pretty compelling evidence that the problem is TextView isn't being laid out properly after updating the text, so I tried various ways of calling forceLayout() and invalidate() on the TextView and its parent views, but it didn't help.
I tried replacing RecyclerView with ListView, no luck. I tried having all ImageSpans use the same drawable, no luck.
I ran HierarchyViewer but it didn't "fix" the layouts like UI Automator did. Not even when I pressed the "invalidate layout" and "request layout" buttons.
I'm not doing anything fancy to set the ImageSpans:
SpannableStringBuilder stringBuilder = new SpannableStringBuilder( rawText );
for( int i = inlineImages.size() - 1; i >= 0; i-- ) {
InlineImage img = inlineImages.get( i );
stringBuilder.insert( img.idx, "x" );
ImageSpan span = new ImageSpan( context, img.drawable );
stringBuilder.setSpan( span, img.idx, img.idx + 1, 0 );
}
holder.mText.setText( stringBuilder );
// none of this helps
holder.mText.forceLayout();
holder.mText.requestLayout();
holder.mText.invalidate();
Here's the relevant part of the layout for each list item:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/speech_bubble"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#drawable/speech_bubble_right"
android:layout_marginLeft="40dp"
>
<TextView
android:id="#+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_toRightOf="#id/timestamp"
/>
</LinearLayout>
</RelativeLayout>
I tried invalidating and forcing a layout on the TextView parent (LinearLayout) but it did nothing.
I tried editing the layout down to literally just this:
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
.. and the problem still happens. It's definitely the fault of TextView itself.

I'm guessing that the issue here isn't with the measurement of the TextView, but rather, the measurement of the TextView's container (some ViewGroup - perhaps a LinearLayout?).
If this ViewGroup's layout params is set to WRAP_CONTENT for the height, then for some reason, the height isn't being calculated again on time. To solve this, try the following:
int widthMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY);
int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
holder.mContainer.measure(widthMeasureSpec, heightMeasureSpec); // perhaps a simple call to requestLayout or forceLayout will be enough?
If you know the exact height the cell should be, you can use that as well - simple replace the line where I calculate the heightMeasureSpec with the following:
int heightMeasureSpec = MeasureSpec.makeMeasureSpec(calculatedHeight + topPadding + bottomPadding, MeasureSpec.EXACTLY);
Hope this helps.

Got a little bit tricky
setTextSize(someDifferentSize);
setTextSize(normalSize);
Seems like it is some kind of line height problem, happened when image span is taller than it. I will dig into that if I have time.

Related

wrap_content on recycleview, take height of item (horizontal list)

I have a RecycleView, set to horizontal. Now i would like the height to match the height of an item in the view. I don't know the height in advance.
Currently i have this:
Main fragment:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="horizontal"
android:layout_marginLeft="1dp"
android:layout_marginRight="1dp"
android:layout_marginTop="1dp"
android:layout_gravity="top"
android:id="#+id/my_listview"/>
</RelativeLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
The image
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/banner_image"
android:adjustViewBounds="true"
android:scaleType="fitXY"
android:background="#color/dark_gray"
/>
but it always takes up the entire screen. so i have a lot of whitespace in between. Is there a way that i could use wrap_content on the recycleview items?
This is what it currently looks like:
I have placed 2 banners currently, the top one with the big whitespace and small image is the one with the recyclerview. The one below is just the image placed in an imageview (is what it should look like, but i want it with a recyclerview so i can scroll through the banners if i have multiple)
Now i would like the height to match the height of an item in the
view. I don't know the height in advance.
During layout pass, LinearLayoutManager cannot predict the height of all the views down in the adapter that are yet to be created, ahead of time.
You can measure() an item view, probably the first one, from the adapter and then set the height of RecycleView through code.
If all items can have different height then you'll have to measure them all, which is certainly not the correct way for a good UI.
You are probably inflating the layout incorrectly.
Did you use?
layoutInflater.inflate(R.layout.your_layout, null);
Try using instead. (The other way messes with measuring)
layoutInflater.inflate(R.layout.your_layout, parent, false);
Is there a reason why you have the RecycleView wrapped inside a RelativeLayout ?
I would try to move the RecycleView out of the RelativeLayout first.
Secondly i see that your ViewPager has a layout_weight but i do not see a android:weightSum attribute in the parent layout. Is there a reason you are specifying the ViewPager to have a weight but not the RecycleView ? Have you tried fixing the size of the RecyleView to some dp to check if the arrangement is correct and the ViewPager is using the weight attribute correctly ?
Thirdly i would try to play around with the Imageview. Try maybe wrapping it inside a RelativeLayout maybe ? You will have to play around with the parameters there and see if it works out for you. Because you want something custom there is not a straight answer to this question.
I also faced the same problem and I wanted to view two images in two columns with the same size in RecyclerView and I could solve the problem by using below code. Please try this.
// inner class to hold a reference to each item of RecyclerView
public static class ViewHolder extends RecyclerView.ViewHolder {
public ImageView imgViewIcon;
public ViewHolder(View itemLayoutView) {
super(itemLayoutView);
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
imgViewIcon = (ImageView) itemLayoutView.findViewById(R.id.item_icon);
int colSpan = 2;
imgViewIcon.getLayoutParams().height = (int) (displayMetrics.widthPixels / colSpan);
imgViewIcon.getLayoutParams().width = (int) (displayMetrics.widthPixels / colSpan);
}
}

How do I make a FrameLayout fill the height of its parent so the whole page scrolls together?

I have a FrameLayout that loads Fragments by tapping on tabs in a TabWidget. I can't figure out how to make the height of the FrameLayout as tall as its content, so that the whole containing ScrollView will scroll together as one instead of a separate scrolling view.
Here's a visual example of this Fragment's structure:
As you can see, the Frame Layout Visible Height only reveals one row of the Fragment, when in fact, there are a few. I can scroll within the FrameLayout to see the other rows as it is now, but that's not what I'm going for. The FrameLayout is made up of a LinearLayout containing a GridView with their layout_heights set to wrap_content.
I tried hardcoding the height of the FrameLayout to something like 500dp and it works great except for the fact that it's no longer dynamically sized. Would I need to resize the FrameLayout programmatically each time a new image is loaded into the inner content? Is there a layout attribute I can set so it'll stretch its height to match its inner content?
Here's my layout xml file:
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="200dp">
<!-- CONTAINS USER INFO AND STATS -->
</RelativeLayout>
<android.support.v4.app.FragmentTabHost
android:id="#android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#ffffff">
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="60dp"
android:weightSum="2">
</TabWidget>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
</FrameLayout>
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
</LinearLayout>
</ScrollView>
Thank you!
Since I'm going to set a bounty on this, I thought I'd share what I've figured out so far.
In the thumbnails, onSuccess when each image is loaded, I'm calling a function in the GridLayout that holds the images that counts the images and sets the height of the GridLayout. This works fine, although it seems like it'd be a bit inefficient.
What I'm doing is setting the GridLayout height and then calling requestLayout and invalidate on it and it's parent(s). This works, but not as the images loading. It'll work if I go to a different tab and return to the thumbnails, oddly enough. Which makes me think I'm not updating at the right time or on the right object.
Anyway, that said. Does anyone know how to make the height of a GridLayout expand to hold its contents (instead of scrolling) so I can scroll the entire page (including the top section)?
I should also add the GridView layout:
<GridView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/grid"
android:stretchMode="columnWidth"
android:gravity="center"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:drawSelectorOnTop="false"
android:fastScrollAlwaysVisible="false"
android:fastScrollEnabled="false"
android:numColumns="3"
android:choiceMode="none">
</GridView>
I was in a similar situation but I had a ListView instead of a GridView. You are right in the part when you have to set the height dynamically each time you add an item or if you call notifyDataSetChanged().
THIS CODE IS FOR LISTVIEW WITH DIFFERENT HEIGHT FOR EACH ROW
private void setListViewHeightBasedOnChildren(MyQueueAdapter listAdapter) {
int desiredWidth = MeasureSpec.makeMeasureSpec(
mListView.getWidth(), MeasureSpec.AT_MOST);
int totalHeight = 0;
View view = null;
int i;
for (i = 0; i < listAdapter.getCount(); i++) {
view = listAdapter.getView(i, view, mListView);
view.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
totalHeight += view.getMeasuredHeight();
}
ViewGroup.LayoutParams params = mListView.getLayoutParams();
params.height = heightList
+ (mListView.getDividerHeight() * (listAdapter
.getCount() + 3));
heightListComplete = params.height;
mListView.setLayoutParams(params);
}
You need to modify this code according to your needs, you don't need the loop as the height of each row is static in your case. If you need more help let me know.
ALTERNATIVE
If you know the height of the view in dp you can easily convert the dp in px and set the height of your gridview according to number of rows.
When using dynamic sizes you'll run into problems once you put match_parent inside a wrap_content thing. One tries to get a small as it's content and the content tries to be as big as it's parent. Neither side will know how to scale properly in the end.
ScrollView is such a thing that falls in this category. It's a scalable window to it's content so it can't be wrap_content and the content can't be match_parent because it's parent is a virtual infinite space.
Change <ScrollView android:layout_height="wrap_content" to match_parent (or a fixed size).
To solve the size of the content
set the root layout (LinearLayout in your case) of your ScrollView to be a fixed size so it's content can be match_parent again.
use wrap_content all the way.
combine the two: wrap_content until a child defines an absolute size, then match_parent inside there.
The wrap_content route will only work if all the elements in the layout from inner to outer most expand properly based on their content. Nothing can rely on parent bounds unless you add some.
Your content looks rather dynamic in size. So it is likely that you need to use some code to manually set sizes based on content. E.g. if those images inside your tab frame are a GridView (essentially ScrollView with grid content again) you'll need to set it's size manually. More than 1 degree of freedom in wrapping dynamically sizing containers isn't solvable automatically.
Parent of your frame layout is linear layout whose height is wrap_content. also, your framelayout's height is wrap_content. change both of them to fill_parent. using match_parent is more preferred now a days insted of fill_parent

Inflate a custom view from XML, then set her height and witdh programmatically

I'm loosing myself in an custom size View problem since a couple of days. After some long research, I finally decide to ask your help... please ! T_T
In my app, I created a custom View with the XML calendrieradmin_day.xml :
<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/CalendrierAdmin_Day_Event_TableRow"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<!-- <TextView
android:id="#+id/CalendrierAdmin_Day_Event_TextView_Name"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:gravity="center" />-->
</TableRow>
For now, it is a simple TableRow, but I'll need to add some other things in the future. (The commented TextView, for example).
I made three classes for using it : Row, EventRow and EmptyRow. Row is abstract and EventRow and EmptyRow inherit of Row. Also, Row inherit of TableRow.
I want to add several EventRow and EmptyRow in a TableLayout and I need to resize them dynamically.
In the constructor method of EmptyRow and EventRow, I call an init() method. Here the one of EventRow :
private void init(Context c, TableLayout root) {
root = (TableLayout)LayoutInflater.from(c).inflate(R.layout.calendrieradmin_day_event, root, true);
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) root.getLayoutParams();
lp.height = getHeightOfMinute() * getDuree();
lp.width = getTheWidth();
/*
Some other stuff
...
...
*/
this.setLayoutParams(lp);
root.addView(this);
setOnClickListener(this);
setOnLongClickListener(this);
}
Of course, it doesn't work as excepted. The EventRow is not showed.
root is my TableLayout I pass in the constructor. getHeightOfMinute() and getDuree() work correctly and give me the right sizes. I used to use the inflate() method like inflate(R.layout.calendrieradmin_day_event, null, false) and it worked fine, but Eclipse gave me a warning, telling me I shouldn't pass null as the RootView argument. Although everything worked fine, I begun to search another solution and this is where I gone so far...
I used the setMinimumHeight() and setMinimumWidth() method to rezise my EventRow and EmptyRow. It works, but I think there is a better way to do that. I tried A LOT of solutions but I messed up ! I think there is something I still not catched about the functioning of inflate() and/or LayoutParams.
Could you help me ? Thanks in advance !
Please tell me if you need more piece of Source code.
PS: Sorry for the bad english, I'm french.
I finally managed it, but a lot of things have been changed.
First, I drop the TableLayout and TableRow. Now it is simply some LinearLayout.
calendrieradmin_day.xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/CalendrierAdmin_Day_Event_LinearLayout_Container"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:orientation="horizontal" >
<TextView
android:id="#+id/CalendrierAdmin_Day_Event_TextView_Name"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="left"
android:background="#drawable/background_event_full"
android:gravity="left" />
</LinearLayout>
And this is the init() method :
private void init(Context c, LinearLayout root) {
LinearLayout container = (LinearLayout) LayoutInflater.from(c).inflate(R.layout.calendrieradmin_day_event, root, false);
TextView name = (TextView) container.findViewById(R.id.CalendrierAdmin_Day_Event_TextView_Name);
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, 0, duree);
container.setLayoutParams(lp);
name.setLayoutParams(lptv);
name.setText(e.getNom());
root.addView(container);
name.setOnClickListener(this);
name.setOnLongClickListener(this);
}
Pay attention to the LayoutParams lp (It's a LinearLayout.LayoutParams). duree is the duration of my event, in minutes.
My EventRow are intended to be in an another LinearLayout, llEvents. It contains all the events for one day, so 1440 minutes (60 x 24). As a result, the weightSum of llEvents is 1440.
I dropped the EmptyRow and the Row class to. I just add some empty LinearLayout to llEvents for the free time schedules, with there duration as weight.
It's REALLY important to presize a "0" height in the LayoutParams
Hope It will help someone ;-) !

Android get Fragment width

I have a layout with 3 fragments:
<LinearLayout android:id="#+id/acciones"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:id="#+id/fragment1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
</LinearLayout>
<LinearLayout
android:id="#+id/fragment2"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:id="#+id/f3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
</LinearLayout>
</LinearLayout>
In the first fragment I have a TableLayout in which I have one custom TextView in each row.
I want to know the width of the fragment because if the custom TextView is wider than the fragment, I'll set the number of lines necessary.
This is what I've done in my custom TextView:
#Override
protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mMaxWidth = (float) (getMeasuredWidth());
}
With this line I got the width from the three Fragments, not only the one which contains the custom TextView.
Thanks.
You should be able to set the width of the TextView to be fill_parent, in which case it will do the wrapping for you. You should not set the widths of your layouts to be match_parent since it is inefficient when you're using layout weights.
Since android's layout system is occasionally mysterious with regards to view sizes, if setting the TextView width to be fill_parent actually makes it take up the whole screen (as your question appears to be implying) do the following:
Set your TextView width to 0 by default. In onCreate of your activity, after setting the content view:
findViewById(R.id.acciones).getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
final int fragmentWidth = findViewById(R.id.releventFragmentId).getWidth();
if (fragmentWidth != 0){
findViewById(R.id.yourTextViewId).getLayoutParams().width = fragmentWidth;
}
}
});
By setting the TextView's width to 0 initially, you prevent it from changing the widths of the fragments. Then you can use a view tree observer to get the width of whatever fragment you're interested in (by looking at its root view) after layout has occurred. Finally you can set your TextView to be that exact width, which in turn will do the wrapping for you automatically.
Note that onGlobalLayout can be called multiple times and is regularly called before all of the views have been completely laid out, hence the != 0 check. You will also probably want to do some kind of check to make sure that you only set the width of the text view once, or otherwise you can get into an infinite layout loop (not the end of the world, but not good for performance).

Android horizontal LinearLayout with wrapped text in TextView

I've observed a behavior with layout_weight that I can't explain. The following is a trivial example:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="This is a very very very very very very very very very very very very very very very long string."
android:layout_weight="1"
/>
<View
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_gravity="center_vertical"
android:background="#ffffffff"
/>
</LinearLayout>
In a QVGA display, the TextView wraps the text. The white square is displayed to the right of the text.
However, if I remove android:layout_weight="1" from the TextView, the TextView now takes up the entire display width. The white square is no longer displayed.
Why would layout_weight in the TextView affect whether or not the white square is displayed? Shouldn't the View with the white background always be assigned 32dpx32dp first? (It makes no difference if the view were any other types - ImageView or TextView).
The problem I was working on is that I want the white square to always be displayed to the right of the TextView (whether or not the text is wrapped), but I don't want any empty space between the TextView and the white square. (If I add android:layout_weight="1" to the TextView, then there is a gap if the text is not wrapped.)
Any help would be appreciated!
To answer my question #1: One thing I learned by looking at the source for LinearLayout: Not only does layout_weight assign unused space to a child, it also shrinks a child with layout_weight if the child extends beyond the bounds of the LinearLayout. That explains why a TextView with wrapped text is shrunk in my layout.
As for the answer to my question #2, I think you meant android:toRigthOf instead of android:layout_alignRight. Using a RelativeLayout instead of a LinearLayout doesn't change the layout behavior. The tricky part is placing a view immediately to the right of a TextView, without gaps, whether or not the text is wrapped. Setting a maxWidth would limit the TextView's width, but that solution doesn't scale across portrait/landscape and different display dimensions.
Solution - Looks like Dyarish's solution is the best available. My layout problem exists regardless of the layout you use. The key is to set a maxWidth for the TextView so that it doesn't take up the all of the horizontal space in the layout. Because hardcoding a android:maxWidth value in the TextView doesn't scale across different displays, setting the maxWidth at runtime, as Dyarish suggested, is a good solution.
Hopefully this is what you are looking for.
First off, here is a great resource I found for Creating UI's.
layout_weight - Specifies how much of the extra space in the layout to be allocated to the View.
If you want to ensure that the white square is always to the right of the textview, you can use a Relative View, and add the parameter to the view. android:layout_alignRight="+id#yourTextViewID". This should always make the box appear right beside the textView area. You should probably also add something like android:maxWidth="250px" This will ensure that you don't push the white box completely out of the screen.
Here is a code sample:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TextView
android:layout_width="wrap_content"
android:maxWidth="250px"
android:id="#+id/TextForWhiteBox"
android:layout_height="wrap_content"
android:layout_gravity="center|left"
android:text="This is a very very very very very very very very very very very very very very very long string."
/>
<View android:background="#ffffffff" android:layout_width="32dp" android:layout_height="32dp" android:id="#+id/view1" android:layout_toRightOf="#+id/TextForWhiteBox"></View>
</RelativeLayout>
You could also add to the View:
android:layout_alignTop="#+id/TextForWhiteBox" android:layout_alignBottom="#+id/TextForWhiteBox"
to make the white box the same size as the TextView.
Firstly I've tested the code from my other answer and it does exactly what you've described you've wanted. (unless I'm misunderstanding what you are asking for). You definitely do not want to use the android:layout_alignRight which is not what is in the code sample. That would simply keep the box on the right hand of the screen and not be affected by the textview at all. This sample uses android:layout_toRightOf="#+id/TextForWhiteBox" which is possible due to it being a relative layout. Since the Relative Layout allows you to place objects in relation to others. That line will always place the box just to the right of the textview with no gaps.
As for the screen orientation changes:
When the orientation changes it creates a new instance of the view.
Here is a simple solution.
//Add to oncreate in your Activity
private TextView textStatus;
textStatus = (TextView) findViewById(R.id.TextForWhiteBox);
// This get's the width of your display.
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int width = displaymetrics.widthPixels;
// Now you know the screen orientation, and it's width. So just set the maxwidth of the text view to match the display width - the pixels of your white box.
textStatus.setMaxWidth(width - 32); // 32 is here because you already know the size of the white box. More logic is needed to dynamically get this value, because you would need to wait for the activity to be fully created.
}
Here is the main.xml I used:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TextView
android:layout_width="wrap_content"
android:id="#+id/TextForWhiteBox"
android:layout_height="wrap_content"
android:layout_gravity="center|left"
android:text="This is a very very very very very very very very very very very very very very very very very very very long string."
/>
<View android:background="#ffffffff" android:layout_width="32px" android:layout_height="32px" android:id="#+id/view1" android:layout_toRightOf="#+id/TextForWhiteBox"></View>
</RelativeLayout>
You might need some additional logic to keep screen values.
This code has been tested, you should be able to literally copy and paste this to work as you asked.
Also depending on your logic you could use something like this to return the screen orientation.
int orient = getResources().getConfiguration().orientation;
Hope this helps!
If this helped you, please click the accepted button. =) Cheers!

Categories

Resources