Two buttons of same width with several words in one line - android

I want to draw two Buttons in one line with equal width. Say, they have captions: "Sample text" and "Extra text". They should occupy as low space as possible, but all words should be written.
Now it looks so:
I wrote this code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:maxLines="1"
android:text="Sample text"
android:textAllCaps="false" />
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:maxLines="1"
android:text="Extra text"
android:textAllCaps="false" />
</LinearLayout>
If I remove android:maxLines="1" and set wrap_content to width, Buttons write a text, but fill different widths.

If you want to locate two buttons on one line, you need to set match_parent to layout_width of LinearLayout
<?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">
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:maxLines="1"
android:text="Sample text"
android:textAllCaps="false" />
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:maxLines="1"
android:text="Extra text"
android:textAllCaps="false" />
</LinearLayout>

Add layout weight to both buttons. So, it will assure you have the same dimensions for both.
android:layout_weight="1"
Also get screen size and set the size programmatically.
Get Screen width and height
Fixing particular button size will effect small size screens.

Let you want to resize second button.
If a button contains an icon, center it with How to center icon and text in a android button with width set to "fill parent". For instance, move a Button inside a FrameLayout or create a LinearLayout with ImageView and TextView.
If your case is custom view and a button is a FrameLayout with icon, override the following event:
boolean isButtonResized;
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if (!isButtonResized) {
int buttonWidth = firstButton.getWidth();
if (buttonWidth != 0) {
isButtonResized = true;
ViewGroup.LayoutParams lp = secondButton.getLayoutParams();
lp.width = buttonWidth;
secondButton.setLayoutParams(lp);
}
}
}
If you have a button without an icon, only text, a resizing will be simplier:
secondButton.setWidth(firstButton.getWidth());

Related

Reason behind extra 8dp margin in a view ? not ways to solve

