How to programmatically add view in Constraint layout? - android

I am trying to design the below layout
<android.support.constraint.ConstraintLayout
android:id="#+id/before_breakfast_option"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/diabetes_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:text="water"
android:textAppearance="#style/TextAppearance.AppCompat.Medium"
android:textColor="#color/black"
app:layout_constraintBaseline_toBaselineOf="#+id/toogle_diabeties"
app:layout_constraintLeft_toLeftOf="parent"/>
<TextView
android:textColor="#color/black"
android:text="almonds"
app:layout_constraintTop_toTopOf="parent"
android:id="#+id/toogle_diabeties"
app:layout_constraintRight_toRightOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</android.support.constraint.ConstraintLayout>
using the below code:
var textView= TextView(this#DietStepFive)
textView.id=100
textView.text="water"
textView.background=ContextCompat.getDrawable(this#DietStepFive,R.drawable.rectangle_diet)
textView.setTextColor(ContextCompat.getColor(this#DietStepFive,R.color.black))
var textView1= TextView(this#DietStepFive)
textView1.id=101
textView1.text="almonds"
textView1.background=ContextCompat.getDrawable(this#DietStepFive,R.drawable.rectangle_diet)
textView1.setTextColor(ContextCompat.getColor(this#DietStepFive,R.color.black))
var constraintset= ConstraintSet()
constraintset.clone(before_breakfast_option)
//left to left of
constraintset.connect(textView.id,ConstraintSet.LEFT,ConstraintSet.PARENT_ID,ConstraintSet.LEFT,0)
//baseline
constraintset.connect(textView.id,ConstraintSet.BASELINE,textView1.id,ConstraintSet.BASELINE,0)
//right to right of
constraintset.connect(textView1.id,ConstraintSet.RIGHT,ConstraintSet.PARENT_ID,ConstraintSet.RIGHT,0)
//top to top of
constraintset.connect(textView1.id,ConstraintSet.TOP,ConstraintSet.PARENT_ID,ConstraintSet.TOP,0)
constraintset.applyTo(before_breakfast_option)
before_breakfast_option.addView(textView)
before_breakfast_option.addView(textView1)
But the XML code is giving me the layout which has two textview one is one left side and one is one right side but kotlin code is giving me the both the textview overlapping on left side. Why?
what wents wrong? any lead?

Add the TextViews to the layout then connect them just like you did when setting up the XML. You added the views THEN connected them.
Move
before_breakfast_option.addView(textView)
before_breakfast_option.addView(textView1)
before
var constraintset= ConstraintSet()
and everything should work.

Maybe anyone else will use it in future. A sound sleep and work done.
I was using the wrong constraint.
Instead of this
//left to left of
constraintset.connect(textView.id,ConstraintSet.LEFT,ConstraintSet.PARENT_ID,ConstraintSet.LEFT,0)
//baseline
constraintset.connect(textView.id,ConstraintSet.BASELINE,textView1.id,ConstraintSet.BASELINE,0)
//right to right of
constraintset.connect(textView1.id,ConstraintSet.RIGHT,ConstraintSet.PARENT_ID,ConstraintSet.RIGHT,0)
//top to top of
constraintset.connect(textView1.id,ConstraintSet.TOP,ConstraintSet.PARENT_ID,ConstraintSet.TOP,0)
use this
//left to right of
constraintset.connect(textView1.id,ConstraintSet.LEFT,textView.id,ConstraintSet.RIGHT,10)
//baseline
constraintset.connect(textView1.id,ConstraintSet.BASELINE,textView.id,ConstraintSet.BASELINE,0)

Try to replace app:layout_constraintRight_toRightOf="parent"
with
app:layout_constraintRight_toRightOf="#+id/toogle_diabeties"

Related

Android Uneven Design

I have an element that should remain centered in the layout and a button on the right size. The button width is variable.
The following design exemplify two scenarios.
Scenario 1: Long text button
Scenario 2: Small text button
The current solution is have an invisible duplicated button on the left. This is not ideal because the button look and feel may also vary for different locales. I have tried guidelines but that would require to define a percentage and I would prefer if it was dynamic. Barriers don't seem to work either because I would need them to be mirrored.
Any tips how to achieve this?
Try doing width with 0dp and give them weight and change this in runtime
may be they are in linear layout which is horizontal.
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)
button.getLayoutParams();
params.weight = 1.0f; // afterwards you can do the same with changing the weight
button.setLayoutParams(params);
Perhaps you can take advantage of the ConstraintLayoutStates:
https://riggaroo.co.za/constraintlayout-constraintlayoutstates/
And have two layouts one for each scenario.
I ended up using a different solution. I used two guidelines, one at 20% and another at 80%, to define the areas where the button could expand to.
When no button is available, I used the property app:layout_constrainedWidth="false" that ignores the constrainst and allow the title to expand to the available space.
I used this solution because I may need multiple buttons with different call to actions according to the selected language. It would be difficult to manage multiple hidden anchor buttons.
If I understand your pictures correctly, you want to have two elements on your screen:
A View that's centered on the screen, it can be any width size.
A Button that's positioned to the right of the View that can also be any width size. You want this button to be centered in the empty space between the View and the edge of the right screen.
You can try this:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="#+id/view"
android:layout_width="100dp"
android:layout_height="100dp"
android:gravity="center"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:text="1"
android:textColor="#FFFFFF"
android:background="#000000"
/>
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="#+id/view"
app:layout_constraintEnd_toEndOf="parent"
android:text="2"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

Cannot set constraint bias

I want to set app:layout_constraintHorizontal_bias="0.0" so that my TextView stays towards left. When I set it from layout editor by dragging the tiny circle to 0, the circle moves back to default 50. Also tried doing it from xml, but the layout has no effect on bias attribute at all.
If I remove the right constraint, the text goes offscreen owing to wrap_content width. Adding right constraint (along with existing left constraint) requires me to set horizontal bias to achieve permanent left alignment
This answer suggests to add constraint to "parent" (instead of another view, I guess), I tried it and set left and right constraints to parent but still no luck. (left was constraint to image view)
I tried left aligning it with another view (by selecting notification_subject and notification_body and using "Align Left Edges"), still no change in layout
This is my TextView
<TextView
android:id="#+id/notification_subject_tv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/notification_subject"
android:textAppearance="#style/TitleTextAppearance"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toRightOf="#id/notification_item_iv"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginRight="16dp"
android:layout_marginLeft="16dp"
app:layout_constraintHorizontal_bias="0.0"/>
Rendered layout in editor:
I think you have two issues here:
You are trying to match the constraint by using layout_width="0dp". I believe this should be set to layout_width="wrap_content".
On one side of your constraints you are using layout_constraintEnd_toEndOf="parent" and then layout_constraintLeft_toRightOf="#id/notification_item_iv" on the opposite side. Please can you change this to layout_constraintStart_toEndOf="#id/notification_item_iv"
Complete code:
<TextView
android:id="#+id/notification_subject_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/notification_subject"
android:textAppearance="#style/TitleTextAppearance"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/notification_item_iv"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginRight="16dp"
android:layout_marginLeft="16dp"
app:layout_constraintHorizontal_bias="0.0"/>

What is meaning of margin in constraint set connect

The official documentation of the constraint set connect says: https://developer.android.com/reference/android/support/constraint/ConstraintSet.html#connect(int, int, int, int, int)
void connect (int startID,
int startSide,
int endID,
int endSide,
int margin)
the margin to constrain (margin must be postive)
For my understanding if I want to connect two views with the left to right of then this margin is left margin.
//left to right of
constraintset.connect(textView.id,ConstraintSet.LEFT,previousTextViewId,ConstraintSet.RIGHT,10)
then 10 is the left margin. Am I right? I have implemented this concept but no margin is set even no right or left. What am I missing?
Update: It looks like this issue has been fixed, but I haven't checked it out. See the bug report.
Your understanding is also how I understand things. Here is a quick way to check how things are working.
In the layout below, the top left corner of textRight lines up with the lower right corner of textLeft. When MainActivity runs, textRight should move 1,000px down and 1,000px to the right. It moves 1,000 px down but does not move to the right at all.
I believe that this is an outstanding issue. See this issue report.
I don't know a work-around and I am surprised that this could even be a bug. I am willing to stand corrected if anyone sees the error.
two_text_views.xml
<?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:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="TextView1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="8dp" />
<TextView
android:id="#+id/textRight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView2"
android:layout_marginTop="0dp"
app:layout_constraintTop_toBottomOf="#+id/textLeft"
app:layout_constraintStart_toEndOf="#+id/textLeft"
android:layout_marginStart="0dp" />
</android.support.constraint.ConstraintLayout>
**MainActivity.java**
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
ConstraintLayout layout;
super.onCreate(savedInstanceState);
setContentView(R.layout.two_text_views);
ConstraintSet constraints = new ConstraintSet();
constraints.clone(layout);
constraints.connect(R.id.textRight, ConstraintSet.LEFT, R.id.textLeft, ConstraintSet.RIGHT, 1000);
constraints.connect(R.id.textRight, ConstraintSet.TOP, R.id.textLeft, ConstraintSet.BOTTOM, 1000);
constraints.applyTo(layout);
}
}
EDIT So, here is a fix. Use ConstraintSet.START and ConstraintSet.END instead of ConstraintSet.LEFT and ConstraintSet.RIGHT. I just tried it and it works OK. I can't say why left and right don't work.

Android Constraint by center

I have guideline 60% from top and LinearLayout with bottom constrain to that guideline (so my LinearLayout will 60% of screen). Now Im need to put half of CardView to the bottom of that LinearLayout (screenshot added).
CardView height is wrap_content, cause will be added dynamically so I dont know height and cannot use something like margin bottom -50dp.
Thats what I have:
I need something like that:
I cannot find future like constrain by center. Could you help me, please.
You just need to set the top anchor of cardview to be connected to the bottom anchor of the linear layout (or to the guideline), and do the same for the bottom anchor. With both top and bottom anchors pointing to the same target, the cardview will be centered vertically on that target. Also, you might not need that linearlayout, depending on what you do. Check the chains functionality in ConstraintLayout.
<android.support.v7.widget.CardView
android:layout_width="300dp"
android:layout_height="200dp"
tools:layout_editor_absoluteX="28dp"
app:layout_constraintBottom_toTopOf="#+id/guideline"
app:layout_constraintTop_toTopOf="#+id/guideline"
tools:layout_editor_absoluteY="156dp" />
<android.support.constraint.Guideline
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/guideline"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5" />
The eaiest way is to do this in code at runtime. Wait until the height has been calculated, then add a top margin of -.5*height.

Weird behavior with buttons and visibility gone

I am having a very weird problem with buttons, vertical centering and visibility gone. In my app I have a list of books, and I am using the swipelistview library to create buttons behind each row. I have 3 buttons: return, send reminder and delete. The return and send reminder buttons visibility is set to Visibility.GONE dynamically if the book isn't lended. Now here's my problem. I have the following xml layout for the back of the rows.
<LinearLayout
android:id="#+id/swipelist_backview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:tag="swipelist_backview"
android:background="#101010">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="55px"
android:layout_gravity="center_vertical"
android:id="#+id/swipe_button1"
android:text="#string/markAsReturned"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:id="#+id/swipe_button2"
android:layout_gravity="center_vertical"
android:text="#string/sendReminder"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:id="#+id/swipe_button3"
android:layout_gravity="center_vertical"
android:text="#string/delete"/>
</LinearLayout>
Now the expected result from this is that the buttons will be vertically centered in the middle of each row, which does happen if the book is lended, and all the buttons are visible. But if the book isn't lended, the only button shown is delete, and it isn't aligned .
I am also setting the left margin of the delete button to 55 px using the following code:
if(!item.isLended())
{
btnReturn.setVisibility(View.GONE);
btnSendReminder.setVisibility(View.GONE);
LayoutParams lp = new LayoutParams(btnDelete.getLayoutParams());
lp.setMargins(55, 0, 0, 0);
btnDelete.setLayoutParams(lp);
}
I thought this might be removing the verical alignment, but LayoutParams doesn't seem to have a way to set layout-gravity, so it doesn't look like it.
Well, I guess it was the LayoutParams. If anyone is intersted, here's how I solved it:
if(!item.isLended())
{
btnReturn.setVisibility(View.GONE);
btnSendReminder.setVisibility(View.GONE);
LayoutParams lp = new LayoutParams(btnDelete.getLayoutParams());
lp.setMargins(55, 0, 0, 0);
lp.gravity = Gravity.CENTER_VERTICAL;
btnDelete.setLayoutParams(lp);
}

Categories

Resources