163d2846409d84487d4856d3b8d18cc4684352e29Steve McKay/*
263d2846409d84487d4856d3b8d18cc4684352e29Steve McKay * Copyright 2017 The Android Open Source Project
363d2846409d84487d4856d3b8d18cc4684352e29Steve McKay *
463d2846409d84487d4856d3b8d18cc4684352e29Steve McKay * Licensed under the Apache License, Version 2.0 (the "License");
563d2846409d84487d4856d3b8d18cc4684352e29Steve McKay * you may not use this file except in compliance with the License.
663d2846409d84487d4856d3b8d18cc4684352e29Steve McKay * You may obtain a copy of the License at
763d2846409d84487d4856d3b8d18cc4684352e29Steve McKay *
863d2846409d84487d4856d3b8d18cc4684352e29Steve McKay *      http://www.apache.org/licenses/LICENSE-2.0
963d2846409d84487d4856d3b8d18cc4684352e29Steve McKay *
1063d2846409d84487d4856d3b8d18cc4684352e29Steve McKay * Unless required by applicable law or agreed to in writing, software
1163d2846409d84487d4856d3b8d18cc4684352e29Steve McKay * distributed under the License is distributed on an "AS IS" BASIS,
1263d2846409d84487d4856d3b8d18cc4684352e29Steve McKay * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1363d2846409d84487d4856d3b8d18cc4684352e29Steve McKay * See the License for the specific language governing permissions and
1463d2846409d84487d4856d3b8d18cc4684352e29Steve McKay * limitations under the License.
1563d2846409d84487d4856d3b8d18cc4684352e29Steve McKay */
1663d2846409d84487d4856d3b8d18cc4684352e29Steve McKay
1763d2846409d84487d4856d3b8d18cc4684352e29Steve McKaypackage com.example.android.supportv7.widget.selection.fancy;
1863d2846409d84487d4856d3b8d18cc4684352e29Steve McKay
19ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.core.util.Preconditions.checkArgument;
2063d2846409d84487d4856d3b8d18cc4684352e29Steve McKay
2163d2846409d84487d4856d3b8d18cc4684352e29Steve McKayimport android.content.Context;
2263d2846409d84487d4856d3b8d18cc4684352e29Steve McKayimport android.net.Uri;
2363d2846409d84487d4856d3b8d18cc4684352e29Steve McKayimport android.view.LayoutInflater;
2463d2846409d84487d4856d3b8d18cc4684352e29Steve McKayimport android.view.View;
2563d2846409d84487d4856d3b8d18cc4684352e29Steve McKayimport android.view.ViewGroup;
2663d2846409d84487d4856d3b8d18cc4684352e29Steve McKayimport android.widget.LinearLayout;
2763d2846409d84487d4856d3b8d18cc4684352e29Steve McKay
282a32c7e1264b14a20ed900abadea828b804a46ceAurimas Liutikasimport androidx.recyclerview.selection.ItemKeyProvider;
292a32c7e1264b14a20ed900abadea828b804a46ceAurimas Liutikasimport androidx.recyclerview.selection.SelectionTracker;
30def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport androidx.recyclerview.widget.RecyclerView;
31def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikas
32def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport com.example.android.supportv7.Cheeses;
33def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport com.example.android.supportv7.R;
3463d2846409d84487d4856d3b8d18cc4684352e29Steve McKay
3563d2846409d84487d4856d3b8d18cc4684352e29Steve McKayfinal class FancySelectionDemoAdapter extends RecyclerView.Adapter<FancyHolder> {
3663d2846409d84487d4856d3b8d18cc4684352e29Steve McKay
3783f7464907e288099c0f2d3014d69acf6e571d16Steve McKay    private final ContentUriKeyProvider mKeyProvider;
3863d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    private final Context mContext;
3963d2846409d84487d4856d3b8d18cc4684352e29Steve McKay
4063d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    // This should be replaced at "bind" time with a real test that
417fb763509e07f98d650efc25c91bff8b1cb239acSteve McKay    // asks SelectionTracker.
4263d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    private SelectionTest mSelTest;
4363d2846409d84487d4856d3b8d18cc4684352e29Steve McKay
4463d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    FancySelectionDemoAdapter(Context context) {
4563d2846409d84487d4856d3b8d18cc4684352e29Steve McKay        mContext = context;
4663d2846409d84487d4856d3b8d18cc4684352e29Steve McKay        mKeyProvider = new ContentUriKeyProvider("cheeses", Cheeses.sCheeseStrings);
4763d2846409d84487d4856d3b8d18cc4684352e29Steve McKay        mSelTest = new SelectionTest() {
4863d2846409d84487d4856d3b8d18cc4684352e29Steve McKay            @Override
4963d2846409d84487d4856d3b8d18cc4684352e29Steve McKay            public boolean isSelected(Uri id) {
5063d2846409d84487d4856d3b8d18cc4684352e29Steve McKay                throw new IllegalStateException(
517fb763509e07f98d650efc25c91bff8b1cb239acSteve McKay                        "Adapter must be initialized with SelectionTracker.");
5263d2846409d84487d4856d3b8d18cc4684352e29Steve McKay            }
5363d2846409d84487d4856d3b8d18cc4684352e29Steve McKay        };
5463d2846409d84487d4856d3b8d18cc4684352e29Steve McKay
5563d2846409d84487d4856d3b8d18cc4684352e29Steve McKay        // In the fancy edition of selection support we supply access to stable
5663d2846409d84487d4856d3b8d18cc4684352e29Steve McKay        // ids using content URI. Since we can map between position and selection key
5763d2846409d84487d4856d3b8d18cc4684352e29Steve McKay        // at will we get fancy dependent functionality like band selection and range support.
5863d2846409d84487d4856d3b8d18cc4684352e29Steve McKay        setHasStableIds(false);
5963d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    }
6063d2846409d84487d4856d3b8d18cc4684352e29Steve McKay
6163d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    ItemKeyProvider<Uri> getItemKeyProvider() {
6263d2846409d84487d4856d3b8d18cc4684352e29Steve McKay        return mKeyProvider;
6363d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    }
6463d2846409d84487d4856d3b8d18cc4684352e29Steve McKay
657fb763509e07f98d650efc25c91bff8b1cb239acSteve McKay    // Glue together SelectionTracker and the adapter.
667fb763509e07f98d650efc25c91bff8b1cb239acSteve McKay    public void bindSelectionHelper(final SelectionTracker<Uri> selectionTracker) {
677fb763509e07f98d650efc25c91bff8b1cb239acSteve McKay        checkArgument(selectionTracker != null);
6863d2846409d84487d4856d3b8d18cc4684352e29Steve McKay        mSelTest = new SelectionTest() {
6963d2846409d84487d4856d3b8d18cc4684352e29Steve McKay            @Override
7063d2846409d84487d4856d3b8d18cc4684352e29Steve McKay            public boolean isSelected(Uri id) {
717fb763509e07f98d650efc25c91bff8b1cb239acSteve McKay                return selectionTracker.isSelected(id);
7263d2846409d84487d4856d3b8d18cc4684352e29Steve McKay            }
7363d2846409d84487d4856d3b8d18cc4684352e29Steve McKay        };
7463d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    }
7563d2846409d84487d4856d3b8d18cc4684352e29Steve McKay
7663d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    void loadData() {
7763d2846409d84487d4856d3b8d18cc4684352e29Steve McKay        onDataReady();
7863d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    }
7963d2846409d84487d4856d3b8d18cc4684352e29Steve McKay
8063d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    private void onDataReady() {
8163d2846409d84487d4856d3b8d18cc4684352e29Steve McKay        notifyDataSetChanged();
8263d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    }
8363d2846409d84487d4856d3b8d18cc4684352e29Steve McKay
8463d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    @Override
8563d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    public int getItemCount() {
8663d2846409d84487d4856d3b8d18cc4684352e29Steve McKay        return Cheeses.sCheeseStrings.length;
8763d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    }
8863d2846409d84487d4856d3b8d18cc4684352e29Steve McKay
8963d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    @Override
9063d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    public long getItemId(int position) {
9163d2846409d84487d4856d3b8d18cc4684352e29Steve McKay        return position;
9263d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    }
9363d2846409d84487d4856d3b8d18cc4684352e29Steve McKay
9463d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    @Override
9563d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    public void onBindViewHolder(FancyHolder holder, int position) {
9663d2846409d84487d4856d3b8d18cc4684352e29Steve McKay        Uri uri = mKeyProvider.getKey(position);
9763d2846409d84487d4856d3b8d18cc4684352e29Steve McKay        holder.update(uri, uri.getLastPathSegment(), mSelTest.isSelected(uri));
9863d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    }
9963d2846409d84487d4856d3b8d18cc4684352e29Steve McKay
10063d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    @Override
10163d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    public FancyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
10263d2846409d84487d4856d3b8d18cc4684352e29Steve McKay        LinearLayout layout = inflateLayout(mContext, parent, R.layout.selection_demo_list_item);
10363d2846409d84487d4856d3b8d18cc4684352e29Steve McKay        return new FancyHolder(layout);
10463d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    }
10563d2846409d84487d4856d3b8d18cc4684352e29Steve McKay
10663d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    @SuppressWarnings("TypeParameterUnusedInFormals")  // Convenience to avoid clumsy cast.
10763d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    private static <V extends View> V inflateLayout(
10863d2846409d84487d4856d3b8d18cc4684352e29Steve McKay            Context context, ViewGroup parent, int layout) {
10963d2846409d84487d4856d3b8d18cc4684352e29Steve McKay
11063d2846409d84487d4856d3b8d18cc4684352e29Steve McKay        return (V) LayoutInflater.from(context).inflate(layout, parent, false);
11163d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    }
11263d2846409d84487d4856d3b8d18cc4684352e29Steve McKay
11363d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    private interface SelectionTest {
11463d2846409d84487d4856d3b8d18cc4684352e29Steve McKay        boolean isSelected(Uri id);
11563d2846409d84487d4856d3b8d18cc4684352e29Steve McKay    }
11663d2846409d84487d4856d3b8d18cc4684352e29Steve McKay}
117