1

我正在创建一个android应用程序。在应用程序中,我有一个登录页面。登录后显示用户列表。用户列表活动是HomeActivity.java,其中包含两个片段,分别命名为UserListFragment.javaChatFragment.java用户列表正在从firebase获取。搜索在操作栏中的片段

UserListFragment.java包含一个具有搜索菜单和注销菜单的操作栏。注销菜单工作正常,但搜索不起作用。搜索图标会显示,但是当我搜索某些内容时,它不会显示任何内容,即没有过滤器。我正在使用firebase来显示用户列表。

我不想显示在ChatFragment.java

的搜索查看我尝试了各种不同的各种解决方案。但没有人为我工作。

这是代码。

UserListFragment.java

public class UsersListFragment extends Fragment { 
// TODO: Rename parameter arguments, choose names that match 
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER 
private static final String ARG_PARAM1 = "param1"; 
private static final String ARG_PARAM2 = "param2"; 
Activity activity; 
// TODO: Rename and change types of parameters 
private String mParam1; 
private String mParam2; 
private static final String TAG = "UsersListFragment"; 
private OnFragmentInteractionListener mListener; 
private ListView listView; 
private List<UserData> users; 
private CustomAdapter adapter; 
SharedPreferences.Editor preferenceEditor; 
Timer myTimer; 
View view; 
ActionBar actionBar; 
private static final String PREFRENCES_NAME = "setPreferences"; 
private ProgressDialog progressBar; 
String partnerKeyValue; 

// TODO: Rename and change types and number of parameters 
public static UsersListFragment newInstance(String param1, String param2) { 
    UsersListFragment fragment = new UsersListFragment(); 
    Bundle args = new Bundle(); 
    args.putString(ARG_PARAM1, param1); 
    args.putString(ARG_PARAM2, param2); 
    fragment.setArguments(args); 
    return fragment; 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    Global.getInstance().unreadMessageUsers.clear(); 
    progressBar = new ProgressDialog(getActivity()); 
    progressBar.setCancelable(false); 
    progressBar.setMessage("Loading..."); 
    progressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER); 
    progressBar.setProgress(0); 
    } 

@Override 
public void onCreateOptionsMenu(Menu menu,MenuInflater inflater) { 

    inflater.inflate(R.menu.menu_userlist,menu); 
    MenuItem item = menu.findItem(R.id.menuSearch); 

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

    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { 
     @Override 
     public boolean onQueryTextSubmit(String query) { 
      return false; 
     } 

     @Override 
     public boolean onQueryTextChange(String newText) { 
      Log.i(TAG,newText); 
      adapter.getFilter().filter(newText); 
      return true; 
     } 
    }); 

    super.onCreateOptionsMenu(menu,inflater); 
} 


private void logoutUser(){ 
    Intent I = new Intent(getActivity(), LoginActivity.class); 
    startActivity(I); 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 

    switch (item.getItemId()) { 
     case R.id.menuSearch : 
      return true; 

     case R.id.menuLogout : 
      logoutUser(); 
      return true; 

     default: 
      return super.onOptionsItemSelected(item); 
    } 

} 

menu_userlist.xml

<?xml version="1.0" encoding="utf-8"?> 
<menu xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto"> 

<item android:id="@+id/menuSearch" 
    android:title="@string/search" 
    android:icon="@drawable/ic_search" 
    app:actionViewClass="android.widget.SearchView" 
    app:showAsAction="always"> 
</item> 

<item android:id="@+id/menuLogout" 
    android:title="@string/logout" 
    android:icon="@drawable/ic_logout" 
    app:showAsAction="always"> 
</item> 

CustomAdapter.java

