设置视图的绝对位置

在 Android 中可以设置视图的绝对位置吗?(我知道有一个 AbsoluteLayout,但它是不被推荐的...)

例如,如果我有一个240x320px 的屏幕,我如何添加一个20x20px 的 ImageView,使其中心在位置(100,100) ?

285579 次浏览

可以使用 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的图像视图(一个黄色,一个红色)分别放置在(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);

将一个30x40的黄色图像视图放在(50,60) ,另一个30x40的红色图像视图放在 < 80,90 > 相对于的黄色图像视图:

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

只是添加到 Andy Zhang 上面的答案,如果你愿意,你可以给 rl.addView 赋予 param,然后稍后对它进行修改,这样:

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 的布局。

一个更清晰和动态的方式,而不硬编码的代码中的任何像素值。

我想定位一个对话框(我在动态膨胀)正好在一个点击按钮下面。

并用这种方法解决了它:

    // 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。

一般来说,通过指定 left Margin 和 topMargin 属性,可以使用 FrameLayout 作为容器在特定位置添加 View

下面的示例将使用 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);
//...

这样做可以解决这个问题,因为边距可以在没有 RelativeLayout 的情况下用作绝对(X,Y)坐标:

enter image description here

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

成交

尝试以下代码设置特定位置的视图:-

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

我的 Xamarin代码, 我正在使用 框架布局为此目的,以下是我的代码:

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


}


}

这对我来说很有用,因为我需要视图的属性根据它们的外观彼此重叠,例如视图得到 一层叠一层

为了以防万一,它可能会有帮助的人,你也可以尝试这个动画师 ViewPropertyAnimator如下

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


myView.animate().translateX(pixelInScreen)

注意: 这个像素与视图无关。这个像素就是这个像素 在屏幕上的位置。

归功于 bpr10的回答