Форум программистов, компьютерный форум CyberForum.ru

Программирование Android

Войти
Регистрация
Восстановить пароль
 
contedevel
57 / 55 / 8
Регистрация: 07.10.2012
Сообщений: 590
#1

Отрисовка текста по центру canvas - Android

18.01.2015, 14:04. Просмотров 365. Ответов 0
Метки нет (Все метки)

Здравствуйте!
Понимаю, вопрос нубский, но никак не получается без костылей отрисовать текст по центру...
Вот код моего view-а:
Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
public class FloatingActionButton extends View {
    private String text;
    private int backgroundColor;
    private int pressedBackgroundColor;
    private int textColor;
    private float textSize;
    private Drawable icon;
    private TextPaint textPaint;
    private Paint paint;
    private Paint shadowPaint;
    //Button's parameters
    private float fabX;
    private float fabY;
    private float fabRadius;
    //Shadow's parameters
    private float shadowX;
    private float shadowY;
    private float shadowRadius;
    private boolean isPressed = false;
 
    public FloatingActionButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.FloatingActionButton,
                0, 0);
        try {
            text = a.getString(R.styleable.FloatingActionButton_text);
            textSize = a.getDimension(R.styleable.FloatingActionButton_textSize, 0);
            backgroundColor = a.getColor(R.styleable.FloatingActionButton_backgroundColor, 0xffffffff);
            pressedBackgroundColor = darker(backgroundColor);
            textColor = a.getColor(R.styleable.FloatingActionButton_textColor, 0xff000000);
            icon = a.getDrawable(R.styleable.FloatingActionButton_src);
        } finally {
            a.recycle();
        }
        init();
    }
 
    private void init() {
        textPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
        textPaint.setColor(textColor);
        textPaint.setTextAlign(Paint.Align.CENTER);
        if(textSize < 0.01f)
            textSize = textPaint.getTextSize();
        else
            textPaint.setTextSize(textSize);
 
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(backgroundColor);
 
        shadowPaint = new Paint(0);
        shadowPaint.setColor(0xb0101010);
        shadowPaint.setMaskFilter(new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL));
    }
 
    private int darker(int color) {
        float[] hsv = new float[3];
        Color.colorToHSV(color, hsv);
        hsv[2] *= 0.8f; // value component
        return Color.HSVToColor(hsv);
    }
 
    public float getTextSize() {
        return textSize;
    }
 
    public void setTextSize(float textSize) {
        this.textSize = textSize;
    }
 
    public String getText() {
        return text;
    }
 
    public void setText(String text) {
        this.text = text;
    }
 
    public int getBackgroundColor() {
        return backgroundColor;
    }
 
    @Override
    public void setBackgroundColor(int backgroundColor) {
        this.backgroundColor = backgroundColor;
        this.pressedBackgroundColor = darker(backgroundColor);
    }
 
    public int getTextColor() {
        return textColor;
    }
 
    public void setTextColor(int textColor) {
        this.textColor = textColor;
    }
 
    public Drawable getIcon() {
        return icon;
    }
 
    public void setIcon(Drawable icon) {
        this.icon = icon;
    }
 
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                isPressed = true;
                invalidate();
                return true;
            case MotionEvent.ACTION_UP:
                isPressed = false;
                invalidate();
                return true;
        }
        return false;
    }
 
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if(isPressed)
            paint.setColor(pressedBackgroundColor);
        else
            paint.setColor(backgroundColor);
        canvas.drawCircle(shadowX, shadowY, shadowRadius, shadowPaint);
        canvas.drawCircle(fabX, fabY, fabRadius, paint);
        if(icon == null)
            canvas.drawText(text, fabX, fabY + textSize/2, textPaint);
    }
 
    @Override
    protected int getSuggestedMinimumWidth() {
        return icon == null ? 0:icon.getMinimumWidth();
    }
 
    @Override
    protected int getSuggestedMinimumHeight() {
        return icon == null ? (int)textSize:icon.getMinimumHeight();
    }
 
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int picSize = Math.max(getSuggestedMinimumWidth(), getSuggestedMinimumHeight());
        int minW = getPaddingLeft() + getPaddingRight() + picSize;
        int w = Math.max(minW, MeasureSpec.getSize(widthMeasureSpec));
        int minH = getPaddingBottom() + getPaddingTop() + picSize;
        int h = Math.max(MeasureSpec.getSize(heightMeasureSpec), minH);
        setMeasuredDimension(w, h);
    }
 
    @Override
    protected void onSizeChanged(int w, int h, int oldW, int oldH) {
        super.onSizeChanged(w, h, oldW, oldH);
        float padLeft = getPaddingLeft();
        float padTop = getPaddingTop();
        float ww = w - padLeft - getPaddingRight();
        float hh = h - padTop - getPaddingBottom();
 
        float radius = Math.min(ww, hh)/2 - 4.0f;
        fabRadius = radius;
        fabX = padLeft + fabRadius + 4.0f;
        fabY = padTop + fabRadius;
        shadowRadius = radius - 4.0f;
        shadowX = padLeft + shadowRadius + 8.0f;
        shadowY = padTop + shadowRadius + 8.0f;
    }
}


Что неправильно в отрисовке? fabX и fabY содержат координаты центра кнопки, и она сама рисуется как надо, но текст по вертикали смещается вниз от центра или вверх, если "-"... Я так понимаю textSize - это не пиксельный размер текста, поэтому пробовал через Paint.getTextBounds получать высоту, но там та же проблема, текст не попадает в центр по вертикали.

Добавлено через 15 часов 1 минуту
Нашел, getTextBounds возвращает предполагаемый размер текста, как я понял, т.е. с учетом самого высокого из возможных символов (хотя не суть). Пришлось делать через descent(), ascent()... если у кого-то та же проблема будет.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.01.2015, 14:04     Отрисовка текста по центру canvas
Посмотрите здесь:

Android многослойная отрисовка
Отрисовка битмапа внутри View Android
Canvas Android
Отрисовка спрайтов Android
Android Динамическое создание кнопок и их кривая отрисовка
GridView и сложная отрисовка Android
Отрисовка View Android
TableLayout по центру Android
Расположение текста по центру экрана Android
Какой тег отвечает за выравнивание по центру текста? Android
Android Отрисовка картинок по щелчу на кнопке
Отрисовка данных в отдельном потоке Android

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Ответ Создать тему
Опции темы

Текущее время: 23:49. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru