Omar
Omar

Reputation: 23

Getting wrong position after Recyclerview filtering using SearchView

I trying to add a SearchView to my app using the website:

http://www.tutorialsbuzz.com/2015/11/Android-Filter-RecyclerView-Using-SearchView-In-ToolBar.html

Yet, I'm unable to send the user to the right Recyclerview position after clicking to the filtered result:

For example: If a user searched for the 2nd result and he click it, the app will send him the next activity (details activity) using the 1st result instead for the 2nd result.

Here are my app codes (ListAdapter.java):

public class ListAdapter extends RecyclerView.Adapter<ListAdapter.GmailVH> {

    ArrayList< Information > dataList;
    String letter;
    Context context;

    public ListAdapter(Context context, ArrayList< Information > dataList) {
        this.context = context;
        this.dataList = dataList;    
    }

    @Override
    public GmailVH onCreateViewHolder(ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_item, viewGroup, false);
        return new GmailVH(view);
    }

    @Override
    public void onBindViewHolder(GmailVH gmailVH, int i) {

        Information current= dataList.get(i);

        gmailVH.title.setText(current.title);

        letter = String.valueOf(current.title2);

        TextDrawable drawable = TextDrawable.builder()
                .buildRound(letter, generator.getRandomColor());

        gmailVH.letter.setImageDrawable(drawable);
  }

    @Override
    public int getItemCount() {
        return dataList == null ? 0 : dataList.size();
    }

    public Object getItem(int location) {
        return dataList.get(location);
    }

    class GmailVH extends RecyclerView.ViewHolder {
        TextView title;
        ImageView letter;

        public GmailVH(View itemView) {
            super(itemView);
            letter = (ImageView) itemView.findViewById(R.id.gmailitem_letter);
            title = (TextView) itemView.findViewById(R.id.gmailitem_title);
        }
    }

    public void setFilter(List<Information> informations) {
        dataList = new ArrayList<>();
        dataList.addAll(informations);
        notifyDataSetChanged();
    }
}

MainActivity.java:

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {

    RecyclerView recyclerView;
    ListAdapter adapter;
    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mDrawerToggle;

    final ArrayList< Information > listData = new ArrayList<>();

    @Override
    protected void onCreate ( Bundle savedInstanceState ) {

        super.onCreate( savedInstanceState );

        setContentView( R.layout.activity_main );


        Toolbar toolbar = ( Toolbar ) findViewById( R.id.toolbar );
        setSupportActionBar( toolbar );

        mNavigationView = ( NavigationView ) findViewById( R.id.nav_view );
        mNavigationView.setNavigationItemSelectedListener( this );

        mDrawerLayout = ( DrawerLayout ) findViewById( R.id.drawer_layout );
        mDrawerToggle = new ActionBarDrawerToggle( this, mDrawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close );
        mDrawerLayout.addDrawerListener( mDrawerToggle );
        mDrawerToggle.syncState();

        recyclerView = ( RecyclerView ) findViewById( R.id.gmail_list );

        recyclerView.setLayoutManager( new LinearLayoutManager( this ) );
        recyclerView.setItemAnimator( new DefaultItemAnimator() );


        String[] title_array = getResources().getStringArray( R.array.title_array );
        String[] letters_array = getResources().getStringArray( R.array.letters_array );


        for ( int i = 0; i < title_array.length && i < letters_array.length; i++ ) {

            Information feed = new Information();

            feed.title = title_array[ i ];
            feed.title2 = letters_array[ i ];

            listData.add( feed );

        }


        if ( adapter == null ) {
            adapter = new ListAdapter( this, listData );
            recyclerView.setAdapter( adapter );
        }

        recyclerView.addOnItemTouchListener( new RecyclerTouchListener( this, recyclerView, new ClickListener() {

            @Override
            public void onClick ( View view, int position ) {

                Intent intent = new Intent( MainActivity.this, Name_info.class );

                Bundle extras = new Bundle();

                String[] title_array = getResources().getStringArray( R.array.title_array );
                final String title_clicked = title_array[ position ];

                String[] letters_array = getResources().getStringArray( R.array.letters_array );
                final String letters_clicked = letters_array[ position ];

                String[] letters_title_array = getResources().getStringArray( R.array.letters_title_array );
                final String letters_title_clicked = letters_title_array [ position ];

                intent.putExtras( extras );
                intent.putExtra( "title_array", title_clicked );
                intent.putExtra( "letters_array", letters_clicked );
                intent.putExtra( "letters_title_array", letters_title_clicked );

                ActivityCompat.startActivity( MainActivity.this, intent, extras );

            }

        }
        ) );


        if ( !didUserSeeDrawer() ) {
            showDrawer();
            markDrawerSeen();
        } else {
            hideDrawer();
        }

    }


    @Override
    public boolean onCreateOptionsMenu ( Menu menu ) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate( R.menu.main, menu );

          final SearchView searchView = ( SearchView ) MenuItemCompat.getActionView( item );

        searchView.setOnQueryTextListener(
                new SearchView.OnQueryTextListener(){

                    @Override
                    public boolean onQueryTextSubmit(String query) {
                        return false;
                    }

                    @Override
                    public boolean onQueryTextChange(String newText) {

                        final ArrayList<Information> filteredModelList = filter(listData , newText);
                        adapter.setFilter(filteredModelList);

                        return true;
                    }
                });

        MenuItemCompat.setOnActionExpandListener( item,
                                                  new MenuItemCompat.OnActionExpandListener() {
                                                      @Override
                                                      public boolean onMenuItemActionCollapse ( MenuItem item ) {
// Do something when collapsed
                                                          adapter.setFilter( listData );
                                                          return true; // Return true to collapse action view
                                                      }

                                                      @Override
                                                      public boolean onMenuItemActionExpand ( MenuItem item ) {
// Do something when expanded
                                                          return true; // Return true to expand action view
                                                      }
                                                  } );
        return true;
    }

    @Override
    public boolean onOptionsItemSelected ( MenuItem item ) {
        switch ( item.getItemId() ) {

            case android.R.id.home:

                mDrawerLayout.openDrawer( GravityCompat.START );
                return true;



        }

        return super.onOptionsItemSelected( item );
    }


