/* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.car.carlauncher; import android.content.ComponentName; import android.content.Context; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView; import java.util.Collections; import java.util.List; /** * The adapter that populates the grid view with apps. */ final class AppGridAdapter extends RecyclerView.Adapter { public static final int RECENT_APPS_TYPE = 1; public static final int APP_ITEM_TYPE = 2; private static final long RECENT_APPS_ID = 0; private static final String TAG = "AppGridAdapter"; private final Context mContext; private final int mColumnNumber; private final LayoutInflater mInflater; private List mApps; private List mMostRecentApps; private boolean mIsDistractionOptimizationRequired; AppGridAdapter(Context context) { mContext = context; mInflater = LayoutInflater.from(context); mColumnNumber = mContext.getResources().getInteger(R.integer.car_app_selector_column_number); // Stable IDs improve performance and make rotary work better. setHasStableIds(true); } void setIsDistractionOptimizationRequired(boolean isDistractionOptimizationRequired) { mIsDistractionOptimizationRequired = isDistractionOptimizationRequired; sortAllApps(); notifyDataSetChanged(); } void setMostRecentApps(@Nullable List mostRecentApps) { mMostRecentApps = mostRecentApps; notifyDataSetChanged(); } @Override public long getItemId(int position) { if (position == 0 && hasRecentlyUsedApps()) { return RECENT_APPS_ID; } if (mApps == null) { Log.w(TAG, "apps list not set"); return RecyclerView.NO_ID; } int index = hasRecentlyUsedApps() ? position - 1 : position; if (index < 0 || index >= mApps.size()) { Log.w(TAG, "index out of range"); return RecyclerView.NO_ID; } ComponentName componentName = mApps.get(index).getComponentName(); long id = componentName.getPackageName().hashCode(); id <<= Integer.SIZE; id |= componentName.getClassName().hashCode(); return id; } void setAllApps(@Nullable List apps) { mApps = apps; sortAllApps(); notifyDataSetChanged(); } public int getSpanSizeLookup(int position) { if (position == 0 && hasRecentlyUsedApps()) { return mColumnNumber; } return 1; } @Override public int getItemViewType(int position) { if (position == 0 && hasRecentlyUsedApps()) { return RECENT_APPS_TYPE; } return APP_ITEM_TYPE; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == RECENT_APPS_TYPE) { View view = mInflater.inflate(R.layout.recent_apps_row, parent, /* attachToRoot= */ false); return new RecentAppsRowViewHolder(view, mContext); } else { View view = mInflater.inflate(R.layout.app_item, parent, /* attachToRoot= */ false); return new AppItemViewHolder(view, mContext); } } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { switch (holder.getItemViewType()) { case RECENT_APPS_TYPE: ((RecentAppsRowViewHolder) holder).bind( mMostRecentApps, mIsDistractionOptimizationRequired); break; case APP_ITEM_TYPE: int index = hasRecentlyUsedApps() ? position - 1 : position; AppMetaData app = mApps.get(index); ((AppItemViewHolder) holder).bind(app, mIsDistractionOptimizationRequired); break; default: } } @Override public int getItemCount() { // If there are any most recently launched apps, add a "most recently used apps row item" return (mApps == null ? 0 : mApps.size()) + (hasRecentlyUsedApps() ? 1 : 0); } private boolean hasRecentlyUsedApps() { return mMostRecentApps != null && mMostRecentApps.size() > 0; } private void sortAllApps() { if (mApps != null) { Collections.sort(mApps, AppLauncherUtils.ALPHABETICAL_COMPARATOR); } } }