Android创建运行时视图,不使用设备的宽度和高度

3
我正在使用API的左侧和顶部值动态创建布局。 API数据如下:
{
"isSuccess": true,
"data": [{
        "left": "159",
        "top": "17",
        "seat_name": "Staff"
    },
    {
        "left": "159",
        "top": "65",
        "seat_name": "Staff"
    },
    {
        "left": "238",
        "top": "15",
        "seat_name": "3"
    },
    {
        "left": "239",
        "top": "66",
        "seat_name": "4"
    },
    {
        "left": "313",
        "top": "13",
        "seat_name": "5"
    },
    {
        "left": "314",
        "top": "67",
        "seat_name": "6"
    },
    {
        "left": "241",
        "top": "223",
        "seat_name": "7"
    },
    {
        "left": "239",
        "top": "160",
        "seat_name": "8"
    },
    {
        "left": "314",
        "top": "159",
        "seat_name": "9"
    },
    {
        "left": "315",
        "top": "223",
        "seat_name": "10"
    },
    {
        "left": "366",
        "top": "223",
        "seat_name": "11"
    },
    {
        "left": "364",
        "top": "160",
        "seat_name": "12"
    },
    {
        "left": "374",
        "top": "71",
        "seat_name": "13"
    },
    {
        "left": "371",
        "top": "12",
        "seat_name": "14"
    },
    {
        "left": "430",
        "top": "12",
        "seat_name": "15"
    },
    {
        "left": "432",
        "top": "68",
        "seat_name": "16"
    },
    {
        "left": "428",
        "top": "158",
        "seat_name": "17"
    },
    {
        "left": "431",
        "top": "223",
        "seat_name": "18"
    },
    {
        "left": "493",
        "top": "12",
        "seat_name": "19"
    },
    {
        "left": "492",
        "top": "64",
        "seat_name": "20"
    },
    {
        "left": "491",
        "top": "158",
        "seat_name": "21"
    },
    {
        "left": "486",
        "top": "222",
        "seat_name": "22"
    },
    {
        "left": "555",
        "top": "14",
        "seat_name": "23"
    },
    {
        "left": "553",
        "top": "65",
        "seat_name": "24"
    },
    {
        "left": "553",
        "top": "160",
        "seat_name": "25"
    },
    {
        "left": "553",
        "top": "220",
        "seat_name": "26"
    },
    {
        "left": "616",
        "top": "16",
        "seat_name": "27"
    },
    {
        "left": "618",
        "top": "65",
        "seat_name": "28"
    },
    {
        "left": "620",
        "top": "117",
        "seat_name": "29"
    },
    {
        "left": "618",
        "top": "166",
        "seat_name": "30"
    },
    {
        "left": "619",
        "top": "216",
        "seat_name": "31"
    }
]}

我编写的用于创建布局的代码如下:

    private void createLayout() {
    ScrollView objScrollView = new ScrollView(this);
    ViewGroup.LayoutParams objLayoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
    objScrollView.setLayoutParams(objLayoutParams);
    RelativeLayout objParentLayout = new RelativeLayout(this);
    RelativeLayout.LayoutParams objParentParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);

    int intId = 100;
    int intLeft = 0;
    for (int i = 0; i < arrobjSeats.size(); i++) {
        Seat objSeat = arrobjSeats.get(i);

        RelativeLayout objItemLayout = new RelativeLayout(this);
        RelativeLayout.LayoutParams objItemParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
        objItemParams.setMargins(objSeat.getIntTop() + 30, objSeat.getIntLeft() - 110, 0, 10);
        intLeft = objSeat.getIntTop();

        ImageView imgSeat = new ImageView(this);
        imgSeat.setImageResource(R.drawable.ic_airline_seat_recline_normal_black_24dp);
        imgSeat.setColorFilter(Color.parseColor(objSeat.getStrSeatColor()), android.graphics.PorterDuff.Mode.SRC_IN);
        imgSeat.setPadding(5, 5, 10, 25);
        imgSeat.setId(intId++);
        RelativeLayout.LayoutParams objImageParams = new RelativeLayout.LayoutParams(120, 80);
        objImageParams.addRule(RelativeLayout.CENTER_HORIZONTAL);

        TextView txtSeatName = new TextView(this);
        RelativeLayout.LayoutParams objTextParams = new RelativeLayout.LayoutParams(120, RelativeLayout.LayoutParams.WRAP_CONTENT);
        objTextParams.addRule(RelativeLayout.ALIGN_BOTTOM, imgSeat.getId());
        txtSeatName.setPadding(5, 10, 5, 5);
        txtSeatName.setTextColor(Color.parseColor(objSeat.getStrSeatColor()));
        txtSeatName.setText(objSeat.getStrSeatName());
        txtSeatName.setGravity(Gravity.CENTER);
        txtSeatName.setTextSize(16);

        objItemLayout.setTag(i);

        objItemLayout.addView(imgSeat, objImageParams);
        objItemLayout.addView(txtSeatName, objTextParams);

        objItemLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int intPosition = (int) v.getTag();
                Seat objSeat = arrobjSeats.get(intPosition);
                Toast.makeText(SeatActivity.this, "Seat=>" + objSeat.getIntSeatId() + "=>" + objSeat.getStrSeatName(), Toast.LENGTH_SHORT).show();
            }
        });
        objParentLayout.setBackgroundColor(Color.CYAN);
        objParentLayout.addView(objItemLayout, objItemParams);
        System.out.println("Final Color=>" + objSeat.getStrSeatColor());
    }
    objScrollView.addView(objParentLayout, objParentParams);
    relativeLayout.addView(objScrollView);
}

