What is equivalent of "toStartOf" and "toTopOf" in ConstraintSet? - android-studio

How is it possible to set correctly layout_constraintStart_toStartOf and layout_constraintTop_toTopOf programmaticly?
<ImageView
android:id="#+id/firstButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/alarm"
app:layout_constraintStart_toStartOf="#+id/guideline4"
app:layout_constraintTop_toTopOf="#+id/guideline" />
So far, I can't find toStartOf and toTopOf properties of ConstraintSet, what is the equivalent of it?
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(main_layout);
constraintSet.connect(R.id.firstButton, ConstraintSet.START, R.id.guideline4, ConstraintSet.END);
constraintSet.connect(R.id.firstButton, ConstraintSet.TOP, R.id.guideline, ConstraintSet.BOTTOM);
constraintSet.applyTo(main_layout);

I guess that if you want start to start and top to top, it is more like
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(main_layout);
constraintSet
.connect(R.id.firstButton, ConstraintSet.START, R.id.guideline4, ConstraintSet.START);
constraintSet
.connect(R.id.firstButton, ConstraintSet.TOP, R.id.guideline, ConstraintSet.TOP);
constraintSet.applyTo(main_layout);
?

Related

Why doesn't textView21.SetLeftTopRightBottom(1,200,45, 275) change the size of a textview?

Why doesn't textView21.SetLeftTopRightBottom(1,200,45, 275) change the size of a textview?
<TextView
android:id="#+id/textView21_id"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_x="22dp"
android:layout_y="105dp"
android:height="50dp"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text=""
android:textSize="30sp"
android:textColor="#000000"
android:background="#9999cc"
android:singleLine="false"/>
There's the activity_main.xml snippet. Is there something there which overrides the SetLeftTopRightBottom?
I am still trying to get two different but ordinary mobile phones (cell phones) to display a view the same.
pic of same app in two phones
You can see the left hand pic shows to below the grey '6:' textview and includes the 'Go' textview and all the right hand 5th-letter-in-the-word textview areas whereas the other pic doesn't.
I've figured out how to get each phone's display metrics
var metrics = Resources.DisplayMetrics;
gnumWidthDp = ConvertPixelsToDp(metrics.WidthPixels);
gnumHeightDp = ConvertPixelsToDp(metrics.HeightPixels);
I thought it would be easy to do the SetLeftTopRightBottom thing and set each textview in the right place.
Please can you tell me what I have missed? Thank you all.
In the official document, SetLeftTopRightBottom method is meant to be used in animations only as it applies this position and size for the view only temporary and it can be changed back at any time by the layout.
More information: https://developer.android.com/reference/android/view/View#setLeftTopRightBottom(int,%20int,%20int,%20int)
In addition, the size of the textview21 had been ensured in the xml. If you want to set the size of it dynamically, you need to use the LayoutParams. Such as:
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(300, 200);
//300 is width and 200 is height
textView.LayoutParameters = layoutParams;

Handling GONE views puzzle in ConstraintLayout

I have a simple enough looking layout with what turns out to be quite a tricky behaviour to accomplish using xml alone i.e. using only the features of ConstraintLayout and not having to do anything programmatically.
I have considered Barriers & Guidlines and many scenarios and trials with no success; so this is my last hope that maybe someone else knows something I don't.
Here is my puzzle:
If 3 lines visible -> image should be centred between line 1 and line
2
If 2 lines visible -> image should be centred between line 1 and
line 2
If 1 line visible (label_text) -> image should be centred in parent, or
centre aligned with line 1 (label_text)
Here are some images to illustrate:
3 Lines - correct
2 Lines - correct
1 Line incorrect but best I can get so far [when only Label is visible]
1 Line correct the way I want it to be [when only Label is visible]
Code:
<androidx.constraintlayout.widget.ConstraintLayout
style="#style/V2.ItemList.Background"
android:minHeight="#dimen/item_minimum_height"
android:paddingVertical="#dimen/=margin_vertical">
<ImageView
android:id="#+id/icon"
app:layout_constraintBottom_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent"
tools:src="#drawable/ic_img"
tools:visibility="visible" />
<TextView
android:id="#+id/label_text"
app:layout_constraintBottom_toTopOf="#id/line1_text"
app:layout_constraintEnd_toStartOf="#id/right_content"
app:layout_constraintStart_toEndOf="#id/icon_start"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:text="Label" />
<TextView
android:id="#+id/line1_text"
android:layout_marginTop="4dp"
app:layout_constraintBottom_toTopOf="#id/line2_text"
app:layout_constraintEnd_toStartOf="#id/right_content"
app:layout_constraintStart_toEndOf="#id/icon"
app:layout_constraintTop_toBottomOf="#id/label_text"
tools:text="Line 1"
tools:visibility="gone" />
<TextView
android:id="#+id/line2_text"
android:layout_marginTop="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#id/right_content"
app:layout_constraintStart_toEndOf="#id/icon"
app:layout_constraintTop_toBottomOf="#id/line1_text"
tools:text="Line 2"
tools:visibility="gone" />
</androidx.constraintlayout.widget.ConstraintLayout>
Any help is much appreciated!
UPDATE
See Cheticamp's answer below which is best solution but in case it's useful for anyone else here's the way I was going to do it programmatically if I couldn't find an xml only solution:
private fun adjustConstraints() {
if(binding.line1Text.isGone && binding.line1Text.isGone) {
ConstraintSet().apply {
clone(binding.itemListLayout)
// Adjust left/start content for single line
connect(
R.id.icon,
ConstraintSet.TOP,
R.id.item_list_layout,
ConstraintSet.TOP
)
connect(
R.id.icon,
ConstraintSet.BOTTOM,
R.id.item_list_layout,
ConstraintSet.BOTTOM
)
// Adjust right/end content for single line
connect(
R.id.right_content,
ConstraintSet.TOP,
R.id.item_list_layout,
ConstraintSet.TOP
)
connect(
R.id.right_content,
ConstraintSet.BOTTOM,
R.id.item_list_layout,
ConstraintSet.BOTTOM
)
}.also {
it.applyTo(binding.itemListLayout)
}
}
}
Constrain the ImageView to the top of label_text and to the bottom of line_1_text.
<ImageView
android:id="#+id/icon"
app:layout_constraintTop_toTopOf="#id/label_text"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="#id/line1_text"
tools:src="#drawable/ic_img"
tools:visibility="visible" />

