1

Я создаю приложение для Android. В приложении у меня есть страница входа. После входа в систему отображается список пользователей. Активность списка пользователей: HomeActivity.java, которая содержит два фрагмента, названных как UserListFragment.java и ChatFragment.java. Список пользователей отображается с firebase.Поиск в панели действий во фрагменте

UserListFragment.java содержит панель действий, в которой есть меню поиска и меню выхода из системы. Меню выхода из системы работает нормально, но поиск не работает. Значок поиска отображается, но когда я что-то ищу, он ничего не отображает, т.е. нет фильтров. Я использую firebase для отображения списка пользователей.

Я не хочу, чтобы SearchView, который будет отображаться в 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 ((Список ) results.values); – Rider