Searchview with MVP

Asked

Viewed 120 times

0

Studying the MVP standard, I refactored an activity that lists the product data, just a simple list more 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 the time came to refactoring the filtering so the question came to me? because it is a filtering of the data in the list I should implement the filtering in presenter? in the Model?

The Adapter I haven’t refactored yet that’s where the questions arose, and he has logic that is the filter itself is a logic so can not stay in the adapatador so where would be this logic someone can help me as I said I reviewed everything and I believe that to meet the standard just missing this.

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

Implementation of the Model

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

Implementation of the presenter

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

Implementation of the View ( 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 Adapter and in it I started filtering the data and realized that this is logical so I must 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());

       }
   }

}

  • Simply put, the filter has to be done in the template, and you must pass it the query or any other information it needs to filter. The presenter is only the bridge, because the responsibility to retrieve the information is the model, and nothing fairer than being responsible for filtering.

  • Hello Wakim thanks for the return, my dear plus the model when the activity started he has already provided in full the records obtained from the bank, by Adapter the recyclerview has its list, the filtering ( handles data without a shadow of a doubt ) but only filters the elements of the list, list this that I put in the presenter so I get the doubt if I could not continue this step in the presenter.

  • Assuming your model is simple, all right, it’s valid. But in real cases, you can have a Model that consumes data from an API or a local bank, or even both. Filtering in presenter might not be a good choice, it all depends on the context.

  • I am actually getting the list for the Sqlite Adapter (Local) this is what the Model does to get the list, and passes it to the presenter where I have a private instance Arraylist<Product> products, I do not intend to do a new search in the bank when doing a filtering (Search), if yes I would again request the template for a new list.

  • Have the filtering in Presenter still go (although I think the Model should provide the filtered data) now the Model has a reference to the Presenter(public ProdutoModel(ListaProdutosMVP.Presenter presenter)) is that not.

  • Hello ramaral good morning, yes the presenter can have a reference to the view public Listingssresenter(Listproductsmvp.View), and the model can not have reference to the Presenter? Why can you explain or suggest? , in this way I believe I was able to implement the standard there is bidirectional communication between the view and presenter, presenter and model

  • This is imposed by the standard: Model <- Presenter <-> View. Presenter "knows" the Model and View, View "knows" the Presenter. The Model has no knowledge of the other two. See this post.

  • Check out these https://guides.codepath.com/android/Architecture-of-Android-Apps#migrating-to-clean-Architecture, and this other one http://konmik.com/post/introduction_to_model_view_presenter_on_android/ and even more this other one http://thefinestartist.com/android/mvp-pattern

  • and if you look at the post you told me it still has part 2 and 3 (you read it), in part 2 we can see public Mainmodel(Mainmvp.Requiredpresenterops mPresenter) I saw no problems in how I implemented the pattern.

  • OK, MainMVP.RequiredPresenterOps is a interface is not the Presenter. I hadn’t noticed that you were also using an interface.

Show 5 more comments
No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.