Android создает представление во время выполнения, не используя ширину и высоту устройства - PullRequest
0 голосов
/ 27 апреля 2018

Я создаю макет динамически, используя левое и верхнее значения 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

Примечание: я уже реализовал этот API в React Native, применив параметр абсолютного положения к виду. Он отлично показывает интерфейс на многих устройствах Android, я его протестировал.

Итак, мои проблемы:

  1. Почему макет не принимает всю ширину и высоту устройства после установки паролей макета в MATCH_PARENT / FILL_PARENT? (Также пробовал с фиксированными значениями макета, такими как ширина и высота 120dp.)
  2. Когда я попытался установить фон для каждого элемента, можно увидеть, что каждый элемент перекрывается с соответствующим элементом. Не знаю, ПОЧЕМУ?

Я что-то не так сделал в приведенном выше коде?

1 Ответ

0 голосов
/ 16 мая 2018

Прежде всего вам необходимо узнать размеры мест, в которых будут размещены места. Простой способ - получить ширину и высоту дисплея:

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), чтобы обеспечить вертикальную прокрутку.

...