package com.android.car.app;
import android.content.Context;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.android.car.stream.ui.R;
import com.android.car.view.PagedListView;
/**
* Base Adapter for displaying items in the CarDrawerActivity's Drawer which uses a PagedListView.
*
* Subclasses must set the title that will be displayed when displaying the contents of the
* Drawer via {@link #setTitle(CharSequence)}. The title can be updated at any point later. The
* title of the root-adapter will also be the main title showed in the toolbar when the drawer is
* closed.
*
* This class also takes care of implementing the PageListView.ItemCamp contract and subclasses
* should implement {@link #getActualItemCount()}.
*/
public abstract class CarDrawerAdapter extends RecyclerView.Adapter implements
PagedListView.ItemCap,
DrawerItemClickListener {
interface TitleChangeListener {
void onTitleChanged(CharSequence newTitle);
}
private final boolean mShowDisabledListOnEmpty;
private final Drawable mEmptyListDrawable;
private int mMaxItems = -1;
private CharSequence mTitle;
private TitleChangeListener mTitleChangeListener;
protected CarDrawerAdapter(
Context context, boolean showDisabledListOnEmpty) {
mShowDisabledListOnEmpty = showDisabledListOnEmpty;
final int iconColor = context.getColor(R.color.car_tint);
mEmptyListDrawable = context.getDrawable(R.drawable.ic_list_view_disable);
mEmptyListDrawable.setColorFilter(iconColor, PorterDuff.Mode.SRC_IN);
}
CharSequence getTitle() {
return mTitle;
}
/**
* Updates the title to display in the toolbar for this Adapter.
*
* @param title Title string.
*/
public final void setTitle(@NonNull CharSequence title) {
if (title == null) {
throw new IllegalArgumentException("title is null!");
}
mTitle = title;
if (mTitleChangeListener != null) {
mTitleChangeListener.onTitleChanged(mTitle);
}
}
void setTitleChangeListener(@Nullable TitleChangeListener listener) {
mTitleChangeListener = listener;
}
// ItemCap implementation.
@Override
public final void setMaxItems(int maxItems) {
mMaxItems = maxItems;
}
private boolean shouldShowDisabledListItem() {
return mShowDisabledListOnEmpty && getActualItemCount() == 0;
}
// Honors ItemCap and mShowDisabledListOnEmpty.
@Override
public final int getItemCount() {
if (shouldShowDisabledListItem()) {
return 1;
}
return mMaxItems >= 0 ? Math.min(mMaxItems, getActualItemCount()) : getActualItemCount();
}
/**
* @return Actual number of items in this adapter.
*/
protected abstract int getActualItemCount();
@Override
public final int getItemViewType(int position) {
if (shouldShowDisabledListItem()) {
return R.layout.car_list_item_empty;
}
return usesSmallLayout(position)
? R.layout.car_menu_list_item_small : R.layout.car_menu_list_item_normal;
}
/**
* Used to indicate the layout used for the Drawer item at given position. Subclasses can
* override this to use normal layout which includes text element below title.
*
* @param position Adapter position of item.
* @return Whether the item at this position will use a small layout (default) or normal layout.
*/
protected boolean usesSmallLayout(int position) {
return true;
}
@Override
public final DrawerItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
return new DrawerItemViewHolder(view);
}
@Override
public final void onBindViewHolder(DrawerItemViewHolder holder, int position) {
if (shouldShowDisabledListItem()) {
holder.getTitle().setText(null);
holder.getIcon().setImageDrawable(mEmptyListDrawable);
holder.setItemClickListener(null);
} else {
holder.setItemClickListener(this);
populateViewHolder(holder, position);
}
}
/**
* Subclasses should set all elements in {@code holder} to populate the drawer-item.
* If some element is not used, it should be nulled out since these ViewHolder/View's are
* recycled.
*/
protected abstract void populateViewHolder(DrawerItemViewHolder holder, int position);
/**
* Called when this adapter has been popped off the stack and is no longer needed. Subclasses
* can override to do any necessary cleanup.
*/
public void cleanup() {}
}