1 /* 2 * Copyright (C) 2018 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 package com.android.car.dialer.ui.calllog; 17 18 import android.content.Context; 19 import android.view.LayoutInflater; 20 import android.view.View; 21 import android.view.ViewGroup; 22 23 import androidx.annotation.IntDef; 24 import androidx.annotation.NonNull; 25 import androidx.recyclerview.widget.LinearLayoutManager; 26 import androidx.recyclerview.widget.RecyclerView; 27 28 import com.android.car.dialer.R; 29 import com.android.car.dialer.log.L; 30 import com.android.car.dialer.ui.common.DialerUtils; 31 import com.android.car.dialer.ui.common.entity.HeaderViewHolder; 32 import com.android.car.dialer.ui.common.entity.UiCallLog; 33 import com.android.car.ui.recyclerview.ContentLimitingAdapter; 34 35 import java.util.ArrayList; 36 import java.util.List; 37 38 import javax.inject.Inject; 39 40 import dagger.hilt.android.qualifiers.ActivityContext; 41 42 /** Adapter for call history list. */ 43 class CallLogAdapter extends ContentLimitingAdapter { 44 45 private static final String TAG = "CD.CallLogAdapter"; 46 47 private Integer mSortMethod; 48 49 /** IntDef for the different groups of calllog lists separated by time periods. */ 50 @IntDef({ 51 EntryType.TYPE_HEADER, 52 EntryType.TYPE_CALLLOG, 53 }) 54 private @interface EntryType { 55 /** Entry typre is header. */ 56 int TYPE_HEADER = 1; 57 58 /** Entry type is calllog. */ 59 int TYPE_CALLLOG = 2; 60 } 61 62 private final CallLogViewHolder.Factory mViewHolderFactory; 63 private List<Object> mUiCallLogs = new ArrayList<>(); 64 private Context mContext; 65 private LinearLayoutManager mLayoutManager; 66 private int mLimitingAnchorIndex = 0; 67 68 @Inject CallLogAdapter(@ctivityContext Context context, CallLogViewHolder.Factory viewHolderFactory)69 CallLogAdapter(@ActivityContext Context context, CallLogViewHolder.Factory viewHolderFactory) { 70 mContext = context; 71 mViewHolderFactory = viewHolderFactory; 72 } 73 74 /** 75 * Sets calllogs. 76 */ setUiCallLogs(@onNull List<Object> uiCallLogs)77 public void setUiCallLogs(@NonNull List<Object> uiCallLogs) { 78 L.d(TAG, "setUiCallLogs: %d", uiCallLogs.size()); 79 mUiCallLogs.clear(); 80 mUiCallLogs.addAll(uiCallLogs); 81 82 // Update the data set size change along with the old anchor point. 83 // The anchor point won't take effect if content is not limited. 84 updateUnderlyingDataChanged(uiCallLogs.size(), 85 DialerUtils.validateListLimitingAnchor(uiCallLogs.size(), mLimitingAnchorIndex)); 86 notifyDataSetChanged(); 87 } 88 89 /** 90 * Sets the sorting method for the list. 91 */ setSortMethod(Integer sortMethod)92 public void setSortMethod(Integer sortMethod) { 93 mSortMethod = sortMethod; 94 } 95 96 @NonNull 97 @Override onCreateViewHolderImpl( @onNull ViewGroup parent, int viewType)98 public RecyclerView.ViewHolder onCreateViewHolderImpl( 99 @NonNull ViewGroup parent, int viewType) { 100 if (viewType == EntryType.TYPE_CALLLOG) { 101 View rootView = LayoutInflater.from(mContext) 102 .inflate(R.layout.call_history_list_item, parent, false); 103 return mViewHolderFactory.create(rootView); 104 } 105 106 View rootView = LayoutInflater.from(mContext) 107 .inflate(R.layout.header_item, parent, false); 108 return new HeaderViewHolder(rootView); 109 } 110 111 @Override onBindViewHolderImpl( @onNull RecyclerView.ViewHolder holder, int position)112 public void onBindViewHolderImpl( 113 @NonNull RecyclerView.ViewHolder holder, int position) { 114 if (holder instanceof CallLogViewHolder) { 115 ((CallLogViewHolder) holder).bind((UiCallLog) mUiCallLogs.get(position), mSortMethod); 116 } else { 117 ((HeaderViewHolder) holder).setHeaderTitle((String) mUiCallLogs.get(position)); 118 } 119 } 120 121 @Override 122 @EntryType getItemViewTypeImpl(int position)123 public int getItemViewTypeImpl(int position) { 124 if (mUiCallLogs.get(position) instanceof UiCallLog) { 125 return EntryType.TYPE_CALLLOG; 126 } else { 127 return EntryType.TYPE_HEADER; 128 } 129 } 130 131 @Override onViewRecycledImpl(@onNull RecyclerView.ViewHolder holder)132 public void onViewRecycledImpl(@NonNull RecyclerView.ViewHolder holder) { 133 if (holder instanceof CallLogViewHolder) { 134 ((CallLogViewHolder) holder).recycle(); 135 } 136 } 137 138 @Override getUnrestrictedItemCount()139 public int getUnrestrictedItemCount() { 140 return mUiCallLogs.size(); 141 } 142 143 @Override getConfigurationId()144 public int getConfigurationId() { 145 return R.id.call_log_list_uxr_config; 146 } 147 148 @Override onAttachedToRecyclerView(@onNull RecyclerView recyclerView)149 public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) { 150 super.onAttachedToRecyclerView(recyclerView); 151 mLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); 152 } 153 154 @Override onDetachedFromRecyclerView(@onNull RecyclerView recyclerView)155 public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) { 156 mLayoutManager = null; 157 super.onDetachedFromRecyclerView(recyclerView); 158 } 159 160 @Override computeAnchorIndexWhenRestricting()161 public int computeAnchorIndexWhenRestricting() { 162 mLimitingAnchorIndex = DialerUtils.getFirstVisibleItemPosition(mLayoutManager); 163 return mLimitingAnchorIndex; 164 } 165 } 166