In my activity xml file i am get an extra 8dp margin in Left side in view(Represented as Underline).
Reason for getting 8dp margin extra in "view"? (underline under TextView.)
i have given 48dp left margin in that view.
above that view i have
<TextView> which has a drawable icon in left.
with left margin 24dp and drawable padding 24dp.
Reason for doing.
I am try to create an underline under my words using a view with black background.
i have given 48dp as left margin in xml.but as shown in photo i am getting 56dp.
difference between lines is 8dp.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#FAFAFA"
android:orientation="vertical"
tools:context="com.hysterics.delhishop.AccountSetting">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="32dp"
android:layout_marginTop="16dp"
android:gravity="center|left"
android:paddingLeft="16dp"
android:textAllCaps="true"
android:textStyle="bold"
android:text="#string/hello_user"
android:textColor="#color/primary_text"
android:textSize="15sp"/>
<TextView
android:id="#+id/user_account_information"
android:layout_width="match_parent"
android:layout_height="54dp"
android:layout_marginLeft="24dp"
android:drawableLeft="#drawable/ic_account_box_black_18dp"
android:drawablePadding="24dp"
android:gravity="center|left"
android:textAllCaps="true"
android:textStyle="bold"
android:text="#string/account_information"
android:textColor="#color/primary_text"
android:textSize="15sp"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_gravity="center"
android:layout_marginLeft="48dp"
android:background="#android:color/darker_gray"/>
<TextView
android:layout_width="match_parent"
android:layout_height="54dp"
android:layout_marginLeft="24dp"
android:drawableLeft="#drawable/ic_home_black_18dp"
android:drawablePadding="24dp"
android:gravity="center|left"
android:textAllCaps="true"
android:textStyle="bold"
android:text="#string/account_address"
android:textColor="#color/primary_text"
android:textSize="15sp"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_gravity="center"
android:layout_marginLeft="48dp"
android:background="#android:color/darker_gray"/>
................
................
</LinearLayout>
</ScrollView>
here is my activity file.
public class AccountSetting extends AppCompatActivity {
public static final String TAG_USER_NAME_DIALOG = "edit_text_dialog";
#InjectView(R.id.account_setting_toolbar) Toolbar accountSettingToolbar;
#InjectView(R.id.user_account_information) TextView userAccountInformation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_account_setting);
ButterKnife.inject(this);
setToolbar();
}
thank you in adavnce :-)
Because you set the underline view's layout_width="match_parent" and layout_gravity="center".
After views measure:
- the linear parent view's width is 1080px;
- the underline view's width is 936px ( because of layout_marginLeft="48dp"(144px))
When views layout:
- Because the linear parent's orientation is "vertical", so when set layout_gravity="center" equal with layout_gravity="center_horizontal".
- For a "center_horizontal" child, the linear parent will margin the child view's X-center with it's X-center
So the X-axis of underline view will be (in px):
540 (X-center of parent) + 144 (48dp margin left) - 468 (half of child's width) = 216px (72dp)
That why with layout_gravity="center", you will see the underline view will get 24dp extra margin.
You are adding drawable padding to the icon and the marginLeft is completely different between the underline and the icon. And also you have to take into account the size of the icon itself. I would be surprised that it would have the exact same align.
Instead of this, why don't you use an horizontal LinearLayout with weight between two linear layouts, one with the icon and another transparent view with the same height as the underline, and the other linear layout that contains text and underline perfectly aligned. No margins no nothing, just distribution of weight. Something like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="100dp"
android:orientation="horizontal"
android:weightSum="10">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<View
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="8"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Account Information"
android:textSize="20sp" />
<View
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
This is just one possible solution that can guarantee you exact alignments.
It because your views width is match_parent & android:layout_marginLeft & android:layout_gravity="center"
is causing view to shift outside of screen bound.
See this for more information..
Try with removing center layout_gravity from your Views(which draws line)
android:layout_gravity="center"
and use
android:layout_marginLeft="#dimen/space_large"
instead of
android:layout_marginLeft="#dimen/space_xxlarge"
According these two lines:
android:drawableLeft="#drawable/ic_account_box_black_18dp"
android:drawablePadding="#dimen/space_large"
You'll have a drawable of width 18dp, then a padding of #dimen/space_large, which looks to be 24dp for a total of 42dp of padding between the left edge of the TextView and the start of the text itself.
However, the layout_marginLeft on your lines is #dimen/space_xxlarge or 48dp. As one is 42dp and the other is 48dp, they won't align. You'll need to change one or the other if you want the elements to appear visually in line.
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_gravity="center"
android:layout_marginLeft="48dp"
android:background="#android:color/darker_gray"/>
There are multiple view in your layout and you are using layout_gravity="center". So View is trying to adjust itself to center inside LinearLayout. Just try removing layout_gravity or use layout_gravity="left".
You have added marginLeft of 24dp also drawablePadding of 24dp and you say a total of 48dp But you forget the width of drawable icon. So, the first latter of ACCOUNT "A" is not at 48dp margin.
You are using LinearLayout and everyting is at the left side so there is no need of any gravity.
Also you say removing gravity from View makes it 36dp from left. YES, thats correct. You missed Drawable Icon width from your calculation.
Set layout_margin of View equals 48dp + width of icon. Thats the reason you got I think.
Just remove
android:layout_gravity="center"
from your view it will fix your problem.

Maintain textview height in LinearLayout

I have two TextViews in LinearLayout. Layout orientation is in horizontal. I have to maintain both Textview height as equal. But as per text length both are shown in different height.
I had tried to make the same text length like below
public static String padRight(String s, int n) {
return String.format("%1$-" + n + "s", s);
}
But height is bit different. How do i solve this ?
If I didn't misunderstand you you want to TextViews inside a horizontal oriented LinearLayout, and both TextViews must in same height.
Then use a layout something like below:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/textView1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#B40431"
android:text="text sample\ntext sample\ntext sample\ntext sample\ntext sample\ntext sample\n"
android:gravity="center_vertical"/>
<TextView
android:id="#+id/textView2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#0000FF"
android:text="text sample\ntext sample\ntext sample"
android:gravity="center_vertical"/>
</LinearLayout>
Output is going to be this:
Because the text is long textview getting bigger So You set the singleLine true of your textView then it will work,
Add this line in your Textview xml:--
android:singleLine="true"
hope it helps you..

scrollable linearlayout with weights bigger than screen in android

I am trying to create a vertical linearlayout with weights that has a size bigger than the screen. Let's say 2x the size of the screen. In order for this to work I would obviously need to be able to scroll through it. Unfortunately I can't figure out a way to do this. I tried using the layout weights, and setting the weight sum as half of the actual sum of the weights of all components (so if all components weights sum is 20 I set the weight sum as 10) and managed to make it work but unfortunately the scrolling is not working anymore for some reason.
Is there anything that I am missing?
this is the code that makes the linearlayout twice as big as the screen but the scroll is not working:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:fillViewport="true">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="2">
<EditText android:id="#+id/id1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:textSize="25dp"
android:gravity="center"
android:layout_weight="2"/>
<EditText android:id="#+id/id2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:textSize="25dp"
android:gravity="center"
android:layout_weight="2"/>
</LinearLayout>
</ScrollView>
Based on your comment, here is a programmatic way of achieving what you're looking for. I do not believe there is a way to accomplish this in pure layout XML.
Layout:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:background="#000000"
android:fillViewport="true" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFFFF"
android:orientation="vertical" >
<EditText
android:id="#+id/id1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#DCDCDC"
android:gravity="center"
android:text="ONE ONE ONE"
android:textIsSelectable="false"
android:textSize="45sp" />
<EditText
android:id="#+id/id2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#AAAAAA"
android:gravity="center"
android:text="TWO TWO TWO"
android:textIsSelectable="false"
android:textSize="45sp" />
<EditText
android:id="#+id/id3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#777777"
android:gravity="center"
android:text="THREE THREE THREE"
android:textIsSelectable="false"
android:textSize="45sp" />
</LinearLayout>
</ScrollView>
Activity:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Get display size -- API L13 and up. Otherwise use getResources().getDisplayMetrics();
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
// You want size to be 50% per EditText, so divide available height by 2.
// Note: this is absolute height, does not take into consideration window decoration!
int editTextHeight = size.y / 2;
// Get a handle to your EditTexts
EditText t1 = (EditText) findViewById(R.id.id1);
EditText t2 = (EditText) findViewById(R.id.id2);
EditText t3 = (EditText) findViewById(R.id.id3);
// Set height to 50% of screen size each
t1.setHeight(editTextHeight);
t2.setHeight(editTextHeight);
t3.setHeight(editTextHeight);
}
That'll do it. End result:
You declared height of your LinearLayout "match_parent" that is equal to its parents height. It will never scroll as long as the content is bigger then ScrollView. First of all you have to give a fixed height like (50dp) or wrap_content or you have to set Its height programmatically(like 2x screen height as you mention).
weightSum and weight will always force your items to fit in your LinearLayouts current size so try not to use it.
I hope this helps.
The problem here is your use of layout_weight and weightSum is invalid. It's important to remember that android:layout_weight can only use the remaining space available in the view; anything exceeding that boundary is automatically cropped.
Therefore, in your example, your first EditText is taking up the entirety of the screen, and your second one is entirely excluded from the view. Because the second EditText is cropped, the LinearLayout has taken the entire screen and there's nothing for the ScrollView to do.
I'm not entirely sure what your end goal is; are you trying to have text inputs that grow with user entry, and the ScrollView handles the overflow?
If so, this will work:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:background="#000000"
android:fillViewport="true" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFFFF"
android:orientation="vertical" >
<EditText
android:id="#+id/id1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#DCDCDC"
android:gravity="center"
android:text="ONE ONE ONE"
android:textIsSelectable="false"
android:textSize="45sp" />
<EditText
android:id="#+id/id2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#AAAAAA"
android:gravity="center"
android:text="TWO TWO TWO"
android:textIsSelectable="false"
android:textSize="45sp" />
</LinearLayout>
</ScrollView>
I've included some basic background colors so that you can see where each item begins & ends in layout preview. Typing in the first EditText will correctly push the second one down, producing a scroll bar.
Also note that you should use sp instead of dp for textSize values.
Edit: I should also note, for clarification, that weightSum will also take away space when necessary. To test this, set the weightSum of your LinearLayout to 2, and then add android:layout_weight="1" to each of the EditText controls. The end result will be a 50/50 split when the view loads, and then as you start typing in the first control, the 2nd space will shrink accordingly. Adding text to the second control will result in a scrollbar appearing.

