Ste*_*ley 376 android android-tablelayout
我正在尝试获取视图左上角的绝对屏幕像素坐标.但是,我可以找到的所有方法,例如getLeft()
并且getRight()
不起作用,因为它们似乎都相对于视图的父级,因此给了我0
.这样做的正确方法是什么?
如果它有帮助,这是为了"让图片重新整理"游戏.我希望用户能够绘制一个框来选择多个部分.我的假设是,做到这一点的最简单方法是getRawX()
,并getRawY()
从MotionEvent
再兑布局保持件的左上角比较这些值.知道了件的大小,我就可以确定已经选择了多少件.我知道我可以使用getX()
和getY()
上MotionEvent
,而是作为一个返回相对位置,使得确定哪个被选择件更困难.(我知道,这并非不可能,但似乎不必要地复杂化).
编辑:这是我用来尝试获取保持容器大小的代码,根据其中一个问题.TableLayout
是包含所有拼图的表.
TableLayout tableLayout = (TableLayout) findViewById(R.id.tableLayout);
Log.d(LOG_TAG, "Values " + tableLayout.getTop() + tableLayout.getLeft());
Run Code Online (Sandbox Code Playgroud)
编辑2:这是我尝试过的代码,遵循更多建议的答案.
public int[] tableLayoutCorners = new int[2];
(...)
TableLayout tableLayout = (TableLayout) findViewById(R.id.tableLayout);
tableLayout.requestLayout();
Rect corners = new Rect();
tableLayout.getLocalVisibleRect(corners);
Log.d(LOG_TAG, "Top left " + corners.top + ", " + corners.left + ", " + corners.right
+ ", " + corners.bottom);
cells[4].getLocationOnScreen(tableLayoutCorners);
Log.d(LOG_TAG, "Values " + tableLayoutCorners[0] + ", " + tableLayoutCorners[1]);
Run Code Online (Sandbox Code Playgroud)
所有初始化完成后添加此代码.图像被分成一个包含在a中的ImageViews(cells []数组)数组TableLayout
.单元格[0]是左上角ImageView
,我选择了单元格[4],因为它位于中间的某个位置,绝对不应该有(0,0)的坐标.
上面显示的代码仍然给我在日志中的所有0,我真的不明白,因为各种拼图正确显示.(我为tableLayoutCorners和默认可见性尝试了public int,两者都给出了相同的结果.)
我不知道这是否重要,但ImageView
s最初没有给出尺寸.ImageView
当我给它一个要显示的图像时,视图自动初始化时确定s 的大小.这可能会导致它们的值为0,即使这些日志代码是在它们被赋予图像并自动调整大小之后吗?为了解决这个问题,我添加了tableLayout.requestLayout()
如上所示的代码,但这没有帮助.
Rom*_*Guy 607
使用View.getLocationOnScreen()
和/或getLocationInWindow()
.
Sur*_*gch 107
接受的答案实际上没有说明如何获得位置,所以这里有更多细节.传入int
长度为2 的数组,并将值替换为视图的(x,y)坐标(顶部,左上角).
int[] location = new int[2];
myView.getLocationOnScreen(location);
int x = location[0];
int y = location[1];
Run Code Online (Sandbox Code Playgroud)
笔记
getLocationOnScreen
用getLocationInWindow
应该给在大多数情况下,相同的结果(见这个答案).但是,如果您在像Dialog或自定义键盘这样的较小窗口中,那么您需要选择哪一个更适合您的需求.(0,0)
如果您调用此方法,则会得到,onCreate
因为视图尚未布局.您可以使用a ViewTreeObserver
来监听布局完成后您可以获得测量的坐标.(见这个答案.)Nav*_*thy 78
首先,您必须获取视图的localVisible矩形
例如:
Rect rectf = new Rect();
//For coordinates location relative to the parent
anyView.getLocalVisibleRect(rectf);
//For coordinates location relative to the screen/display
anyView.getGlobalVisibleRect(rectf);
Log.d("WIDTH :", String.valueOf(rectf.width()));
Log.d("HEIGHT :", String.valueOf(rectf.height()));
Log.d("left :", String.valueOf(rectf.left));
Log.d("right :", String.valueOf(rectf.right));
Log.d("top :", String.valueOf(rectf.top));
Log.d("bottom :", String.valueOf(rectf.bottom));
Run Code Online (Sandbox Code Playgroud)
希望这会有所帮助
Sim*_*mon 46
使用全局布局监听器一直很适合我.它具有能够在布局改变时重新测量事物的优点,例如,如果将某些内容设置为View.GONE或添加/删除子视图.
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// inflate your main layout here (use RelativeLayout or whatever your root ViewGroup type is
LinearLayout mainLayout = (LinearLayout ) this.getLayoutInflater().inflate(R.layout.main, null);
// set a global layout listener which will be called when the layout pass is completed and the view is drawn
mainLayout.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
//Remove the listener before proceeding
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
mainLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
mainLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
// measure your views here
}
}
);
setContentView(mainLayout);
}
Run Code Online (Sandbox Code Playgroud)
Ste*_*ley 18
按照Romain Guy的评论,这是我如何修复它.希望它能帮助那些也有这个问题的人.
我确实试图在屏幕布局之前获得观点的位置,但事实并非如此.这些行已经在初始化代码运行后放置,所以我假设一切准备就绪.但是,此代码仍在onCreate()中; 通过试验Thread.sleep()我发现布局实际上没有完成,直到onCreate()一直到onResume()完成执行.实际上,代码试图在布局完成定位在屏幕上之前运行.通过将代码添加到OnClickListener(或其他一些Listener),获得了正确的值,因为它只能在布局完成后触发.
以下行被建议为社区编辑:
请用 onWindowfocuschanged(boolean hasFocus)
Ami*_*emi 12
第一种方式:
在Kotlin中,我们可以为视图创建一个简单的扩展:
fun View.getLocationOnScreen(): Point
{
val location = IntArray(2)
this.getLocationOnScreen(location)
return Point(location[0],location[1])
}
Run Code Online (Sandbox Code Playgroud)
并简单地获取坐标:
val location = yourView.getLocationOnScreen()
val absX = location.x
val absY = location.y
Run Code Online (Sandbox Code Playgroud)
第二种方式:
第二种方法更简单:
fun View.absX(): Int
{
val location = IntArray(2)
this.getLocationOnScreen(location)
return location[0]
}
fun View.absY(): Int
{
val location = IntArray(2)
this.getLocationOnScreen(location)
return location[1]
}
Run Code Online (Sandbox Code Playgroud)
并简单地得到X view.absX()
和Yview.absY()
您可以使用getLocationOnScreen()
或获取视图的坐标getLocationInWindow()
之后,x
并且y
应该是视图的左上角。如果您的根布局小于屏幕(如在对话框中),则使用getLocationInWindow
将相对于其容器,而不是整个屏幕。
int[] point = new int[2];
view.getLocationOnScreen(point); // or getLocationInWindow(point)
int x = point[0];
int y = point[1];
Run Code Online (Sandbox Code Playgroud)
注意:如果值始终为 0,则您可能会在请求位置之前立即更改视图。
为确保视图有机会更新,请在使用view.post
以下命令计算视图的新布局后运行您的位置请求:
view.post(() -> {
// Values should no longer be 0
int[] point = new int[2];
view.getLocationOnScreen(point); // or getLocationInWindow(point)
int x = point[0];
int y = point[1];
});
Run Code Online (Sandbox Code Playgroud)
~~
val point = IntArray(2)
view.getLocationOnScreen(point) // or getLocationInWindow(point)
val (x, y) = point
Run Code Online (Sandbox Code Playgroud)
注意:如果值始终为 0,则您可能会在请求位置之前立即更改视图。
为确保视图有机会更新,请在使用view.post
以下命令计算视图的新布局后运行您的位置请求:
view.post {
// Values should no longer be 0
val point = IntArray(2)
view.getLocationOnScreen(point) // or getLocationInWindow(point)
val (x, y) = point
}
Run Code Online (Sandbox Code Playgroud)
我建议创建一个扩展函数来处理这个:
// To use, call:
val (x, y) = view.screenLocation
val View.screenLocation get(): IntArray {
val point = IntArray(2)
getLocationOnScreen(point)
return point
}
Run Code Online (Sandbox Code Playgroud)
如果您需要可靠性,还可以添加:
view.screenLocationSafe { x, y -> Log.d("", "Use $x and $y here") }
fun View.screenLocationSafe(callback: (Int, Int) -> Unit) {
post {
val (x, y) = screenLocation
callback(x, y)
}
}
Run Code Online (Sandbox Code Playgroud)
除了上述答案之外,对于您应该在何时何地致电的问题getLocationOnScreen
?
对于与 相关的任何信息,view
只有在视图在屏幕上布局(创建)后才可用。因此,要获取位置,请将您的代码放入view.post(Runnable)
其中,view
在布局后调用,如下所示:
view.post(new Runnable() {
@Override
public void run() {
// This code will run when view created and rendered on screen
// So as the answer to this question, you can put the code here
int[] location = new int[2];
myView.getLocationOnScreen(location);
int x = location[0];
int y = location[1];
}
});
Run Code Online (Sandbox Code Playgroud)
我的utils函数用于获取视图位置,它将返回一个Point
带有x value
和的对象y value
public static Point getLocationOnScreen(View view){
int[] location = new int[2];
view.getLocationOnScreen(location);
return new Point(location[0], location[1]);
}
Run Code Online (Sandbox Code Playgroud)
运用
Point viewALocation = getLocationOnScreen(viewA);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
265174 次 |
最近记录: |