Как отсортировать Recyclerview?

Я пытаюсь отсортировать список настраиваемых объектов и отобразить в Recyclerview. После отображения элементов в recyclerview. Я сортирую список в Activity и вызываю adapter.notifyDataSetChanged(), но он не работает.

Код в MainActivity.java:

Collections.sort(beerDataList, new Comparator<BeerData>() {
                            @Override
                            public int compare(BeerData o1, BeerData o2) {
                                return o1.getAbv().compareToIgnoreCase(o2.getAbv());
                            }
                        });
                        adapter.notifyDataSetChanged();

Код адаптера:

public class BeerListAdapter extends RecyclerView.Adapter<BeerListAdapter.MyViewHolder> {

    private static ClickListener clickListener;

    private Context context;
    private LayoutInflater inflater;
    private List<BeerData> beerDataList;
    private List<BeerData> copyList;

    public BeerListAdapter(Context context) {
        this.context = context;
        inflater = LayoutInflater.from(context);
        beerDataList = new ArrayList<>();
        copyList = new ArrayList<>();
    }

    public void setList(List<BeerData> beerDataList) {
        if (this.beerDataList.isEmpty()) {
            this.beerDataList.addAll(beerDataList);
            copyList.addAll(beerDataList);
        }
        notifyDataSetChanged();
    }

    public void filter(String query) {
        beerDataList.clear();
        if (query.isEmpty()) {
            beerDataList.addAll(copyList);
        } else {
            for (BeerData beerData : copyList) {
                if (beerData.getName().replaceAll("[\\s]", "").toLowerCase().contains(query.replaceAll("[\\s]", "").toLowerCase())) {
                    beerDataList.add(beerData);
                }
            }
        }
        notifyDataSetChanged();
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = inflater.inflate(R.layout.custom_beer_row, parent, false);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        holder.beerName.setText(beerDataList.get(position).getName());
        holder.styleName.setText(beerDataList.get(position).getStyle());
        holder.alcoholContent.setText("Alcohol Content: " + beerDataList.get(position).getAbv());
        holder.quantity.setText(beerDataList.get(position).getQuantity().toString());
    }

    @Override
    public int getItemCount() {
        return beerDataList.size();
    }

    public void setOnItemClickListener(ClickListener clickListener) {
        BeerListAdapter.clickListener = clickListener;
    }


    class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        TextView beerName, alcoholContent, styleName, quantity;
        ImageView add, minus;

        MyViewHolder(View itemView) {
            super(itemView);
            beerName = itemView.findViewById(R.id.beerName);
            alcoholContent = itemView.findViewById(R.id.alcoholContent);
            styleName = itemView.findViewById(R.id.beerStyle);
            quantity = itemView.findViewById(R.id.quantity);
            add = itemView.findViewById(R.id.add);
            minus = itemView.findViewById(R.id.minus);
            add.setOnClickListener(this);
            minus.setOnClickListener(this);

        }


        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.add:
                    clickListener.onAddClick(getAdapterPosition(), v);
                    break;
                case R.id.minus:
                    clickListener.onMinusClick(getAdapterPosition(), v);
                    break;
            }
        }
    }

    public interface ClickListener {
        void onAddClick(int position, View v);

        void onMinusClick(int position, View v);
    }
}

Вот мой MainActivity:

public class MainActivity extends AppCompatActivity implements SearchView.OnQueryTextListener, LoginResultCallBack {

    private static final String TAG = MainActivity.class.getSimpleName();
    @Inject
    MyApplication application;

    LoginViewModel loginViewModel;

    @BindView(R.id.beerListRecyclerView)
    RecyclerView recyclerView;
    @BindView(R.id.progressBar)
    ProgressBar progressBar;

    private BeerListAdapter adapter;

    private List<BeerData> beerDataList;

    private Menu menu;

