ConstraintLayout constraints attribute in style - android

How to use constraint attributes in style?
When I'm trying to use it as any other attributes with custom namespace it's has no effect on my view.
<style name="Header.Center" parent="Header">
<item name="layout_constraintBottom_toBottomOf">parent</item>
</style>
Adding namespace app: is not helping.

First of all, make sure that the View that you're applying the style on is a direct child of the ConstraintLayout. Otherwise, the constraints will not be taken into account when positioning the View.
I have tried it and the way you tried does in fact work. I have added the following style to the styles.xml:
<style name="CustomStyle">
<item name="layout_constraintBottom_toBottomOf">parent</item>
<item name="layout_constraintEnd_toEndOf">parent</item>
</style>
Created a basic layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="Text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/CustomStyle"/>
</android.support.constraint.ConstraintLayout>
And it does indeed position the TextView at the bottom right corner of the parent.

maybe your view's attribute is "match_parent",but it is wrong.
It should be "wrap_content".
<TextView
android:text="Text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/CustomStyle"/>

Related

Align TextViews in specific way

I am currently learning some techniques in Android and I would like to add TextViews via button press (via Java) into the app (View). But before they get added through code I want to attach to each TextView a self made preconfigurartion style from "res/values/styles.xml". That is the main idea so far.
Basically I would like to know how to configure my TextViews (in styles.xml) and the given Layout (e.g. main_activity.xml) in the XML file of an Activity in such a way so they look like in this picture:
So the goal is to preconfigure the Layout and TextView in such a way, that I only have to add the TextViews one after another so that they align themselfes in the way like in the picture.
What do I have to do exactly in order to achieve this?
// main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
...>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView style="#style/AddedTextView" />
</RelativeLayout>
...
<Button
android:id="#+id/btn_add"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
// res/values/styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AddedTextView" parent="Widget.AppCompat.TextView">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:background">#drawable/custom_textview_design</item>
<item name="android:text">TestTV</item>
<item name="android:textColor">#color/common_text_color</item>
<item name="android:textSize">7pt</item>
<item name="android:layout_alignParentLeft">true</item>
</style>
</resources>
You can apply the style programmatically using a ContextThemeWrapper:
val textView = TextView(ContextThemeWrapper(this, R.style.AddedTextView))
And to add TextViews connected to one another and wrap them vertically, you can use the Google's FlexBoxLayout
Here's the basic layout:
<com.google.android.flexbox.FlexboxLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/flexLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:flexDirection="row"
app:flexWrap="wrap">
</com.google.android.flexbox.FlexboxLayout>
And adding the views programmatically is very straightforward:
val flexboxLayout = findViewById<View>(R.id.flexLayout) as FlexboxLayout
for (i in 1..50) {
val textView = TextView(ContextThemeWrapper(this, R.style.AddedTextView))
val layoutParams = FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)
layoutParams.rightMargin = 40
textView.layoutParams = layoutParams
textView.text = "TextView $i"
flexboxLayout.addView(textView)
}

Changing android:layout_height and android:gravity in styles.xml

