blob: 4e010fd206697b09b6509754eab3c3f720848a93 [file] [log] [blame]
/*
* 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.settings.homepage.contextualcards;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.LayoutRes;
import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.LifecycleOwner;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer;
import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer;
import com.android.settings.homepage.contextualcards.slices.SwipeDismissalDelegate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class ContextualCardsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
implements ContextualCardUpdateListener, SwipeDismissalDelegate.Listener {
static final int SPAN_COUNT = 2;
private static final String TAG = "ContextualCardsAdapter";
private static final int HALF_WIDTH = 1;
private static final int FULL_WIDTH = 2;
@VisibleForTesting
final List<ContextualCard> mContextualCards;
private final Context mContext;
private final ControllerRendererPool mControllerRendererPool;
private final LifecycleOwner mLifecycleOwner;
private RecyclerView mRecyclerView;
public ContextualCardsAdapter(Context context, LifecycleOwner lifecycleOwner,
ContextualCardManager manager) {
mContext = context;
mContextualCards = new ArrayList<>();
mControllerRendererPool = manager.getControllerRendererPool();
mLifecycleOwner = lifecycleOwner;
setHasStableIds(true);
}
@Override
public long getItemId(int position) {
return mContextualCards.get(position).hashCode();
}
@Override
public int getItemViewType(int position) {
final ContextualCard card = mContextualCards.get(position);
return card.getViewType();
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, @LayoutRes int viewType) {
final ContextualCardRenderer renderer = mControllerRendererPool.getRendererByViewType(
mContext, mLifecycleOwner, viewType);
final View view = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
return renderer.createViewHolder(view, viewType);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final ContextualCard card = mContextualCards.get(position);
final ContextualCardRenderer renderer = mControllerRendererPool.getRendererByViewType(
mContext, mLifecycleOwner, card.getViewType());
renderer.bindView(holder, card);
}
@Override
public int getItemCount() {
return mContextualCards.size();
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
mRecyclerView = recyclerView;
final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
final GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
final int viewType = mContextualCards.get(position).getViewType();
if (viewType == ConditionContextualCardRenderer.VIEW_TYPE_HALF_WIDTH
|| viewType == SliceContextualCardRenderer.VIEW_TYPE_HALF_WIDTH) {
return HALF_WIDTH;
}
return FULL_WIDTH;
}
});
}
}
@Override
public void onContextualCardUpdated(Map<Integer, List<ContextualCard>> cards) {
final List<ContextualCard> contextualCards = cards.get(ContextualCard.CardType.DEFAULT);
final boolean previouslyEmpty = mContextualCards.isEmpty();
final boolean nowEmpty = contextualCards == null || contextualCards.isEmpty();
if (contextualCards == null) {
mContextualCards.clear();
notifyDataSetChanged();
} else {
final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(
new ContextualCardsDiffCallback(mContextualCards, contextualCards));
mContextualCards.clear();
mContextualCards.addAll(contextualCards);
diffResult.dispatchUpdatesTo(this);
}
if (mRecyclerView != null && previouslyEmpty && !nowEmpty) {
// Adding items to empty list, should animate.
mRecyclerView.scheduleLayoutAnimation();
}
//TODO(b/119465242): flickering conditional cards after collapsing/expanding
}
@Override
public void onSwiped(int position) {
final ContextualCard card = mContextualCards.get(position).mutate()
.setIsPendingDismiss(true).build();
mContextualCards.set(position, card);
notifyItemChanged(position);
}
}