    private String sortType = "unsorted";
    private Disposable networkDisposable;
    List<BeerData> originalList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        ((MyApplication) getApplication()).getComponent().inject(this);
        loginViewModel = ViewModelProviders.of(this,new LoginViewModelFactory(application,this)).get(LoginViewModel.class);
        adapter = new BeerListAdapter(this);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setHasFixedSize(true);
        recyclerView.setAdapter(adapter);

        adapter.setOnItemClickListener(new BeerListAdapter.ClickListener() {
            @Override
            public void onAddClick(int position, View v) {
                addItem(position);
            }

            @Override
            public void onMinusClick(int position, View v) {
                removeItem(position);
            }
        });
    }



    public void fetchData() {
        progressBar.setVisibility(View.VISIBLE);
        loginViewModel.fetchData();
        loginViewModel.result.observe(this, new Observer<NetworkResponse>() {
            @Override
            public void onChanged(@Nullable NetworkResponse networkResponse) {
                progressBar.setVisibility(View.GONE);
                assert networkResponse != null;
                if (networkResponse.getPostData() != null) {
                    beerDataList = new ArrayList<>();
                    originalList = networkResponse.getPostData();
                    beerDataList = networkResponse.getPostData();
                    Log.e(TAG, "Response: " + networkResponse.getPostData().get(0).getAbv());
                    progressBar.setVisibility(View.GONE);
                    adapter.setList(networkResponse.getPostData());
                } else {
                    Log.e(TAG, "Response: " + networkResponse.getError().getLocalizedMessage());
                    progressBar.setVisibility(View.GONE);
                }
            }
        });

    }

    @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);
        this.menu = menu;

        MenuItem searchItem = menu.findItem(R.id.searchBar);

        SearchView searchView = (SearchView) searchItem.getActionView();
        searchView.setQueryHint("Search Beer");
        searchView.setOnQueryTextListener(this);
        searchView.setIconified(false);

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.cart:
                Log.e(TAG, "cart clicked");
                break;
            case R.id.sort:
                if (beerDataList != null) {
                    if (sortType.equalsIgnoreCase("unsorted")) {
                        Log.e(TAG,beerDataList.size()+" Size");
                        Collections.sort(beerDataList, new Comparator<BeerData>() {
                            @Override
                            public int compare(BeerData o1, BeerData o2) {
                                return o1.getAbv().compareToIgnoreCase(o2.getAbv());
                            }
                        });
                        adapter.notifyDataSetChanged();
                        sortType = "ascend";
                        menu.getItem(2).setTitle(R.string.unsorted);

                    } else if (sortType.equalsIgnoreCase("ascend")) {
                        Log.e(TAG,beerDataList.size()+" Size");
                        Collections.sort(beerDataList, new Comparator<BeerData>() {
                            @Override
                            public int compare(BeerData o1, BeerData o2) {
                                return o2.getAbv().compareToIgnoreCase(o1.getAbv());
                            }
                        });
                        adapter.notifyDataSetChanged();
                        sortType = "descend";
                        menu.getItem(2).setTitle(R.string.view_original);
                    } else {
                        Log.e(TAG,beerDataList.size()+" Size");
                        beerDataList.clear();
                        beerDataList.addAll(originalList);
                        adapter.notifyDataSetChanged();
                        sortType = "unsorted";
                        menu.getItem(2).setTitle(R.string.sort);
                    }
                }
                break;
        }
        return super.onOptionsItemSelected(item);
    }

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

    @Override
    public boolean onQueryTextChange(String newText) {
        adapter.filter(newText);
        return true;
    }

    @Override
    protected void onResume() {
        super.onResume();
        networkDisposable = ReactiveNetwork.observeNetworkConnectivity(application)
                .subscribeOn(Schedulers.io())
                .filter(ConnectivityPredicate.hasState(NetworkInfo.State.CONNECTED))
                .filter(ConnectivityPredicate.hasType(ConnectivityManager.TYPE_WIFI))
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Connectivity>() {
                    @Override
                    public void accept(final Connectivity connectivity) {
                        // do something
                        if (connectivity.isAvailable()) {
                            fetchData();
                        } else {
                            Toast.makeText(MainActivity.this, R.string.internet_issue, Toast.LENGTH_LONG).show();
                        }
                    }
                });
    }

    private void addItem(int position) {
        int quantity = beerDataList.get(position).getQuantity();
        quantity++;
        beerDataList.get(position).setQuantity(quantity);
        menu.getItem(1).setIcon(ContextCompat.getDrawable(MainActivity.this, R.drawable.ic_cart_full));
        adapter.notifyDataSetChanged();
    }

    private void removeItem(int position) {
        if (beerDataList.get(position).getQuantity() > 0) {
            int quantity = beerDataList.get(position).getQuantity();
            quantity--;
            if (quantity == 0)
                menu.getItem(1).setIcon(ContextCompat.getDrawable(MainActivity.this, R.drawable.ic_cart_empty));

            beerDataList.get(position).setQuantity(quantity);
            adapter.notifyDataSetChanged();
        }
    }

    private void safelyDispose(Disposable... disposables) {
        for (Disposable subscription : disposables) {
            if (subscription != null && !subscription.isDisposed()) {
                subscription.dispose();
            }
        }
    }

    @Override protected void onPause() {
        super.onPause();
        safelyDispose(networkDisposable);
    }

    @Override
    public void onSuccess(String message) {

    }

    @Override
    public void onError(String message) {

    }

    @Override
    public void showProgress() {

    }

    @Override
    public void hideProgress() {

    }
}

