Yearly Archives:2015

Bysutradi

Criando um Spinner customizado com valores preenchidos por enum

O uso de Spinners em aplicativos Android é muito comum e isso pode ser feito de muitas maneiras, seguinte a rotina: crie o spinner, passe a lista, crie o adapter, crie o layout, etc.

Em alguns casos, tais Spinners são preenchidos com informações de domínio fechado.

Diante desta necessidade, é possível usar classes do tipo enum para preencher os valores em um Spinner customizado.

Neste tutorial, mostrarei como fazer isso criando algumas classes.

Vamos começar pela interface, para padronizar as classes enum.

public interface SpinnerEnum {

   public long getId();
   public String getNome();
   public Object[] listar();
}

Usaremos esta interface em todas as nossas futuras classes de enum.

O que precisamos agora é de nosso Adapter.

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import com.sutradi.lib.drawer.DatabaseModel;

import java.util.List;

public class SpinnerAdapter extends ArrayAdapter<DatabaseModel> {

	private final Context contexto;
	private final List<DatabaseModel> lista;
	DatabaseModel tempValues = null;
	int textViewID;
	int textViewNome;
	int spinnerLayoutID;

	/**
	 * Construtor.
	 * @param contexto
	 * @param listaObjetos
	 * @param spinnerLayout Layout que contenha 02 objetos TextView para ID e Nome
	 * @param _textViewID TextView para armazenar o ID
	 * @param _textViewNome TextView para armazenar o Nome
	 */
	public SpinnerAdapter(Context contexto, List<DatabaseModel> listaObjetos,
			int spinnerLayout, int _textViewID, int _textViewNome) {

		super(contexto, spinnerLayout, listaObjetos);
		this.contexto = contexto;
		this.lista = listaObjetos;
		this.textViewID = _textViewID;
		this.textViewNome = _textViewNome;
		this.spinnerLayoutID = spinnerLayout;
	}

	@Override
	public View getDropDownView(int position, View convertView, ViewGroup parent) {
		return getCustomView(position, convertView, parent);
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		return getCustomView(position, convertView, parent);
	}

	public View getCustomView(int position, View convertView, ViewGroup parent) {
		LayoutInflater inflater = (LayoutInflater) contexto
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		View rowView = inflater.inflate(spinnerLayoutID, parent, false);
		tempValues = null;
		tempValues = (DatabaseModel) lista.get(position);

		TextView viewID = (TextView) rowView.findViewById(textViewID);
		TextView viewNome = (TextView) rowView.findViewById(textViewNome);
		viewID.setText(tempValues.getId());
		viewNome.setText(tempValues.getNome());

		return rowView;
	}
}

Em nosso Adapter, informaremos o ID para o layout e os IDs para os campos que representação o ID e Nome que serão usados no Spinner.

