Can not set gravity with setGravity vertically programatically. Is this an android bug or feature?

StackOverflow https://stackoverflow.com/questions/8821039

  •  27-10-2019
  •  | 
  •  

Question

I have a custom View with four buttons. I created the view in Java because I want to animate the buttons. I want to center the text on the buttons, but I can do this only horizontally (left-right) but not vertically. The text sticks to the top.

Here is the most basic code I could get working:

public class CopyOfGameView extends ViewGroup implements View.OnClickListener {

    private Main main;

    public CopyOfGameView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CopyOfGameView(Context context) {
        super(context);
    }

    public void reset(Main main) {
        this.main = main;
        removeAllViews();

        for (int c = 0; c < 4; c++) {
            ButtonView buttonView = new ButtonView(getContext(), c);
            buttonView.setText("x");
            buttonView.setTextSize(6);
            buttonView.setGravity(Gravity.CENTER);
            addView(buttonView);
        }
    }
        @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int w = getWidth();
        int h = getHeight();
        int oneFourth = h / 4;

        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            ButtonView buttonView = (ButtonView) getChildAt(i);
            int left = 0;
            int top = oneFourth * buttonView.getRow();
            int right = w;
            int bottom = oneFourth * buttonView.getRow() + oneFourth;
            buttonView.layout(left, top, right, bottom);
        }
    }

    public void onClick(View v) {}

    protected ButtonView findButtonView(int row) {
        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            View v = getChildAt(i);
            if (v instanceof ButtonView) {
                ButtonView buttonView = (ButtonView) v;
                if (buttonView.getRow() == row) {
                    return buttonView;
                }
            }
        }
        return null;
    }

    protected class ButtonView extends Button {
        private int row;

        protected ButtonView(Context context, int row) {
            super(context);
            this.row = row;

            Drawable image = getResources().getDrawable(R.drawable.btn_black);
            setBackgroundDrawable(image);
            setClickable(true);
            setOnClickListener(CopyOfGameView.this);
        }

        public int getRow() {
            return row;
        }

        public void setRow(int row) {
            this.row = row;
        }
    }
}

Is this normal or is this a bug in Android? How can I center the text vertically?

Was it helpful?

Solution

The project was revived under another name and with one year experience I was able to solve the problem. I also implemented AutoResizeTextView, because it fit with the project. I took AutoResizeTextView from the following post: Auto Scale TextView Text to Fit within Bounds

But I had to modify it as this solution applies the measured dimensions in the onLayout method. But I needed the dimensions at measuring so I moved this logic from onLayout to onMeasure.

Basically I inherited ButtonView from LinearLayout, gave it an AutoResizeTextView child and played with Android Measuring (onMeasure, onLayout and layout).

Remember, I could not use Chase's solution of inheriting the whole View from LinearLyout, because I animated the ButtonViews.

Details about measuring: I measured the ButtonView in CopyOfGameView's onMeasure, then measured the AutoResizeTextView in ButtonView's onMeasure. Then in ButtonView's layout method I centered the TextView vertically.

OTHER TIPS

I would recommend inheriting from LinearLayout and not ViewGroup as it seems that it would be easier to accomplish the layout you need but I understand that this might not be an option because of animations you want to apply.

What is probably happening with your buttons is that the layout height is set to wrap content, which makes them only as tall as the text when measured. This would make the text appear to vertically aligned to the top even though you specify a center gravity. To fix this, you will have to calculate and set the dimensions (the height and width of the LayoutParams) of your button views (calling buttonView.layout() will not do this).

As a hint, try setting the background color of your button views to get a better understanding of the position and size of your views.

Can you add more details? i believe you need to specify this

setLayoutParams(new LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));

so that you could set it to center... because i think the default for android is that it wraps it's content

setLayoutParams(new LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); so you don't need to adjust it anymore....

please add a screenshot... so that we could help you :)

you need to set the Layout Params like this

LayoutParams lp;
lp = (LayoutParams) buttonView.getLayoutParams();
lp.gravity = Gravity.CENTER;
buttonView.setLayoutParams(lp);

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top