164a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar/*
264a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar * Copyright (C) 2015 The Android Open Source Project
364a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar *
464a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
564a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar * you may not use this file except in compliance with the License.
664a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar * You may obtain a copy of the License at
764a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar *
864a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar *      http://www.apache.org/licenses/LICENSE-2.0
964a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar *
1064a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar * Unless required by applicable law or agreed to in writing, software
1164a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
1264a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1364a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar * See the License for the specific language governing permissions and
1464a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar * limitations under the License.
1564a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar */
1664a8c125fb1a50ea756176931aefa6743335a734Yigit Boyarpackage com.example.android.supportv7.util;
1764a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar
1864a8c125fb1a50ea756176931aefa6743335a734Yigit Boyarimport android.os.Bundle;
1964a8c125fb1a50ea756176931aefa6743335a734Yigit Boyarimport android.view.KeyEvent;
2064a8c125fb1a50ea756176931aefa6743335a734Yigit Boyarimport android.view.LayoutInflater;
2164a8c125fb1a50ea756176931aefa6743335a734Yigit Boyarimport android.view.View;
2264a8c125fb1a50ea756176931aefa6743335a734Yigit Boyarimport android.view.ViewGroup;
2364a8c125fb1a50ea756176931aefa6743335a734Yigit Boyarimport android.view.inputmethod.EditorInfo;
2464a8c125fb1a50ea756176931aefa6743335a734Yigit Boyarimport android.widget.CheckBox;
2564a8c125fb1a50ea756176931aefa6743335a734Yigit Boyarimport android.widget.CompoundButton;
2664a8c125fb1a50ea756176931aefa6743335a734Yigit Boyarimport android.widget.EditText;
2764a8c125fb1a50ea756176931aefa6743335a734Yigit Boyarimport android.widget.TextView;
2864a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar
29def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport androidx.appcompat.app.AppCompatActivity;
30def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport androidx.recyclerview.widget.LinearLayoutManager;
31def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport androidx.recyclerview.widget.RecyclerView;
32def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport androidx.recyclerview.widget.SortedList;
33def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport androidx.recyclerview.widget.SortedListAdapterCallback;
34def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikas
35a7eda07bf9dba63dde6cb4eaa06a5229cfd832ecAurimas Liutikasimport com.example.android.supportv7.R;
36a7eda07bf9dba63dde6cb4eaa06a5229cfd832ecAurimas Liutikas
3764a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar/**
3864a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar * A sample activity that uses {@link SortedList} in combination with RecyclerView.
3964a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar */
40a7eda07bf9dba63dde6cb4eaa06a5229cfd832ecAurimas Liutikaspublic class SortedListActivity extends AppCompatActivity {
4164a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar    private RecyclerView mRecyclerView;
4264a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar    private LinearLayoutManager mLinearLayoutManager;
4364a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar    private SortedListAdapter mAdapter;
4464a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar    @Override
4564a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar    protected void onCreate(Bundle savedInstanceState) {
4664a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        super.onCreate(savedInstanceState);
4764a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        setContentView(R.layout.sorted_list_activity);
48fa2e2acf79d791a90410025daad438968550d18cAlan Viverette        mRecyclerView = findViewById(R.id.recycler_view);
4964a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        mRecyclerView.setHasFixedSize(true);
5064a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        mLinearLayoutManager = new LinearLayoutManager(this);
5164a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        mRecyclerView.setLayoutManager(mLinearLayoutManager);
5264a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        mAdapter = new SortedListAdapter(getLayoutInflater(),
5364a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                new Item("buy milk"), new Item("wash the car"),
5464a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                new Item("wash the dishes"));
5564a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        mRecyclerView.setAdapter(mAdapter);
5664a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        mRecyclerView.setHasFixedSize(true);
57fa2e2acf79d791a90410025daad438968550d18cAlan Viverette        final EditText newItemTextView = findViewById(R.id.new_item_text_view);
5864a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        newItemTextView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
5964a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar            @Override
6064a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar            public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
6164a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                if (id == EditorInfo.IME_ACTION_DONE &&
6264a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                        (keyEvent == null || keyEvent.getAction() == KeyEvent.ACTION_DOWN)) {
6364a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                    final String text = textView.getText().toString().trim();
6464a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                    if (text.length() > 0) {
6564a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                        mAdapter.addItem(new Item(text));
6664a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                    }
6764a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                    textView.setText("");
6864a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                    return true;
6964a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                }
7064a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                return false;
7164a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar            }
7264a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        });
7364a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar    }
7464a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar
7564a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar    private static class SortedListAdapter extends RecyclerView.Adapter<TodoViewHolder> {
7664a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        SortedList<Item> mData;
7764a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        final LayoutInflater mLayoutInflater;
7864a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        public SortedListAdapter(LayoutInflater layoutInflater, Item... items) {
7964a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar            mLayoutInflater = layoutInflater;
8064a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar            mData = new SortedList<Item>(Item.class, new SortedListAdapterCallback<Item>(this) {
8164a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                @Override
8264a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                public int compare(Item t0, Item t1) {
8364a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                    if (t0.mIsDone != t1.mIsDone) {
8464a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                        return t0.mIsDone ? 1 : -1;
8564a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                    }
8664a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                    int txtComp = t0.mText.compareTo(t1.mText);
8764a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                    if (txtComp != 0) {
8864a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                        return txtComp;
8964a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                    }
9064a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                    if (t0.id < t1.id) {
9164a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                        return -1;
9264a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                    } else if (t0.id > t1.id) {
9364a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                        return 1;
9464a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                    }
9564a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                    return 0;
9664a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                }
9764a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar
9864a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                @Override
9964a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                public boolean areContentsTheSame(Item oldItem,
10064a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                        Item newItem) {
10164a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                    return oldItem.mText.equals(newItem.mText);
10264a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                }
10364a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar
10464a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                @Override
10564a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                public boolean areItemsTheSame(Item item1, Item item2) {
10664a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                    return item1.id == item2.id;
10764a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                }
10864a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar            });
10964a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar            for (Item item : items) {
11064a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                mData.add(item);
11164a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar            }
11264a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        }
11364a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar
11464a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        public void addItem(Item item) {
11564a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar            mData.add(item);
11664a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        }
11764a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar
11864a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        @Override
11964a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        public TodoViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
12064a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar            return new TodoViewHolder (
12164a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                    mLayoutInflater.inflate(R.layout.sorted_list_item_view, parent, false)) {
12264a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                @Override
12364a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                void onDoneChanged(boolean isDone) {
12464a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                    int adapterPosition = getAdapterPosition();
12564a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                    if (adapterPosition == RecyclerView.NO_POSITION) {
12664a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                        return;
12764a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                    }
12864a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                    mBoundItem.mIsDone = isDone;
12964a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                    mData.recalculatePositionOfItemAt(adapterPosition);
13064a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                }
13164a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar            };
13264a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        }
13364a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar
13464a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        @Override
13564a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        public void onBindViewHolder(TodoViewHolder holder, int position) {
13664a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar            holder.bindTo(mData.get(position));
13764a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        }
13864a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar
13964a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        @Override
14064a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        public int getItemCount() {
14164a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar            return mData.size();
14264a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        }
14364a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar    }
14464a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar
14564a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar    abstract private static class TodoViewHolder extends RecyclerView.ViewHolder {
14664a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        final CheckBox mCheckBox;
14764a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        Item mBoundItem;
14864a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        public TodoViewHolder(View itemView) {
14964a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar            super(itemView);
15064a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar            mCheckBox = (CheckBox) itemView;
15164a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar            mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
15264a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                @Override
15364a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
15464a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                    if (mBoundItem != null && isChecked != mBoundItem.mIsDone) {
15564a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                        onDoneChanged(isChecked);
15664a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                    }
15764a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar                }
15864a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar            });
15964a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        }
16064a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar
16164a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        public void bindTo(Item item) {
16264a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar            mBoundItem = item;
16364a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar            mCheckBox.setText(item.mText);
16464a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar            mCheckBox.setChecked(item.mIsDone);
16564a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        }
16664a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar
16764a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        abstract void onDoneChanged(boolean isChecked);
16864a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar    }
16964a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar
17064a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar    private static class Item {
17164a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        String mText;
17264a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        boolean mIsDone = false;
17364a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        final public int id;
17464a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        private static int idCounter = 0;
17564a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar
17664a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        public Item(String text) {
17764a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar            id = idCounter ++;
17864a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar            this.mText = text;
17964a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar        }
18064a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar    }
18164a8c125fb1a50ea756176931aefa6743335a734Yigit Boyar}
182