Layout: how to make image to change its width and height proportionally?

I have such layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_toLeftOf="#+id/my_image"
android:ellipsize="end"
android:singleLine="true"
android:text="Some text"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView
android:id="#+id/my_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/title"
android:layout_alignBottom="#+id/title"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:adjustViewBounds="true"
android:src="#drawable/my_bitmap_image" />
This layout does almost what I need: it makes image view height the same as text view. The image graphic contents stretched also keeping aspect ratio.
But, the width of the image view does not change! As a result, I have a wide gap between text and the image view! As a temporal solution, I override View#onLayout.
The question: how to change image width in xml layout?
UPDATE:
This is a final layout I need (text + a few images).
Look at the first image: its width should be exactly the same as scaled image in it with no paddings and margins:
For the imageView you can add the images to a linearlayout and give the weight property. For example if you have 3 images then give the linearlayout weight as 3 and then for each image you give the weight as 1. This way it will be uniformly aligned with equal width for all the images. Make linear orientation as horizontal hope so u got my point.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="3"
>
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_weight ="1" />
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_weight ="1" />
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_weight ="1" />
</LinearLayout>
OK, as I see from the answers, there is no solution to force image views to change theirs width and height proportionally.
So, this can be solved only programmatically.
There is my solution below :
a) Create you custom layout class
(don't forget to override all the parent constructors with public access modifier, otherwise GUI editor will fail):
public class MyLayout extends RelativeLayout {...
b) Override method: Deprecated - changing layout params in this method might cause side effects. See recommended approach below
protected void onLayout(boolean changed, int l, int t, int r, int b) {
ImageView icon = (ImageView) findViewById(R.id.my_image);
icon.setMaxWidth(icon.getMeasuredHeight());
super.onLayout(changed, l, t, r, b);
}
b) Add creational method:
public static MyLayout createLayout(ViewGroup parent) {
Context context = parent.getContext();
MyLayout item = (MyLayout) LayoutInflater.from(context).inflate(
R.layout.my_layout, parent, false);
TextView tv = (TextView) findViewById(R.id.title);
ImageView icon = (ImageView) findViewById(R.id.my_image);
ViewGroup.LayoutParams p = icon.getLayoutParams();
p.width = (int) tv.getTextSize();;
icon.setLayoutParams(p);
return item;
}
c) Final layout:
<?xml version="1.0" encoding="utf-8"?>
<com.mypackage.MyLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_toLeftOf="#+id/my_image"
android:ellipsize="end"
android:singleLine="true"
android:text="Some text"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView
android:id="#+id/my_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/title"
android:layout_alignBottom="#+id/title"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:adjustViewBounds="true"
android:src="#drawable/my_bitmap_image" />
</com.mypackage.MyLayout>
Instead of RelativeLayout, use LinearLayout. You may add "Weight" property to ensure desired spacing.
see the code below
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/logonFormButtons"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:baselineAligned="true"
android:orientation="horizontal">
<TextView
android:id="#+id/logonFormBTLogon"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Some Text"
android:layout_weight="0.5" />
<ImageView
android:id="#+id/logonFormBTCancel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:src="#drawable/apk"
android:layout_weight="0.5" />
</LinearLayout>
I guess this has to do with android:layout_alignParentRight="true" for your ImageView. Have you tried layout_toRightOf="#id/title" ?
Also you can try android:scaleType="fitStart" on the ImageView. This should align the image to the top left of the ImageView.
As for me I appreciate to change width or height dinamically in my code using getLayoutParams()... for example
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int wwidth = displaymetrics.widthPixels;
convertPixelsToDp(wwidth, getApplicationContext());
// Toast.makeText(getApplicationContext(), height+ "= "+convertPixelsToDp(height, getApplicationContext()) +
// " " + wwidth+ "= "+convertPixelsToDp(wwidth, getApplicationContext()), Toast.LENGTH_LONG).show();
//scroll view 1 screen height size
scr1 = (ScrollView) findViewById(R.id.ScrollView01);
scr1.getLayoutParams().height=height - 200;
put image view in Linear Layout . the give weight to each and every image view.. it will increase the size proportionately ..
try to add scaleType = fitXY OR centerInside property to imageView