所以使用上述代码,我得到的输出结果如下(几乎完美)。只是每个项目之间的间距有问题:

enter image description here

注意:我已经通过在视图上应用绝对位置参数,在React Native中实现了此API。它在许多Android设备上完美地显示,我已经进行了测试。
所以我的问题是:
  1. 为什么布局在将布局参数设置为MATCH_PARENT/FILL_PARENT后没有占满整个设备的宽度和高度?(还尝试使用固定布局值,如给定120dp的宽度和高度。)
  2. 当我尝试为每个项目设置背景时,可以看到每个项目与其相应的项目重叠。不知道为什么?
在上面的代码中,我做错了什么吗?

1
你的 objItemLayoutwrap_content,因为你没有设置任何 LayoutParams。除此之外,我建议使用布局 XML,并使用 LayoutInflater 在运行时填充视图。在运行时排列视图将导致大量代码行,并且在某些情况下可能过于棘手。 - ADM
relativeLayout 是如何定义的?它似乎是您的顶层视图,但我不知道它在哪里定义。另外,您能提供一下 Seat 类吗? - Cheticamp
@Cheticamp,你可以在上面的代码中看到我的父布局是_Scrollview_,它的主要子布局是相对布局,而这个相对布局每个座位都是一个相对布局。**Seat类**只是一个模型类,用于存储座位名称、颜色和位置相关信息。 - Anil Ravsaheb Ghodake
我明白了。然而,代码的最后一行是relativeLayout.addView(objScrollView);。这将您的滚动视图添加到relativeLayout中,但我没有看到relativeLayout的定义在哪里。这就是我要问的相对布局。它与objParentLayout不同。 - Cheticamp
1
@AnilGhodake,您需要获取objScrollView的宽度。如何操作请参考https://dev59.com/8XI95IYBdhLWcg3wyA-c。然后找到最左边点的座位,接着可以计算所有座位左右边距的比例系数。例如,如果objScrollView的宽度为600,最左边点的位置是250,座位的宽度是100,则比例系数为(600-100)/250=2;之后,您只需使用objItemParams.setMargins(objSeat.getIntTop() * scaleCoef, objSeat.getIntLeft() - 110, 0, 10)即可添加座位。 - Danylo.Vus
显示剩余20条评论
1个回答

2

首先,您需要获取座位所放置的视图大小。 简单的方法是获取显示器的宽度和高度:

Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;

但这样很难维护(您将没有机会将其移动到其他容器中)更好的方法-创建自定义ViewGroup(例如FrameLayout),并覆盖onMeasure / onLayout方法,请参见如何根据其父级尺寸调整Android视图的大小

在获取尺寸后,您必须重新计算位置。首先获取最大左侧和最大顶部点。然后计算比例系数。例如,如果屏幕宽度为600,最大左侧点为250,座位宽度为100,则缩放宽度系数为(600-100)/ 250 = 2,然后使用系数添加所有座位:

objItemParams.setMargins(objSeat.getIntTop() * scaleCoefWidth, objSeat.getIntLeft() * scaleCoefHeigth, 0, 0);

请注意,如果您想将此内容添加到垂直滚动中,则需要更改获取高度的逻辑(例如,如果座位数量少于10个,请在屏幕上全部绘制;如果超过10个,则高度必须大于屏幕(或ViewGroup)高度以允许垂直滚动)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接