Repeated background affects TextViews height - android

I have a Image that I want to repeat on the x axis to match the width.
repeating_section_header.xml :
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/table_section_header_light"
android:tileMode="repeat" />
so far so good.
Now I set this as background of a TextView:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/row_headline_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/repeating_section_header"
android:gravity="left|center_vertical"
android:textColor="#color/white"
android:textSize="14sp"
android:textStyle="bold"/>
But now the the TextViews height is the height of #drawable/table_section_header_light, even if I have set TextViews height to wrap_content.
Any idea how to fix that (make the TextViews height to wrap content)

One way of doing this is by programmatically determining the height of the textview with just the text, and fixing the height, and the setting the background drawable. This way, it will adjust to the height of your textview depending on how many lines is used.
Java:
TextView v = (TextView) findViewById(R.id.row_headline_text);
v.setText("<your text here>");
v.measure(android.view.View.MeasureSpec.UNSPECIFIED, android.view.View.MeasureSpec.UNSPECIFIED);
android.view.ViewGroup.LayoutParams params = v.getLayoutParams();
params.height = v.getMeasuredHeight();
v.setLayoutParams(params);
v.setBackgroundResource(R.drawable.table_section_header_light);
xml:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/row_headline_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="left|center_vertical"
android:textColor="#color/white"
android:textSize="14sp"
android:textStyle="bold" />

If you okay with this technique, try it:
Wrap your TextView into a RelativeLayout.
Add a View as the first child in this RelativeLayout. (let the TextView be the second child)
Remove your background from the TextView to this new View
Set the layout params of your TextView (AlignLeft, AlignRight, AlignTop, AlignBottom) to #+id/row_headline_text
This should work. If your TextView's parent is already a RelativeLayout, you won't need the new RelativeLayout.

Related

How to `wrap_content` while autosizing an Android TextView?

Consider this layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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="match_parent">
<TextView
android:id="#+id/textView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:autoSizeTextType="uniform"
android:gravity="center"
android:maxLines="1"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_max="50dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>
Because of the height_max constraint this leads to a TextView where the text fills the vertical space but there's a lot of horizontal padding inside of the TextView:
What I want is for the width of that TextView to be set such that it matches the width of the autosized text content. But when I set android:layout_width="wrap_content" the width gets set based on the non-autosized text content:
Is there any way to get the best of both worlds---have the text autosize based on a known height, and then set the width based on the width of the autosized text?
Google's developer documentation specifically recommends against using wrap_content with autosized TextViews:
Note: If you set autosizing in an XML file, it is not recommended to use the value "wrap_content" for the layout_width or layout_height attributes of a TextView. It may produce unexpected results.
If you simply want your text to have a height of 50dp instead of 50sp, you could set the textSize to 50dp. But I suspect your goal is to have a textView that will autosize the text smaller based on layout constraints, and that solution won't do the job.
If you really can't have the extra horizontal space on your TextView from using a width of match_parent or 0dp, you could try programmatically setting the textview width layout parameter based on measuring the text with a TextPaint after the layout is created:
textView.post(new Runnable() {
#Override
public void run() {
TextPaint textPaint = new TextPaint();
textPaint.setTextSize(textView.getTextSize());
float width = textPaint.measureText(textView.getText().toString());
ViewGroup.LayoutParams layoutParams = textView.getLayoutParams();
layoutParams.width = (int)width;
textView.setLayoutParams(layoutParams);
}
});
Keep in mind that if you go this route, you'll probably want to add some left and right padding to it. TextViews have a sort of internal padding, even if you set their padding to zero - but that gets overridden when the width parameter is set directly.
Try using 0dp (which equals MATCH_CONSTRAINT) for the android:layout_width attribute of the TextView.
It sounds like you want the display ratio of the text to change, for the text to act akin to scaleXY for an ImageView. Autosize does not do that. Rasterizing and scaling up is a bad approach as it will result in half-pixels. You could rasterize at the desired width and then squash the height, scaling the height down to minimise the distortion.
You can try this
<TextView
android:id="#+id/vName"
android:layout_width="56dp"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="Groupa"
app:autoSizeMinTextSize="12sp"
app:autoSizeMaxTextSize="20sp"
app:autoSizeTextType="uniform"
/>

How do I achieve the following layout - one fixed height views at the middle and two equal height views in the top and bottom?

How do I achieve the following vertical layout in Android ?
View1
View2
View3
All three views have width that fits the screen.
View2 height is fixed (= 100).
View1 height is equal to view3's height.
Am I able to achieve this with LinearLayout, RelativeLayout, ConstraintLayout?
I'd appreciate if there is a programmatical solution, instead of the XML layout.
Try this using LinearLayout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="wrap_content"
android:background="#color/colorAccent"/>
<View
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#color/colorDarkBlue"/>
<View
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"/>
</LinearLayout>
OUTPUT
Not sure this is what you want but you can get screen height.
Subtract View2's height and just set heights of View1 and View3 to half of your result.
You need to use RelativeLayout and sort them as you want.

