Home | History | Annotate | Download | only in drawer
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.android.car.media.drawer;
     17 
     18 import android.content.Context;
     19 import android.support.annotation.Nullable;
     20 import android.support.v7.widget.RecyclerView;
     21 
     22 import androidx.car.drawer.CarDrawerAdapter;
     23 import androidx.car.drawer.CarDrawerController;
     24 import androidx.car.drawer.DrawerItemViewHolder;
     25 
     26 /**
     27  * Subclass of CarDrawerAdapter used by the Media app.
     28  * <p>
     29  * This adapter delegates actual fetching of items (and other operations) to a
     30  * {@link MediaItemsFetcher}. The current fetcher being used can be updated at runtime.
     31  */
     32 class MediaDrawerAdapter extends CarDrawerAdapter {
     33     private final CarDrawerController mDrawerController;
     34     private MediaItemsFetcher mCurrentFetcher;
     35     private MediaFetchCallback mFetchCallback;
     36     private int mCurrentScrollPosition;
     37 
     38     /**
     39      * Interface for a callback object that will be notified of changes to the fetch status of
     40      * items in a media drawer.
     41      */
     42     interface MediaFetchCallback {
     43         /**
     44          * Called when a fetch for items starts.
     45          */
     46         void onFetchStart();
     47 
     48         /**
     49          * Called when a fetch for items ends.
     50          */
     51         void onFetchEnd();
     52     }
     53 
     54     MediaDrawerAdapter(Context context, CarDrawerController drawerController) {
     55         super(context, true /* showDisabledListOnEmpty */);
     56         mDrawerController = drawerController;
     57     }
     58 
     59     /**
     60      * Sets the object to be notified of changes to the fetching of items in the media drawer.
     61      */
     62     void setFetchCallback(@Nullable MediaFetchCallback callback) {
     63         mFetchCallback = callback;
     64     }
     65 
     66     /**
     67      * Switch the {@link MediaItemsFetcher} being used to fetch items. The new fetcher is kicked-off
     68      * and the drawer's content's will be updated to show newly loaded items. Any old fetcher is
     69      * cleaned up and released.
     70      *
     71      * @param fetcher New {@link MediaItemsFetcher} to use for display Drawer items.
     72      */
     73     void setFetcherAndInvoke(MediaItemsFetcher fetcher) {
     74         setFetcher(fetcher);
     75 
     76         if (mFetchCallback != null) {
     77             mFetchCallback.onFetchStart();
     78         }
     79 
     80         mCurrentFetcher.start(() -> {
     81             closeFetch();
     82             notifyDataSetChanged();
     83         });
     84     }
     85 
     86     void setFetcher(MediaItemsFetcher fetcher) {
     87         if (mCurrentFetcher != null) {
     88             mCurrentFetcher.cleanup();
     89         }
     90         mCurrentFetcher = fetcher;
     91         notifyDataSetChanged();
     92     }
     93 
     94     @Override
     95     protected int getActualItemCount() {
     96         return mCurrentFetcher != null ? mCurrentFetcher.getItemCount() : 0;
     97     }
     98 
     99     @Override
    100     protected boolean usesSmallLayout(int position) {
    101         return mCurrentFetcher.usesSmallLayout(position);
    102     }
    103 
    104     @Override
    105     protected void populateViewHolder(DrawerItemViewHolder holder, int position) {
    106         if (mCurrentFetcher == null) {
    107             return;
    108         }
    109 
    110         mCurrentFetcher.populateViewHolder(holder, position);
    111         scrollToCurrent();
    112     }
    113 
    114     @Override
    115     public void onItemClick(int position) {
    116         if (mCurrentFetcher != null) {
    117             mCurrentFetcher.onItemClick(position);
    118         }
    119     }
    120 
    121     @Override
    122     public void cleanup() {
    123         super.cleanup();
    124         if (mCurrentFetcher != null) {
    125             mCurrentFetcher.cleanup();
    126             mCurrentFetcher = null;
    127             notifyDataSetChanged();
    128         }
    129         closeFetch();
    130     }
    131 
    132     private void closeFetch() {
    133         if (mFetchCallback != null) {
    134             mFetchCallback.onFetchEnd();
    135             mFetchCallback = null;
    136         }
    137     }
    138 
    139     public void scrollToCurrent() {
    140         if (mCurrentFetcher == null) {
    141             return;
    142         }
    143         int scrollPosition = mCurrentFetcher.getScrollPosition();
    144         if (scrollPosition != MediaItemsFetcher.DONT_SCROLL
    145                 && mCurrentScrollPosition != scrollPosition) {
    146             mDrawerController.scrollToPosition(scrollPosition);
    147             mCurrentScrollPosition = scrollPosition;
    148         }
    149     }
    150 
    151     @Override
    152     public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    153         if (mCurrentFetcher != null) {
    154             MediaItemsFetcher fetcher = mCurrentFetcher;
    155             fetcher.cleanup();
    156             setFetcherAndInvoke(fetcher);
    157         }
    158     }
    159 
    160 }
    161