Android에서 뷰 위치를 동적으로 설정하려면 어떻게해야합니까?


102

코드를 통해보기 위치를 변경하려면 어떻게해야합니까? X, Y 위치를 변경하는 것과 같습니다. 가능할까요?

답변:


117

Honeycomb (API 레벨 11) 이하의 경우 setLayoutParams(...).

당신이 벌집에 지원을 제한 할 수있는 경우 사용할 수있는 최대 setX(...), setY(...), setLeft(...), setTop(...), 등


40
setTop () developer.android.com/reference/android/view/… 의 문서에서 : sets the top position of this view relative to its parent. This method is meant to be called by the layout system and should not generally be called otherwise, because the property may be changed at any time by the layout.-그게 좋은 생각이 아닐 수도 있습니다;)
katzenhut

47

예, Android에서보기 위치를 동적으로 설정할 수 있습니다. 마찬가지로 당신은이 ImageViewLinearLayout당신의 XML을 통해 당신의 위치를 설정할 수 있습니다 file.So LayoutParams나누었다 취할 있는지 확인 LayoutParams하여 XML file.There에서 촬영 레이아웃에 따라 다른 LayoutParams촬영 레이아웃에 따라.

설정할 코드는 다음과 같습니다.

    LayoutParams layoutParams=new LayoutParams(int width, int height);
    layoutParams.setMargins(int left, int top, int right, int bottom);
    imageView.setLayoutParams(layoutParams);

자리를 잡는 데 도움이 되었으면합니다.


15
또한 android.widget.LinearLayout.LayoutParams를 가져와야합니다. 기본값은 ViewGroup의 LayoutParams
David T입니다.

이것은 Android 8 이상에서 작동하지 않는 것 같습니다. 비슷한 문제에 직면 했습니까?
MyFlashLab

Andriod 디자이너가 프로 게 머가 X, Y를 사용하여 물건을 배치하는 것을 막기 위해 왜 그런 문제를 겪는 지 알 수 있습니다. 결국 모든 것이 그렇게 그려 져야합니다. 이는 Android가 코딩 할 수없는 사람들이 설계하고 있음을 의미합니다.
Paul McCarthy

33

이미 다른 유효한 답변이 있지만 해당 API 수준 제한을 제외하고 어떤 경우에 사용할 방법을 올바르게 제안하는 것은 없습니다.

  • 레이아웃주기를 기다릴 수 있고 상위 뷰 그룹이 MarginLayoutParams(또는 하위 클래스)를 지원 하는 경우 marginLeft/ marginTop그에 따라 설정하십시오 .

  • 위치를 즉시 지속적으로 변경해야하는 경우 (예 : PopupMenu 앵커의 경우) 추가로 layout(l, t, r, b)동일한 좌표로 호출 하십시오. 이것은 레이아웃 시스템이 나중에 확인할 것을 선점합니다.

  • 즉각적인 (임시적인) 변경 (예 : 애니메이션)의 경우 대신 setX()/를 setY()사용합니다. 부모 크기가 WRAP_CHILDREN에 의존하지 않는 경우 setX()/ setY()배타적 으로 사용하는 것이 좋습니다 .

  • setLeft()/ setRight()/ setBottom()/를 사용 하지 마십시오setTop() . 아래를 참조하십시오.

배경 : mLeft/ mTop/ mBottom/ mRight필드는 layout ()의 해당 LayoutParams에서 채워집니다. 레이아웃은 Android 뷰 레이아웃 시스템에서 암시 적 및 비동기 적으로 호출됩니다. 따라서를 설정하는 MarginLayoutParams것이 위치를 영구적으로 설정하는 가장 안전하고 깨끗한 방법 인 것 같습니다. 그러나 비동기 레이아웃 지연은 경우에 따라 문제가 될 수 있습니다. 예를 들어 뷰를 사용하여 커서를 렌더링 할 때 위치를 변경하고 동시에 PopupMenu 앵커 역할을해야합니다. 이 경우 전화가 layout()잘 작동했습니다.