//...

            class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {


                private GestureDetector gestureDetector;
                private ClickListener clickListener;

                public RecyclerTouchListener ( Context context, final RecyclerView recyclerView, final ClickListener
                        clickListener ) {

                    this.clickListener = clickListener;


                    gestureDetector = new GestureDetector( context, new GestureDetector
                            .SimpleOnGestureListener() {

                        @Override
                        public boolean onSingleTapUp ( MotionEvent e ) {
                            return true;
                        }

                    } );

                }

                @Override
                public boolean onInterceptTouchEvent ( RecyclerView rv, MotionEvent e ) {

                    View child = rv.findChildViewUnder( e.getX(), e.getY() );

                    if ( child != null && clickListener != null && gestureDetector.onTouchEvent( e ) )

                    {

                        clickListener.onClick( child, rv.getChildAdapterPosition( child ) );

                    }

                    return false;
                }

                @Override
                public void onTouchEvent ( RecyclerView rv, MotionEvent e ) {

                }

                @Override
                public void onRequestDisallowInterceptTouchEvent ( boolean disallowIntercept ) {

                }
            }

            public interface ClickListener {

                void onClick ( View view, int position );

            }



    private ArrayList<Information> filter(ArrayList<Information> models, String query) {
        query = query.toLowerCase();

        final ArrayList<Information> filteredModelList = new ArrayList<>();
        for (Information model : models) {
            final String text = model.getName().toLowerCase();
            if (text.contains(query)) {
                filteredModelList.add(model);
            }
       }
        return filteredModelList;
    }
}

Information.java

public class Information {

    String title;
    String title2;

    public String getName() {
        return title;
    }

}

Thanks in advance.


Update with solution:

By adding the following code to Information.java:

public class Information {

    String title;
    String title2;
    String title3;

    public String getName() {
        return title;
    }

    public String getLetter() {
        return title2;
    }

    public String getLetter_title() {
        return title3;
    }
}

And replacing String[] arrays & putExtra in MainActivity.java with:

        Information information = (Information )adapter.getItem(position);


       intent.putExtra( "title_array", information.getName() );
       intent.putExtra( "letters_array", information.getLetter() );
       intent.putExtra( "letters_title_array", information.getLetter_title() );

Upvotes: 2

Views: 2005

Answers (1)

masp
masp

Reputation: 515

In your onclick method you always take each item from the same arrays. So even if you filter your data you pick the wrong items to send.

Upvotes: 1

Related Questions