• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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          */
onFetchStart()46         void onFetchStart();
47 
48         /**
49          * Called when a fetch for items ends.
50          */
onFetchEnd()51         void onFetchEnd();
52     }
53 
MediaDrawerAdapter(Context context, CarDrawerController drawerController)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      */
setFetchCallback(@ullable MediaFetchCallback callback)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      */
setFetcherAndInvoke(MediaItemsFetcher fetcher)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 
setFetcher(MediaItemsFetcher fetcher)86     void setFetcher(MediaItemsFetcher fetcher) {
87         if (mCurrentFetcher != null) {
88             mCurrentFetcher.cleanup();
89         }
90         mCurrentFetcher = fetcher;
91         notifyDataSetChanged();
92     }
93 
94     @Override
getActualItemCount()95     protected int getActualItemCount() {
96         return mCurrentFetcher != null ? mCurrentFetcher.getItemCount() : 0;
97     }
98 
99     @Override
usesSmallLayout(int position)100     protected boolean usesSmallLayout(int position) {
101         return mCurrentFetcher.usesSmallLayout(position);
102     }
103 
104     @Override
populateViewHolder(DrawerItemViewHolder holder, int position)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
onItemClick(int position)115     public void onItemClick(int position) {
116         if (mCurrentFetcher != null) {
117             mCurrentFetcher.onItemClick(position);
118         }
119     }
120 
121     @Override
cleanup()122     public void cleanup() {
123         super.cleanup();
124         if (mCurrentFetcher != null) {
125             mCurrentFetcher.cleanup();
126             mCurrentFetcher = null;
127             notifyDataSetChanged();
128         }
129         closeFetch();
130     }
131 
closeFetch()132     private void closeFetch() {
133         if (mFetchCallback != null) {
134             mFetchCallback.onFetchEnd();
135             mFetchCallback = null;
136         }
137     }
138 
scrollToCurrent()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
onAttachedToRecyclerView(RecyclerView recyclerView)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