Can a child element in Android ignore its containing style? - android

I have a containing LinearLayout which has a style associated with it that gives the container 20dp of padding. This is great for 99% of the elements contained inside. There may be 1 element which I'd like to have extend across the screen (android:layout_width="match_parent") and ignore the padding set by the containing LinearLayout. Is this possible? Or, do I need to remove the style from the containing LinearLayout and apply it to every other element individually?
(some attributes excluded for brevity)
<LinearLayout
android:padding="20dp">
<TextView
android:id="#+id/txtTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/txtDate"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!-- Would like this to ignore padding, extend fully. -->
<TextView
android:id="#+id/txtExperienceTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="#style/sub_header_title" />
</LinearLayout>

Yes, you can't really pick and choose like that. I'd remove the padding from the LinearLayout and apply margin to the children.
To expand on what loeschg said in the comment below, I'd recommend using a "child style". Since it looks like each child will only need left/right margins, it will save some typing and look cleaner to just have one line on each child, rather than setting both left and right separately on each.

You cannot reach out of the container. Apply a style to the elements rather than the container if you have an exception.

Yes It will ignore it, the layout that you wrote is something like this.
General thinking
int x = 7;
x = 20;
Show me that x = 7; ---You wanted to do something like this whit your layout
<TextView
android:id="#+id/txtTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/txtDate"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!-- Would like this to ignore padding, extend fully. -->
<TextView
android:id="#+id/txtExperienceTitle"
style="#style/sub_header_title" // --- Style before adding laout_width if you want the layout to be match_parent
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>

Related

Design UI Android (Element between CardViews)

My question is more informative. I just want to know how to make such design. I found android application called "weather timeline" and inside of that application between CardViews (as I understand) they used this element which I pointed out in picture below. I think its just ImageView but how to set it as here. It will be interesting to know any idea about that! Thanks for attection!
You could easily do it in the following way.
Let us assume that we are using a collection view where the card element is one type and the black gap with text in the middle is the other.
The cardView would look something like this
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="#dimen/circle_radius_half_size"
android:layout_marginBottom="#dimen/circle_radius_half_size">
</CardView>
<ImageView
android:layout_width="#dimen/circle_radius"
android:layout_height="#dimen/circle_radius"
android:layout_align_parentLeft="true"
android:layout_marginLeft="24dp"
android:src="#drawable/circle"
android:rotation="180"/>
<ImageView
android:layout_width="#dimen/circle_radius"
android:layout_height="#dimen/circle_radius"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginLeft="24dp"
android:src="#drawable/circle" />
</RelativeLayout>
Where drawable circle looks something like this
and the layout for black grape with text in the middle looks something like this
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp">
<View
android:layout_width="#dimen/width_of_line"
android:layout_height="match_parent"
android:layout_margin_left="#dimen/line_margin"
android:background="#color/white" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_margin_left="#dimen/line_margin" >
<!-- The Text View Layouts Here -->
</LinearLayout>
</LinearLayout>
Where line_margin is 24dp + CircleHalfSize - LineWidthHalfSize
Of course the CircleHalfSize and LineWidthHalfSize are in DP
Now it is just a question of arranging them properly via the adapter. Personally I would use the RecyclerView. Great Flexibility.
Also this way if you wanted the bubbles to be gone, all you have to do is set the bubble ImageView's visibility to GONE and that too you can do specifically either for the top or the bottom.
I'm pretty sure that this could be accomplished using 9-patched images.
By determining the way to draw your patches and how to set them as a background for your layouts you'll get the same result.
Quick illustrated demo
By adjusting the two backgrounds exactly one above the other you'll get the UI you posted.
Hope it helps.
Further reading
To see how to draw 9-patched images here is a documentation.
This can be accomplished by using a RelativeLayout. Then you can align all your views however you want inside your main view.
Thus, you would layout Card1 at the top, then layout the bubble connector with your marginTop attribute (remember this is from the top of the container, not from the bottom of the card) to layout that view wherever you want.
Basically, you would use a single RelativeLayout, then align the various views within that container wherever you want in relation to each other (or really in relation to the the top of your main view).
Checkout this Pseudo-code:
<RelativeLayout >
<CardView
layout_height = "8dp"
alignParentTop = "true"
/>
<!-- Connector Image -->
<ImageView
alignParentTop = "true"
layoutMarginTop = "10dp" <!-- or whatever it takes to align properly with CardView -->
/>
</RelativeLayout>

Adding Views to layout runtime, going ahead when the line ends: How To?

I need to add views in a layout going to a new line at the end of one, filling every line from left to right. Imagine the layout is a paper and every word you write is a textview, and you have to write a long text. I don't even know which kind of layout I should use, does anyone have an idea?
I think you're looking for a LinearLayout set to an horizontal orientation. Something like the below. I have used two TextViews but you can use whatever kind of view you'd like. They will stack horizontally to the right.
<?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="horizontal"
android:gravity="left" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Item 1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Item 2" />
<!-- etc. -->
</LinearLayout>
I would go with nested LinearLayouts. Start with a vertical LinearLayout and a horizontal LinearLayout inside it. Then to add a View:
measure the View (let's call it 'myView').
Then:
if(currentHorizontalLayout.getChildCount==0 ||
myView.getWidth() > currentHorizontalLayout.getWidth()-currentHorizontalLayout.getChildAt(currentHorizontalLayout.getChildCount()-1)).getRight()){
currentHorizontalLayout = new LinearLayout(getContext());
verticalLayout.addView(currentHorizontalLayout);
currentHorizontalLayout.addView(myView);
}

