2016-04-18 4 views
1

У меня есть одна активность в моем приложении, где пользователь ищет конкретный элемент из списка, но он также может сортировать эти элементы в списке по городам. И это я делаю со спиннером. После того, как он нажимает на spinner для сортировки элементов, он снова выводит данные с сервера.Не удается получить данные в RecyclerView из JSON после фильтрации

Проблема возникает, когда он выполняет поиск перед заказом товаров в списке по городам. Фильтрация работает нормально, но после того, как мы фильтруем элементы в списке, я больше не могу использовать счетчик и получать упорядоченные данные по выбранному городу. В списке отображаются предыдущие записи, упорядоченные в начале со значением по умолчанию от счетчика. Не удается получить данные больше. Я не знаю почему.

Это код от этой деятельности:

public class SearchGroupsActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener, SearchView.OnQueryTextListener { 

    Toolbar mToolbar; 
    SessionManager mSessionManager; 
    List<Group> mGroups; 
    RecyclerView mList; 
    RecyclerGroupsAdapter mAdapter; 
    SharedPreferences mSharedPreferences; 
    MyProgressDialog mDialog; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 
      Window w = getWindow(); // in Activity's onCreate() for instance 
      w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); 
     } 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_search_groups); 
     mSessionManager = new SessionManager(this); 
     mSharedPreferences = new SharedPreferences(this); 
     mGroups = new ArrayList<>(); 

     final SearchView searchView = (SearchView) findViewById(R.id.search); 
     searchView.setIconifiedByDefault(false); 
     searchView.setOnQueryTextListener(this); 

     setAdapter(); 
     setToolbar(); 

     Spinner spinner = (Spinner) mToolbar.findViewById(R.id.spinner); 
     spinner.setOnItemSelectedListener(this); 
     // Create an ArrayAdapter using the string array and a default spinner layout 
     ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, 
       R.array.group_cities, android.R.layout.simple_spinner_item); 
     // Specify the layout to use when the list of choices appears 
     adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
     // Apply the adapter to the spinner 
     spinner.setAdapter(adapter); 

     if (!mSessionManager.isLoggedIn()) { 
      startActivity(new Intent(this, LoginActivity.class)); 
      this.finish(); 
     } 

    } 

    private void setAdapter() { 
     mList = (RecyclerView) findViewById(R.id.list); 
     mAdapter = new RecyclerGroupsAdapter(this, mGroups); 
     RecyclerView.LayoutManager manager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false); 
     mList.setLayoutManager(manager); 
     mList.setItemAnimator(new DefaultItemAnimator()); 
     mList.setAdapter(mAdapter); 
    } 

    private void loadGroups(String selectedCity) { 
     mDialog = new MyProgressDialog(this, 1); 
     mDialog.show(); 

     StringRequest stringRequest = new StringRequest(Request.Method.GET, 
       AppConfig.ORDER_GROUPS_BY_CITY + "/" + selectedCity, 
       new Response.Listener<String>() { 
      @Override 
      public void onResponse(String response) { 
       hidePDialog(); 

       if (mGroups.size() > 0) { 
        mGroups.clear(); 
       } 

       try { 
        JSONObject object = new JSONObject(response); 
        boolean error = object.getBoolean("error"); 
        JSONArray groups = object.getJSONArray("groups"); 
        if (!error) { 
         for (int i = 0; i < groups.length(); i++) { 
          JSONObject groupObject = groups.getJSONObject(i); 
          Group group = new Group(); 
          group.setGroupName(groupObject.optString("group_name")); 
          mGroups.add(group); 
         } 
        } 

        // notify adapter that data has changed 
        mAdapter.notifyDataSetChanged(); 
       } catch (JSONException e) { 
        e.printStackTrace(); 
       } 
      } 
     }, new Response.ErrorListener() { 
      @Override 
      public void onErrorResponse(VolleyError error) { 
       hidePDialog(); 
       Toast.makeText(SearchGroupsActivity.this, error.getMessage(), Toast.LENGTH_SHORT).show(); 
      } 
     }); 

     AppController.getInstance().addToRequestQueue(stringRequest); 
    } 

    private String orderGroupsByCity() { 
     String cityName = ""; 
     int selectedFilterOption = mSharedPreferences.getCityFilter(); 

     switch (selectedFilterOption) { 
      case 0: 
       cityName = "Nis"; 
       break; 
      case 1: 
       cityName = "Beograd"; 
       break; 
      case 2: 
       cityName = "Paracin"; 
       break; 
     } 

     return cityName; 
    } 

    private void setToolbar() { 
     mToolbar = (Toolbar) findViewById(R.id.toolbar); 
     if (mToolbar != null) { 
      setSupportActionBar(mToolbar); 
     } 
     getSupportActionBar().setHomeButtonEnabled(true); 
     getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
     getSupportActionBar().setTitle("NADJI EKIPU"); 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     int id = item.getItemId(); 

     switch (id) { 
      case android.R.id.home: 
       this.finish(); 
       break; 
     } 

     return false; 
    } 

    @Override 
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 
     int selectedCityFilter = GroupsCity.NIS; 
     switch (position) { 
      case 0: 
       // NIS 
       selectedCityFilter = GroupsCity.NIS; 
       break; 
      case 1: 
       // BEOGRAD 
       selectedCityFilter = GroupsCity.BEOGRAD; 
       break; 
      case 2: 
       // PARACIN 
       selectedCityFilter = GroupsCity.PARACIN; 
       break; 
     } 
     mSharedPreferences.setCityFilter(selectedCityFilter); 
     String selectedCity = orderGroupsByCity(); 
     loadGroups(selectedCity); // HERE WE ARE FETCHING DATA ORDERED BY SELECTED CITY 
    } 

    @Override 
    public void onNothingSelected(AdapterView<?> parent) { 

    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     hidePDialog(); 
    } 

    private void hidePDialog() { 
     if (mDialog != null) { 
      mDialog.dismiss(); 
      mDialog = null; 
     } 
    } 

    @Override 
    public boolean onQueryTextSubmit(String query) { 

     return false; 
    } 

    @Override 
    public boolean onQueryTextChange(String newText) { 
     final List<Group> filteredModelList = filter(mGroups, newText); 
     mAdapter.setFilter(filteredModelList); 

     return true; 
    } 

    private List<Group> filter(List<Group> groups, String query) { 
     query = query.toLowerCase(); 

     final List<Group> filteredModelList = new ArrayList<>(); 
     for (Group group : groups) { 
      final String text = group.getGroupName().toLowerCase(); 
      if (text.contains(query)) { 
       filteredModelList.add(group); 
      } 
     } 
     return filteredModelList; 
    } 
} 
+0