@Override 
public Filter getFilter() { 
    Filter filter = new Filter() { 

     @SuppressWarnings("unchecked") 
     @Override 
     protected void publishResults(CharSequence constraint,FilterResults results) { 

      users = (List<UserData>) results.values; // has the filtered values 
      notifyDataSetChanged(); // notifies the data with new filtered values 
     } 

     @Override 
     protected FilterResults performFiltering(CharSequence constraint) { 
      FilterResults results = new Filter.FilterResults();  

      List<String> FilteredArrList = new ArrayList<String>(); 

       if (mOriginalValues != null) { 

       if (constraint == null || constraint.length() == 0) { 

        // set the Original result to return 
        results.count = mOriginalValues.size(); 
        results.values = mOriginalValues; 
       } else { 
        constraint = constraint.toString().toLowerCase(); 
        for (int i = 0; i < mOriginalValues.size(); i++) { 
         String data = mOriginalValues.get(i).toString(); 
         if (data.toLowerCase().contains(constraint.toString())) { 
          FilteredArrList.add(data); 
         } 
        } 
        // set the Filtered result to return 
        results.count = FilteredArrList.size(); 
        results.values = FilteredArrList; 
       } 
      } 

      return results; 
     } 
    }; 
    return filter; 
} 
} 
+0

是您的滤波方法的工作?您是否检查了'results'返回变量的值 – Dibzmania

+0

@Dibzmania my ** results **变量包含此值 **[email protected]** 每次我键入一些字母表某些值越来越多为每个字母生成我输入搜索如上。我不知道它是什么。 – Rider

+0

@Dibzmania我想我得到空值。当我试图打印** results.values **时,我得到了空异常错误。我该如何解决它? – Rider

回答

0

我自己解决了我的问题。它可能会帮助别人。 :)

CustomAdapter.java

@Override 
public Filter getFilter() { 
    Filter filter = new Filter() { 

     @SuppressWarnings("unchecked") 
     @Override 
     protected void publishResults(CharSequence constraint, 
             FilterResults results) { 
      clear(); 
      addAll((List<UserData>) results.values); 
      arrayList = (List<UserData>)results.values; 
      notifyDataSetChanged(); 
     } 


     @Override 
     protected FilterResults performFiltering(CharSequence constraint) { 
      FilterResults results = new FilterResults();  // Holds the results of a filtering operation in values 
      List<UserData> FilteredArrList = new ArrayList<UserData>(); 

      if (mOriginalValues == null) { 
       mOriginalValues = new ArrayList<UserData>(arrayList); 
      } 


      if (constraint == null || constraint.length() == 0) { 
       results.count = mOriginalValues.size(); 
       results.values = mOriginalValues; 
      } else { 
       constraint = constraint.toString().toLowerCase(); 


       for (int i = 0; i < mOriginalValues.size(); i++) { 
        String data = mOriginalValues.get(i).getName(); 

        if (data.toLowerCase().contains(constraint.toString())) { 
         FilteredArrList.add(mOriginalValues.get(i)); 
        } 
       } 
       // set the Filtered result to return 
       results.count = FilteredArrList.size(); 
       results.values = FilteredArrList; 
      } 

      return results; 
     } 

    }; 
    return filter; 
} 
1

更改下面的代码段 -

@SuppressWarnings("unchecked") 
    @Override 
    protected void publishResults(CharSequence constraint,FilterResults results) { 
     clear(); 
     addAll((List<UserData>) results.values) 
     users = (List<UserData>) results.values; // has the filtered values 

     notifyDataSetChanged(); // notifies the data with new filtered values 
    } 

这主要可以解决这个问题。但源代码中存在很多不一致之处。您正在扩展ArrayAdpater,它已经实现了Filterable接口。

此外,还查看为什么你需要下面的状态变量 -

private List<UserData> messages; 
private List<UserData> users; 
private List<UserData> mOriginalValues; 

请注意,您正在扩展ArrayAdapter和要传递的初始数据在构造函数中设置。之后在数据集中发生任何变化,您需要将其重置为父母ArrayAdapter。只是改变你的子类中的状态变量,是不会有帮助的。

+0

您为编辑建议的代码导致应用程序崩溃。 '私人列表消息;'' 私人列表用户;'' 私人列表 mOriginalValues;' 用户和mOrigninalValues我已经使用过滤器的方法。我是android新手,因此使用了某些源代码。我用于未读消息数的消息,我需要在用户名旁边显示。 如果您可以提供一些更改并指导我,我应该更改哪些内容。这对我真的很有帮助。非常感谢。 :) – Rider

+0

什么是崩溃堆栈跟踪?我没有真正运行代码,所以它可能会有所有可能。但想法是清除底层数据并添加新数据。 – Dibzmania

+0

java.lang.NullPointerException:尝试在此行的空对象引用上调用接口方法java.lang.Object [] java.util.Collection.toArray()'。 addAll((List )results.values); – Rider