2010-07-20 8 views
156

Kann die absolute Position einer Ansicht in Android festgelegt werden? (Ich weiß, dass es ein AbsoluteLayout, aber es ist veraltet ...)Einstellen der absoluten Position einer Ansicht

Zum Beispiel, wenn ich einen 240x320px Bildschirm habe, wie könnte ich ein ImageView hinzufügen, die ist 20x20px so dass sein Zentrum an der Position (100,100) ?

+3

siehe auch 'view.setTranslationX()' oder 'view.offsetLeftAndRight()' –

+0

Ich habe eine Bibliothek nur veröffentlicht, die hier von Interesse gewesen sein kann. github.com/ManuelPeinado/ImageLayout – Manuel

+1

Dies ist so schwierig, weil 99,9% der Zeit absolute Positionierung ist eine schlechte Idee auf Android. Wenn Sie eine App schreiben, die * NUR * jemals auf einem physischen Gerät ausgeführt wird, könnte dies funktionieren, aber das ist im Allgemeinen keine sichere Annahme. Laden Sie das beispielsweise nicht in Google Play hoch.Es funktioniert gut auf iOS, da es nur eine Handvoll Hardwaregeräte gibt und Sie können für jedes ein eigenes Storyboard erstellen. – edthethird

Antwort

231

Sie können RelativeLayout verwenden. Nehmen wir an, Sie wollten ein 30x40 ImageView an der Position (50,60) in Ihrem Layout haben. Irgendwo in Ihrer Aktivität:

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

Weitere Beispiele:

Orte zwei 30x40 ImageViews (eine gelbe, eine rote) bei (50,60) und (80,90) verbunden sind:

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

Orte eine 30x40 gelb Image bei (50,60) und einem weiteren 30x40 roten Image < 80,90>relativ zu das gelben Image:

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

Ich werde es heute Abend versuchen, das ist eine ziemlich nette Idee, ich weiß nicht, warum ich nicht darüber nachgedacht habe. Da ich mehrere 'ImageView' habe, wäre es nicht besser ein' FrameLayout' zu verwenden? – Sephy

+0

In der Tat scheint dies zu funktionieren, aber es funktioniert nur, wenn ein Bild auf diese Weise hinzugefügt wird. wenn ich versuche, eine zweite hinzuzufügen, verschwindet die erste ... – Sephy

+1

Die zwei Bilder sind nur übereinander. Ich werde meiner Lösung oben einen Code hinzufügen, um dies zu erklären. –

15

Gerade über Andy Zhang Antwort hinzufügen möchten, wenn Sie wollen, können Sie param zu rl.addView geben, dann später Änderungen daran vornehmen, so:

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

könnte genauso gut sein geschrieben als: so

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

, wenn Sie die params Variable behalten, können Sie das Layout iv jederzeit ändern, nach dem Hinzufügen zu rl.

+0

liebte dieses Beispiel. Können Sie mir vorschlagen, wie kann ich die x, y-Achse einstellen, wenn ich das Bild im XML-Layout habe (Ich versuche, das Bild zu skalieren und ich muss das Bild an einer bestimmten Stelle) –

+0

Ich fürchte ich verstehe nicht ganz, was du verlangst. Versuchen Sie, auf das LayoutParams-Objekt zuzugreifen, das einem Objekt zugeordnet ist, das mit dem XML-Layout positioniert wurde? Ich bin mir nicht sicher, wie das geht. Es könnte sich lohnen, eine neue Frage zu stellen, um diese beantwortet zu bekommen, wenn Sie die Antwort nicht anderswo finden können. – Excrubulent

+0

Bitte werfen Sie einen Blick auf diese Frage http://stackoverflow.com/questions/12028404/resizing-the-imageview-makes-it-change-its-place/12028508#comment16054261_12028508 –

5

Eine sauberere und dynamischere Methode, ohne Pixelwerte im Code zu kodieren.

Ich wollte einen Dialog (den ich gerade aufblasen) genau unter einem angeklickten Knopf positionieren.

und löste es auf diese Weise:

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

immer Sie sicher, dass die Eltern das Layout myView ist eine Instanz RelativeLayout zu machen.

komplettere Code:

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

diese Weise können Sie immer noch das Ziel im Hinblick auf mögliche Layout-Parameter einzustellen erwarten können einstellen Layout XML-Dateien verwenden, statt hartzucodieren jene Pixel/dps in Ihrem Java-Code.

41

Im Allgemeinen können Sie eine Ansicht an einer bestimmten Position mit einem FrameLayout als Container hinzufügen, indem Sie die Attribute leftMargin und topMargin angeben.

Im folgenden Beispiel wird eine 20x20px Image an Position (100,200) einen FrameLayout als Vollbild-Container platzieren mit:

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> 

Aktivität/Fragment/Benutzerdefinierte Ansicht

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

Dies wird den Trick machen, da Margen als verwendet werden können bsolute (X, Y) Koordinaten ohne RelativeLayout:

enter image description here

+1

Brilliant! Die 500 wert! +1 –

1

Check screenshot

Platz jede Aussicht auf Ihren Wunsch X & Y Punkt

Layout-Datei

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

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

Geschehen

-1

unten Code Versuchen Blick auf bestimmten Ort festgelegt: -

  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

Mein Code für Xamarin, Ich benutze FrameLayout für diesen Zweck und folgende ist mein Code:

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

      } 

     } 

Es war nützlich für mich, weil ich die Eigenschaft Ansicht benötigt einander auf Basis ihres Aussehens zu überlappen, beispiels die Ansichten über andere gestapelt bekommen.

0

Nur falls es jemanden helfen kann, können Sie auch versuchen, diesen Animator ViewPropertyAnimator wie unten

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

myView.animate().translateX(pixelInScreen) 

Hinweis: Dieses Pixel ist die Ansicht nicht relativ. Dieses Pixel ist die Position des Pixels auf dem Bildschirm.

Kredite bpr10 answer

Verwandte Themen