So the initial layout consists of a large circular "parent" button and multiple circular "child" buttons that are centered behind the parent button. So all the child buttons share the same center as the parent button. The reason for this layout is so during runtime, I can move the child buttons in and out of the parent button using translateX and translateY.
However, I'm stuck on the initial layout. How can I center the child buttons to the center of the parent button without hardcoding any child attributes?
Make the views the same size and add padding to the children so they get reduced. If the views are all in the same position the layout will look as you wish. Anyways, you can always change the properties in code.
I solved this myself using a container RelativeLayout as an anchor, with the parent button and all child buttons given android:layout_centerInParent. Then, to solve the issue of the child buttons disappearing when leaving the container, I gave the container android:clipChildren(false) and also set clipChildren to false on all of its ancestors as well.
Note that the container has to be bigger than all of its child elements, or all the child elements will be clipped to the same dimensions, even when they move outside of the container! To solve this, I gave the container a width and height of wrap_content.
Thus, all my child buttons were centered in the parent button no matter where I positioned the parent, and the child buttons were free to move around as well.
EDIT
A major flaw in this is that buttons can't recieve touch events if they are outside of their parent. To fix this, you can either use event coordinates or make the parent container big enough to always encompass the child elements (maybe twice the screen width/height?)
Here is the code:
res/layout/listfragment.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false" >
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<RelativeLayout
android:onClick="onButterflyMenuClicked"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_marginBottom="20sp"
android:layout_marginRight="15sp"
android:clipChildren="false" >
<Button
android:id="#+id/btn_north_1"
style="#style/PeekabooButton"
android:text="1st"
android:translationY="-65sp" />
<Button
android:id="#+id/btn_north_2"
style="#style/PeekabooButton"
android:text="2nd"
android:translationY="-115sp" />
<Button
android:id="#+id/kingbutton"
android:layout_width="65sp"
android:layout_height="65sp"
android:layout_centerInParent="true"
android:gravity="center_vertical|center_horizontal"
android:textSize="16sp"
android:text="KING" />
</RelativeLayout>
</FrameLayout>
res/values/styles.xml
<style name="PeekabooButton">
<item name="android:layout_width">45sp</item>
<item name="android:layout_height">45sp</item>
<item name="android:layout_centerInParent">true</item>
<item name="android:textSize">10sp</item>
</style>
Use android:gravity="center" on all views after putting them all inside a FrameLayout (possibly nesting the FrameLayout inside another layout). You can then offset each Button's position in its parent by changing the layout_margin* values. Or you could translate the parent FrameLayout that holds all the Buttons however you wish.
To make the button circular, change your button's android:background value to point to a custom selector.
Related
I have two layouts. The inner one wraps its contents for height and matches parent for width.
<RelativeLayout
android:id="#+id/lytMoreInfo"
android:layout_width="match_parent"
android:layout_height="0dp" >
<LinearLayout
android:id="#+id/lytMoreInfoButtons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:orientation="horizontal" >
<!-- OTHER VIEWS HERE -->
</LinearLayout>
<!-- OTHER VIEWS HERE -->
</RelativeLayout>
The outer layout, instead, need to be animated for its height, kinda open to show its content. To do that, I use a value animator that change the height of the outer layout. The animation works correctly.
The problem is that the views inside the inner layout are stretched during the animation, because the inner layout is resized together with the outer layout during the animation.
So my question is, is there a way to specify the inner layout to wrap its content (for height), regardless the size of the outer layout?
Its not the proper solution to make height/width fix. As it will
varies with device. You can use scrollview for that.
I have a Relativelayout that is clickable. I have an element inside it (an ImageButton) that I also want to be clickable.
The layout was clickable just fine until I added the ImageButton; now only that is clickable.
I have tried all combinations of focusable and focusableInTouchMode = true and false in both elements (I tried only in xml layout). How can I make them BOTH clickable?
My code; note this is inside a ListView and each row has this; there is a non-clickable LinearLayout surrounding this:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/row_selector"
android:duplicateParentState="true"
android:paddingBottom="10dp" >
// several TextViews edited out
<ImageButton
android:id="#+id/ibMenu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="#color/row_overflow_state"
android:contentDescription="menu"
android:src="#drawable/ic_action_overflow" />
</RelativeLayout>
Use this to your parent
android:addStatesFromChildren="true"
if used this then don't use the following otherwise you will get stuck overflow exception
what about setting this to your child
android:duplicateParentState="true"
I had faced the same problem. I had a rectangular view which had to receive clicks for some other functionality, as well as an ImageView inside the rectangle, had to receive clicks for some other functionality.
Used Relative Layout for this purpose where Relative Layout was clickable=true and having the property
android:descendantFocusability="afterDescendants"
which means that the layout will receive focus only if none of its descendants want.
So parent, as well as the child, was clickable for two different functionalities.
Set android:descendantsFocusability="blocksDescendants" on the
RelativeLayout.
Okay so I have a horizontal Relative Layout on a ListView and I want a margin between the different Rows on the ListView but I have one problem. I have a button that is being pushed to the far right and I want the click zone to be as big as possible. If there was no margin on the root element of relative layout I would be fine and my button would take up the entire height of the row. But the problem is because there is margin there is an opportunity for the user to click above and below the button where the margin is to trigger the OnItemClick event which isn't the desired functionality of the button which could get frustrating at times.
Example:
<RelativeLayout android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_marginLeft="5dp">
<ImageButton
android:id="#+id/list_button"
android:layout_alignParentRight="true"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:src="#drawable/btn"
android:background="#android:drawable/list_selector_background" />
</RelativeLayout>
Any help would be greatly appreciated obviously its possible I just can't see it sadly.
One way around this is to wrap the ImageButton in a transparent layoutview (relative, linear, frame - depending on your needs) that does take up the whole space (i.e. android:layout_width and android:layout_height are fill_parent). Then add the same click handler to the outer layout as you do for the button.
I wanna put image in top of View and a listview bottom of it.
what's best and correct way?
LinearLayout?RelativeLayout?
and with which attribute?
layout_gravity="top"?
layout_alignParentTop="true"?
please give me a snipped code and a brief description about:
what's different between layout_gravity="top" and android:layout_alignParentTop="true"?
I wanna put image in top of View and a listview bottom of it. what's
best and correct way?
If you want to place a ListView below an ImageView positioned at the top of the current view then you could use both layouts, it isn't any real difference.
The layour_gravityis used to place the children relative within its parent bounds(the Relativelayout doesn't have this attribute). For example you could use a LinearLayout with orientation vertical which will stack your two children one on top of the other like you want. Also layout_gravity="top" is ignored for a vertical orientated LinearLayout as it doesn't make sense, so you could remove it from the layout completely:
<LinearLayout android:orientation="vertical">
<!-- the layout_gravity is useless int this case and could be removed-->
<ImageView android:layout_gravity="top"/>
<ListView />
</LinearLayout>
layout_alignParentTop is a placement rule for children of RelativeLayout(only for this type of layout!) which tells them to position aligning the top of the children with the top of the parent RelativeLayout. In this case, to stack the children you would do:
<RelativeLayout>
<!-- you could remove the layout_alignParentTop attribute because by default the Relativelayout will position it's children there -->
<ImageView android:id="#+id/imageId" android:layout_alingParentTop="true" />
<!-- Position this child below the other -->
<ListView android:layout_below="#id/imageId"/>
</RelativeLayout>
I need to implement the layout as in the picture. Parent and Sibling are in a vertical LinearLayout. So I need to make a child view to overlap it's parent. Can I do that in android?
If:
sibling is a sibling of parent
parent is a ViewGroup
and you really want child to be a child of parent
then maybe you could consider using android:clipChildren set to false on parent.
I was actually just looking at an example of a FrameLayout that had a TextView overlaid on top of an ImageView. So, there are obviously multiple ways to get it done. Your next question might be which one is best ... to that I have no idea, but here's a guy that might:
http://www.curious-creature.org/2009/03/01/android-layout-tricks-3-optimize-part-1/
Just contain them all within a RelativeLayout, and remember the draw order is top to bottom, so put the top most view on the bottom of the XML definition.
If you use a RelativeLayout you should have no problem achieving this effect. By default it will stack all of its children on top of each other in the top left corner if you don't supply them with android:layout parameters. So it will definitely support overlapping children. You'd just have to figure out what the best way to tell it where the child should go on the screen relative to something else.
There are at least two layouts that can do that. AbsoluteLayout and RelativeLayout. I suggest that you put your views in a RelativeLayout and add them with LayoutParams that specify their offset form the top and left of the parent:
RelativeLayout.LayoutParams rlp;
label = new TextView(ctx);
label.setBackgroundColor(0x00000000);
label.setTextColor(0xFF7ea6cf);
label.setTextSize(13);
label.setGravity(Gravity.LEFT);
label.setText("Examples:\n- Fentanyl\n- Dilaudid 2 mg PO q 4 hours prn moderate pain");
rlp = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT,100);
rlp.topMargin=189;
rlp.leftMargin=30;
rlp.rightMargin=30;
rlParent.addView(label,rlp);
In my case, I have to set android:clipCildren to be false on the parent of parent.
i.e.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:id="#+id/parent1">
<FrameLayout
android:id="#+id/parent2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="64dp"
android:background="#android:color/holo_blue_bright">
<View
android:id="#+id/This_is_the_view_I_want_to_overlap_parent2"
android:layout_width="160dp"
android:layout_height="80dp"
android:layout_gravity="top|start"
android:layout_marginTop="-40dp"
android:background="#000000" />
</FrameLayout>
</FrameLayout>