web-dev-qa-db-ja.com

Androidでビューの位置を動的に設定するにはどうすればよいですか?

コードを使用してビューの位置を変更するにはどうすればよいですか? X、Yの位置を変更するように。出来ますか?

90
AB1209

Honeycomb(APIレベル11)未満の場合は、setLayoutParams(...)を使用する必要があります。

Honeycomb以上にサポートを制限できる場合は、setX(...)setY(...)setLeft(...)setTop(...)などを使用できます。

111
Perishable Dave

さまざまな有効な回答が既にありますが、対応するAPIレベルの制限を除いて、どのメソッドをどのケースで使用するかを適切に提案するものはありません。

  • レイアウトサイクルを待つことができ、親ビューグループがMarginLayoutParams(またはサブクラス)をサポートする場合、それに応じてmarginLeft/marginTopを設定します。

  • 位置を即座に永続的に変更する必要がある場合(たとえば、PopupMenuアンカーの場合)、さらに同じ座標でlayout(l, t, r, b)を呼び出します。これは、レイアウトシステムが後で確認する内容を先取りします。

  • 即時の(一時的な)変更(アニメーションなど)の場合は、代わりにsetX()/setY()を使用します。親のサイズがWRAP_CHILDRENに依存しない場合は、setX()/setY()を排他的に使用しても問題ない場合があります。

  • NeversetLeft()/setRight()/setBottom()/setTop()を使用、以下を参照してください。

BackgroundmLeft/mTop/mBottom/mRightフィールドは、layout()の対応するLayoutParamsから入力されます。レイアウトは、Androidビューレイアウトシステムによって暗黙的かつ非同期的に呼び出されます。したがって、MarginLayoutParamsを設定することは、位置を永続的に設定する最も安全でクリーンな方法のようです。ただし、非同期レイアウトラグは、場合によっては問題になる可能性があります。ビューを使用してカーソルをレンダリングする場合、カーソルは再配置され、同時にPopupMenuアンカーとして機能することになっています。この場合、layout()を呼び出すとうまくいきました。

setLeft()setTop()の問題は次のとおりです。

  • それらを単独で呼び出すだけでは十分ではありません。ビューの伸縮を避けるために、setRight()setBottom()を呼び出す必要もあります。

  • これらのメソッドの実装は比較的複雑に見えます(=各メソッドによって引き起こされるビューサイズの変更を考慮していくつかの作業を行う)

  • 入力フィールドで奇妙な問題を引き起こすようです: EditTextソフトテンキーキーボードは時々数字を許可しない

setX()およびsetY()はレイアウトシステムの外部で機能し、対応する値はレイアウトシステムによって決定された左/上/下/右の値への追加オフセットとして扱われ、それに応じてビューをシフトします。アニメーション用に追加されたようです(レイアウトサイクルを経由せずに即時の効果が必要な場合)。

25
Stefan Haustein

NineOldAndroids というライブラリがあります。これにより、Honeycombアニメーションライブラリをバージョン1まで使用できます。

これは、わずかに異なるインターフェースで、左、右、平行移動X/Yを定義できることを意味します。

仕組みは次のとおりです。

ViewHelper.setTranslationX(view, 50f);

ViewHelperクラスの静的メソッドを使用して、ビューと、設定する値を渡します。

18
Ben

setTranslationXsetTranslationYを使用することをお勧めします。私はこれを自分で始めたばかりですが、これらはビューを移動する最も安全で好ましい方法のようです。あなたがまさに何をしようとしているのかに大きく依存していると思いますが、これは2Dアニメーションで私にとってうまく機能しています。

15
brianmearns

HoneyComb Sdk(API Level 11)を使用している場合は、次の方法を使用できます。

view.setX(float x);

パラメータxは、このビューの視覚的なx位置です。

view.setY(float y);

パラメータyは、このビューの視覚的なy位置です。

あなたの役に立つことを願っています。 :)

12
Chickenrice

すべてのAPIレベルをサポートするには、次のように it を使用できます。

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

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)も使用できることに注意してください。ただし、これはコンポーネントの位置を設定しません。コンポーネントの左境界の位置のみを設定し、残りは残ります。同じ位置で。

4

親に対するこのビューの左位置を設定します。

view.setLeft(int leftPosition);

親に対するこのビューの正しい位置を設定します。

view.setRight(int rightPosition);

親に対するこのビューの最上部の位置を設定します。

view.setTop(int topPosition);

親に対するこのビューの下部の位置を設定します。

view.setBottom(int bottomPositon);

上記のメソッドは、親に関連するビューの位置を設定するために使用されます。

4
Balaji.K

RelativeLayoutを使用してビューを配置し、ビューからRelativeLayout.LayoutParamsオブジェクトを取得し、必要に応じてマージンを設定します。次に、ビューでrequestLayout()を呼び出します。これは私が知っている唯一の方法です。

3
glodos

@Stefan Hausteinは私の経験に非常に近いことがわかりましたが、100%確実ではありません。私の提案は次のとおりです。

  • setLeft()/setRight()/setBottom()/setTop()は時々動作しません。
  • 一時的に位置を設定する(たとえば、アニメーションを行うため、階層に影響を与えない)ビューが追加および表示されたの場合、ただsetX()/setY()を使用代わりに。 (difference setLeft()setX()でさらに検索したい場合があります)
  • また、X、Yは絶対的であるように思われ、AbsoluteLayoutでサポートされていましたが、現在は廃止されています。したがって、X、Yはもうサポートされていないと思われます。はい、そうですが、一部だけです。 ビューが追加され、setX()、setY()が完全に機能する場合;それ以外の場合、whenしようとするビューグループレイアウトにビューを追加(例:FrameLayout、LinearLayout、RelativeLayout)、設定する必要がありますとそのLayoutParams marginLeft、marginTop代わりに(この場合、setX()、setY()は時々動作しません)。
  • marginLeftおよびmarginTopによるビューの位置の設定非同期プロセスです。 階層を更新するのに少し時間が必要ですマージンを設定した直後にビューを使用するの場合、間違った値を取得する可能性があります.
0
Nguyen Tan Dat