blob: 15d1f4ec2a8e17178268d2f6124553b3c52e8dbc [file] [log] [blame]
/*
* Copyright (C) 2015 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.deskclock.alarms.dataadapter;
import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Vibrator;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.android.deskclock.LogUtils;
import com.android.deskclock.R;
import com.android.deskclock.alarms.AlarmTimeClickHandler;
import com.android.deskclock.alarms.ScrollHandler;
import com.android.deskclock.provider.Alarm;
import com.android.deskclock.provider.AlarmInstance;
/**
* Data adapter for alarm time items.
*/
public final class AlarmTimeAdapter extends RecyclerView.Adapter<AlarmTimeViewHolder> {
private static final String TAG = "CwAlarm";
private static final String KEY_EXPANDED_ID = "expandedId";
private static final int VIEW_TYPE_ALARM_TIME_COLLAPSED = R.layout.alarm_time_collapsed;
private static final int VIEW_TYPE_ALARM_TIME_EXPANDED = R.layout.alarm_time_expanded;
private final Context mContext;
private final LayoutInflater mInflater;
private final AlarmTimeClickHandler mAlarmTimeClickHandler;
private final ScrollHandler mScrollHandler;
private final boolean mHasVibrator;
private int mExpandedPosition = -1;
private long mExpandedId = Alarm.INVALID_ID;
private Cursor mCursor;
public AlarmTimeAdapter(Context context, Bundle savedState,
AlarmTimeClickHandler alarmTimeClickHandler, ScrollHandler smoothScrollController) {
mContext = context;
mInflater = LayoutInflater.from(context);
mScrollHandler = smoothScrollController;
mAlarmTimeClickHandler = alarmTimeClickHandler;
mHasVibrator = ((Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE))
.hasVibrator();
if (savedState != null) {
mExpandedId = savedState.getLong(KEY_EXPANDED_ID, Alarm.INVALID_ID);
}
setHasStableIds(true);
}
@Override
public AlarmTimeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final View v = mInflater.inflate(viewType, parent, false /* attachToRoot */);
if (viewType == VIEW_TYPE_ALARM_TIME_COLLAPSED) {
return new CollapsedAlarmViewHolder(v, mAlarmTimeClickHandler, this);
} else {
return new ExpandedAlarmViewHolder(v, mHasVibrator, mAlarmTimeClickHandler, this);
}
}
@Override
public void onViewRecycled(AlarmTimeViewHolder viewHolder) {
super.onViewRecycled(viewHolder);
viewHolder.clearData();
}
@Override
public void onBindViewHolder(AlarmTimeViewHolder viewHolder, int position) {
if (!mCursor.moveToPosition(position)) {
LogUtils.e(TAG, "Failed to bind alarm " + position);
return;
}
final Alarm alarm = new Alarm(mCursor);
final AlarmInstance alarmInstance = alarm.canPreemptivelyDismiss()
? new AlarmInstance(mCursor, true /* joinedTable */) : null;
viewHolder.bindAlarm(mContext, alarm, alarmInstance);
}
@Override
public int getItemCount() {
return mCursor == null ? 0 : mCursor.getCount();
}
@Override
public long getItemId(int position) {
if (mCursor == null || !mCursor.moveToPosition(position)) {
return RecyclerView.NO_ID;
}
// TODO: Directly read id instead of instantiating Alarm object.
return new Alarm(mCursor).id;
}
@Override
public int getItemViewType(int position) {
final long stableId = getItemId(position);
return stableId != RecyclerView.NO_ID && stableId == mExpandedId
? VIEW_TYPE_ALARM_TIME_EXPANDED : VIEW_TYPE_ALARM_TIME_COLLAPSED;
}
public void saveInstance(Bundle outState) {
outState.putLong(KEY_EXPANDED_ID, mExpandedId);
}
/**
* Request the UI to expand the alarm at selected position and scroll it into view.
*/
public void expand(int position) {
final long stableId = getItemId(position);
if (mExpandedId == stableId) {
return;
}
mExpandedId = stableId;
mScrollHandler.smoothScrollTo(position);
if (mExpandedPosition >= 0) {
notifyItemChanged(mExpandedPosition);
}
mExpandedPosition = position;
notifyItemChanged(position);
}
public void collapse(int position) {
mExpandedId = Alarm.INVALID_ID;
mExpandedPosition = -1;
notifyItemChanged(position);
}
/**
* Swaps the adapter to a new data source.
*
* @param cursor A cursor generated by Cursor loader from {@link Alarm#getAlarmsCursorLoader}.
*/
public void swapCursor(Cursor cursor) {
if (mCursor == cursor) {
return;
}
if (mCursor != null) {
mCursor.close();
}
mCursor = cursor;
notifyDataSetChanged();
}
}