By studying the MVP pattern, I refactored an activity that lists the product data, just a simple list that I do the data filtering, the information comes from the internal database, and the filtering was done in the adapter list.
I believe I was able to apply the concept until it was time to refactor the filter so the question came to me? because it is a filtering of the list data should I implement the filtering in the presenter? in the Model?
The Adapter has not refactored yet, so the questions have arisen, and it has logic, that is, the filter itself is logic so it can not stay in the adapter so where would this logic stay? Can someone help me like I said I reviewed everything and I believe to meet the standard just lack it.
follow the codes
interface ListaProdutosMVP {
interface View {
void atualizaLista();
void showToastError(String mensagem);
void showToastInfo(String mensagem);
void showToastWarning(String mensagem);
void showToastSuccess(String mensagem);
}
interface Presenter {
void recuperarProdutos();
void atualizaLista(ArrayList<Produto> produtos);
ArrayList<Produto> getProdutos();
Context getContext();
}
interface Model {
void recuperarProdutos();
}
Model Implementation
class ProdutoModel implements ListaProdutosMVP.Model {
private DAOProduto dao ;
private ListaProdutosMVP.Presenter presenter;
public ProdutoModel(ListaProdutosMVP.Presenter presenter) {
this.presenter = presenter;
this.dao = new DAOProduto(presenter.getContext()) ;
}
public Produto BuscaporId(int Id) { return dao.buscarPorId(Id); }
public List<Produto> buscarTodos() {
return dao.buscarTodos();
}
@Override
public void recuperarProdutos() {
ArrayList<Produto> lista = (ArrayList<Produto>) dao.getListaOrdenada();
presenter.atualizaLista( lista );
}
}
Presenter implementation
class ListaProdutosPresenter implements ListaProdutosMVP.Presenter {
private ArrayList<Produto> produtos = new ArrayList<>();
private ListaProdutosMVP.Model model;
private ListaProdutosMVP.View view;
public ListaProdutosPresenter(ListaProdutosMVP.View view){
this.view = view;
this.model = new ProdutoModel(this);
}
@Override
public void recuperarProdutos() {
model.recuperarProdutos();
}
@Override
public void atualizaLista(ArrayList<Produto> lista) {
produtos.clear();
produtos.addAll(lista);
view.atualizaLista();
}
@Override
public ArrayList<Produto> getProdutos() {
return produtos;
}
@Override
public Context getContext() {
return (Context) view;
}
}
View implementation (Activity)
class ListaProdutosActivity extends AppCompatActivity
implements ListaProdutosMVP.View {
private static final String TAG = "ListaProdutos";
private RecyclerView recyclerView;
private ProdutosAdapter adapter;
private ListaProdutosMVP.Presenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lista_produtos);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Log.i(TAG, "onCreate()");
if(presenter == null){
presenter = new ListaProdutosPresenter(this);
}
presenter.recuperarProdutos();
adapter = new ProdutosAdapter(this, presenter.getProdutos());
recyclerView = (RecyclerView) findViewById(R.id.rv_lista);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new
LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
}
@Override
protected void onResume() {
super.onResume();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if(id == android.R.id.home){
finish();
}
return true;
}
@Override
public void atualizaLista() {
adapter.notifyDataSetChanged();
}
and finally the adapter and in it I started filtering the data and realized that this is logical so should I change this logic to the presenter or model?
class ProdutosAdapter extends
RecyclerView.Adapter<ProdutosAdapter.MyViewHolder>
implements Filterable {
private ListaProdutosActivity activity;
private ArrayList<Produto> items;
private ArrayList<Produto> mFilteredList;
public ProdutosAdapter(ListaProdutosActivity activity, ArrayList<Produto> items) {
this.activity = activity;
this.items = items;
this.mFilteredList = items;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater
.from(viewGroup.getContext())
.inflate(R.layout.model_produto_item, viewGroup, false);
return new MyViewHolder(v);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.setDados(mFilteredList.get(position));
}
@Override
public int getItemCount() {
return mFilteredList.size();
}
// Lógica
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
mFilteredList = items;
} else {
ArrayList<Produto> filteredList = new ArrayList<>();
for (Produto p : items) {
if (p.getNome().toLowerCase().contains(charString) ||
p.getEan_13().toLowerCase().contains(charString)
|| p.getDescricao().toLowerCase().contains(charString)) {
filteredList.add(p);
}
}
mFilteredList = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = mFilteredList;
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
mFilteredList = (ArrayList<Produto>) filterResults.values;
notifyDataSetChanged();
}
};
}
class MyViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener {
public TextView txtNome;
public TextView txtValor;
public TextView txtStatus;
public MyViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
txtNome = (TextView)itemView.findViewById(R.id.txtNome);
txtValor = (TextView)itemView.findViewById(R.id.txtValor);
txtStatus = (TextView)itemView.findViewById(R.id.txtStatus);
}
@Override
public void onClick(View v) {
Produto p = mFilteredList.get(getAdapterPosition());
activity.selectItem(p);
}
public void setDados(Produto produto) {
txtNome.setText(produto.getNome());
txtValor.setText( LetrasUtils.monetarioMask(produto.getValor()));
txtStatus.setText("Ativo: " + produto.getAtivo());
}
}
}