Простой пользовательский интерфейс Android - круги (дочерние виды) в RelativeLayout - PullRequest
0 голосов
/ 06 мая 2011

Я очень новичок в Android, и у меня возникают проблемы с выяснением того, как программно размещать представления в RelativeLayout. Я хочу создать 4 окружности (дочерние представления) с определенным радиусом (скажем, 50 пикселей) в центре контейнера RelativeLayout, чтобы выглядело, как будто у меня есть воображаемый квадрат в центре RelativeLayout, и каждая вершина является центр одного из кругов.

Я могу нарисовать круг на виде; это достаточно просто:)

class CircleView extends View {
    ...
    protected void onDraw(Canvas canvas) {
        // draw circle on canvas
    }
}

Что я не могу понять, так это как расположить представления. Кажется, что они нарисованы друг на друге, хотя я устанавливаю LayoutParams и Id для каждого из дочерних представлений.

class Circles extends RelativeLayout {
    public Circles(Context c) {
        super(c);
        addChildViews();
    }

    ...
    private void addChildViews() {
        final Context c = getContext();
        final CircleView v0 = new CircleView(c);
        v0.setId(0);

        final RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        params.addRule(RelativeLayout.LEFT_OF, 1);
        params.addRule(RelativeLayout.ABOVE, 2);
        v0.setLayoutParams(params);
        addView(v0);
        ....
        // and so on, with relative layout params for other 3 views
    }
}

Может кто-нибудь поставить меня на правильный путь, пожалуйста? Я также не знаю, вызываю ли я addChildViews в нужное время в цикле рисования, и приводит ли это к тому, что они рисуются друг на друге. Большое спасибо за любую помощь.

1 Ответ

0 голосов
/ 06 мая 2011

Две вещи

1) Действие по умолчанию для представления - заполнить его родительский элемент, поэтому, применяя (LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT) в качестве LayoutParams, вы создаете четыре вида с высотой и шириной размера родительского макета ( предположительно экран), поэтому вы увидите только один, так как остальные будут расположены за кадром.

Чтобы это исправить, либо установите желаемый размер кружков в качестве LayoutParms,

float dpi = getResources().getDisplayMetrics().density;
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams((int)(50.0f * dpi), (int)(50.0f * dpi));

или вы можете переопределить метод onMeasure (int x, int y) в круговом представлении следующим образом:

        @Override
        public void onMeasure(int x, int y) {
            float dpi = getResources().getDisplayMetrics().density;
            setMeasuredDimension((int)(50.0f * dpi), (int)(50.0f * dpi));
            }

2) Не устанавливайте для своего идентификатора просмотра значение 0 ... Я не могу вспомнить, зарезервировано ли оно системой или чем-то, но это не очень хорошо играет.

Кроме того, если вы хотите, чтобы все круги центрировались в ваших кругах, вам нужно будет установить их гравитацию в центр следующим образом.

    public class Circles extends RelativeLayout {
        public Circles (Context ctx) {
            super(ctx);
            this.setGravity(Gravity.CENTER);
            addViewChildren();
        }

Это отцентрирует всех детей кругов, давая вам желаемый результат.

...