deekay
deekay

Reputation: 35

Android RelativeLayout programmatically ALIGN_PARENT_BOTTOM and marginBottom behavior

I'm trying to build a simple circleView with two TextViews and a divider in the middle. I'm trying to do it without XML.

First, I added the circleView to a LinearLayout which takes space in entire screen. When a TextView is ALIGN_PARENT_TOP, it behaves as I 0expected (it sticks to the top of the circleView), but when the TextView has ALIGN_PARENT_BOTTOM, the circleView stretches vertically all the way in the entire screen height. Why the behavior?

enter image description here

My code:

public class MainActivity extends AppCompatActivity {

  @RequiresApi(api = Build.VERSION_CODES.O)
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    int screenHeight = Resources.getSystem().getDisplayMetrics().heightPixels;

    LinearLayout layout = new LinearLayout(this);
    layout.setOrientation(LinearLayout.VERTICAL);
    setContentView(layout);

    RelativeLayout circleView = new RelativeLayout(this);
    GradientDrawable gd = new GradientDrawable();
    gd.setSize(screenHeight/3, screenHeight/3);
    gd.setColor(Color.WHITE);
    gd.setStroke(10, Color.GRAY);
    gd.setCornerRadius(screenHeight/3/2);
    circleView.setBackground(gd);
    layout.addView(circleView);

    View divider = new View(this);
    divider.setBackgroundColor(Color.GRAY);
    RelativeLayout.LayoutParams dividerLP = new RelativeLayout.LayoutParams(screenHeight / 3 / 10 * 9, 3);
    dividerLP.addRule(RelativeLayout.CENTER_IN_PARENT);
    divider.setLayoutParams(dividerLP);

    circleView.addView(divider);

    TextView tvTop = new TextView(this);
    tvTop.setText("Top");
    tvTop.setTextSize(50);
    RelativeLayout.LayoutParams tvTopLP = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
    tvTopLP.addRule(RelativeLayout.ALIGN_PARENT_TOP);
    tvTopLP.addRule(RelativeLayout.CENTER_HORIZONTAL);
    tvTopLP.topMargin = 100;
    tvTop.setLayoutParams(tvTopLP);

    circleView.addView(tvTop);

    TextView tvBottom = new TextView(this);
    tvBottom.setText("Bottom");
    tvBottom.setTextSize(50);
    RelativeLayout.LayoutParams tvBottomLP = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
    tvBottomLP.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); // this seems to break the layout
    tvBottomLP.addRule(RelativeLayout.CENTER_HORIZONTAL);
    tvBottomLP.bottomMargin = 100;
    tvBottom.setLayoutParams(tvBottomLP);
    circleView.addView(tvBottom);

    getSupportActionBar().hide();
  }
}

As my attempt to solve the problem, I wrapped the circleView in a LinearLayout of a desired hight. Now the circleView does not stretch, but bottomMargin of the TextView does not work. How can I get the bottomMargin to work, or is there a better way of achieving what I want?

enter image description here

public class MainActivity extends AppCompatActivity {

  @RequiresApi(api = Build.VERSION_CODES.O)
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    int screenHeight = Resources.getSystem().getDisplayMetrics().heightPixels;

    LinearLayout layout = new LinearLayout(this);
    layout.setOrientation(LinearLayout.VERTICAL);
    setContentView(layout);

    LinearLayout linearLayout1 = new LinearLayout(this);
    linearLayout1.setBackgroundColor(Color.CYAN);
    LinearLayout.LayoutParams lp1 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);
    lp1.weight = 1;
    linearLayout1.setLayoutParams(lp1);
    layout.addView(linearLayout1);

    LinearLayout linearLayout2 = new LinearLayout(this);
    linearLayout2.setGravity(Gravity.CENTER);
    linearLayout2.setBackgroundColor(Color.YELLOW);
    LinearLayout.LayoutParams lp2 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);
    lp2.weight = 1;
    linearLayout2.setLayoutParams(lp2);
    layout.addView(linearLayout2);

    RelativeLayout circleView = new RelativeLayout(this);
    GradientDrawable gd = new GradientDrawable();
    gd.setSize(screenHeight/3, screenHeight/3);
    gd.setColor(Color.WHITE);
    gd.setStroke(10, Color.GRAY);
    gd.setCornerRadius(screenHeight/3/2);
    circleView.setBackground(gd);
    linearLayout2.addView(circleView);

    View divider = new View(this);
    divider.setBackgroundColor(Color.GRAY);
    RelativeLayout.LayoutParams dividerLP = new RelativeLayout.LayoutParams(screenHeight / 3 / 10 * 9, 3);
    dividerLP.addRule(RelativeLayout.CENTER_IN_PARENT);
    divider.setLayoutParams(dividerLP);

    circleView.addView(divider);

    TextView tvTop = new TextView(this);
    tvTop.setText("Top");
    tvTop.setTextSize(50);
    RelativeLayout.LayoutParams tvTopLP = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
    tvTopLP.addRule(RelativeLayout.ALIGN_PARENT_TOP);
    tvTopLP.addRule(RelativeLayout.CENTER_HORIZONTAL);
    tvTopLP.topMargin = 100;
    tvTop.setLayoutParams(tvTopLP);

    circleView.addView(tvTop);

    TextView tvBottom = new TextView(this);
    tvBottom.setText("Bottom");
    tvBottom.setTextSize(50);
    RelativeLayout.LayoutParams tvBottomLP = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
    tvBottomLP.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
    tvBottomLP.addRule(RelativeLayout.CENTER_HORIZONTAL);
    tvBottomLP.bottomMargin = 100; // why this isn't working?
    tvBottom.setLayoutParams(tvBottomLP);

    circleView.addView(tvBottom);

    LinearLayout linearLayout3 = new LinearLayout(this);
    linearLayout3.setBackgroundColor(Color.BLUE);
    LinearLayout.LayoutParams lp3 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);
    lp3.weight = 1;
    linearLayout3.setLayoutParams(lp3);
    layout.addView(linearLayout3);

    getSupportActionBar().hide();
  }
}