Programmatically added LinearLayouts not equally spaced

I am having some spacing trouble when building part of my UI programmatically in Android 4.0. I am trying to add stylized buttons to a stylized LinearLayout. To space the buttons equally, each one is wrapped in a LinearLayout with a weight of 1. I started with a layout defined in XML (somewhat of a proof of concept,) which renders like I expect:
<LinearLayout android:id="#+id/dialog_footer"
android:layout_width="500dp"
android:layout_height="wrap_content"
android:background="#drawable/dialog_footer">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal"
android:gravity="center">
<Button android:id="#+id/cancel"
style="#style/Button"
android:layout_width="130dp"
android:layout_height="38dp"
android:text="Cancel" />
</LinearLayout>
<!-- Another LinearLayout with a nested Button like the one above -->
</LinearLayout>
To add buttons programmatically, I removed the inner LinearLayouts and put them in their own layout file that I can inflate and add to the outer LinearLayout in Java. It is nearly identical.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal"
android:gravity="center" >
<Button android:id="#+id/button"
style="#style/Button"
android:layout_width="130dp"
android:layout_height="38dp" />
</LinearLayout>
And this is roughly how I'm adding buttons in code:
LinearLayout dialogFooter = (LinearLayout)dialogView.findViewById(R.id.dialog_footer);
LinearLayout wrappedButton = (LinearLayout)getLayoutInflater().inflate(R.layout.dialog_button_wrapped, null);
Button button = (Button)wrappedButton.findViewById(R.id.button);
button.setText(R.string.button_one_text);
// button.setOnClickListener(...);
dialogFooter.addView(wrappedButton);
The buttons appear but now they are grouped together and shifted to the left. Is there something Android does when it parses a Layout that I would need to do myself if I'm adding to the dialog_footer? Since weights come into play here, I thought that calling setWeightSum() on the container I'm adding to (dialog_footer) might be necessary but that didn't help. Does anyone have any ideas what might be causing the difference between the XML and Java approaches?
I believe this is your problem:
LinearLayout wrappedButton = (LinearLayout)getLayoutInflater().inflate(R.layout.dialog_button_wrapped, null);
The null should be replaced with the parent view , so that it will get the layoutParams you want to set for it .
Another thing is about the weight you set - you should set the width/height to 0px so that the weight won't cause the layout process work in a weird/inefficient way .
BTW , you can remove the inner layout (that has the button) and use a single button instead. just set the layout_gravity there to center_horizontal .

Collapsing margins in Android layouts

Is it possible to make margins collapse in Android? Let's say I have a LinearLayout and add three TextViews, each with an android:layout_margin of 10dp. I get the following result:
However, I'd like to get this result:
I know that I could workaround this by setting different top/bottom margins for the different items:
set the top margin of the first item and the bottom margin of the last item to 10dp,
set the remainding top/bottom margins to 5dp,
but that makes the design more complicated (especially if the TextViews are dynamically created). Is there some way to make the margins behave like in CSS? (For an explanation of why this makes sense, see: What is the point of CSS collapsing margins?)
What I typically do to fix this myself, is to simply cut the View's (i.e. your TextView) margin in half, and add that same number as padding to the containing ViewGroup (i.e. your LinearLayout). This way you will end up with even spacing around all items. For example:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="5dip"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dip"
android:text="I'm a TextView!"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dip"
android:text="I'm a TextView!"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dip"
android:text="I'm a TextView!"
/>
</LinearLayout>
Posting a solution for someone who might need this in future. Works for static as well as AdapterViews where list items are dynamic.
Example parent container:
<RecyclerView
----
android:padding_top="10dp"
android:padding_start="10dp"
android:padding_end="10dp"
----
>
</RecyclerView>
The padding ensures the spacing from top, left & right of the window.
Only thing remaining now is the vertical gap between two consecutive children & bottom gap after last child.
Example child / item view:
<RelativeLayout
----
android:margin_bottom="10dp"
----
>
<DynamicChild1 />
<DynamicChild2 />
</RelativeLayout>
For this question specifically, the child view will just be a TextView with bottom margin.
This will give you the exact output as expected in the question.

position android widgets

How to place a widget exactly at the required location, say for example in relative layout, I am trying to place two buttons one below another and then increase width of button, but using drag and drop in eclipse, it resizes other widgets in the layout. In short, I want to place widget independent of parent widgets, anywhere in layout to visualize the UI I want to design. Thanks for your help.
You could use RelativeLayout and margins to position precisely. For example:
<RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent">
<!-- Use android:layout_marginLeft for X and android:layout_marginTop for Y -->
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="50dp" android:layout_marginTop="50dp"
android:text="Button1" />
</RelativeLayout>
You could also use an AbsoluteLayout, which is actually probably more suited for this:
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent">
<!-- Use android:layout_x for X and android:layout_y for y -->
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="50dp" android:layout_y="50dp" android:text="Positionable" />
</AbsoluteLayout>

Categories

Resources