Establecer la posición absoluta de una vista

¿Es posible establecer la posición absoluta de una vista en Android? (Sé que hay un AbsoluteLayout , pero está en desuso …)

Por ejemplo, si tengo una pantalla de 240x320px, ¿cómo podría agregar un ImageView que es 20x20px de modo que su centro esté en la posición (100,100)?

Puede usar RelativeLayout. Digamos que usted quería una ImageView de 30×40 en la posición (50,60) dentro de su diseño. En algún lugar de tu actividad:

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

Más ejemplos:

Coloca dos imágenes de 30×40 (una amarilla, una roja) a (50,60) y (80,90), respectivamente:

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

Coloca un ImageView amarillo de 30×40 en (50,60) y otro ImageView rojo de 30×40 <80,90> en relación con el ImageView amarillo:

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

En general, puede agregar una Vista en una posición específica usando FrameLayout como contenedor especificando los atributos leftMargin y topMargin .

El siguiente ejemplo colocará un ImageView de 20x20px en la posición (100,200) usando un FrameLayout como contenedor de pantalla completa:

XML

   

Actividad / Fragmento / Vista personalizada

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

Esto hará el truco porque los márgenes se pueden usar como coordenadas absolutas (X, Y) sin un RelativeLayout:

enter image description here

Solo para agregar a la respuesta anterior de Andy Zhang, si lo desea, puede darle un parámetro a rl.addView, luego realice los cambios en él más adelante, así que:

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

Podría igualmente escribirse como:

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

Por lo tanto, si conserva la variable params, puede cambiar el diseño de iv en cualquier momento después de agregarlo a rl.

Una forma más limpia y dinámica sin codificar ningún valor de píxel en el código.

Quería colocar un cuadro de diálogo (que infló sobre la marcha) exactamente debajo de un botón presionado.

y lo resolvió de esta manera:

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

Sin embargo, debe asegurarse de que el diseño principal de myView sea ​​una instancia de RelativeLayout .

código más completo:

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

De esta forma, puede esperar que la vista de destino se ajuste a los parámetros de diseño establecidos mediante los archivos XML de diseño, en lugar de codificar esos píxeles / dps en su código Java.

Ver captura de pantalla

Coloque cualquier vista en su punto de X e Y deseado

archivo de diseño

        

Clase de 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); } } 

Hecho

En caso de que pueda ayudar a alguien, también puedes probar este animador ViewPropertyAnimator como se muestra a continuación

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

Nota: Este pixel no es relativo a la vista. Este píxel es la posición de píxel en la pantalla.

créditos a bpr10 respuesta

Pruebe a continuación el código para establecer la vista en una ubicación específica: –

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

Mi código para Xamarin , estoy usando FrameLayout para este propósito y el siguiente es mi código:

  List content = new List(); 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; } } } 

Me resultó útil porque necesitaba que la propiedad de la vista se superpusiera entre sí en función de su apariencia, por ejemplo, las vistas se astackn una sobre otra .