Что я здесь делаю не так?

Привет, @XoXo, не могли бы вы полностью показать свой MainActivity.java, пожалуйста?

SonhnLab 29.06.2018 19:39

@SonhnLab обновлен

sagar suri 29.06.2018 19:41

Я думаю, вы сортируете beerDataList в MainActivity, а не beerDataList в BeerListAdapter, поэтому он не работает.

SonhnLab 29.06.2018 19:48

Но я звоню в adapter.notifyDataSetChanged(). Все еще не работает.

sagar suri 29.06.2018 19:48

Вы можете использовать ниже ответ Дж. Джефферсона или меня. Это может решить вашу проблему. Надеюсь, поможет!

SonhnLab 29.06.2018 19:55

Хороший ответ @SonhnLab. Вероятно, немного лучше, чем у меня, так как это разделит ответственность за сортировку от основного действия на класс адаптера. +1 за хорошую практику программирования.

J. Jefferson 29.06.2018 20:06
1
6
206
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы не передаете отсортированный список своему адаптеру. Вы просто вызываете notifyDataSetChanged (), который просто сообщает адаптеру, что в его классе есть новые данные, и использует baerDataList, который в настоящее время установлен в классе, для обновления списка. Попробуйте это в своей основной деятельности.

Collections.sort(beerDataList, new Comparator<BeerData>() {
                        @Override
                        public int compare(BeerData o1, BeerData o2) {
                            return o1.getAbv().compareToIgnoreCase(o2.getAbv());
                        }
                    });
                    adapter.setBeerDataList(beerDataList);

И setBeerDataList () в вашем классе адаптера.

private List<BeerData> beerDataList;

public void setBeerDataList(List<BeerData> sortedBeerDataList){
    this.beerDataList = sortedBeerDataList;
    notifyDataSetChanged();
}

Поместите функцию сортировки из MainActivity в BeerListAdapter:

private void sortBeer() {
    Collections.sort(beerDataList, new Comparator<BeerData>() {
        @Override
        public int compare(BeerData o1, BeerData o2) {
            return o1.getAbv().compareToIgnoreCase(o2.getAbv());
        }
    });
    notifyDataSetChanged();
}

затем вызовите adapter.sortBeer(), когда выполните действие сортировки

Другие вопросы по теме