I have following setup.
There is an edittext with controllers on left and right for resizing.
When user resizes by touching and moving the left controller, I am calculating the distance between moved x-coordinate and the mid-point of right side of edittext.
The idea is that the right side has to remain static, where as on resizing from left, the left bound has to increase of decrease like wise. I am assigning new width and center to edittext on resize from left as follows:
ivLeftControl.setPivotX(traversedPoint.x);
editTextViewNew.setGravity(Gravity.CENTER);
editTextViewNew.setWidth((int) (traversedWidth-ivLeftControl.getWidth()*2));
editTextViewNew.setPivotX(centerX - (traversedWidth - originalWidth)/2);
But the resize is happening only along the right side of edittext, instead of happening along left side. Even when I dont change the pivot, the resize happens along right side only.
Any suggestion on how this features could be addressed the best?! Keeping in mind, the entire setup of controllers and edittext is enveloped using a parent layout.
Solution - MarginLayoutParams
you need to create MarginLayoutParams and then set height , width , margins in it and set to your view.
MarginLayoutParams layoutParams = (MarginLayoutParams) getLayoutParams();
layoutParams.width = mPixelSize;
layoutParams.height = mPixelSize;
layoutParams.setMargins(mLeftMargin, mTopMargin, 0, 0);
requestLayout();
According to the docs for the View class:
The geometry of a view is that of a rectangle. A view has a location, expressed as a pair of left and top coordinates, and two dimensions, expressed as a width and a height. The unit for location and dimensions is the pixel.
It is possible to retrieve the location of a view by invoking the methods getLeft() and getTop(). The former returns the left, or X, coordinate of the rectangle representing the view. The latter returns the top, or Y, coordinate of the rectangle representing the view.
In addition, several convenience methods are offered to avoid unnecessary computations, namely getRight() and getBottom(). These methods return the coordinates of the right and bottom edges of the rectangle representing the view. For instance, calling getRight() is similar to the following computation: getLeft() + getWidth().
My interpretation of the above is that the View's position is controlled by its "Left" and "Top" values, while its width and height are controlled by its "Width" and "Height" values. This seems especially clear considering that last sentence, where "Right" is derived by adding Left and Width.
Despite this, when I use setLeft() and/or setTop() to change the position of the View, the SIZE of the View changes on screen! Meanwhile, the lower right corner of the View stays anchored to its original spot. This behavior implies that "Right" and "Bottom" are actual values, not derived as described in the docs.
So what is really going on here? The docs say one thing, but the behavior says the opposite. What is the proper way to reposition a View?
EDIT: I added a RelativeLayout:
myParams = new RelativeLayout.LayoutParams(300,300);
myParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
myParams.addRule(RelativeLayout.CENTER_VERTICAL);
myView.setLayoutParams(myParams);
...to create a View 300x300 centered on the screen. Works perfectly. But examining that RelativeLayout, the location seems to be controlled by leftMargin and topMargin - yet both are zero! That raises the questions of 1) how can you examine the LayoutParams to know where the View is right now, and 2) how can you alter the LayoutParams to move it to a different location?
EDIT: As an experiment, I added an onTouch method to the View and did this within it (excerpt):
if (MotionEvent.ACTION_MOVE == iAction) {
myParams = (RelativeLayout.LayoutParams) v.getLayoutParams();
myParams.leftMargin = 0;
myParams.topMargin = 0;
v.setLayoutParams(myParams);
}
...on the theory that my vertically and horizontally centered View would then move to the upper left corner of the screen. Result: It didn't move at all. Not exactly surprising, since .leftMargin and .topMargin were already zero, but I wanted to try it just in case there was some magic hiding here.
Other suggestions?
I want to have an EditText in focus so it is edited, but also invisible. In other words, all the user will see is the keyboard.
Is that possible?
AFAIK, an invisibility Edittext cannot have a view( I have never tried) so the workaround for you is
You can set a transaparent background for edittext to achieve this.
youredittext.setBackgroundResource(android.R.color.transparent);
or you can directly set the attribute in XML like this
android:background="#null"
I know I might be late, but recently I had to face a similar problem.
The solution could also be this one (use in styles.xml or in the layout):
android:layout_width = 0dp
android:layout_height = 0dp
That will also let your EditText be still focusable.
My two alternate approaches:
Approach 1: Fade it out
view.animate().alpha(0.0f).setDuration(0);
and fade it in when you want it back
view.animate().alpha(1.0f).setDuration(0);
Setting duration to 0 ensures it happens instantaneously.
Approach 2: Set the view outside the screen
LayoutParams params = view.getLayoutParameters();
int offset = -80; // offset from the screen border, choose your own
params.setMargins(0, 0, offset, 0); // left, top, right, bottom
view.setLayoutParams(params);
and do
params.setMargins(0, 0, 0, 0); // left, top, right, bottom
view.setLayoutParams(params);
when you want it back.
Hi am developing android application with graph view. i got an open source graph application to show my values with graph lines. Here i am face problem while adding view. i am not able to add my custom view properly with relative layout.
Here i attached my custom view alignment .
In that image point 1. is my result while trying to add mt custom view.
But i need to add that as shown in 2. part.
my custom view is like shown in 3 .part
I am getting that line starting x,y and ending x,y values. I tried with that values but i got result as 2 part. Please provide me any suggestion
Or let me know is there any alignments required.
My code is like
View View v1=infalter.inflate(R.layout.bullet, null);
RelativeLayout.LayoutParams rl=new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
rl.setMargins(myX,myY, 0, 0);
mRelative.addView(v1,rl);
You are setting the margins for the x, y point that you got, so the view will start at x, y at the top left, which is what you got. You want to align the bottom center of the view, so you need to calculate this.
So:
top= y - viewHeight
left= x - viewWidht/2
I don't know what your values of myX and myY are, but it looks like you're trying to align the top right with your x and y margins applied to the right and top respectively. If this is indeed the case, you're probably better off with something like this:
rl.setMargins(0, 0, myX, myY);
rl.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
The arguments to setMargins go in order as follows: left, top, right, bottom. If your myX value is the right margin and you want the object right aligned, the code above will specify these two preferences.
While playing with a relative layout to provide a help screen overlay I ran into weird things and had to set margins relative to the bottom right and not upper left. So I had a rule to align the view at the bottom and the right + the margins.
Maybe that will help.
How can I change the position of view through code? Like changing its X, Y position. Is it possible?
For anything below Honeycomb (API Level 11) you'll have to use setLayoutParams(...).
If you can limit your support to Honeycomb and up you can use the setX(...), setY(...), setLeft(...), setTop(...), etc.
Yes, you can dynamically set the position of the view in Android. Likewise, you have an ImageView in LinearLayout of your XML file. So you can set its position through LayoutParams.But make sure to take LayoutParams according to the layout taken in your XML file. There are different LayoutParams according to the layout taken.
Here is the code to set:
LayoutParams layoutParams=new LayoutParams(int width, int height);
layoutParams.setMargins(int left, int top, int right, int bottom);
imageView.setLayoutParams(layoutParams);
There are different valid answers already, but none seems to properly suggest which method(s) to use in which case, except for the corresponding API level restrictions:
If you can wait for a layout cycle and the parent view group supports MarginLayoutParams (or a subclass), set marginLeft / marginTop accordingly.
If you need to change the position immediately and persistently (e.g. for a PopupMenu anchor), additionally call layout(l, t, r, b) with the same coordinates. This preempts what the layout system will confirm later.
For immediate (temporary) changes (such as animations), use setX() / setY() instead. In cases where the parent size doesn't depend on WRAP_CHILDREN, it might be fine to use setX() / setY() exclusively.
Never use setLeft() / setRight() / setBottom() / setTop(), see below.
Background:
The mLeft / mTop / mBottom / mRight fields get filled from the corresponding LayoutParams in layout(). Layout is called implicitly and asynchronously by the Android view layout system. Thus, setting the MarginLayoutParams seems to be the safest and cleanest way to set the position permanently. However, the asynchronous layout lag might be a problem in some cases, e.g. when using a View to render a cursor, and it's supposed to be re-positioned and serve as a PopupMenu anchor at the same time. In this case, calling layout() worked fine for me.
The problems with setLeft() and setTop() are:
Calling them alone is not sufficient -- you also need to call setRight() and setBottom() to avoid stretching or shrinking the view.
The implementation of these methods looks relatively complex (= doing some work to account for the view size changes caused by each of them)
They seem to cause strange issues with input fields: EditText soft numeric keyboard sometimes does not allow digits
setX() and setY() work outside of the layout system, and the corresponding values are treated as an additional offset to the left / top / bottom / right values determined by the layout system, shifting the view accordingly. They seem to have been added for animations (where an immediate effect without going through a layout cycle is required).
There is a library called NineOldAndroids, which allows you to use the Honeycomb animation library all the way down to version one.
This means you can define left, right, translationX/Y with a slightly different interface.
Here is how it works:
ViewHelper.setTranslationX(view, 50f);
You just use the static methods from the ViewHelper class, pass the view and which ever value you want to set it to.
I would recommend using setTranslationX and setTranslationY. I'm only just getting started on this myself, but these seem to be the safest and preferred way of moving a view. I guess it depends a lot on what exactly you're trying to do, but this is working well for me for 2D animation.
You can try to use the following methods, if you're using HoneyComb Sdk(API Level 11).
view.setX(float x);
Parameter x is the visual x position of this view.
view.setY(float y);
Parameter y is the visual y position of this view.
I hope it will be helpful to you. :)
For support to all API levels you can use it like this:
ViewPropertyAnimator.animate(view).translationYBy(-yourY).translationXBy(-yourX).setDuration(0);
Set the left position of this view relative to its parent:
view.setLeft(int leftPosition);
Set the right position of this view relative to its parent:
view.setRight(int rightPosition);
Set the top position of this view relative to its parent:
view.setTop(int topPosition);
Set the bottom position of this view relative to its parent:
view.setBottom(int bottomPositon);
The above methods are used to set the position the view related to its parent.
Use LayoutParams.
If you are using a LinearLayout you have to import android.widget.LinearLayout.LayoutParams, else import the proper version of LayoutParams for the layout you're using, or it will cause a ClassCastException, then:
LayoutParams layoutParams = new LayoutParams(int width, int height);
layoutParams.setMargins(int left, int top, int right, int bottom);
imageView.setLayoutParams(layoutParams);
NB: Note that you can use also imageView.setLeft(int dim), BUT THIS WON'T set the position of the component, it will set only the position of the left border of the component, the rest will remain at the same position.
Use RelativeLayout, place your view in it, get RelativeLayout.LayoutParams object from your view and set margins as you need. Then call requestLayout() on your view. This is the only way I know.
In Kotlin you can do it as below;
view
.animate()
.x(50f)
.y(100f)
.duration = 500L
I found that #Stefan Haustein comes very close to my experience, but not sure 100%. My suggestion is:
setLeft() / setRight() / setBottom() / setTop() won't work sometimes.
If you want to set a position temporarily (e.g for doing animation, not affected a hierachy) when the view was added and shown, just use setX()/ setY() instead. (You might want search more in difference setLeft() and setX())
And note that X, Y seem to be absolute, and it was supported by AbsoluteLayout which now is deprecated. Thus, you feel X, Y is likely not supported any more. And yes, it is, but only partly. It means if your view is added, setX(), setY() will work perfectly; otherwise, when you try to add a view into view group layout (e.g FrameLayout, LinearLayout, RelativeLayout), you must set its LayoutParams with marginLeft, marginTop instead (setX(), setY() in this case won't work sometimes).
Set position of the view by marginLeft and marginTop is an unsynchronized process. So it needs a bit time to update hierarchy. If you use the view straight away after set margin for it, you might get a wrong value.
One thing to keep in mind with positioning is that each view has an index relative to its parent view. So if you have a linear layout with three subviews, the subviews will each have an index: 0, 1, 2 in the above case.
This allows you to add a view to the last position (or the end) in a parent view by doing something like this:
int childCount = parent.getChildCount();
parentView.addView(newView, childCount);
Alternatively you could replace a view using something like the following:
int childIndex = parentView.indexOfChild(childView);
childView.setVisibility(View.GONE);
parentView.addView(newView, childIndex);