Вам необходимо найти конкретную проблему в вашем приложении, а затем покажет вам свою проблему, а не код, и поможет вам найти причину. –

+0

Я знаю, где проблема, но я не знаю, как ее решить. В методе переопределения onQueryTextChange я устанавливаю для адаптера новый filterList с найденными элементами. После того, как я попытаюсь загрузить данные с сервера в метод loadGroups с новыми переданными параметрами, я получаю тот же список фильтров. –

+1

Если вы выполните поиск, а затем нажмите «Spinner», вы сначала фильтруете адаптер (который будет работать нормально), а затем вы выполните этот запрос. Однако, когда запрос возвращается с данными, вы просто добавляете его в список групп, на котором ваш адаптер не основан (мое предположение), поэтому вызов notifyDatasetChanged() будет бесполезным. Поэтому в вашем методе loadGroups() вам нужно снова выполнить фильтрацию, вызвав метод filter() и установив на адаптере результирующий список (например, вы в данный момент выполняете в слушателе для SearchView). – Luksprog

ответ

1

Если вы первый поиска, а затем нажмите Spinner вы отфильтруете адаптер (который будет работать нормально), а затем вы будете делать этот запрос (если пользователь выбирает город) на сервер.

Однако, когда запрос возвращается с данными, вы в настоящее время просто добавляете его в список groups, на котором нет вашего адаптера (мое предположение, когда вы передаете новый список при фильтрации). Поэтому в этом случае просто вызов notifyDatasetChanged() будет бесполезным, поскольку адаптер не увидит новые элементы данных.

Чтобы решить эту проблему, в вашем методе loadGroups() вам нужно снова выполнить фильтрацию, вызвав метод filter() и установив на адаптере результирующий список (например, вы в настоящее время выполняете в слушателе для SearchView).