我正在写一个游戏,可以在屏幕上拖动计数器。我想为每个计数器使用City
子视图,并在ImageView
父视图内设置绝对位置。
我已经阅读了一些SO帖子,介绍了各种布局类相对于已弃用的FrameLayout
的优势,并且我不想使用AbsoluteLayout
,因为计数器必须彼此独立地移动。这些帖子似乎都没有解决我遇到的特定问题,尽管如果有人可以指出我的建议,我会很高兴。
这是布局XML:
RelativeLayout
因为我不想对屏幕的大小做假设,所以我将每个孩子的大小设置为父屏幕大小的一小部分,放在<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_game"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff808080">
</FrameLayout>
中:
onMeasure()
出于完整性考虑,这里是我将子视图添加到父视图的地方:
package uk.co.fractalmaze.counterspin.widget
import android.content.Context
import android.graphics.Color
import android.util.Log
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.ImageView
class CounterView(context: Context, private val label: String, private val offset: Int) : ImageView(context)
{
init
{
// Set the background color.
val color = if (offset > 0) Color.GREEN else Color.RED
setBackgroundColor(color)
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int)
{
// Set the position and size.
val parentWidth = MeasureSpec.getSize(widthMeasureSpec)
val parentHeight = MeasureSpec.getSize(heightMeasureSpec)
val size = Math.min(parentWidth, parentHeight) / 2
val left = offset * size
Log.i(javaClass.simpleName, "Parent size ($parentWidth, $parentHeight) to $label child position ($left, 0) size $size")
setMeasuredDimension(size, size)
layoutParams = createLayoutParams(left, 0, size, size)
}
private fun createLayoutParams(left: Int, top: Int, width: Int, height: Int): ViewGroup.LayoutParams
{
// Create a margin params object.
val params = FrameLayout.LayoutParams(width, height)
params.leftMargin = left
params.topMargin = top
return params
}
}
以下是结果的屏幕截图:
我希望红色和绿色的子视图可以并排显示并填充整个屏幕,但是它们合起来仅占据一半的宽度。这由logcat输出确认,该输出显示package uk.co.fractalmaze.counterspin.activity
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.FrameLayout
import uk.co.fractalmaze.counterspin.R
import uk.co.fractalmaze.counterspin.widget.CounterView
class GameActivity : AppCompatActivity()
{
override fun onCreate(savedInstanceState: Bundle?)
{
// Call the superclass.
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_game)
// Add a left and right view to the group.
val group = findViewById<FrameLayout>(R.id.activity_game)
group.addView(CounterView(applicationContext, "left", 0))
group.addView(CounterView(applicationContext, "right", 1))
}
}
解码的父级宽度为1080,然后为540,导致子级宽度为540,然后为270。这在模拟的Pixel 3上运行,该像素3的屏幕宽度为1080像素:< / p>
MeasureSpec
谁能告诉我:
答案 0 :(得分:0)
使用LinearLayout
代替FrameLayout
,例如:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:weightSum="2">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#ff0000">
<!--child 1-->
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#00ff00">
<!--child 2-->
</LinearLayout>
</LinearLayout>
答案 1 :(得分:0)
我有一个解决方法,但是我不确定为什么会起作用。我更改了an error occurred on property 730
Trillium Ln
Lilburn, GA 30047:
Message: no such element: Unable to locate element: {"method":"css selector","selector":"span.current-bid"}
(Session info: chrome=74.0.3729.131)
(Driver info: chromedriver=2.40.565498 (ea082db3280dd6843ebfb08a625e3eb905c4f5ab),platform=Windows NT 10.0.14393 x86_64)
an error occurred on property 225 Marriott Ave
Schenectady, NY 12304:
Message: no such element: Unable to locate element: {"method":"css selector","selector":"span.current-bid"}
(Session info: chrome=74.0.3729.131)
(Driver info: chromedriver=2.40.565498 (ea082db3280dd6843ebfb08a625e3eb905c4f5ab),platform=Windows NT 10.0.14393 x86_64)
an error occurred on property 17 Spring Meadows Dr
Ormond Beach, FL 32174:
Message: no such element: Unable to locate element: {"method":"css selector","selector":"span.current-bid"}
(Session info: chrome=74.0.3729.131)
(Driver info: chromedriver=2.40.565498 (ea082db3280dd6843ebfb08a625e3eb905c4f5ab),platform=Windows NT 10.0.14393 x86_64)
an error occurred on property 730
Trillium Ln
Lilburn, GA 30047:
Message: no such element: Unable to locate element: {"method":"css selector","selector":"span.current-bid"}
(Session info: chrome=74.0.3729.131)
(Driver info: chromedriver=2.40.565498 (ea082db3280dd6843ebfb08a625e3eb905c4f5ab),platform=Windows NT 10.0.14393 x86_64)
an error occurred on property 225 Marriott Ave
Schenectady, NY 12304:
Message: no such element: Unable to locate element: {"method":"css selector","selector":"span.current-bid"}
(Session info: chrome=74.0.3729.131)
(Driver info: chromedriver=2.40.565498 (ea082db3280dd6843ebfb08a625e3eb905c4f5ab),platform=Windows NT 10.0.14393 x86_64)
,以便它使用 parent 视图的所需大小创建布局参数:
CounterView.onMeasure()
这是结果:
请注意,logcat输出显示父视图大小不减半:
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int)
{
// Set the position and size.
val parentWidth = MeasureSpec.getSize(widthMeasureSpec)
val parentHeight = MeasureSpec.getSize(heightMeasureSpec)
val parentSize = Math.min(parentWidth, parentHeight)
val size = parentSize / 2
val left = offset * size
Log.i(javaClass.simpleName, "Parent size ($parentWidth, $parentHeight) to $label child position ($left, 0)")
setMeasuredDimension(size, size)
layoutParams = createLayoutParams(left, 0, parentSize, parentSize)
}
这足以让我继续编写应用程序,但是任何人都可以解释一下这里发生了什么吗?