用子视图网格填充屏幕,但是子视图是预期大小的一半 - java

我正在写一个游戏,可以在屏幕上拖动计数器。我想为每个计数器使用ImageView子视图,并在FrameLayout父视图内设置绝对位置。

我已经阅读了一些SO帖子,介绍了各种布局类优于不推荐使用的AbsoluteLayout的优势,并且我不想使用RelativeLayout,因为计数器必须彼此独立地移动。这些帖子似乎都没有解决我遇到的特定问题,但是如果有人可以指出我的建议,我会很高兴。

这是布局XML:

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

为了完整起见,这里是我将子视图添加到父视图的地方:

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

这是结果的屏幕截图:

用子视图网格填充屏幕,但是子视图是预期大小的一半 - java

我希望红色和绿色的子视图可以并排显示并填充整个屏幕,但是它们合起来仅占据一半的宽度。这由logcat输出确认,该输出显示MeasureSpec解码后的父级宽度为1080,然后为540,导致子级宽度为540,然后为270。这在模拟的Pixel 3上运行,该像素3的屏幕宽度为1080像素:

2019-05-09 22:06:33.493 15575-15575/uk.co.fractalmaze.counterspin I/CounterView: Parent size (1080, 1808) to left child position (0, 0) size 540
2019-05-09 22:06:33.493 15575-15575/uk.co.fractalmaze.counterspin I/CounterView: Parent size (1080, 1808) to right child position (540, 0) size 540
2019-05-09 22:06:33.560 15575-15575/uk.co.fractalmaze.counterspin I/CounterView: Parent size (540, 540) to left child position (0, 0) size 270
2019-05-09 22:06:33.561 15575-15575/uk.co.fractalmaze.counterspin I/CounterView: Parent size (540, 540) to right child position (270, 0) size 270

谁能告诉我:

为什么父视图将自身调整为宽度540?
如何使子视图填充整个1080像素?

参考方案

使用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>

Android Firebase:将数据保存到数据库 - java

我正在尝试从Firebase保存和检索数据,但是在获取正确的语法时遇到了一些麻烦。用户通过电子邮件和密码的身份验证方法进行注册,并使用相同的详细信息登录。我有两个编辑文本字段,要求输入名称和语句。在两个编辑文本框下面有一个按钮,用于将数据保存到数据库。private void saveQuote(){ String name = author.getText…

当回复有时是一个对象有时是一个数组时,如何在使用改造时解析JSON回复? - java

我正在使用Retrofit来获取JSON答复。这是我实施的一部分-@GET("/api/report/list") Observable<Bills> listBill(@Query("employee_id") String employeeID); 而条例草案类是-public static class…

java.net.URI.create异常 - java

java.net.URI.create("http://adserver.adtech.de/adlink|3.0") 抛出java.net.URISyntaxException: Illegal character in path at index 32: http://adserver.adtech.de/adlink|3.0 虽然n…

java:继承 - java

有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…

Java-如何将此字符串转换为日期? - java

我从服务器收到此消息,我不明白T和Z的含义,2012-08-24T09:59:59Z将此字符串转换为Date对象的正确SimpleDateFormat模式是什么? java大神给出的解决方案 这是ISO 8601标准。您可以使用SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM…