Android 设置视图的绝对位置
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3294590/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Set the absolute position of a view
提问by Sephy
Is it possible to set the absolute position of a view in Android? (I know that there is an AbsoluteLayout
, but it's deprecated...)
是否可以在 Android 中设置视图的绝对位置?(我知道有一个AbsoluteLayout
,但它已被弃用......)
For example, if I have a 240x320px screen, how could I add an ImageView
which is 20x20px such that its center is at the position (100,100)?
例如,如果我有一个 240x320 像素的屏幕,我如何添加一个 20x20 像素的屏幕,ImageView
使其中心位于 (100,100) 位置?
回答by Andy Zhang
You can use RelativeLayout. Let's say you wanted a 30x40 ImageView at position (50,60) inside your layout. Somewhere in your activity:
您可以使用相对布局。假设您想要在布局内的位置 (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);
More examples:
更多例子:
Places two 30x40 ImageViews (one yellow, one red) at (50,60) and (80,90), respectively:
分别在 (50,60) 和 (80,90) 处放置两个 30x40 ImageViews(一个黄色,一个红色):
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);
Places one 30x40 yellow ImageView at (50,60) and another 30x40 red ImageView <80,90> relative tothe yellow ImageView:
将一个 30x40 黄色 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);
回答by bonnyz
In general, you can add a View in a specific position using a FrameLayout as container by specifying the leftMargin and topMargin attributes.
通常,您可以通过指定 leftMargin 和 topMargin 属性,使用 FrameLayout 作为容器在特定位置添加 View。
The following example will place a 20x20px ImageView at position (100,200) using a FrameLayout as fullscreen container:
以下示例将使用 FrameLayout 作为全屏容器在位置 (100,200) 放置一个 20x20 像素的 ImageView:
XML
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>
Activity / Fragment / Custom view
活动/片段/自定义视图
//...
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);
//...
This will do the trick because margins can be used as absolute (X,Y) coordinates without a RelativeLayout:
这可以解决问题,因为边距可以用作没有相对布局的绝对 (X,Y) 坐标:
回答by Excrubulent
Just to add to Andy Zhang's answer above, if you want to, you can give param to rl.addView, then make changes to it later, so:
只是为了补充上面安迪张的回答,如果你愿意,你可以给 rl.addView 参数,然后稍后对其进行更改,因此:
params = new RelativeLayout.LayoutParams(30, 40);
params.leftMargin = 50;
params.topMargin = 60;
rl.addView(iv, params);
Could equally well be written as:
同样可以写成:
params = new RelativeLayout.LayoutParams(30, 40);
rl.addView(iv, params);
params.leftMargin = 50;
params.topMargin = 60;
So if you retain the params variable, you can change the layout of iv at any time after adding it to rl.
所以如果你保留params变量,你可以在将它添加到rl后随时更改iv的布局。
回答by Hari Krishna Ganji
A more cleaner and dynamic way without hardcoding any pixel values in the code.
一种更简洁和动态的方式,无需在代码中硬编码任何像素值。
I wanted to position a dialog (which I inflate on the fly) exactly below a clicked button.
我想在单击的按钮正下方放置一个对话框(我会即时膨胀)。
and solved it this way :
并以这种方式解决它:
// 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;
}
However you have to make sure the parent layout of myView
is an instance of RelativeLayout
.
但是,您必须确保 的父布局myView
是RelativeLayout
.
more complete 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;
}
This way you can still expect the target view to adjust to any layout parameters set using layout XML files, instead of hardcoding those pixels/dps in your Java code.
通过这种方式,您仍然可以期望目标视图调整为使用布局 XML 文件设置的任何布局参数,而不是在 Java 代码中对这些像素/dps 进行硬编码。
回答by Hiren Patel
Place any view on your desire X& Ypoint
将任何视图放在您想要的X和Y点上
layout file
布局文件
<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
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);
}
}
Done
完毕
回答by praveenb
Just in case it may help somebody, you may also try this animator ViewPropertyAnimatoras below
以防万一它可以帮助某人,您也可以尝试这个动画师ViewPropertyAnimator如下
myView.animate().x(50f).y(100f);
myView.animate().translateX(pixelInScreen)
Note: This pixel is not relative to the view. This pixel is the pixel position in the screen.
注意:此像素与视图无关。这个像素是屏幕中的像素位置。
credits to bpr10 answer
归功于bpr10 答案
回答by duggu
Try below code to set view on specific location :-
尝试使用以下代码在特定位置设置视图:-
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);
回答by Technacron
My code for Xamarin, I am using FrameLayoutfor this purpose and following is my code:
我的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;
}
}
}
It was useful for me because I needed the property of view to overlap each other on basis of their appearance, e.g the views get stacked one above other.
这对我很有用,因为我需要视图的属性根据它们的外观相互重叠,例如,视图堆叠在一起。