Depois de algum tempo venho falar sobre a criação de views e encerrar uma sequência de 3 posts relacionados a este assunto. Nos posts anteriores mostrei como customizar uma View e também como criar uma View composta de outras Views. Neste post vou mostrar como criar uma View a partir da extensão da classe android.view.View.
A View criada neste post não terá funcionalidade, será apenas um desenho multi direcional, pois vou abordar em um post mais a frente como dar vida a este tipo de controle utilizando o acelerômetro do dispositivo. Este post servirá como base para o conhecimento da estrutura de uma View criada do zero.
No final nossa View ficará como a imagem abaixo:
Aproveito este post para fazer um convite a vocês a instalar a versão Jelly Bean 4.1.2 de testes da Samsung. Está fantástica. Veja sobre no site SamMobile.com
O primeiro passo para se construir uma View do zero é criar uma classe fazer a extensão da classe android.view.View. Fazendo isso, você está herdando todos os comportamentos básicos de uma View. O ponto seguinte é se preocupar me sobrecarregar todos os construtores da classe.
public class DirectionalView extends View
public DirectionalView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initDirectionalView();
}
public DirectionalView(Context context, AttributeSet attrs) {
super(context, attrs);
initDirectionalView();
}
public DirectionalView(Context context) {
super(context);
initDirectionalView();
}
Repare que todos o três construtores fazem chamada ao initDirectionalView. Este procedimento é utilizando para inicializar as variáveis que serão utilizadas pelo sistema. É uma boa prática fazer a inicialização das várias logo no início do aplicativo, assim você não evita de executar uma ação de inicialização várias vezes desnecessariamente, lembre-se é importante se preocupar com o processo durante a execução de um aplicativo móvel.
O procedimento initDirectionalView está definindo que o controle não irá receber foco, definindo os objetos que irão desenhar as linhas na tela, carregando os textos dos Resources para exibição em tela e definindo a cor da tela baseando se nos Resources.
private void initDirectionalView()
{
if (this.isInEditMode())
return;
// esta ação define que o validador não receberá foco...
setFocusable(false);
// referencia todos os itens...
Resources r = this.getResources();
linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
linePaint.setColor(r.getColor(R.color.borderColor));
linePaint.setStyle(Paint.Style.FILL);
linePaint.setStrokeWidth(1);
textHeight = 20;
textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
textPaint.setColor(r.getColor(R.color.foreColor));
textPaint.setTextSize(textHeight);
textEast = r.getString(R.string.east);
textNorth = r.getString(R.string.north);
textSouth = r.getString(R.string.south);
textWest = r.getString(R.string.west);
this.setBackgroundColor(r.getColor(R.color.backcolor));
}
Até o momento descrevi apenas como a View é inicializada, agora precisamos ver como a View é desenhada. O desenho da View é feito dentro da chamada onDraw, que recebe como parâmetro o Canvas, que é o local onde fazemos o desenho da View. Esta chamada é feita sempre que for necessário redesenhar a tela.
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
/* define os valores que podem virar parametros*/
int lineMargin = 40;
int textMargin = 20;
int height = this.getHeight();
int width = this.getWidth();
/* encontra os centros */
int centerX = width/2 ;
int centerY = height/2;
/* define os pontos*/
int topX = centerX;
int topY = lineMargin;
int bottomX = centerX;
int bottomY = height - lineMargin;
int leftX = lineMargin;
int leftY = centerY;
int rightX = width - lineMargin;
int rightY = centerY;
int topLeftX = width / 3;
int topLeftY = height /3;
int bottomRightX = (width * 2)/3;
int bottomRightY = (height * 2)/3;
int topRightX = (width * 2)/3;
int topRightY = height/3;
int bottomLeftX = width / 3 ;
int bottomLeftY = (height * 2)/3;
/* desenha as linhas principais */
canvas.drawLine(topX, topY,bottomX ,bottomY, linePaint);
canvas.drawLine(leftX, leftY,rightX ,rightY, linePaint);
canvas.drawLine(topLeftX, topLeftY,bottomRightX ,bottomRightY, linePaint);
canvas.drawLine(topRightX, topRightY, bottomLeftX, bottomLeftY, linePaint);
/* desenha as linhas secundárias */
canvas.drawLine(topX, topY, topLeftX, topLeftY, linePaint);
canvas.drawLine(topLeftX, topLeftY, leftX, leftY, linePaint);
canvas.drawLine(leftX, leftY, bottomLeftX, bottomLeftY, linePaint);
canvas.drawLine(bottomLeftX, bottomLeftY, bottomX, bottomY, linePaint);
canvas.drawLine(bottomX, bottomY, bottomRightX, bottomRightY, linePaint);
canvas.drawLine(bottomRightX, bottomRightY, rightX, rightY, linePaint);
canvas.drawLine(rightX, rightY, topRightX, topRightY, linePaint);
canvas.drawLine(topRightX, topRightY, topX, topY, linePaint);
canvas.drawText(textNorth, topX, textMargin, textPaint);
canvas.drawText(textSouth, bottomX,bottomY + textMargin+textHeight, textPaint);
canvas.drawText(textEast, rightX + textHeight, rightY, textPaint);
canvas.drawText(textWest, textMargin, leftY, textPaint);
}
Repare no código acima que a partir do canvas todas as linhas são feitas e os textos escritos.
Outro ponto importante é o redimensionamento da View. Todas as vezes que a View for redimensionada é necessário verificar o tamanho e reaplicar o redimensionamento. Repare que propositalmente eu criei uma função que verifica o tamanho retornado pelo chamada onMeasure e atribui o tamanho. Se não tiver um tamanho especificado utiliza 400dp.
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
/*captura as medidas de altura e largura...*/
int measuredWidth = measure(widthMeasureSpec);
int measuredHeight = measure(heightMeasureSpec);
/*define a medida baseando-se na menor*/
int d = Math.min(measuredWidth, measuredHeight);
setMeasuredDimension(d, d);
}
private int measure(int measureSpec) {
/* verifica o modo de medida e se não tiver tamanho define o valor 200 como padrão */
int mode = MeasureSpec.getMode(measureSpec);
int size = MeasureSpec.getSize(measureSpec);
if (mode == MeasureSpec.UNSPECIFIED)
size = 400;
return size;
}
A utilização da View é do mesmo formato que defini nos posts anteriores. Mas basta relembrar:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/backcolor"
>
<com.example.criandoviews.DirectionalView
android:id="@+id/directional1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
/>
</RelativeLayout>
O download do código fonte pode ser feito clicando aqui.
Abraço
Nenhum comentário:
Postar um comentário