Home | History | Annotate | Download | only in speeddial
      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 
     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
     66   public int getItemViewType(int position) {
     67     return cursor.getRowType(position);
     68   }
     69 
     70   @Override
     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
     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
    107   public int getItemCount() {
    108     return cursor == null || cursor.isClosed() ? 0 : cursor.getCount();
    109   }
    110 
    111   public void setCursor(SpeedDialCursor cursor) {
    112     this.cursor = cursor;
    113     notifyDataSetChanged();
    114   }
    115 
    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
    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