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

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

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

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

18.01.2015, 14:04. Просмотров 446. Ответов 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):

Расположение текста по центру экрана - Программирование Android
В LinearLayout (горизонтальный) располагаю иконку (стороны по 40 dp из dimens) и затем справа TextView (widht = match_parent). Как...

Какой тег отвечает за выравнивание по центру текста? - Программирование Android
Есть переменная типа String, в ней большой текст. Этот текст присваивается textView. Как выровнять по центру частичку этого большего...

Canvas.TextOut отрисовка текста относительно центра - Delphi
Доброго времени суток. Подскажите какое свойство Font нужно отредактировать, что бы текст отрисовывался относительно цента. По умолчанию...

Отрисовка линии на canvas - C# WPF
Только начинаю работать с wpf. Мне нужно создать usercontrol линию на canvas. Рисую линию таким образом: Line MyLine =...

Отрисовка потоком в Canvas - C++ Builder
Доброго времени суток. В общем ситуация такова: есть таймер, работающий с точностью в 10мс в отдельном потоке. В зависимости от времени, на...

.NET 4.x WPF canvas отрисовка точки - C# WPF
Здравствуйте уважаемые Форумчане. Может что то не правильно понимаю, так как многого не знаю. Объясните пожалуйста как в приложении...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.01.2015, 14:04
Привет! Вот еще темы с ответами:

Отрисовка сложных фигур на canvas - C# WPF
собственно вопрос, как из простых фигур, можно делать сложные? Когда я рисовал такие вот фигурки https://i.paste.pics/1PB0O.png все...

.NET 4.x Отрисовка на Canvas при использовании MVVM - C# WPF
Проблема следующая: Есть список объектов, которые должны быть отражены в виде прямоугольников на холсте (Canvas). Места их отображения...

Работа с timage.canvas, отрисовка нескольких картинок - Delphi
Задача такая, есть белый фон, нужно отрисовать несколько картинок (всего 3), картинки примерно 10*10 пикселов, они будут заполнять канву...

Canvas. Отрисовка заданного количества вертикальных линий с определенным шагом - Delphi
Здравствуйте. Помогите разобраться с проблемой. Есть таблица StringGrid1. В ней будет определенное количество строк. Каждый раз разное. К...


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

Или воспользуйтесь поиском по форуму:
Ответ Создать тему
Опции темы

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