Two TextViews side by side, only one to ellipsize?

I want to have two TextView elements appear side by side (in a list item), one aligned to the left, one to the right. Something like:
|<TextView> <TextView>|
(the | represent the screen's extremities)
However, the TextView on the left can have content that is too long to fit on the screen. In this case, I want to have it ellipsize but still show the entire right TextView. Something like:
|This is a lot of conte...<TextView>|
I have had numerous attempts at this, using both LinearLayout and RelativeLayout, and the only solution I have come up with is to use a RelativeLayout and put a marginRight on the left TextView big enough to clear the right TextView. As you can imagine, though, this is not optimal.
Are there any other solutions?
Final, LinearLayout solution:
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:orientation="horizontal"
>
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:inputType="text"
/>
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_weight="0"
android:layout_gravity="right"
android:inputType="text"
/>
</LinearLayout>
Old, TableLayout solution:
<TableLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:stretchColumns="1"
android:shrinkColumns="0"
>
<TableRow>
<TextView android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
/>
<TextView android:id="#+id/date"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:singleLine="true"
android:ellipsize="none"
android:gravity="right"
/>
</TableRow>
</TableLayout>
Just an idea, why don't you declare first in the xml layout the textview on the right and set its width as wrap content, android:layout_alignParentRight="true" and android:gravity="right". Then declare the textview on the left, set its width as fill parent, android:layout__toLeftOf={the id of the textview on the right} having RelativeView as the root view.
By declaring first the right textview, its required width will be computed first and occupy the view while the textview on the left will occupy the remaining space of the view.
I still have not tried this though it might give you some idea.
[Update]
I tried creating an xml resource layout... and it somehow works...
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/right"
android:layout_alignParentRight="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
android:text="right"
>
</TextView>
<TextView
android:id="#+id/left"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#id/right"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="1"
android:singleLine="true"
android:maxLines="1"
android:text="too looooooooooong ofskgjo sdogj sdkogjdfgds dskjgdsko jgleft"
>
</TextView>
</RelativeLayout>
The LinearLayout answer worked for me with this same problem. Posted as a separate answer because it wasn't clear what did and didn't work for the asker.
One difference. TableLayout was less ideal for me because I had two rows of data, and I wanted the bottom row to behave as this question describes, and the top row to span the area. That question's been answered in another SO question: Colspan in TableLayout, but LinearLayout was simpler.
Though getting the widths right took me a bit. I included the android lint tweak of using 0dp width on the scaling item for performance.
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:orientation="horizontal"
>
<TextView
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
android:ellipsize="end"
android:inputType="text"
/>
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_weight="0"
android:layout_gravity="right"
android:inputType="text"
/>
</LinearLayout>
Use TableLayout and put both TextView in table row, have a try. I haven't tried
There are many answers to this and practically equivalent, duplicate questions on SO. The suggested approaches usually work, sort of. Putting it into a LinearLayout, wrap the whole in an extra RelativeLayout, use a TableLayout; all these seem to solve it for a simpler layout but if you need these two TextViews inside something more complicated, or the same layout will be reused, for instance, by a RecyclerView, things get broken very quickly.
The only solution I found that really works all the time, regardless of what bigger layout you put it into, is a custom layout. It's very simple to implement, and being as lean as it possibly gets, it will keep the layout reasonably flat, it's easy to maintain—so in the long run, I consider this the best solution to the problem.
public class TwoTextLayout extends ViewGroup {
public TwoTextLayout(Context context) {
super(context);
}
public TwoTextLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TwoTextLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int count = getChildCount();
if (count != 2)
throw new IllegalStateException("TwoTextLayout needs exactly two children");
int childLeft = this.getPaddingLeft();
int childTop = this.getPaddingTop();
int childRight = this.getMeasuredWidth() - this.getPaddingRight();
int childBottom = this.getMeasuredHeight() - this.getPaddingBottom();
int childWidth = childRight - childLeft;
int childHeight = childBottom - childTop;
View text1View = getChildAt(0);
text1View.measure(MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.AT_MOST));
int text1Width = text1View.getMeasuredWidth();
int text1Height = text1View.getMeasuredHeight();
View text2View = getChildAt(1);
text2View.measure(MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.AT_MOST));
int text2Width = text2View.getMeasuredWidth();
int text2Height = text2View.getMeasuredHeight();
if (text1Width + text2Width > childRight)
text1Width = childRight - text2Width;
text1View.layout(childLeft, childTop, childLeft + text1Width, childTop + text1Height);
text2View.layout(childLeft + text1Width, childTop, childLeft + text1Width + text2Width, childTop + text2Height);
}
}
The implementation couldn't be simpler, it just measures the two texts (or any other child views, actually) and if their combined width exceeds the layout width, reduces the width of the first view.
And if you need modifications, eg. to align the second text to the baseline of the first, you can solve that easily, too:
text2View.layout(childLeft + text1Width, childTop + text1Height - text2Height, childLeft + text1Width + text2Width, childTop + text1Height);
Or any other solution, like shrinking the second view in relation to the first, aligning to the right, etc.
Why don't you put a left margin on the right TextView? I'm using this approach for a
|<TextView> <ImageButton>|
and it works.
Solution with ConstraintLayout
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<TextView
android:id="#+id/leftText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
app:layout_constraintEnd_toStartOf="#id/rightText"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="This is a lot of content that should be cut" />
<TextView
android:id="#+id/rightText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Right text" />
</androidx.constraintlayout.widget.ConstraintLayout>
When I faced with the sililar issue, I did following:
I needed:
|<TextView, may be long> <TextViewFixedSize> |
|<TextView, may be longer ...> <TextViewFixedSize>|
|<TextViewLong> <TextViewFixedSize> |
You may use a solution like this:
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/layoutRecommendedServiceDescription"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="#+id/textViewRecommendedServiceTitle"
app:layout_constraintTop_toBottomOf="#id/textViewRecommendedServiceTitle">
<TextView
android:id="#+id/textViewRecommendedService1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:ellipsize="end"
android:lines="1"
android:maxLines="1"
app:layout_constrainedWidth="true"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintEnd_toStartOf="#+id/textViewRecommendedServicePopular"
app:layout_constraintStart_toStartOf="parent"
tools:text="Long text"
tools:visibility="visible" />
<TextView
android:id="#+id/textViewRecommendedServicePopular"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="8dp"
android:lines="1"
android:text="#string/services_popular"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/textViewRecommendedService1"
app:layout_goneMarginStart="0dp"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>

Categories

Resources