2010-07-20 5 views
156

Можно ли установить абсолютное положение представления в Android? (Я знаю, что есть AbsoluteLayout, но это не рекомендуется ...)Установить абсолютное положение вида

Например, если у меня есть экран 240x320px, как бы я добавляю ImageView который 20x20px таким образом, что его центр находится в положении (100,100) ?

+3

также см 'view.setTranslationX()' или 'view.offsetLeftAndRight()' –

+0

Я только что выпустили библиотеку, которая, возможно, был интерес здесь. github.com/ManuelPeinado/ImageLayout – Manuel

+1

Это так сложно, потому что 99,9% времени абсолютного позиционирования - плохая идея для Android. Если вы пишете приложение, которое будет * ТОЛЬКО когда-либо выполняться на одном физическом устройстве, это может сработать, но это, как правило, не является безопасным предположением. Например, не загружайте это в игру Google.Он отлично работает на iOS, потому что есть только несколько аппаратных устройств, и вы можете создавать собственные раскадровки для каждого из них. – edthethird

ответ

231

Вы можете использовать RelativeLayout. Предположим, вы хотели получить 30x40 ImageView в позиции (50,60) внутри вашего макета. Где-то в вашей деятельности:

// 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); 

места один 30х40 желтый ImageView в (50,60), а другой 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

+0

Действительно, похоже, что это работает, однако, он работает только при добавлении одного изображения таким образом. если я попытаюсь добавить второй, первый просто исчезнет ... – Sephy

+1

Два изображения находятся только друг над другом. Я добавлю код в мое решение выше, чтобы объяснить. –

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, вы можете изменить расположение IV в любое время после добавления его в Rl.

+0

любил этот образец. Можете ли вы предложить мне, как я могу установить ось x, y, когда у меня есть изображение в макете xml. (Я пытаюсь изменить размер изображения, и мне нужно установить изображение в определенном положении) –

+0

Боюсь, я не совсем понимаю, что вы просите. Вы пытаетесь получить доступ к объекту LayoutParams, связанному с объектом, который был помещен с использованием макета XML? Я не уверен, как это делается. Возможно, стоит задать новый вопрос, чтобы ответить на этот вопрос, если вы не можете найти ответ в другом месте. – Excrubulent

+0

, пожалуйста, взгляните на этот вопрос http://stackoverflow.com/questions/12028404/resizing-the-imageview-makes-it-change-its-place/12028508#comment16054261_12028508 –

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.

41

В общем, вы можете добавить представление в определенную позицию, используя контейнер FrameLayout в качестве контейнера, указав атрибуты leftMargin и topMargin.

В следующем примере будет поместить 20x20px ImageView в положении (100,200) с помощью FrameLayout в полноэкранном режиме контейнера:

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 –

1

Check screenshot

Место любой взгляд на ваше желание X & Y точка

файл макета

<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 Class

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; 
        } 

      } 

     } 

Это было полезно для меня, потому что мне нужно было свойство зрения, чтобы перекрывать друг друга на основе их внешнего вида, например взгляды получить сложены друг над другом.

0

Только в случае, если это может помочь кому-то, вы можете также попробовать этот аниматор ViewPropertyAnimator, как показано ниже

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

myView.animate().translateX(pixelInScreen) 

Примечание: Этот пиксель не относительно точки зрения. Этот пиксель представляет собой пиксель позиция на экране.

кредиты bpr10 answer

Смежные вопросы