Upvotes: 0

Views: 79

Answers (1)

Jaydeep parmar
Jaydeep parmar

Reputation: 569

I have modified your code and used LinearLayout for circle instead of RelativeLayout and added Gravity to LinearLayout so your UI problem is fixed. I have attached the modified code below.

  public class MainActivity extends AppCompatActivity {
    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        int screenHeight = Resources.getSystem().getDisplayMetrics().heightPixels;

        LinearLayout layout = new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);
        setContentView(layout);

        LinearLayout linearLayout1 = new LinearLayout(this);
        linearLayout1.setBackgroundColor(Color.CYAN);
        LinearLayout.LayoutParams lp1 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);
        lp1.weight = 1;
        linearLayout1.setLayoutParams(lp1);
        layout.addView(linearLayout1);

        LinearLayout linearLayout2 = new LinearLayout(this);
        linearLayout2.setGravity(Gravity.CENTER);
        linearLayout2.setBackgroundColor(Color.YELLOW);
        LinearLayout.LayoutParams lp2 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);
        lp2.weight = 1;
        linearLayout2.setLayoutParams(lp2);
        layout.addView(linearLayout2);

        LinearLayout circleView = new LinearLayout(this);
        circleView.setOrientation(LinearLayout.VERTICAL);
        circleView.setGravity(Gravity.CENTER)
        GradientDrawable gd = new GradientDrawable();
        gd.setSize(screenHeight/3, screenHeight/3);
        gd.setColor(Color.WHITE);
        gd.setStroke(10, Color.GRAY);
        gd.setCornerRadius(screenHeight/3/2);
        circleView.setBackground(gd);
        linearLayout2.addView(circleView);

        TextView tvTop = new TextView(this);
        tvTop.setText("Top");
        tvTop.setTextSize(50);
        RelativeLayout.LayoutParams tvTopLP = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
        tvTopLP.addRule(RelativeLayout.ALIGN_PARENT_TOP);
        tvTopLP.addRule(RelativeLayout.CENTER_HORIZONTAL);
        tvTopLP.bottomMargin = 70;
        tvTop.setLayoutParams(tvTopLP);

        circleView.addView(tvTop);

        View divider = new View(this);
        divider.setBackgroundColor(Color.GRAY);
        RelativeLayout.LayoutParams dividerLP = new RelativeLayout.LayoutParams(screenHeight / 3 / 10 * 9, 3);
        dividerLP.addRule(RelativeLayout.CENTER_IN_PARENT);
        divider.setLayoutParams(dividerLP);

        circleView.addView(divider);

        TextView tvBottom = new TextView(this);
        tvBottom.setText("Bottom");
        tvBottom.setTextSize(50);
        RelativeLayout.LayoutParams tvBottomLP = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
        tvBottomLP.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
        tvBottomLP.addRule(RelativeLayout.CENTER_HORIZONTAL);
        tvBottomLP.topMargin = 50; // why this isn't working?
        tvBottom.setLayoutParams(tvBottomLP);

        circleView.addView(tvBottom);

        LinearLayout linearLayout3 = new LinearLayout(this);
        linearLayout3.setBackgroundColor(Color.BLUE);
        LinearLayout.LayoutParams lp3 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);
        lp3.weight = 1;
        linearLayout3.setLayoutParams(lp3);
        layout.addView(linearLayout3);

        getSupportActionBar().hide();
    }
}

Hope you got your solution :)

Upvotes: 1

Related Questions