2010-07-20 192 views
156

是否可以在Android中設置視圖的絕對位置? (我知道有一個AbsoluteLayout,但它過時...)設置視圖的絕對位置

舉例來說,如果我有一個240x320px屏幕,我怎麼能添加ImageView是20x20px使得它的中心是在位置(100,100) ?

+3

也看到'view.setTranslationX()'或'view.offsetLeftAndRight()' – 2013-01-19 20:49:51

+0

我剛剛發佈了可能是感興趣這裏的圖書。 github.com/ManuelPeinado/ImageLayout – Manuel 2013-04-18 06:36:09

+1

這很難,因爲99.9%的時間絕對定位在android上是一個壞主意。如果你正在編寫一個只能在一個物理設備上運行的應用程序,那麼這可能會起作用,但這通常不是一個安全的假設。例如,不要上傳到谷歌播放。它在iOS上運行良好,因爲只有少數硬件設備,並且可以爲每個硬件設備創建一個自定義故事板。 – edthethird 2015-01-06 21:11:00

回答

231

您可以使用RelativeLayout。假設您需要在佈局中的位置(50,60)處使用30x40的ImageView。某處在您的活動:

// Some existing RelativeLayout from your layout xml 
RelativeLayout rl = (RelativeLayout) findViewById(R.id.my_relative_layout); 

ImageView iv = new ImageView(this); 

RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(30, 40); 
params.leftMargin = 50; 
params.topMargin = 60; 
rl.addView(iv, params); 

更多的例子:

兩處30X40 ImageViews(一個黃色,一個紅色)在(50,60)和(80,90),分別爲:

RelativeLayout rl = (RelativeLayout) findViewById(R.id.my_relative_layout); 
ImageView iv; 
RelativeLayout.LayoutParams params; 

iv = new ImageView(this); 
iv.setBackgroundColor(Color.YELLOW); 
params = new RelativeLayout.LayoutParams(30, 40); 
params.leftMargin = 50; 
params.topMargin = 60; 
rl.addView(iv, params); 

iv = new ImageView(this); 
iv.setBackgroundColor(Color.RED); 
params = new RelativeLayout.LayoutParams(30, 40); 
params.leftMargin = 80; 
params.topMargin = 90; 
rl.addView(iv, params); 

在地點(50,60)一個30X40黃色的ImageView和另一30X40紅色的ImageView < 80,90>相對於黃色ImageView的:

RelativeLayout rl = (RelativeLayout) findViewById(R.id.my_relative_layout); 
ImageView iv; 
RelativeLayout.LayoutParams params; 

int yellow_iv_id = 123; // Some arbitrary ID value. 

iv = new ImageView(this); 
iv.setId(yellow_iv_id); 
iv.setBackgroundColor(Color.YELLOW); 
params = new RelativeLayout.LayoutParams(30, 40); 
params.leftMargin = 50; 
params.topMargin = 60; 
rl.addView(iv, params); 

iv = new ImageView(this); 
iv.setBackgroundColor(Color.RED); 
params = new RelativeLayout.LayoutParams(30, 40); 
params.leftMargin = 80; 
params.topMargin = 90; 

// This line defines how params.leftMargin and params.topMargin are interpreted. 
// In this case, "<80,90>" means <80,90> to the right of the yellow ImageView. 
params.addRule(RelativeLayout.RIGHT_OF, yellow_iv_id); 

rl.addView(iv, params); 
+1

我今晚會去,這是一個非常好的主意,不知道爲什麼我沒有想到這一點。由於我有幾個'ImageView',所以使用'FrameLayout'會更好嗎? – Sephy 2010-07-21 07:51:44

+0

事實上,這似乎工作,但是,它只有在這樣添加一張圖片時才起作用。如果我嘗試添加第二個,那麼第一個就會消失... – Sephy 2010-07-21 21:03:33

+1

這兩個圖像只是彼此重疊。我會在上面的解決方案中添加一些代碼來解釋。 – 2010-07-21 21:19:11

15

只需添加到張小寶的回答上面,如果你願意,你可以給參數去rl.addView,然後進行更改後,所以:

params = new RelativeLayout.LayoutParams(30, 40); 
params.leftMargin = 50; 
params.topMargin = 60; 
rl.addView(iv, params); 

也同樣可以寫成:

params = new RelativeLayout.LayoutParams(30, 40); 
rl.addView(iv, params); 
params.leftMargin = 50; 
params.topMargin = 60; 

所以,如果你保留params變量,你可以在添加到rl後隨時更改iv的佈局。

+0

喜歡這個樣本。 你可以建議我如何設置x,y軸當我有圖像在xml佈局(我想調整圖像大小,我需要設置圖像在某個位置) – 2012-08-21 07:08:18

+0

恐怕我不太明白你在問什麼。您是否試圖訪問與使用XML佈局定位的對象關聯的LayoutParams對象?我不確定這是如何完成的。如果你在其他地方找不到答案,那麼可以設置一個新的問題來回答這個問題。 – Excrubulent 2012-08-22 23:43:08

+0

請看看這個問題http://stackoverflow.com/questions/12028404/resizing-the-imageview-makes-it-change-its-place/12028508#comment16054261_12028508 – 2012-08-23 03:04:23

5

在代碼中沒有硬編碼任何像素值的更清潔和動態的方式。

我想在一個點擊的按鈕下方放置一個對話框(我正在充氣)。

,解決這樣說:

// get the yoffset of the position where your View has to be placed 
    final int yoffset = < calculate the position of the view > 

    // position using top margin 
    if(myView.getLayoutParams() instanceof MarginLayoutParams) { 
     ((MarginLayoutParams) myView.getLayoutParams()).topMargin = yOffset; 
    } 

但是你必須確保的myView父佈局的RelativeLayout一個實例。

更完整的代碼:

// identify the button 
    final Button clickedButton = <... code to find the button here ...> 

    // inflate the dialog - the following style preserves xml layout params 
    final View floatingDialog = 
     this.getLayoutInflater().inflate(R.layout.floating_dialog, 
      this.floatingDialogContainer, false); 

    this.floatingDialogContainer.addView(floatingDialog); 

    // get the buttons position 
    final int[] buttonPos = new int[2]; 
    clickedButton.getLocationOnScreen(buttonPos);   
    final int yOffset = buttonPos[1] + clickedButton.getHeight(); 

    // position using top margin 
    if(floatingDialog.getLayoutParams() instanceof MarginLayoutParams) { 
     ((MarginLayoutParams) floatingDialog.getLayoutParams()).topMargin = yOffset; 
    } 

這樣你仍然可以期待的目標視圖,以適應任何佈局參數使用佈局XML文件中設置的,而不是硬編碼的像素在Java代碼/ DPS。

41

通常,通過指定leftMargin和topMargin屬性,您可以使用FrameLayout作爲容器在特定位置添加視圖。

下面的例子將放置在位置使用的FrameLayout作爲全屏容器20x20px ImageView的(100,200):

XML

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/root" 
    android:background="#33AAFF" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" > 
</FrameLayout> 

活動/片段/自定義視圖

//... 
FrameLayout root = (FrameLayout)findViewById(R.id.root); 
ImageView img = new ImageView(this); 
img.setBackgroundColor(Color.RED); 
//..load something inside the ImageView, we just set the background color 

FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(20, 20); 
params.leftMargin = 100; 
params.topMargin = 200; 
root.addView(img, params); 
//... 

這將做到這一點,因爲利潤可以用作bsolute(X,Y)座標沒有的RelativeLayout:

enter image description here

+1

太棒了!值得500! +1 – 2016-02-13 14:33:50

1

Check screenshot

放在你想要的任何視圖X & Ÿ

佈局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context="com.example.test.MainActivity" > 

    <AbsoluteLayout 
     android:id="@+id/absolute" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" > 

     <RelativeLayout 
      android:id="@+id/rlParent" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" > 

      <ImageView 
       android:id="@+id/img" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:background="@drawable/btn_blue_matte" /> 
     </RelativeLayout> 
    </AbsoluteLayout> 

</RelativeLayout> 

的Java類

public class MainActivity extends Activity { 

