使用SearchView过滤Recyclerview后获得错误的位置 [英] Getting wrong position after Recyclerview filtering using SearchView
问题描述
我试图使用该网站将SearchView添加到我的应用中:
http://www. tutorialsbuzz.com/2015/11/Android-Filter-RecyclerView-Using-SearchView-In-ToolBar.html
但是,点击过滤后的结果后,我无法将用户重定向到正确的Recyclerview位置:
例如:如果用户搜索了第二个结果并单击它,则应用程序将使用第一个结果而不是第二个结果向他发送下一个活动(详细活动).>
这是我的应用代码( 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;
}
}
谢谢.
更新解决方案:
通过将以下代码添加到 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;
}
}
并替换String []数组& MainActivity.java 中的putExtra,带有:
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() );
在您的onclick方法中,您总是从相同的数组中获取每个项目.因此,即使您过滤了数据,也会选择发送错误的项目.
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() );
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.
这篇关于使用SearchView过滤Recyclerview后获得错误的位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!