ConstraintLayout Barrier in dynamic feature module fails - android

I have a ConstraintLayout within an XML layout, it contains 3 views and a Barrier, they are button2, textView2, barrier2, and button3. As expected, button3 is successfully placed under both button2 and textView2, constrained by using barrier2. However it seems fail to refer to the constraining views (button2 and textView2) when used in the dynamic feature module, so that button3 sticks to top.
These screenshots show it is successful is base module, but not working in dynamic feature module:
The XML layouts both in base and dynamic feature are like this:
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView 2"
app:layout_constraintStart_toEndOf="#id/button2"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Barrier
android:id="#+id/barrier2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="button2,textView2" />
<Button
android:id="#+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/barrier2" />
</androidx.constraintlayout.widget.ConstraintLayout>
However, it is success if I set the constraint with code instead of XML:
barrier2.referencedIds = intArrayOf(R.id.button2, R.id.textView2)
How to correctly refer to button2 and textView2 within the XML layout?

Inspecting the (decompiled) source code, I found a (hacky?) solution: by using fully qualified resource ID (package:type/entry). It seems this is not "an official way" since the linter give an error, but it works.
Suppose the app package is com.example.app and the dynamic feature module name is dynfeat, prepend the ID with <package>.<module>:id/ like this:
app:constraint_referenced_ids="com.example.app.dynfeat:id/button2,com.example.app.dynfeat:id/textView2"
I am actually not satisfied with this solution, because code like is hard to maintain, for example, when renaming the dynamic feature module name. So that, the other solution is by subclassing the Barrier class and handle it in the constructor.

Related

How to position 2 Views relative to each other?

