I am developing an Android app where I have two different views. Both views are actually canvas drawings (drawn programmatically) with a bunch of text views and buttons on top. The positions of these buttons and text views need to be changed depending on the view selection. I created a relative layout with my drawing and the buttons and text views. I use one of the text views as an anchor for the others and programmatically change its position.
Here is a part of the xml:
<TextView
android:layout_width="50dp"
android:layout_height="wrap_content"
android:id="#+id/tvAnchor"
android:layout_above="#id/btnCtrl"
android:layout_marginBottom="130dp"
android:textSize="15sp"
android:textColor="#color/lightGrey"
android:gravity="center"
android:text="#string/Select1"
android:background="#drawable/controls_border_not_active"
android:clickable="true"/>
<TextView
android:layout_width="50dp"
android:layout_height="wrap_content"
android:id="#+id/tvAlign"
android:layout_alignBottom="#id/tvAnchor"
android:layout_toStartOf="#id/tvAnchor"
android:layout_marginEnd="2dp"
android:textSize="15sp"
android:textColor="#color/lightGrey"
android:gravity="center"
android:text="#string/Select2"
android:background="#drawable/controls_border_not_active"
android:clickable="true"/>
In my main I have the following code to change the position of the text views accordingly:
private void PositionControls(){
RelativeLayout.LayoutParams lopAnchor = (RelativeLayout.LayoutParams) tvAnchor.getLayoutParams();
if (isView1Selected){
lopAnchor.resolveLayoutDirection(relativeLayout.getLayoutDirection());
lopAnchor.removeRule(RelativeLayout.ALIGN_START);
lopAnchor.setMargins(0,0,0,370);
lopAnchor.addRule(RelativeLayout.CENTER_HORIZONTAL);
}else{
lopAnchor.setMargins(0,0,0,300);
lopAnchor.removeRule(RelativeLayout.CENTER_HORIZONTAL);
lopAnchor.addRule(RelativeLayout.ALIGN_START,swDoIt.getId());
}
tvAnchor.setLayoutParams(lopAnchor);
}
Basically, in View1, the tvAnchor should be centered horizontally and in the other view it should be positioned off center - in the middle of 'center-to-right screen edge'. In order to do that when the second view is selected I remove the CENTER_HORIZONTAL rule and add a rule 'ALIGN_START' with a switch that is already positioned in the desired X coordinate. It works just fine. The problem occurs when View 1 is selected again and I switch from View 2 to View 1. In this situation I remove the ALIGN_START rule and add the CENTER_HORIZONTAL one. The thing is that tvAnchor remains aligned to the switch as if the ALIGN_START rule was not removed. I tried to get the direction of the layout, used requestLayout and other things that could think of, but nothing seems to remove that rule.
Did you check that there isn't coming some mystery values enabled??
I had case where is moved clockwidget place in layout
I did add ALIGN_PARENT_END and removed CENTER_IN_PARENT but when i set layout back i could not get clock widget centered.
RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) mTextClockWidget.getLayoutParams();
p.addRule(RelativeLayout.ALIGN_PARENT_END, 1);
p.removeRule(RelativeLayout.CENTER_IN_PARENT);
mTextClockWidget.setLayoutParams(p);
Then noticed that from somewhere my layout params got ALIGN_PARENT_RIGHT enabled and when tried to remove ALIGN_PARENT_END and enable CENTER_IN_PARENT it didn't work. So i had to also add remove for ALIGN_PARENT_RIGHT to get it work.
RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) mTextClockWidget.getLayoutParams();
p.removeRule(RelativeLayout.ALIGN_PARENT_END);
p.removeRule(RelativeLayout.ALIGN_PARENT_RIGHT);
p.addRule(RelativeLayout.CENTER_IN_PARENT, 1);
mTextClockWidget.setLayoutParams(p);
Related
I have 2 views and I'm showing them one below the other one like this(both of them children of the same parent:
<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">
<View
android:id="#+id/view1"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#00FF00"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="#+id/view2"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#0000FF"
app:layout_constraintTop_toBottomOf="#id/view1" />
</android.support.constraint.ConstraintLayout>
All works fine but when I change view1 position with setY method the view2 view not updating it's y position too.
I tried to call invalidate and requestLayout, but nothing helps.
How can I refresh or update the constraints after setting the position.
This is a little confusing, so bear with me. setY() does the following:
Sets the visual y position of this view, in pixels. This is equivalent to setting the translationY property to be the difference between the y value passed in and the current top property.
And setTranslationY() does this:
Sets the vertical location of this view relative to its top position. This effectively positions the object post-layout, in addition to wherever the object's layout placed it.
The key phrase here is "positions the object post-layout." In other words, the view that is the subject of setY()is positioned according to the layout then is moved to the new location based upon the argument to setY(). This does not result in another layout. In essence, although the view appears in its new location, it is, effectively, still in its original location. Invalidating and requesting another layout just causes the same layout to occur followed by the translation.
Setting the top margin as Ben P. suggests should work to move the view.
I am not exactly sure why setY() doesn't also update the second view, but you can work around it by setting the first view's top margin instead of calling setY():
ConstraintLayout.LayoutParams params =
(ConstraintLayout.LayoutParams) view1.getLayoutParams();
params.topMargin = 200;
view1.setLayoutParams(params);
Here is my solution:
Just move view1 using setTranslationY(), then assign view1 translationY to view2.
Java example:
view1.setTranslationY(10f);
view2.setTranslationY(view1.getTranslationY())
Kotlin version:
view1.translationY = 10f
view2.translationY = view1.translationY
When I use Android:margin to position textView half-outside it's parent, it acts weirdly: changes it's own size and text is moving inside textView box. How do I prevent it?
On image: left textView has cropped text at the end, and I don't want that.
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="16dp"
android:clipChildren="false">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:ellipsize="none"
android:singleLine="true"
android:textColor="#FFFFFF"
android:textSize="22.5dp"
android:layout_marginRight="200dp"
tools:text="0 TEXT VIEWVIEW"
tools:textColor="#000000" />
<...>
</FrameLayout>
FrameLayout always overlaps its Children. For effective placing widgets I suggest to use,
LinearLayout with layout_weight
arrange widgets relative to another widget by using RelativeLayout
You have two problems here:
You are using a FrameLayout. This means that when you keep increasing the margin of child, the view is gonna move out of the parent. Why? Because that's how FrameLayout is designed. Read documentation here: http://developer.android.com/reference/android/widget/FrameLayout.html
FrameLayout is designed to block out an area on the screen to display a single item. Generally, FrameLayout should be used to hold a single child view, because it can be difficult to organize child views in a way that's scalable to different screen sizes without the children overlapping each other.
So instead you could use RelativeLayout or LinearLayout.
The second problem you have is android:singleLine="true". This means that as the text increases in length, it will still be shown in a single line and hence the text will be clipped. So set this to false, or just remove this attribute.
android:singleLine="false"
i think you need to change the line:
android:singleLine="true"
to false.
I am using the Code from JawsWare - Overlay View to create a View that lays above everything.
This works fine, but I failed to adapt the given layout to my needs.
What I want: Two Phases.
First Phase: A button in the upper left corner that is always there above all other apps.
When this button is pressed, we enter the Second Phase:
The button is replaced by two images which are to be horizontally aligned at a certain distance from the top, again floating above everything else.
I have to admit that I dont really understand Android Layouting, but I've tried fiddling with a RelativeLayout and an ImageView but it seems buggy.
Additionally, I encountered a very strange behaviour: Even if the Image is only about 200x200 px in the upper left corner, nearly the whole screen is "blocked" by the View (it receives all TouchEvents, even though there shouldt be anything). It seems that if I position the Layout using Margins to float in the middle of the screen, everything to the left and top of the visible button is also receiving touch events and not letting them pass through to the underlying app (even though there is no visible content).
Any ideas to why this happens and how to circumvent that?
Secondly: How can I achieve the two layouts from earlier?
Edit 1: My Layout. (please keep in mind that I just copied this and then did what I thought was right)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="0dp"
android:onClick="overlayTextClicked"
android:padding="0dp"
android:id="#+id/overlay_layout_id"
>
<ImageView
android:id="#+id/imageview_info"
android:layout_width="200px"
android:layout_height="200px"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:scaleType="fitXY"
android:src="#drawable/picture_010512233437384578"
android:contentDescription=""/>
<TextView
android:id="#+id/textview_info"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:text="info"
android:textColor="#FFF"
android:orientation="vertical"
android:textAppearance="?android:attr/textAppearanceSmall" />
</RelativeLayout>
Afterwards I am trying to set the RelativeLayouts Gravity to TOP | CENTER_VERTICAL with a Top-Margin of 200px.
I believe what's going on here is your TextView is filling out the entire screen.
wrap_content bounds the size of a View with its content. match_parent fills a view to as big as it can get (i.e., whatever size the container is bound to).
So in this case, your RelativeLayout is does not have a max size it's bound to. Your TextView is going to try to get as big as it can get, so it's going to fill the screen. Likewise, the RelativeLayout is going to blow up to that size to wrap around the TextView.
Also, RelativeLayout doesn't really respond to Gravity well. That is used in LinearLayout and FrameLayout containers a lot, but RelativeLayout relational rules like "CENTER_IN_PARENT" are going to override whatever Gravity you set (if you set Gravity.RIGHT and "CENTER_IN_PARENT", then one has to win out I guess).
My layout is the following:
<TextView
android:id="#+id/display_city"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/pollenType"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_below="#+id/get_pollen_index"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_marginTop="51dp"
android:textSize="40sp" />
As you can tell, Philadelphia, PA is left-aligned. No matter what I change, whether it's centering horizontal and vertical to true, it stays left-aligned.
I have tried changing the layout via the XML and graphical user interface. In the graphical user interface, it indeed is "centered", but it remains non-centered. My layout positions are consistent across all my textviews, so I am unsure as to why this particular TextView is not centered.
Two options...
One: Give the TextView android:layout_width="wrap_content"
Two: Keep the android:layout_width="match_parent" and use android:gravity="center_horizontal"
layout_gravity defines gravity of the view within its parent. Your textView already takes the full width because of match_parent, so centering it horizontally inside its parent does nothing.
gravity, on the other hand, defines the gravity of its contents.
You can center the text using the gravity xml attributes :
android:gravity="center"
Your width equals match_parent and therefore the edges of your TextView already touch the edges of the parent view. You should rather center the text in the TextView with android:gravity="center".
You're telling the display_city TextView to be as wide as the screen.
android:layout_width="match_parent"
However, its text is left aligned by default. That's why it looks this way.
You have two alternatives for what you want:
Keep the width as match_parent and center the text inside the TextView (with gravity).
Set the width to wrap_content and center the View inside its parent (with layout_gravity).
I am having a spot of bother with a fairly simple layout. Here it is:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/id1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:ellipsize="end"
android:maxLines="1"/>
<TextView
android:id="#+id/id2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"/>
</LinearLayout>
3 Questions:
How do I center vertical both TextViews (or perhaps better said, the text within those views) within the parent LinearLayout? The left view is vertically centered OK, but the right one (because it has a smaller font) is not. It seems to be centered vertically at the top. I obviously tried playing with layout_gravity of the second view but that makes no difference whatsoever. The only way I can solve it is to wrap the second TextView in a LinearLayout with its layout height parameter set to match_parent (but is this the correct way of doing this?)
Similarly, I want the View on the left horizontally centered on the left, and the View on the right horizontally centered on the right. Currently the right View is placed immediatly next to the left one. The only way I can solve this is by adding something like this inbetween the two text views:
<TextView
android:layout_width="0dip"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="">
basically acting as a spacer which decreases in size depending on the legth of the text in both TextViews
I want the text in the left View to be truncated if the combined text of the Views does not fit horizontally. No wrapping onto a new line. Currently the text in the left View simply "pushes" the right one out of the parent. No idea how to achieve that (apart from adding android:maxLines="1" to stop the text from wrapping). I have tried android:ellipsize="end" but that does not seem to have any effect.
Best way is to use Relative layout , but still if you want to do the same thing in Linear layout than do some changes in your xml file
-First is set Linear layout hight as match parent :
<LinearLayout android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="horizonatal">
-Second for making the views visible at centre vertical do
android:layout_gravity="center_vertical"
same property android:layout_gravity = "center_horizontal" , you have to add in second text view also.
It will make your both text view appear at centre vertical but one next to other.
To make the second view appear on right I think you can add
android:layout_marginLeft="xx dp"
put some value in place of xx.
For your third question about truncating your text, you should give some size to your TextView not wrap content..Like android:layout_width ="25dp"
and then use android:ellipsize="end".
I guess you will get that..Actually I am in hurry,time to leave the office.