quinta-feira, 18 de outubro de 2012

Customizando Views

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();
}
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);

}

Repare que sempre será verificado o foco e depois será chamada a função da classe estendida.

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!

Nenhum comentário:

Postar um comentário