I would like to position 2 views relative to each other but not simply w.r.t the top, bottom, left or right but in a proportionate way. Let me explain. Here are 4 scenarios of positioning:
Of these, 2) and 4) are easy to do and have in-built support provided by the standard layout containers such as RelativeLayout, ConstraintLayout but my current task requires a positioning depicted in scenarios 1)/3)
A simple solution to this problem involves setting different left/top margins for both the Views w.r.t parent but this means if the need arises to place both the Views together to some other position, all the margins shall have to change.
Instead, what I would like is to have some sort of relative positioning arrangement between these 2 views that keeps them relatively at "right" distance no matter where they are placed as a unit in the parent.
How can I achieve the same? An efficient solution(with flattened hierarchy, no view hacks) would be appreciated.
An efficient solution(with flattened hierarchy, no view hacks) would be appreciated., You can use ConstraintLayout with guidelines.
guidelines have app:layout_constraintGuide_percent attribute making them responsive to the screen size.
you can use it while adding your buttons the app:layout_constraintWidth_percent and app:layout_constraintHeight_percent attributes (not mandatory, you can constraint your views to the guidelines but I believe that it is more simple).
Here is an example for your wanted layout with flattened hierarchy:
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/button2"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="Button"
app:layout_constraintHeight_percent=".1"
app:layout_constraintStart_toStartOf="#+id/guideline"
app:layout_constraintTop_toTopOf="#+id/guideline2"
app:layout_constraintWidth_percent=".3" />
<Button
android:id="#+id/button"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="Button"
app:layout_constraintBottom_toTopOf="#+id/guideline4"
app:layout_constraintEnd_toStartOf="#+id/guideline"
app:layout_constraintHeight_percent=".1"
app:layout_constraintWidth_percent=".3" />
<android.support.constraint.Guideline
android:id="#+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent=".5" />
<android.support.constraint.Guideline
android:id="#+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent=".4" />
<android.support.constraint.Guideline
android:id="#+id/guideline4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent=".45" />
</android.support.constraint.ConstraintLayout>
It will look like this(I am adding screenshot from the preview for better understanding guidelines):
This was just an example but with those tools, you can create your layout however you would like to.
Some extra information
My solution does not contain any fixed size dimensions on my views, this will make the layout responsive(no need to build a layout for every screen size)
You may also find ConstraintLayout: Circular Positioning related to your question, but I don't think that this is the best thing for you in this specific case.
Yes it is possible using constraint layout checkout below XML code for Point 3.(Same point 2 will be implemeted let me know if you have query)
<?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"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/buttonA"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="Add"
android:layout_marginTop="15dp"
/>
<androidx.appcompat.widget.AppCompatButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="#id/buttonA"
app:layout_constraintEnd_toEndOf="#id/buttonA"
app:layout_constraintTop_toBottomOf="#id/buttonA"
android:text="Add"
/>
</androidx.constraintlayout.widget.ConstraintLayout>`
Please check out below code this is kind of patch but works fine.Here we can put big block to relative to small block.As we have used constraint so will be stick together no matter wherever you put. let me know if i did any thing wrong.
Here we use one dummyView and also app:layout_constraintHorizontal_bias="0.1" for making it relative value changes from 0 to 1 like 1 means 100% stating left to small block smae way 0.5 means 50% from starting small blobk to left.
<?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"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/buttonA"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:text="Add"
android:layout_marginTop="15dp"
/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/dummyView"
app:layout_constraintTop_toBottomOf="#id/buttonA"
app:layout_constraintStart_toStartOf="#id/buttonA"
app:layout_constraintEnd_toEndOf="#id/buttonA"
app:layout_constraintHorizontal_bias="0.1"/>
<androidx.appcompat.widget.AppCompatButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/buttonA"
app:layout_constraintStart_toEndOf="#id/dummyView"
android:text="Add"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

Android components are not matched in position when running the app using phone

I placed a button in the middle of design layout from activity_main.xml but when i run the app through my phone, the positioning is not the same as the design inside activity_main.xml.
Tried to change layout to relative and the problem still exist.
<Button
android:id="#+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="160dp"
android:layout_marginLeft="160dp"
android:layout_marginTop="276dp"
android:text="Button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
I expect that the design position from activity_main is the same when run through an actual android phone.
From the design layout
from the actual phone
First of all, you might want to adjust button relatively with other components. i.e. try to align your button on top of other component or maybe on bottom of another component.
Refer this link, it has all information
https://developer.android.com/reference/android/widget/RelativeLayout.LayoutParams#attr_android:layout_alignBottom
If you have confusion, share whole xml file for us to refer.
You need just to change the <ConstraintLayout/> in <RelativeLayout/> and replace the Button code by this:
<Button
android:id="#+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Button" />
Hope this will help.
First of all remove that margins from attributes. There is the left margin which make your button to go right and top margin which move button below the actual center point in small density devices.
So If you want to add button in center of screen in all devices. Use below code without any margin. But if your want to add spacing between other view then use small margin in other views.
<Button
android:id="#+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
Refer this guide to learn basics of constraints : guide
<RelativeLayout 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"
android:background="#efeff1">
<Button
android:id="#+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Button" />
</RelativeLayout>

What layout elements to use for following type of layout

I am certainly newbie to Andorid Development, and have a knowledge of basic stuff, Relative Layout, Linear Layout, Intent, File Handling etc....
I need to build a project similar to some E-commerce app.
Here's an image of what I want.
How do I achieve the given view of products, as like in blogs or other websites.
Do I have to use List View?
And Please tell what do I have to use to make that "Add Filter Tags" section and how to achieve what I have shown in the picture.
Below is the code which will create skeleton for your UI requirement. You can modify it according to your need.
Your Activity/Fragment xml will look like :
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.constraint.ConstraintLayout
android:id="#+id/cl_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
<com.google.android.material.chip.ChipGroup
android:id="#+id/entry_chip_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/cl_parent">
</com.google.android.material.chip.ChipGroup>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/entry_chip_group"
/>
</android.support.constraint.ConstraintLayout>
You Adapter xml for RecyclerView will look like:
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/iv_product"
android:layout_width="100dp"
android:layout_height="match_parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Product Name"
app:layout_constraintStart_toEndOf="#id/iv_product"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/tv_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Product Information"
app:layout_constraintStart_toStartOf="#id/tv_name"
app:layout_constraintTop_toBottomOf="#id/tv_name" />
<TextView
android:id="#+id/tv_more_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="More info"
app:layout_constraintStart_toStartOf="#id/tv_name"
app:layout_constraintTop_toBottomOf="#id/tv_info" />
<TextView
android:id="#+id/tv_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Data"
app:layout_constraintStart_toStartOf="#id/tv_name"
app:layout_constraintTop_toBottomOf="#id/tv_more_info" />
<TextView
android:id="#+id/tv_tags"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tags"
app:layout_constraintStart_toStartOf="#id/tv_name"
app:layout_constraintTop_toBottomOf="#id/tv_data" />
</android.support.constraint.ConstraintLayout>
You should use Chips for your Filter tag. You can add them dynamically to your chip group. Below is the link for reference.
How to use Android Chips
A ListView would be the "default" way. I would also have a look at RecyclerView (a newer incarnation of the same idea). It handles scrolling and recycling the list elements as you scroll, which are all things you don't really want to do on your own.
You'll probably have a separate layout for the individual cards, probably mostly LinearLayouts (horizontal for image -> content, and then a vertical one to hold the content, and maybe a third horizontal one to list the tags).
For the tags, you might want to take a look at Material Design "chips", but honestly that's the part of this mockup that would have me the most concerned. You can make it look however you want, but I'm not sure what your designer means there exactly. Is that a static list of filtering options? Is that on a new page? In a dialog?
EDIT: And as for the top bar, check out the standard App Bar before reinventing the wheel there.
I would definitely go with Recyclerview or this tutorial for your products(images and the product description...) and FrameLayout for the top that includes logo and stuff and finally a regular RelativeLayout for the tags.

Is it advisable to use LinearLayout inside ConstraintLayout in Android?

I am new to ConstraintLayout in Android and newbie to Android too. I have a question. Is it advisable to use LinearLayout inside ConstraintLayout? For example:
<?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"
app:srcCompat="#drawable/landing_screen"
android:layout_height="match_parent"
tools:context="com.braigolabs.braigo.landing.LandingActivity">
<ImageView
android:id="#+id/imageView"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:srcCompat="#drawable/landing_screen"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintVertical_bias="1.0"
app:layout_constraintHorizontal_bias="1.0"
tools:layout_constraintTop_creator="1"
tools:layout_constraintRight_creator="1"
tools:layout_constraintBottom_creator="1"
tools:layout_constraintLeft_creator="1"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="51dp">
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="66dp"
android:layout_marginStart="66dp"
android:gravity="center"
android:text="#string/login_welcome_braigolabs" android:textAppearance="#style/TextAppearance.AppCompat.Large"
tools:layout_editor_absoluteX="93dp"
tools:layout_editor_absoluteY="403dp"/>
<Button
android:id="#+id/login_button"
style="#style/Widget.AppCompat.Button.Colored"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="2dp"
android:text="#string/login_login_button_title"
android:textAllCaps="false"
tools:layout_editor_absoluteX="116dp"
tools:layout_editor_absoluteY="543dp"/>
</LinearLayout>
</android.support.constraint.ConstraintLayout>
Also curious to know how popular is the ConstraintLayout among the developers?
Is it advisable to use LinearLayout inside ConstraintLayout?
No... usually.
In general, the idea behind ConstraintLayout is that it allows you to position all of your children without having to nest any other ViewGroups inside the ConstraintLayout. As such, I would say that it is not advisable.
However, there are some things that a LinearLayout can do that a ConstraintLayout can't (mostly revolving around weighted spacing of views), and so if you need these particular corner cases in your layout, you won't have any option other than falling back to a LinearLayout.
how popular is the ConstraintLayout among the developers?
ConstraintLayout is relatively new, but it is quite powerful and certainly something that you ought to familiarize yourself with. It won't always be the perfect tool for the job at hand, but it will often allow you to easily create layouts you would otherwise spend hours on.
I can't speak to widespread adoption statistics, but I can say that I've seen tons of questions on this site about the correct usage of ConstraintLayout, so clearly devs around the world are starting to work with it.
As of the 2.0.0-alpha5 release of the constraintlayout library, it's now possible to declare a Flow virtual layout element within your ConstraintLayout which (as the name suggests) determines how referenced items are to flow (e.g. vertically, horizontally) within the ConstraintLayout. So it's no longer necessary to declare a LinearLayout within your ConstraintLayout.
For example, if you wanted items within your ConstraintLayout to flow vertically, you'd do so like this:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="I am the first TextView" />
<TextView
android:id="#+id/textView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="I am the second TextView" />
<TextView
android:id="#+id/textView3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="I am the third TextView" />
<androidx.constraintlayout.helper.widget.Flow
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="vertical"
app:constraint_referenced_ids="textView1,textView2,textView3"
app:flow_horizontalAlign="start"
app:flow_verticalGap="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
You can play around with the app:flow_ attributes in the Flow element to achieve different flow behaviour. For more information about the Flow element, refer to the release notes here. For an example, see here.

Elements overlapping on each other in my android studio emulator

I am new to Android Studio, when I created my app all my elements overlapped on each other. I am not sure how to edit this code. Please give me a detailed description.
Layout editor and emulator result
Code for the layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="schemas.android.com/apk/res/android";
xmlns:app="schemas.android.com/apk/res-auto";
xmlns:tools="schemas.android.com/tools";
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.first.anew.MainActivity">
<TextView
android:layout_width="216dp"
android:layout_height="60dp"
android:text="Hello World!"
tools:layout_editor_absoluteY="16dp"
tools:layout_editor_absoluteX="61dp" />
<Button
android:id="#+id/button"
android:layout_width="100dp"
android:layout_height="45dp"
android:text="Login"
tools:layout_editor_absoluteY="343dp"
tools:layout_editor_absoluteX="177dp" />
<TextView
android:id="#+id/textView"
android:layout_width="215dp"
android:layout_height="65dp"
android:text="username"
tools:layout_editor_absoluteY="117dp"
tools:layout_editor_absoluteX="61dp" />
<android.support.constraint.Guideline
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/guideline"
app:layout_constraintGuide_begin="20dp"
android:orientation="horizontal" />
<EditText
android:id="#+id/editText"
android:layout_width="217dp"
android:layout_height="57dp"
android:ems="10"
android:inputType="textPassword"
tools:layout_editor_absoluteY="218dp"
tools:layout_editor_absoluteX="61dp" />
</android.support.constraint.ConstraintLayout>
Your emulator screen and the layout editor are different because of tools namespace. In a few words, it is a tool that helps you to better visualise the written code. This tool also generates constraints like tools:layout_editor_absoluteY="343dp", which inform the layout editor on how it should draw the views. The problem is that this constraints will not be present in your app code, resulting in that weird behaviour when all views are overlapped (since the above mentioned constraints are not used in the app code we can deduct that there are no constraint at all).
Since you are a beginner I would recommend to start with a LinearLayout or RelativeLayout because I think that ConstraintLayout is harder to understand, use and debug.
put the whole code. if you are using Relativelayout, this will happen. change it to Linearlayout at the top i mean the bottom most element, and put orientation as vertical
see this - for me my soltion works...
add this in xml to the button etc
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.57"
then play with it in the design.
Good luck! :)
you can click the infer Constraints buttonclick on this
and run your programme again..it will solve your problem

Categories

Resources