I'm new to android development and I've stumbled upon a problem I couldn't solve with the help of existing StackOverflow questions.
In the list of custom items I'm loading a TextView object which can use 2 different styles (both defined in styles.xml) - if there's a secondary TextView object, the style applied is itemHeadingText_Medium, and if not it's itemHeadingText_Large. I'm changing the style programmaticaly in the ListItemAdapter class.
<!-- Heading in each list item -->
<style name="itemHeadingText_Large" parent="#android:style/TextAppearance.Large">
<item name="android:textStyle">bold</item>
<item name="android:textColor">#android:color/black</item>
<!-- Testing height and gravity -->
<item name="android:layout_height">100dp</item>
<item name="android:gravity">center_vertical</item>
</style>
<!-- Heading in each list item -->
<style name="itemHeadingText_Medium" parent="#android:style/TextAppearance.Medium">
<item name="android:textStyle">bold</item>
<item name="android:textColor">#android:color/black</item>
</style>
Sadly, the android:layout_height and android:gravity aren't applied to the view, and whole app looks like that. Here's how both TextViews are defined:
<TextView
android:id="#+id/heading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/darker_gray"/>
<TextView
android:id="#+id/secondary"
style="#style/itemSecondaryText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/holo_red_light"/>
I would like to center vertically the Lorem Ipsum heading of the second item provided in the screenshot.
EDIT: 25 June 2017
I managed to achieve what I wanted by changing the height programmatically using the getLayoutParams().height and adding the android:gravity attribute to the TextView xml definition - after all in both styles text can be centered vertically within its TextView.
Nevertheless, my question on how to do that in styles.xml is still open!
android:gravity will specify how the text should be laid out within the TextView, if the View is larger than the text
android:layout_gravity will specify how the View itself should be laid out in its ViewGroup.
I would try replacing gravity with layout_gravity
The issue that I can see in your code is:
<TextView
android:id="#+id/secondary"
style="#style/itemSecondaryText" // Look at this line
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/holo_red_light"/>
You are using "itemSecondaryText" style for your textview, but in your styles.xml there isn't any style named "itemSecondaryText". You have "itemHeadingText_Medium" and "itemHeadingText_Large" in your style.xml but there isn't item named "itemSecondaryText".
I guess this is the issue, otherwise everything looks good.

Using <include> in android.support.v7.widget.GridLayout not displaying correctly

I'm trying to use <include> to include ImageButtons inside a android.support.v7.widget.GridLayout. The problem is, if I don't specify all the attributes explicitly on my <include> elements, they don't display properly. In other words, the include is pointless since I have to redeclare all the attributes on every <include> element.
dialpad_button.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageButton
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:grid="http://schemas.android.com/apk/res-auto"
android:layout_width="0dp"
android:layout_height="0dp"
grid:layout_columnWeight="1"
grid:layout_rowWeight="1"
grid:layout_gravity="fill"
android:layout_margin="5dp"
android:scaleType="centerInside"/>
dialpad_view.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.GridLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:grid="http://schemas.android.com/apk/res-auto"
android:id="#+id/dialpad_grid_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
grid:alignmentMode="alignBounds"
grid:columnCount="2"
grid:rowCount="1">
<include
android:id="#+id/dialpad_view_btn1"
android:src="#drawable/dialpad_1"
layout="#layout/dialpad_button" />
<include
android:id="#+id/dialpad_view_btn2"
android:src="#drawable/dialpad_2"
layout="#layout/dialpad_button" />
</android.support.v7.widget.GridLayout>
If I declare all the attributes directly on the <include>s, here's what it looks like in XML:
<include
layout="#layout/dialpad_button"
android:id="#+id/dialpad_view_btn1"
android:src="#drawable/dialpad_1"
android:layout_width="0dp"
android:layout_height="0dp"
grid:layout_columnWeight="1"
grid:layout_rowWeight="1"
grid:layout_gravity="fill"
android:layout_margin="5dp"
android:scaleType="centerInside" />
As you can see in the comparison image below, the buttons now scale properly but the images are nowhere to be seen.
And if I change the <include>s to ImageButton, things work as expected.
<ImageButton
android:id="#+id/dialpad_view_btn1"
android:src="#drawable/dialpad_1"
android:layout_width="0dp"
android:layout_height="0dp"
grid:layout_columnWeight="1"
grid:layout_rowWeight="1"
grid:layout_gravity="fill"
android:layout_margin="5dp"
android:scaleType="centerInside" />
Is there a workaround to this?
Since I'm going to have 12 near-identical buttons in my dialpad, I'd really like to clean the XML up by including a "template" and only modifying the necessary attributes for each button (i.e. src and id).
EDIT
Trying to use styles, as suggested in one answer, did not work. None of the views that I applied the styles to get displayed. What's even more strange, even if I just apply the style to one of the views in the GridLayout, only the last view gets displayed (I've shortened down the sample code here to only two views for readability, in reality I have twelve).
Here's the style I tried using:
<?xml version="1.0" encoding="utf-8"?>
<resources
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:grid="http://schemas.android.com/apk/res-auto" >
<style name="dialPadButtonStyle">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">0dp</item>
<item name="grid:layout_columnWeight">1</item>
<item name="grid:layout_rowWeight">1</item>
<item name="grid:layout_gravity">fill</item>
<item name="android:layout_margin">5dp</item>
<item name="android:scaleType">centerInside</item>
<item name="android:background">#android:color/transparent</item>
</style>
</resources>
Maybe you can use a style to declare the common attributes and then set it for every button.
<style name="dialPadButtonStyle">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">0dp</item>
<item name="android:layout_columnWeight">1</item>
<item name="android:layout_rowWeight">1</item>
<item name="android:layout_margin">5dp</item>
<item name="android:src">#android:drawable/ic_menu_camera</item>
</style>
I also added: columnCount to 3 and rowCount to 4 for GridLayout and added 12 ImageButtons with that style. The final result is this:

Set all the viewgroups #null background by default

I am trying to achieve a simple thing instead of always setting the parent layout background to be null, have it null by default with by changing the application theme.
It should look something like the following style:
<style name="MyViewGroupsStyle" parent="android:Widget.ViewGroup">
<item name="android:background">#null</item>
</style>
And have my main theme include it
How do I achieve that?
The result should be like the follows:
<?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="match_parent"
android:orientation="vertical"
android:background="#null" >
</LinearLayout>
But without adding a style attribute to every layout(view group).

Are layout_alignParentRight or layout_alignParentLeft work for include layout?

I have a little problem.
I am creating a custom button widget
<?xml version="1.0" encoding="utf-8"?>
<Button
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/barBtn"
android:layout_width="wrap_content"
android:layout_height="32dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:textColor="#color/white"
android:background="#drawable/sel_btn_bar"
android:layout_centerVertical="true"
/>
Then I place it into the RelativeLayout
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:scaleType="fitXY"
android:src="#drawable/bar"/>
<include layout="#layout/segm_btn_stores"/>
<include
layout="#layout/btn_bar"
android:layout_alignParentRight="true"/>
</RelativeLayout>
But align doesn't work until I place include tag into RelativeLayout which I can move as I want. But this method is creating another problems: button will be narrower than if it was outside RelativeLayout. What can I do? I want to setup button params in one place.
And yes, I can add this line: android:layout_alignParentRight="true" to Button tag and it will work!
So the question is: why it works for Button tag and doesn't work for include tag?
Update
Button and fragments layout are there.
I think the android:layout_centerVertical attribute (for your Button layout) is only valid in a RelativeLayout (at least it's documented in the RelativeLayout.LayoutParams document: http://developer.android.com/reference/android/widget/RelativeLayout.LayoutParams.html), hence I wouldn't expect it to work in, say, a LinearLayout.
As of the case when the button gets narrower within the RelativeLayout than outside it, I don't really know what to say. Given the XML snippet you provided it seems like your RelativeLayout is the document root, i.e. moving the <include ... /> tag outside it would generate illegal XML, hence compile errors (if using Eclipse).
I would actually prefer to define button themes in custom styles, which you then could set up in a application global style xml, like this, for example:
<resources>
<style name="my_custom_style" parent="android:style/Theme.NoTitleBar">
<item name="android:buttonStyle">#style/my_button_style</item>
</style>
<style name="my_button_style" parent="#android:style/Widget.Button">
<item name="android:gravity">center_vertical|center_horizontal</item>
<item name="android:background">#drawable/my_button_background</item>
<item name="android:focusable">true</item>
<item name="android:clickable">true</item>
<item name="android:textColor">#color/my_custom_red_color</item>
<item name="android:textStyle">bold</item>
<item name="android:textSize">11sp</item>
</style>
</resources>
and then you'd set your custom style in the AndroidManifest.xml, like this:
<application
android:icon="#drawable/ic_launcher"
android:label="#string/application_title"
android:theme="#style/my_custom_style">
<!-- Your Activities, Services etc goes here -->
</application>
I'm confused about what your problem is. You are trying to take your view out of the relativelayout? If your making a layout, your views are going to have to belong to a ViewGroup. Align doesn't work because your view is outside of the ViewGroup which defines that attribute "RelativeLayout"

Categories

Resources