    private RelativeLayout rlParent; 
    private int width = 100, height = 150, x = 20, y= 50; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     AbsoluteLayout.LayoutParams param = new AbsoluteLayout.LayoutParams(width, height, x, y); 
     rlParent = (RelativeLayout)findViewById(R.id.rlParent); 
     rlParent.setLayoutParams(param); 
    } 
} 

完成

-1

嘗試下面的代碼來設置具體位置視圖: -

  TextView textView = new TextView(getActivity()); 
      textView.setId(R.id.overflowCount); 
      textView.setText(count + ""); 
      textView.setGravity(Gravity.CENTER); 
      textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12); 
      textView.setTextColor(getActivity().getResources().getColor(R.color.white)); 
      textView.setOnClickListener(new OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        // to handle click 
       } 
      }); 
      // set background 
      textView.setBackgroundResource(R.drawable.overflow_menu_badge_bg); 

      // set apear 

      textView.animate() 
        .scaleXBy(.15f) 
        .scaleYBy(.15f) 
        .setDuration(700) 
        .alpha(1) 
        .setInterpolator(new BounceInterpolator()).start(); 
      FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
        FrameLayout.LayoutParams.WRAP_CONTENT, 
        FrameLayout.LayoutParams.WRAP_CONTENT); 
      layoutParams.topMargin = 100; // margin in pixels, not dps 
      layoutParams.leftMargin = 100; // margin in pixels, not dps 
      textView.setLayoutParams(layoutParams); 

      // add into my parent view 
      mainFrameLaout.addView(textView); 
0

我對代碼Xamarin, 我使用FrameLayout於此目的,下面是我的代碼:

   List<object> content = new List<object>(); 

     object aWebView = new {ContentType="web",Width="300", Height = "300",X="10",Y="30",ContentUrl="http://www.google.com" }; 
     content.Add(aWebView); 
     object aWebView2 = new { ContentType = "image", Width = "300", Height = "300", X = "20", Y = "40", ContentUrl = "https://www.nasa.gov/sites/default/files/styles/image_card_4x3_ratio/public/thumbnails/image/leisa_christmas_false_color.png?itok=Jxf0IlS4" }; 
     content.Add(aWebView2); 
     FrameLayout myLayout = (FrameLayout)FindViewById(Resource.Id.frameLayout1); 
     foreach (object item in content) 
     { 

      string contentType = item.GetType().GetProperty("ContentType").GetValue(item, null).ToString(); 
      FrameLayout.LayoutParams param = new FrameLayout.LayoutParams(Convert.ToInt32(item.GetType().GetProperty("Width").GetValue(item, null).ToString()), Convert.ToInt32(item.GetType().GetProperty("Height").GetValue(item, null).ToString())); 
      param.LeftMargin = Convert.ToInt32(item.GetType().GetProperty("X").GetValue(item, null).ToString()); 
      param.TopMargin = Convert.ToInt32(item.GetType().GetProperty("Y").GetValue(item, null).ToString()); 

      switch (contentType) { 
       case "web":{ 
         WebView webview = new WebView(this); 

         //webview.hei; 
         myLayout.AddView(webview, param); 
         webview.SetWebViewClient(new WebViewClient()); 
         webview.LoadUrl(item.GetType().GetProperty("ContentUrl").GetValue(item, null).ToString()); 

         break; 
        } 
       case "image": 
        { 
         ImageView imageview = new ImageView(this); 

         //webview.hei; 
         myLayout.AddView(imageview, param); 
         var imageBitmap = GetImageBitmapFromUrl("https://www.nasa.gov/sites/default/files/styles/image_card_4x3_ratio/public/thumbnails/image/leisa_christmas_false_color.png?itok=Jxf0IlS4"); 
         imageview.SetImageBitmap(imageBitmap); 


         break; 
        } 

      } 

     } 

,因爲我需要看的財產,以相互重疊自己的外表的基礎上對我來說這非常有用,e.g的意見得到堆疊其他以上。

0

萬一它可以幫助別人,你也可以嘗試這個動畫ViewPropertyAnimator如下

myView.animate().x(50f).y(100f); 

myView.animate().translateX(pixelInScreen) 

注意:此像素不相對於視圖。該像素是屏幕中的像素位置 。

學分bpr10 answer