• 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 
17 package com.android.dialer.speeddial;
18 
19 import android.content.Context;
20 import android.support.annotation.VisibleForTesting;
21 import android.support.v7.widget.GridLayoutManager;
22 import android.support.v7.widget.GridLayoutManager.SpanSizeLookup;
23 import android.support.v7.widget.RecyclerView;
24 import android.support.v7.widget.RecyclerView.LayoutManager;
25 import android.view.LayoutInflater;
26 import android.view.ViewGroup;
27 import com.android.dialer.common.Assert;
28 import com.android.dialer.speeddial.FavoritesViewHolder.FavoriteContactsListener;
29 import com.android.dialer.speeddial.HeaderViewHolder.SpeedDialHeaderListener;
30 import com.android.dialer.speeddial.SpeedDialCursor.RowType;
31 import com.android.dialer.speeddial.SuggestionViewHolder.SuggestedContactsListener;
32 
33 /**
34  * RecyclerView adapter for {@link SpeedDialFragment}.
35  *
36  * <p>Displays a list in the following order:
37  *
38  * <ol>
39  *   <li>Favorite contacts header (with add button)
40  *   <li>Favorite contacts
41  *   <li>Suggested contacts header
42  *   <li>Suggested contacts
43  * </ol>
44  */
45 final class SpeedDialAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
46 
47   private final Context context;
48   private final FavoriteContactsListener favoritesListener;
49   private final SuggestedContactsListener suggestedListener;
50   private final SpeedDialHeaderListener headerListener;
51 
52   private SpeedDialCursor cursor;
53 
SpeedDialAdapter( Context context, FavoriteContactsListener favoritesListener, SuggestedContactsListener suggestedListener, SpeedDialHeaderListener headerListener)54   public SpeedDialAdapter(
55       Context context,
56       FavoriteContactsListener favoritesListener,
57       SuggestedContactsListener suggestedListener,
58       SpeedDialHeaderListener headerListener) {
59     this.context = context;
60     this.favoritesListener = favoritesListener;
61     this.suggestedListener = suggestedListener;
62     this.headerListener = headerListener;
63   }
64 
65   @Override
getItemViewType(int position)66   public int getItemViewType(int position) {
67     return cursor.getRowType(position);
68   }
69 
70   @Override
onCreateViewHolder(ViewGroup parent, int viewType)71   public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
72     LayoutInflater inflater = LayoutInflater.from(context);
73     if (viewType == RowType.STARRED) {
74       return new FavoritesViewHolder(
75           inflater.inflate(R.layout.favorite_item_layout, parent, false), favoritesListener);
76     } else if (viewType == RowType.SUGGESTION) {
77       return new SuggestionViewHolder(
78           inflater.inflate(R.layout.suggestion_row_layout, parent, false), suggestedListener);
79     } else if (viewType == RowType.HEADER) {
80       return new HeaderViewHolder(
81           inflater.inflate(R.layout.speed_dial_header_layout, parent, false), headerListener);
82     } else {
83       throw Assert.createIllegalStateFailException("Invalid viewType: " + viewType);
84     }
85   }
86 
87   @Override
onBindViewHolder(RecyclerView.ViewHolder holder, int position)88   public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
89     cursor.moveToPosition(position);
90     switch (cursor.getRowType(position)) {
91       case RowType.HEADER:
92         ((HeaderViewHolder) holder).setHeaderText(cursor.getHeader());
93         ((HeaderViewHolder) holder).showAddButton(cursor.hasFavorites() && position == 0);
94         break;
95       case RowType.STARRED:
96         ((FavoritesViewHolder) holder).bind(context, cursor);
97         break;
98       case RowType.SUGGESTION:
99         ((SuggestionViewHolder) holder).bind(context, cursor);
100         break;
101       default:
102         throw Assert.createIllegalStateFailException("Invalid view holder: " + holder);
103     }
104   }
105 
106   @Override
getItemCount()107   public int getItemCount() {
108     return cursor == null || cursor.isClosed() ? 0 : cursor.getCount();
109   }
110 
setCursor(SpeedDialCursor cursor)111   public void setCursor(SpeedDialCursor cursor) {
112     this.cursor = cursor;
113     notifyDataSetChanged();
114   }
115 
getLayoutManager(Context context)116   LayoutManager getLayoutManager(Context context) {
117     GridLayoutManager layoutManager = new GridLayoutManager(context, 3 /* spanCount */);
118     layoutManager.setSpanSizeLookup(
119         new SpanSizeLookup() {
120           @Override
121           public int getSpanSize(int position) {
122             return SpeedDialAdapter.this.getSpanSize(position);
123           }
124         });
125     return layoutManager;
126   }
127 
128   @VisibleForTesting
getSpanSize(int position)129   int getSpanSize(int position) {
130     switch (cursor.getRowType(position)) {
131       case RowType.SUGGESTION:
132       case RowType.HEADER:
133         return 3; // span the whole screen
134       case RowType.STARRED:
135         return 1; // span 1/3 of the screen
136       default:
137         throw Assert.createIllegalStateFailException(
138             "Invalid row type: " + cursor.getRowType(position));
139     }
140   }
141 }
142