의 문제는 다음 setLeft()setTop()같습니다.

  • 혼자 그들을 호출하는 것만으로는 충분하지 않습니다 - 당신은 또한 호출해야 setRight()하고 setBottom()스트레칭이나 뷰를 축소시키지 마십시오.

  • 이러한 메서드의 구현은 비교적 복잡해 보입니다 (= 각각에 의해 발생하는보기 크기 변경을 설명하기 위해 몇 가지 작업 수행).

  • 입력 필드에 이상한 문제가 발생하는 것 같습니다. EditText 소프트 숫자 키보드가 때때로 숫자를 허용하지 않습니다.

setX()setY()작업 레이아웃 시스템의 외부에서, 상기 대응하는 값은 이에 따라 볼을 이동, 배치 시스템에 의해 결정된 좌 / 상 / 하 / 좌 오프셋 값 추가로 처리된다. 애니메이션에 추가 된 것 같습니다 (레이아웃주기를 거치지 않고 즉각적인 효과가 필요한 경우).


안녕 스테판. 안드로이드 레이아웃 시스템이 어떻게 작동하는지 이해할 수있는 몇 권의 책이나 기사를 조언 해 주시겠습니까? layout () onMeasure () onDraw () 호출의 시퀀스를 이해하지만 더 자세한 내용을 알고 싶습니다. 미리 감사드립니다
Sergey Brazhnik 2011

불행히도 난 못해 - 제일과 가장 확실한 기준은 실제 안드로이드 소스 코드 O : 것 같다
스테판 HAUSTEIN

보기를 변경하기 위해 setY를 사용합니다. 즉시가 아닌 다음 레이아웃주기에서 변경됩니까?
신호기

이것을 어떻게 결정 했습니까?
Stefan Haustein

그것의 가치가 지적 marginLeft사용하여 설정할 수 있습니다 setLayoutParamsA가 함께 new FrameLayout.LayoutParams(width, height)하는 당신은 설정marginLeft
lucidbrot을

18

NineOldAndroids 라는 라이브러리가있어 Honeycomb 애니메이션 라이브러리를 버전 1까지 사용할 수 있습니다.

즉, 약간 다른 인터페이스로 왼쪽, 오른쪽, translationX / Y를 정의 할 수 있습니다.

작동 방식은 다음과 같습니다.

ViewHelper.setTranslationX(view, 50f);

ViewHelper 클래스의 정적 메서드를 사용하고 뷰와 설정하려는 값을 전달하기 만하면됩니다.


16

setTranslationX및을 사용하는 것이 좋습니다 setTranslationY. 나는 이것에 대해 단지 시작일 뿐이지 만 이것은 뷰를 이동하는 가장 안전하고 선호되는 방법 인 것 같습니다. 정확히 무엇을하려고하는지에 따라 크게 달라지는 것 같지만 2D 애니메이션에서는 잘 작동합니다.


13

HoneyComb Sdk (API 레벨 11)를 사용하는 경우 다음 방법을 사용해 볼 수 있습니다.

view.setX(float x);

매개 변수 x는이 뷰의 시각적 x 위치입니다.

view.setY(float y);

매개 변수 y는이보기의 시각적 y 위치입니다.

도움이 되었으면합니다. :)


4
2.2 Froyo에서 작업 중이며 이러한 방법은 사용할 수 없습니다.
Arun Badole

7

모든 API 레벨에 대한 지원을 위해 다음 과 같이 사용할 수 있습니다 .

ViewPropertyAnimator.animate(view).translationYBy(-yourY).translationXBy(-yourX).setDuration(0);

그는 위치를 변경하려면 위 솔루션은 더하지 않아도 애니메이션이기 때문에
FireZenk

또한 번역으로 인해 뷰가 (부분적으로) 화면에서 벗어날 수 있습니다
mewa

4

부모를 기준으로이 뷰의 왼쪽 위치를 설정합니다.

view.setLeft(int leftPosition);

부모를 기준으로이 뷰의 올바른 위치를 설정합니다.

view.setRight(int rightPosition);

부모를 기준으로이 뷰의 상단 위치를 설정합니다.

view.setTop(int topPosition);

부모를 기준으로이 뷰의 하단 위치를 설정합니다.

view.setBottom(int bottomPositon);

위의 방법은 부모와 관련된 뷰의 위치를 ​​설정하는 데 사용됩니다.


죄송합니다이 방법은 사용할 수 없습니다. 코드를 보내 주시겠습니까?
Arun Badole 2011 년

