Anil Ravsaheb Ghodake
Anil Ravsaheb Ghodake

Reputation: 1596

Android creating run-time view not using device width and height

I am creating layout dynamically by using left and top values of api. The api data is is like below:-

{
"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"
    }
]}

And the code I have written to create layout is:

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

So using above code, I am getting output like below (almost perfect). Just having issue with spacing between each item:

enter image description here

Note: I have already implemented this api in React Native by applying absolute position parameter on view. It's showing UI perfectly on many Android devices, I have tested it.

So my problems are:

  1. Why layout not taking full device width and height, after setting layout parmas to MATCH_PARENT/FILL_PARENT? (Also tried with fixed layout values like 120dp width and height given.)
  2. When I tried with setting background to each item, can see each item gets overlapped with its corresponding item. Don't know WHY?

Have I done anything wrong in the above code?

Upvotes: 3

Views: 387

Answers (1)

Danylo.Vus
Danylo.Vus

Reputation: 1009

First of all you need to get sizes of view in which seats will be placed. Easy way - to get display width and height:

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

but this will be hard to maintain (you will have no opportunity to move this to other container) Better way - create custom ViewGroup (for example FrameLayout) and override onMeasure/onLayout methods see How to size an Android view based on its parent's dimensions

After you get sizes, you must recalculate positions. First get maximum left and maximum top point. Than calculate scale coefficient. For example if screan width is 600, maximum left point is 250 and width of seat is 100 than scale width coefficient is (600-100)/250 = 2 Than add all your seats using coefficients :

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

Note,that if you want to add this to vertical scroll than you need change logic of getting height (for example if number of seat is less than 10,draw them all on screan, if more that 10,than height must be more than screen(or ViewGroup) heigth to allow vertical scroll.

Upvotes: 2

Related Questions