Home | History | Annotate | Download | only in app
      1 package com.android.car.app;
      2 
      3 import android.content.Context;
      4 import android.graphics.PorterDuff;
      5 import android.graphics.drawable.Drawable;
      6 import android.support.annotation.NonNull;
      7 import android.support.annotation.Nullable;
      8 import android.support.annotation.StringRes;
      9 import android.support.car.ui.PagedListView;
     10 import android.support.v7.widget.RecyclerView;
     11 import android.view.LayoutInflater;
     12 import android.view.View;
     13 import android.view.ViewGroup;
     14 
     15 import com.android.car.stream.ui.R;
     16 
     17 /**
     18  * Base Adapter for displaying items in the CarDrawerActivity's Drawer which uses a PagedListView.
     19  * <p>
     20  * Subclasses must set the title that will be displayed when displaying the contents of the
     21  * Drawer via {@link #setTitle(CharSequence)}. The title can be updated at any point later. The
     22  * title of the root-adapter will also be the main title showed in the toolbar when the drawer is
     23  * closed.
     24  * <p>
     25  * This class also takes care of implementing the PageListView.ItemCamp contract and subclasses
     26  * should implement {@link #getActualItemCount()}.
     27  */
     28 public abstract class CarDrawerAdapter extends RecyclerView.Adapter<DrawerItemViewHolder> implements
     29         PagedListView.ItemCap,
     30         DrawerItemClickListener {
     31     interface TitleChangeListener {
     32         void onTitleChanged(CharSequence newTitle);
     33     }
     34 
     35     private final boolean mShowDisabledListOnEmpty;
     36     private final boolean mUseSmallLayout;
     37     private final Drawable mEmptyListDrawable;
     38     private int mMaxItems = -1;
     39     private CharSequence mTitle;
     40     private TitleChangeListener mTitleChangeListener;
     41 
     42     protected CarDrawerAdapter(
     43             Context context, boolean showDisabledListOnEmpty,boolean useSmallLayout) {
     44         mShowDisabledListOnEmpty = showDisabledListOnEmpty;
     45         mUseSmallLayout = useSmallLayout;
     46         final int iconColor = context.getColor(R.color.car_tint);
     47         mEmptyListDrawable = context.getDrawable(R.drawable.ic_list_view_disable);
     48         mEmptyListDrawable.setColorFilter(iconColor, PorterDuff.Mode.SRC_IN);
     49     }
     50 
     51     CharSequence getTitle() {
     52         return mTitle;
     53     }
     54 
     55     /**
     56      * Updates the title to display in the toolbar for this Adapter.
     57      *
     58      * @param title Title string.
     59      */
     60     public final void setTitle(@NonNull CharSequence title) {
     61         if (title == null) {
     62             throw new IllegalArgumentException("title is null!");
     63         }
     64         mTitle = title;
     65         if (mTitleChangeListener != null) {
     66             mTitleChangeListener.onTitleChanged(mTitle);
     67         }
     68     }
     69 
     70     void setTitleChangeListener(@Nullable TitleChangeListener listener) {
     71         mTitleChangeListener = listener;
     72     }
     73 
     74     // ItemCap implementation.
     75     @Override
     76     public final void setMaxItems(int maxItems) {
     77         mMaxItems = maxItems;
     78     }
     79 
     80     private boolean shouldShowDisabledListItem() {
     81         return mShowDisabledListOnEmpty && getActualItemCount() == 0;
     82     }
     83 
     84     // Honors ItemCap and mShowDisabledListOnEmpty.
     85     @Override
     86     public final int getItemCount() {
     87         if (shouldShowDisabledListItem()) {
     88             return 1;
     89         }
     90         return mMaxItems >= 0 ? Math.min(mMaxItems, getActualItemCount()) : getActualItemCount();
     91     }
     92 
     93     /**
     94      * @return Actual number of items in this adapter.
     95      */
     96     protected abstract int getActualItemCount();
     97 
     98     @Override
     99     public final int getItemViewType(int position) {
    100         if (shouldShowDisabledListItem()) {
    101             return R.layout.car_list_item_empty;
    102         }
    103         return mUseSmallLayout
    104                 ? R.layout.car_menu_list_item_small : R.layout.car_menu_list_item_normal;
    105     }
    106 
    107     @Override
    108     public final DrawerItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    109         View view = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
    110         return new DrawerItemViewHolder(view);
    111     }
    112 
    113     @Override
    114     public final void onBindViewHolder(DrawerItemViewHolder holder, int position) {
    115         if (shouldShowDisabledListItem()) {
    116             holder.getTitle().setText(null);
    117             holder.getIcon().setImageDrawable(mEmptyListDrawable);
    118             holder.setItemClickListener(null);
    119         } else {
    120             holder.setItemClickListener(this);
    121             populateViewHolder(holder, position);
    122         }
    123     }
    124 
    125     /**
    126      * Subclasses should set all elements in {@code holder} to populate the drawer-item.
    127      * If some element is not used, it should be nulled out since these ViewHolder/View's are
    128      * recycled.
    129      */
    130     protected abstract void populateViewHolder(DrawerItemViewHolder holder, int position);
    131 
    132     /**
    133      * Called when this adapter has been popped off the stack and is no longer needed. Subclasses
    134      * can override to do any necessary cleanup.
    135      */
    136     public void cleanup() {}
    137 }
    138