public SpinnerAdapter(Context contexto, List<DatabaseModel> listaObjetos,
			int spinnerLayout, int _textViewID, int _textViewNome) {

Essa implementação permitirá que você crie layouts diferentes para o Spinner. Caso queira padronizar o Spinner, basta remover estas informações do construtor e definir as informações corretas na implementação em getCustomView.

A classe DatabaseModel deve conter uma implementação POJO que contém ID e Nome. Bem simples.

Agora que temos o Adapter definido, vamos criar nosso Spinner customizado.

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.Spinner;

import com.sutradi.lib.drawer.DatabaseModel;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Classe de apoio para uso de Spinners que apresentam somente Texto, carregando
 * dados a partir de um Enum (que deve extender à SpinnerEnum) O layout do
 * spinner deve ter somente um EditText para ID (hide) e outro para Nome.
 *
 * @author SUTRADI
 */
public class SpinnerUI extends Spinner {
    ArrayList<DatabaseModel> lista = null;

    /**
     * Construtor.
     *
     * @param _context
     */
    public SpinnerUI(Context _context) {
        super(_context);
    }

    /**
     * Construtor.
     *
     * @param _context
     * @param _attrs
     * @param _defStyle
     * @param _mode
     */
    public SpinnerUI(Context _context, AttributeSet _attrs, int _defStyle,
                     int _mode) {
        super(_context, _attrs, _defStyle, _mode);
    }

    /**
     * Construtor.
     *
     * @param _context
     * @param _attrs
     * @param _defStyle
     */
    public SpinnerUI(Context _context, AttributeSet _attrs, int _defStyle) {
        super(_context, _attrs, _defStyle);
    }

    /**
     * Construtor.
     *
     * @param _context
     * @param _attrs
     */
    public SpinnerUI(Context _context, AttributeSet _attrs) {
        super(_context, _attrs);
    }

    /**
     * Construtor.
     *
     * @param _context
     * @param _mode
     */
    public SpinnerUI(Context _context, int _mode) {
        super(_context, _mode);
    }

    /**
     * @param context
     * @param spinnerText
     * @param listaEnum
     * @param spinnerLayout
     * @param spinnerItemId
     * @param spinnerItemNome
     */
    public void loadSpinner(Context context, String spinnerText,
                            SpinnerEnum[] listaEnum, int spinnerLayout, int spinnerItemId,
                            int spinnerItemNome, SpinnerEnum... enumIgnorar) {

        ArrayList<DatabaseModel> listaDatabaseModel = montaLista(spinnerText,
                listaEnum, enumIgnorar);

        SpinnerAdapter msa = new SpinnerAdapter(context, listaDatabaseModel,
                spinnerLayout, spinnerItemId, spinnerItemNome);

        this.setAdapter(msa);

    }

    /**
     * @param labelPrimeiro
     * @param listaEnum
     * @return
     */
    private ArrayList<DatabaseModel> montaLista(final String labelPrimeiro,
                                                SpinnerEnum[] listaEnum, SpinnerEnum... enumIgnorar) {
        List<SpinnerEnum> temp = new ArrayList<SpinnerEnum>(Arrays.asList(listaEnum));

        for(SpinnerEnum e : enumIgnorar) {
            temp.remove(e);
        }
        lista = new ArrayList<DatabaseModel>();
        lista.add(new DatabaseModel("0", labelPrimeiro));
        for (SpinnerEnum obj : temp) {
            DatabaseModel dm = new DatabaseModel(String.valueOf(obj.getId()),
                    obj.getNome());
            lista.add(dm);
        }

        return lista;
    }

}

A implementação pública loadSpinner será a responsável por receber as informações necessárias para o preenchimento do Spinner, com base nas necessidades do SpinnerAdapter. Notem que além de informar a lista de nossa interface SpinnerEnum, também é necessário informar os IDs do layout, ID e Nome. De quebra, é possível também passarmos uma lista de itens do SpinnerEnum que não queremos que seja adicionado.

public void loadSpinner(Context context, String spinnerText,
                            SpinnerEnum[] listaEnum, int spinnerLayout, int spinnerItemId,
                            int spinnerItemNome, SpinnerEnum... enumIgnorar) {

A implementação privada montaLista conterá toda a lógica para o preenchimento do Spinner. Note que o primeiro elemento terá o valor “0” sempre.

E como podemos usar este SpinnerUI ?

SpinnerUI spinner = (SpinnerUI) view.findViewById(R.id.spinnerUI_despesas);
        spinner.loadSpinner(getActivity(), getString(R.string.despesaSelecionar), DespesaEnum.getSortedVaules(), R.layout.spinner_ui, R.id.spinnerUI_id, R.id.spinnerUI_nome, DespesaEnum.ABASTECIMENTO, DespesaEnum.TROCA_OLEO, DespesaEnum.REVISAO);

E como implementamos nossas classes do tipo enum? Veja uma implementação simples abaixo.

import com.sutradi.lib.ui.spinner.SpinnerEnum;

import java.util.Arrays;
import java.util.Comparator;

public enum DespesaEnum implements SpinnerEnum {

	REVISAO(1, "Revisão"), 
	ABASTECIMENTO(2, "Abastecimento"), 
	TROCA_OLEO(3,"Troca de Óleo"), 
	MANUTENCAO(4, "Manutenção / Mecânica"), 
	OUTRA(99, "Outras");

	private long id;
	private String nome;

	DespesaEnum(long _id, String _nome) {
		this.id = _id;
		this.nome = _nome;
	}

	public static DespesaEnum getById(long id) {
		for (DespesaEnum item : DespesaEnum.values()) {
			if (item.getId() == id) {
				return item;
			}
		}
		return DespesaEnum.OUTRA;
	}

	/**
	 * @return the id
	 */
	public long getId() {
		return id;
	}

	/**
	 * @param id
	 *            the id to set
	 */
	public void setId(long id) {
		this.id = id;
	}

	/**
	 * @return the nome
	 */
	public String getNome() {
		return nome;
	}

	/**
	 * @param nome
	 *            the nome to set
	 */
	public void setNome(String nome) {
		this.nome = nome;
	}

	@Override
	public Object[] listar() {
		return DespesaEnum.values();
	}
	
	public static DespesaEnum[] getSortedVaules(DespesaEnum... ignore) {
		DespesaEnum[] statures = values();
		Arrays.sort(statures, EnumByNameComparator.INSTANCE);
		return statures;
	}

	private static class EnumByNameComparator implements Comparator<Enum<?>> {
		public static final Comparator<Enum<?>> INSTANCE = new EnumByNameComparator();
		public int compare(Enum<?> enum1, Enum<?> enum2) {
			return enum1.name().compareTo(enum2.name());
		}
	}

}

Você será obrigado a implementar os métodos getId e getNome, que farão a ligação com os elementos no layout do Spinner.

Você pode adicionar mais atributos na interface SpinnerEnum e enriquecer sua implementação.

Bysutradi

Remover um Database no Oracle 11g sem usar o Console de Administração (dbca)

Se você, por algum motivo que só Deus consiga explicar, não conseguir fazer a remoção de um Database por vias normais usando o Console de Administração (dbca), faça o seguinte:

  • Exporte o ORACLE_SID para o Database que quer remover.

  • Acesse o SQL Plus (escrevo SQL Plux toda vez… não faço idéia pq) sem autenticação.

  • Autentique como SYS e faça o shutdown no Database

  • Pare o Listener

  • Remova os diretórios, arquivos e configurações da Database

Edite o arquivo $ORACLE_HOME/network/admin/tnsnames.ora e remova o trecho referente à base de dados
Vá ao diretório $ORACLE_HOME/dbs e remova os arquivos e diretórios referentes à base de dados
Vá ao diretório $ORACLE_HOME/admin e remova os arquivos e diretórios referentes à base de dados
Vá ao diretório $ORACLE_HOME/oradata e remova os arquivos e diretórios referentes à base de dados
Edite o arquivo /etc/oratab e remova a linha referente à base de dados

  • Inicie o Listenet