4
"이 메서드는 레이아웃 시스템에서 호출하기위한 것이며 일반적으로 다른 방식으로 호출해서는 안됩니다. 속성은 레이아웃에 의해 언제든지 변경 될 수 있기 때문입니다."
GDanger 2014 년

4

LayoutParams를 사용하세요. LinearLayout을 사용하는 경우 android.widget.LinearLayout.LayoutParams를 가져와야합니다. 그렇지 않으면 사용중인 레이아웃에 맞는 LayoutParams 버전을 가져와야합니다. 그렇지 않으면 ClassCastException 이 발생합니다 .

LayoutParams layoutParams = new LayoutParams(int width, int height);
layoutParams.setMargins(int left, int top, int right, int bottom);
imageView.setLayoutParams(layoutParams);

참고 : imageView.setLeft (int dim)도 사용할 수 있지만 구성 요소의 위치를 ​​설정하지 않고 구성 요소의 왼쪽 테두리 위치 만 설정하고 나머지는 동일한 위치에 유지합니다. .


그렇다면 원래 뷰에 영향을주지 않고 뷰를 특정 위치로 이동하려면 어떻게해야합니까?
james

보기를 이동하려면보기를 이동한다는 사실에 의해 변경되기 때문에 문제를 이해했는지 잘 모르겠습니다. 어쨌든, 뷰를 독립적으로 다른 뷰로 이동하려면 메인 레이아웃에 FrameLayout 뷰가 필요할 수 있으며 그 안에 독립 뷰를 배치 할 수 있습니다 (분명히 메인 뷰 아래로 이동하려면 ) 주 일 전에 FrameLayout이를 배치해야
알레산드로 Muzzi에게

3

를 사용 RelativeLayout하여 뷰를 배치하고 뷰에서 RelativeLayout.LayoutParams개체를 가져 오고 필요에 따라 여백을 설정합니다. 그런 다음 requestLayout()당신의 견해를 불러라 . 이것이 내가 아는 유일한 방법입니다.


1

@Stefan Haustein이 내 경험에 매우 가깝지만 100 % 확실하지는 않습니다. 내 제안은 다음과 같습니다.

  • setLeft()/ setRight()/ setBottom()/ setTop()가끔 작동하지 않습니다.
  • 당신이 할 경우 (예를 들어 애니메이션을하고 들어, hierachy 영향을받지 않습니다) 일시적으로 위치를 설정할뷰가 추가 나타났다 그냥 사용 setX()/setY() 대신. (당신은 더 많은 검색 할 수 있습니다 차이 setLeft()setX() )
  • 그리고 X, Y는 절대적인 것처럼 보이며 현재 사용되지 않는 AbsoluteLayout에서 지원되었습니다. 따라서 X, Y가 더 이상 지원되지 않을 가능성이 높습니다. 그리고 그렇습니다. 그러나 부분적으로 만 그렇습니다. 그것은 당신의 경우 의미 보기를 추가, setX ()가, setY ()가 완벽하게 작동한다 ; 그렇지 않으면 뷰 그룹 레이아웃 (예 : FrameLayout, LinearLayout, RelativeLayout) 에 뷰추가 하려고 할 대신 marginLeft, marginTop을 사용 하여 LayoutParams를 설정해야합니다 (이 경우 setX (), setY ()이 경우 가끔 작동하지 않음).
  • marginLeft 및 marginTop으로보기 위치 설정동기화되지 않은 프로세스입니다. 따라서 계층을 업데이트하는 데 약간의 시간필요합니다 . 여백설정 한 후 바로보기사용하면 잘못된 값을 얻을있습니다 .

0

위치 지정과 관련하여 명심해야 할 한 가지는 각 뷰에 상위 뷰에 상대적인 인덱스가 있다는 것입니다. 따라서 세 개의 하위보기가있는 선형 레이아웃이있는 경우 하위보기는 각각 위의 경우 0, 1, 2의 인덱스를 갖습니다.

이렇게하면 다음과 같은 작업을 수행하여 상위 뷰의 마지막 위치 (또는 끝)에 뷰를 추가 할 수 있습니다.

int childCount = parent.getChildCount();
parentView.addView(newView, childCount);

또는 다음과 같은 것을 사용하여보기를 바꿀 수 있습니다.

int childIndex = parentView.indexOfChild(childView);
childView.setVisibility(View.GONE);

parentView.addView(newView, childIndex);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.