Olá pessoal,
Este é o primeiro de 3 artigos que irei escrever sobre como trabalhar com as views que a API do Android nos proporciona. Se você leu os artigos anteriores irá saber que as views são os componentes que fazem a interface de interação com o usuário, são como os tão conhecidos "controles" presentes em linguagens como Visual Basic e C#.
Hoje vou escrever sobre como customizar uma View já existente, já os próximos dois posts serão sobre como criar views compostas e como criar novas views.
Não é minha intenção descrever todas as views da API do Android mas como é importante que você saiba que elas existem, e são muitas, segue o link oficial com a definição de todas as Views.
http://developer.android.com/reference/android/view/View.html
No post de hoje vamos ver como funciona a customização de uma View. Vamos neste exemplo vamos criar uma View que será uma caixa de texto que muda de cor ao receber o foco e retorna ao seu estado original quando o perde. É um exemplo simples, mas que nos trará entendimento sobre conceitos interessantes e sobre este processo.
O processo de customizar uma View é feito através da estensão de uma classe para o tipo desejado. No nosso exemplo estamos customizando uma View do tipo EditText, então temos que criar uma classe que estenda-a, isso faz com que possamos ter uma View com todas as funcionalidades da View que queremos customizar.
public class FocusableText extends EditText
Depois de ter a classe estendida, temos que configurar os seus construtores e o seu método onDraw. Repare no código abaixo que eu criei também uma função chamada Init, que será usada para inicializar variáveis de memória logo após o construtor ser chamado.
public FocusableText(Context context, AttributeSet ats, int ds) {
super(context, ats, ds);
init();
}
public FocusableText(Context context) {
super(context);
init();
}
public FocusableText(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
this.setFocusable(true);
this.setFocusableInTouchMode(true);
myResources = getResources();
borderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
marginPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
margin = myResources.getDimension(R.dimen.marginFocusableText);
this.setBackgroundColor( myResources.getColor(R.color.defaultTextBackcolor));
}
É importante saber que todos os métodos que estendemos chamam a rotina principal da classe estendida.
Agora é o momento onde a customização visual da View acontece. No método onDraw é onde definimos o layout da nossa View.
@Override
public void onDraw(Canvas canvas) {
borderPaint.setColor(myResources.getColor(R.color.focusableTextBorderColor));
marginPaint.setColor( myResources.getColor(R.color.focusableTextBorderColor));
canvas.drawLine(0, 0, getMeasuredWidth(), 0, borderPaint);
canvas.drawLine(0, 0, 0, getMeasuredHeight(), borderPaint);
canvas.drawLine(0, getMeasuredHeight(),getMeasuredWidth(), getMeasuredHeight(), borderPaint);
canvas.drawLine(getMeasuredWidth(),getMeasuredHeight(),getMeasuredWidth(), 0, borderPaint);
canvas.drawLine(0, 0, getMeasuredWidth(), 0, borderPaint);
canvas.save();
canvas.translate(margin, 0);
super.onDraw(canvas);
canvas.restore();
}
Repare que sempre será verificado o foco e depois será chamada a função da classe estendida.
Este é o primeiro de 3 artigos que irei escrever sobre como trabalhar com as views que a API do Android nos proporciona. Se você leu os artigos anteriores irá saber que as views são os componentes que fazem a interface de interação com o usuário, são como os tão conhecidos "controles" presentes em linguagens como Visual Basic e C#.
Hoje vou escrever sobre como customizar uma View já existente, já os próximos dois posts serão sobre como criar views compostas e como criar novas views.
Não é minha intenção descrever todas as views da API do Android mas como é importante que você saiba que elas existem, e são muitas, segue o link oficial com a definição de todas as Views.
http://developer.android.com/reference/android/view/View.html
No post de hoje vamos ver como funciona a customização de uma View. Vamos neste exemplo vamos criar uma View que será uma caixa de texto que muda de cor ao receber o foco e retorna ao seu estado original quando o perde. É um exemplo simples, mas que nos trará entendimento sobre conceitos interessantes e sobre este processo.
O processo de customizar uma View é feito através da estensão de uma classe para o tipo desejado. No nosso exemplo estamos customizando uma View do tipo EditText, então temos que criar uma classe que estenda-a, isso faz com que possamos ter uma View com todas as funcionalidades da View que queremos customizar.
public class FocusableText extends EditText
Depois de ter a classe estendida, temos que configurar os seus construtores e o seu método onDraw. Repare no código abaixo que eu criei também uma função chamada Init, que será usada para inicializar variáveis de memória logo após o construtor ser chamado.
public FocusableText(Context context, AttributeSet ats, int ds) {
super(context, ats, ds);
init();
}
public FocusableText(Context context) {
super(context);
init();
}
public FocusableText(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
this.setFocusable(true);
this.setFocusableInTouchMode(true);
myResources = getResources();
borderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
marginPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
margin = myResources.getDimension(R.dimen.marginFocusableText);
this.setBackgroundColor( myResources.getColor(R.color.defaultTextBackcolor));
}
É importante saber que todos os métodos que estendemos chamam a rotina principal da classe estendida.
Agora é o momento onde a customização visual da View acontece. No método onDraw é onde definimos o layout da nossa View.
@Override
public void onDraw(Canvas canvas) {
borderPaint.setColor(myResources.getColor(R.color.focusableTextBorderColor));
marginPaint.setColor( myResources.getColor(R.color.focusableTextBorderColor));
canvas.drawLine(0, 0, getMeasuredWidth(), 0, borderPaint);
canvas.drawLine(0, 0, 0, getMeasuredHeight(), borderPaint);
canvas.drawLine(0, getMeasuredHeight(),getMeasuredWidth(), getMeasuredHeight(), borderPaint);
canvas.drawLine(getMeasuredWidth(),getMeasuredHeight(),getMeasuredWidth(), 0, borderPaint);
canvas.drawLine(0, 0, getMeasuredWidth(), 0, borderPaint);
canvas.save();
canvas.translate(margin, 0);
super.onDraw(canvas);
canvas.restore();
}
Este código a principio parece complicado, mas é de simples entendimento. Aqui estamos definindo a borda do controle, a margem, escrevendo as linhas que irão formar a borda através do canvas.drawLine, salvando a área do controle, chamado aqui de canvas e chamando o método onDraw da classe estendida. Neste momento a interface do controle é construida e aplicada.
Não é necessário entrar em maiores detalhes sobre cores ou medidas, pois tudo aqui está vindo dos arquivos de Resources.
O objetivo principal do nosso controle é feito pela simples ação de sobrecarregar o método onFocusChanged da classe estendida.
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
if (focused)
this.setBackgroundColor(getResources().getColor(R.color.focusableTextBackcolor));
else
this.setBackgroundColor(getResources().getColor(R.color.defaultTextBackcolor));
// TODO Auto-generated method stub
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
Quando você for utilizar a View basta abrir uma tag dentro do arquivo de layout começando pelo nome do package do seu aplicativo e finalizando com o nome da sua classe criada. Veja no exemplo abaixo:
<LinearLayout 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/linearLayoutBackcolor"
>
<com.example.customizandoviews.FocusableText
android:id="@+id/focusableText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/hintFirstName"
android:singleLine="true"
android:layout_margin="@dimen/marginFocusableText" />
<com.example.customizandoviews.FocusableText
android:id="@+id/focusableText2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/hintLastName"
android:singleLine="true"
android:layout_margin="@dimen/marginFocusableText" />
<com.example.customizandoviews.FocusableText
android:id="@+id/focusableText3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/hintAge"
android:inputType="number"
android:layout_margin="@dimen/marginFocusableText" />
</LinearLayout>
Atente há alguns detalhes que citei no começo do artigo e são comprovados aqui. Quando estendi a classe herdei todas as funcionalidades da classe pai e estou fazendo uso delas, note a utilização do hint, singleline e até mesmo do inputType.
Depois de pronto temos esta visualização, o campo focado sempre assume outra cor.
Abraço e boa sorte!