How to set both gravity and layout gravity of a LinearLayout programatically

I am risking writing a duplicate question, but as I was researching the answer to another SO question, I realized that I couldn't find a simple question and answer that included setting both gravity and layout_gravity of a LinearLayout. Also, I was confused as to the difference between them when talking about a ViewGroup rather than just a view. I am answering my question below.
Here are some of the other questions I viewed:
How to set gravity to layout programmatically?
Set gravity for LinearLayout programmatically
android - setting LayoutParams programmatically
LayoutParams gravity not working
layout_gravity in LinearLayout
Problem with setLayoutParams method in android UI
how to set setLayoutParams for linear layout elements
Is it possible to change the layout width and height in Android at run time?
Short answer
Set gravity
linearLayout.setGravity(Gravity.CENTER);
Set layout gravity
// the LinearLayout's parent is a FrameLayout
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(400, 400);
params.gravity = Gravity.TOP|Gravity.RIGHT;
linearLayout.setLayoutParams(params);
Background
Previously, I have explained the difference between 'gravity' and `layout_gravity' for views within a layout.
Setting the gravity of a LinearLayout itself changes the location of the views within it. Setting the layout_gravity of a LinearLayout changes how the LinearLayout is arranged within its parent layout.
This image shows a LinearLayout (brown) within a FrameLayout (white). The LinearLayout's gravity is set to center_horizontal and its layout_gravity is set to right|bottom.
Here is the xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/llExample"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="right|bottom"
android:background="#e3e2ad"
android:gravity="center_horizontal"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="100dp"
android:layout_height="50dp"
android:background="#bcf5b1"
android:text="TextView 1" />
<TextView
android:id="#+id/textView1"
android:layout_width="100dp"
android:layout_height="50dp"
android:background="#aacaff"
android:text="TextView 2" />
</LinearLayout>
</FrameLayout>
Changing things programmatically
The following code shows how to change both the gravity and the layout_gravity of the LinearLayout.
public class LinearLayoutGravity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.linear_layout_gravity);
// Change the gravity (not layout_gravity) of the LinearLayout
LinearLayout ll = (LinearLayout) findViewById(R.id.llExample);
ll.setGravity(Gravity.CENTER);
// Change the layout_gravity (not gravity) of the LinearLayout
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(400, 400);
params.gravity = Gravity.TOP|Gravity.RIGHT;
ll.setLayoutParams(params);
}
}
And here is the result:
See also
RelativeLayout and LinearLayout with gravity: What is the effect?
If you are using KOTLIN use or operator like this:
GRAVITY = Gravity.RIGHT or Gravity.CENTER_VERTICAL
frameContainer.layoutParams = FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT,
GRAVITY)

How to rewrap_content for an android view?

I have a list view with two textviews, one of them has its visibility set to View.GONE by default, so the listview does the wrap_content for the minimum size, the size of the listview with all the secondary textviews GONE, when I turn one of them View.VISIBLE (by clicking on the item), the height stays the same height it calculated from the very first wrap_content when it was first viewed. Tried different approaches that I read but none of them worked on my case such as
mListView.invalidate();
mListView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)mListView.getLayoutParams();
params.height = params.WRAP_CONTENT;
is there any way to force the view to recalculate the height wrap_content value after each click?
Edit1:- This is my listview layout (two is the one that is set to GONE)
<?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="wrap_content">
<TextView
android:id="#+id/list_item_one"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Question?"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:paddingTop="8dp"
android:paddingBottom="4dp"
android:textStyle="bold"/>
<TextView
android:id="#+id/list_item_two"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Answer!"
android:layout_below="#id/list_item_one"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:paddingBottom="4dp"/>
</RelativeLayout>
You should call requestLayout() when you want to re-calculate the dimensions. That is according to this neat view lifecycle:
Original link here.

ImageView increases and decreases dynamically after the size of a textfield

I have a layout like this one:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/tabBar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#272727"
android:orientation="horizontal" >
<ImageButton
android:id="#+id/BtnSlide"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#null"
android:src="#drawable/lin" />
<TextView
android:id="#+id/textView1"
android:layout_width="275dp"
android:layout_height="50dp"
android:gravity="center"
android:paddingLeft="20dp"
android:paddingRight="100dp"
android:text="HEADER"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView
android:id="#+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="2.2dp"
android:src="#drawable/logo" />
The ImageView is placed to the right of the screen. But I'm facing an issue, the ImageView increases and decreases in height and width depending on the length of the TextView, how can I make this work properly, without the ImageView changing size?
The problem here is that your ImageView matches the size of your parent, that is your LinearLayout (with id tabBar).
That LinearLayout wraps the content on his height, so, it sums all "heights" of his contents. The LinearLayout will take the height of TextView + the height of the ImageButton. Then, the ImageView will match that height.
A solution depends on what you are trying to do, but you can try to:
Set a predefined height in your ImageView
Use a RelativeLayout instead of a LinearLayout and align all your views depending on each other
My suggestion is to set layout_weight to all the components so that their size is fixed regardless of their contents:) See here for more details

Categories

Resources