how do I change the android:layout_marginTop of a button?

I need to change the property android:layout_marginTop of a button programmatically. But the code below does not produce the same result as changing on the xml. I wonder if anyone can spot the issue, here's my button:
<Button
android:id="#+id/cta_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="0dp"
android:background="#color/cta_button_background"
android:text="CTA"
android:textColor="#color/cta_button_foreground"
android:textSize="18sp"
android:visibility="visible" />
now I need to change the "marginTop" programmatically based on some logic. Here is what I have tired but does not work properly.
// Adjust button to float above the image
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
int marginTop = Pixel.convertPxToDp(someNumber);
params.setMargins(0, marginTop, 0, 0);
mCallToActionButton.setLayoutParams(params);
mCallToActionButton.invalidate();
"mCallToActionButton" has a valid pointer to the button and 'someNumber' can be anything value.
I used this thread but the button is moving somewhere else, not just changing its topMargin
How to set a button's parameters programatically
thank you.
This way works:
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mCallToActionButton.getLayoutParams();
params.topMargin = Pixel.convertDpToPx(newImageMargin);
mCallToActionButton.setLayoutParams(params);
Try to set gravity to your LayoutParams
params.gravity = Gravity.CENTER_HORIZONTAL;

RelativeLayout with ImageView - calculate position of elements

I have a problem with my android code. I have the following code
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main_layout_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:orientation="vertical">
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:layout_centerVertical="true"
android:src="#drawable/pdf" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/imageView1"
android:layout_alignLeft="#+id/imageView1"
android:text="Test-Label"
android:textColor="#color/red" />
</RelativeLayout>
I want to position the textview now in my imageview and use the following code
ImageView iv = (ImageView) findViewById(R.id.imageView1);
int width = iv.getWidth();
int height = iv.getHeight();
float percentMarginTop = 58f;
float percentMarginLeft = 65f;
float percentTextSize = 3f;
float marginTop = height / 100f * percentMarginTop;
float marginLeft = width / 100f * percentMarginLeft;
TextView tv = (TextView) findViewById(R.id.textView1);
tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, Math.round(height / 100f * percentTextSize));
RelativeLayout.LayoutParams lpTv = (RelativeLayout.LayoutParams) tv.getLayoutParams();
lpTv.topMargin = Math.round(marginTop);
lpTv.leftMargin = Math.round(marginLeft);
So I want to position the elements with the percentage values calculated of the actual width and height of the imageview. So in my opinion the elements should position correct on each device not carrying about the density (ldpi, mdpi, xhdpi, ...) and screen size (small, normal, large, xlarge, ...) but the position on a handy (4") is correct but not correct on another device like a tablet (10"). How could that be when I'm working with percentages on the given ImageView?
Looks like it was a dumb beginner mistake I didn't want to see or wanted to ignore it ;)
width / 100 returns not the float value, but the int value. And then the whole calculation fails due to a false value which gets multiplicated.
I changed my code which is now a working snippet

Android TextView Programmatically following XML

I currently have this xml:
<TextView android:id="#+id/dummy"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="#string/test"
android:textStyle="bold" />
And im trying to convert it to a java version so that I can set a typeface:
setContentView(R.layout.activity_main);
// the get the activity_main layout (getContentView method does not exist?)
FrameLayout layout = (FrameLayout) findViewById(android.R.id.content);
final TextView textView = new TextView(context);
textView.setId(R.id.dummy);
FrameLayout.LayoutParams contentLayout = new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
contentLayout.gravity = Gravity.CENTER;
textView.setText(R.string.test);
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/arial.ttf");
textView.setTypeface(tf);
layout.addView(textView, contentLayout);
The problem I'm having is that either does not gravity work or match_parent. The texts ends up in the upper right corner and not in the center as it does on the xml version.
In the XML you're setting the gravity of the text inside the TextView. In the code you are setting the TextView's layout gravity.
To replicate what you've done in the XML, change the line:
contentLayout.gravity = Gravity.CENTER;
to:
textView.setGravity(Gravity.CENTER);
If your XML had android:layout_gravity="center" instead of android:gravity="center" then your code would match as it is.

Resources