Skip to content

Instantly share code, notes, and snippets.

@douglasjunior
Last active January 20, 2019 00:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save douglasjunior/b26d4a34c5fe43c70249 to your computer and use it in GitHub Desktop.
Save douglasjunior/b26d4a34c5fe43c70249 to your computer and use it in GitHub Desktop.
Implementação de Adapter genérico para utilizar no com.weiwangcn.betterspinner.library.material.MaterialBetterSpinner (ver comentários)
package com.youtproject.util;
import android.text.Editable;
import android.text.TextWatcher;
/**
* Listener used to capture "on selected item" event on MaterialBetterSpinner.
* Created by douglas on 22/09/15.
*/
public abstract class OnItemSelectedListener implements TextWatcher {
@Override
public final void beforeTextChanged(CharSequence s, int start, int count, int after) {
// nothing here
}
@Override
public final void onTextChanged(CharSequence s, int start, int before, int count) {
// nothing here
}
@Override
public final void afterTextChanged(Editable editable) {
onItemSelected(editable.toString());
}
protected abstract void onItemSelected(String string);
}
package com.seuprojeto.adapter;
import android.content.Context;
import android.widget.ArrayAdapter;
import com.seuprojeto.R;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* <p>Versão português</p>
* <p>Classe que implementa um Adapter genérico para ser utilizado no <code>com.weiwangcn.betterspinner.library.material.MaterialBetterSpinner</code>.</p>
* <p>Para permitir a customização da visuzaliação é implementado o padrão de projeto Proxy.</p>
* <p/>
* <p>Created by douglas on 01/09/15.</p>
*/
public abstract class SpinnerArrayAdapter<T> extends ArrayAdapter<SpinnerArrayAdapter<T>.ItemProxy> {
public SpinnerArrayAdapter(Context context, List<T> objects) {
super(context, R.layout.simple_spinner_dropdown_item);
setNotifyOnChange(false);
clear();
addAll(wrapItems(objects));
notifyDataSetChanged();
}
public SpinnerArrayAdapter(Context context, T[] objects) {
this(context, Arrays.asList(objects));
}
/**
* <p>Por padrão, o ArrayAdapter utiliza o <code>toString()</code> para exibição dos items, e em alguns casos, como quando utilizado o framework Realm Database, não é possível sobrescrever o <code>toString()</code> das classes de modelo.
* Sendo assim, foi criada a solução com Proxy (classe para envolver o objeto), o que permite a customização do <code>toString()</code> dos proxys. </p>
* <p>Este método faz o trabalho de envolver as classes de modelo originais em Proxy.</p>
*
* @param objects
* @return
*/
private List<ItemProxy> wrapItems(List<T> objects) {
List<ItemProxy> proxies = new ArrayList<>(objects.size());
for (T item : objects) {
ItemProxy proxy = new ItemProxy(item);
proxies.add(proxy);
}
return proxies;
}
/**
* <p>Converte o item em <code>String</code>.</p>
* <p>Sobreescreva este método para customizar a visualização do item.</p>
*
* @param item
* @return
*/
public String itemToString(T item) {
return item.toString();
}
/**
* <p>Converte a <code>String</code> em objeto.</p>
* <p>Este método pode ser utilizado para detectar o item que está selecionado no Spinner.</p>
* <p>Exemplo:</p>
* <code>
* <pre>
*
* MaterialBetterSpinner spPessoa;
* SpinnerArrayAdapter<Pessoa> adapterPessoa;
* ....
* Pessoa pSelecionada = adapterPessoa.stringToItem(spPessoa.getText())
*
* </pre>
* </code>
*
* @param toString Texto selecionado no Spinner.
* @return Objeto Pessoa convertido a partir do texto selecionado.
*/
public T stringToItem(String toString) {
for (int i = 0; i < getCount(); i++) {
T item = getItem(i).object;
if (itemToString(item).equals(toString)) {
return item;
}
}
return null;
}
/**
* <p>Converte a <code>String</code> em objeto.</p>
* <p>Este método pode ser utilizado para detectar o item que está selecionado no Spinner.</p>
* <p>Exemplo:</p>
* <code>
* <pre>
*
* MaterialBetterSpinner spPessoa;
* SpinnerArrayAdapter<Pessoa> adapterPessoa;
* ....
* Pessoa pSelecionada = adapterPessoa.stringToItem(spPessoa.getText())
*
* </pre>
* </code>
*
* @param toString Texto selecionado no Spinner.
* @return Objeto convertido a partir do texto selecionado.
*/
public T stringToItem(CharSequence toString) {
return stringToItem(toString.toString());
}
/**
* Classe que implementa o padrão de projeto Proxy para o SpinnerArrayAdapter genérico.
*/
public class ItemProxy {
final T object;
protected ItemProxy(T object) {
this.object = object;
}
@Override
public String toString() {
return itemToString(object);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof SpinnerArrayAdapter.ItemProxy)) return false;
ItemProxy itemProxy = (ItemProxy) o;
return !(object != null ? !object.equals(itemProxy.object) : itemProxy.object != null);
}
@Override
public int hashCode() {
return object != null ? object.hashCode() : 0;
}
}
/**
* Override ArrayAdapter.getFilter() to return our own filtering.
*/
@Override
public Filter getFilter() {
if (noFilter == null) {
noFilter = new NoFilter();
}
return noFilter;
}
/**
* Class which does not perform any filtering.
* Filtering is already done by the web service when asking for the list,
* so there is no need to do any more as well.
* This way, ArrayAdapter.mOriginalValues is not used when calling e.g.
* ArrayAdapter.add(), but instead ArrayAdapter.mObjects is updated directly
* and methods like getCount() return the expected result.
*/
private class NoFilter extends Filter {
protected FilterResults performFiltering(CharSequence prefix) {
return new FilterResults();
}
protected void publishResults(CharSequence constraint,
FilterResults results) {
// Do nothing
}
}
}
package com.youtproject.adapter;
import android.content.Context;
import android.os.Build;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.youtproject.R;
/**
* <p>English version</p>
* <p>Class that implements a generic adapter to be used in <code>com.weiwangcn.betterspinner.library.material.MaterialBetterSpinner</code>.</p>
* <p>To enable customization of the display is implemented the pattern Proxy.</p>
* <p/>
* <p>Created by douglas on 01/09/15.</p>
*/
public class SpinnerArrayAdapter<T> extends ArrayAdapter<SpinnerArrayAdapter<T>.ItemProxy> {
private NoFilter noFilter;
public SpinnerArrayAdapter(Context context) {
this(context, new ArrayList<T>());
}
public SpinnerArrayAdapter(Context context, List<T> objects) {
super(context, R.layout.simple_spinner_dropdown_item);
setNotifyOnChange(false);
addAll(objects);
notifyDataSetChanged();
}
public SpinnerArrayAdapter(Context context, T[] objects) {
this(context, Arrays.asList(objects));
}
/**
* <p>For default, the ArrayAdapter uses <code>toString()</code> for item view, in somes cases when uses a framework like Realm Database, is not possible to overrides the <code>toString()</code> in model classes.
* Then, the proxy solutions has implemented.
* <p>This method encapsulates the original object into a proxy.</p>
*
* @param objects
* @return
*/
private List<ItemProxy> wrapItems(List<T> objects) {
List<ItemProxy> proxies = new ArrayList<>(objects.size());
for (T item : objects) {
ItemProxy proxy = new ItemProxy(item);
proxies.add(proxy);
}
return proxies;
}
/**
* <p>Converts the item to <code>String</code>.</p>
* <p>Overrides this method for cutomize the text view.</p>
*
* @param item
* @return
*/
public String itemToString(T item) {
return item.toString();
}
/**
* <p>Converts a <code>String</code> in object.</p>
* <p>This method can be used to get selected item.</p>
* <p>Example:</p>
* <code>
* <pre>
*
* MaterialBetterSpinner spPeople;
* SpinnerArrayAdapter<People> adapterPeople;
* ....
* People pSelected = adapterPeople.stringToItem(spPeople.getText())
*
* </pre>
* </code>
*
* @param toString Selected text.
* @return Object converted from selected text.
*/
public T stringToItem(String toString) {
for (int i = 0; i < getCount(); i++) {
T item = getItem(i).object;
if (itemToString(item).equals(toString)) {
return item;
}
}
return null;
}
/**
* <p>Converts a <code>String</code> in object.</p>
* <p>This method can be used to get selected item.</p>
* <p>Example:</p>
* <code>
* <pre>
*
* MaterialBetterSpinner spPeople;
* SpinnerArrayAdapter<People> adapterPeople;
* ....
* People pSelected = adapterPeople.stringToItem(spPeople.getText())
*
* </pre>
* </code>
*
* @param toString Selected text.
* @return Object converted from selected text.
*/
public T stringToItem(CharSequence toString) {
return stringToItem(toString.toString());
}
public void addAll(List<T> objects) {
clear();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
addAll(wrapItems(objects));
} else {
for (ItemProxy p : wrapItems(objects)) {
add(p);
}
}
}
/**
* Proxy for generic SpinnerArrayAdapter.
*/
public class ItemProxy {
public final T object;
protected ItemProxy(T object) {
this.object = object;
}
@Override
public String toString() {
return itemToString(object);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof SpinnerArrayAdapter.ItemProxy)) return false;
ItemProxy itemProxy = (ItemProxy) o;
return !(object != null ? !object.equals(itemProxy.object) : itemProxy.object != null);
}
@Override
public int hashCode() {
return object != null ? object.hashCode() : 0;
}
}
/**
* Override ArrayAdapter.getFilter() to return our own filtering.
*/
@Override
public Filter getFilter() {
if (noFilter == null) {
noFilter = new NoFilter();
}
return noFilter;
}
/**
* Class which does not perform any filtering.
* Filtering is already done by the web service when asking for the list,
* so there is no need to do any more as well.
* This way, ArrayAdapter.mOriginalValues is not used when calling e.g.
* ArrayAdapter.add(), but instead ArrayAdapter.mObjects is updated directly
* and methods like getCount() return the expected result.
*/
private class NoFilter extends Filter {
protected FilterResults performFiltering(CharSequence prefix) {
return new FilterResults();
}
protected void publishResults(CharSequence constraint,
FilterResults results) {
// Do nothing
}
}
}
@andresantos78
Copy link

Olá Douglas
Boa tarde

Essas classes corrigem o problema setSelection do MaterialBetterSpinner?
O Componente é legal, mas está com alguns errinhos e o Wei Wang não está fazendo as correções.

Aguardo o seu retorno.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment