/*
* Copyright (C) 2014 ParanoidAndroid 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.reindeercrafts.notificationpeek.peek;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.service.notification.StatusBarNotification;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import com.reindeercrafts.notificationpeek.R;
import com.reindeercrafts.notificationpeek.utils.SwipeHelper;
public class NotificationLayout extends LinearLayout implements SwipeHelper.Callback {
private SwipeHelper mSwipeHelper;
private NotificationPeek mNotificationPeek;
private boolean mContentShowing;
public NotificationLayout(Context context) {
this(context, null);
}
public NotificationLayout(Context context, AttributeSet attrs) {
super(context, attrs);
float densityScale = context.getResources().getDisplayMetrics().density;
float pagingTouchSlop = ViewConfiguration.get(context).getScaledPagingTouchSlop();
mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, pagingTouchSlop);
}
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
float densityScale = getContext().getResources().getDisplayMetrics().density;
mSwipeHelper.setDensityScale(densityScale);
float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
mSwipeHelper.setPagingTouchSlop(pagingTouchSlop);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
return mSwipeHelper.onInterceptTouchEvent(event) || super.onInterceptTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return mSwipeHelper.onTouchEvent(event) || super.onTouchEvent(event);
}
public void setNotificationPeek(NotificationPeek peek) {
mNotificationPeek = peek;
}
public NotificationPeek getNotificationPeek() {
return mNotificationPeek;
}
@Override
public View getChildAtPosition(MotionEvent ev) {
return getChildContentView(null);
}
@Override
public View getChildContentView(View v) {
return mNotificationPeek.getNotificationView();
}
@Override
public boolean canChildBeDismissed(View v) {
StatusBarNotification n =
(StatusBarNotification) mNotificationPeek.getNotificationView().getTag();
return n.isClearable();
}
@Override
public void onChildDismissed(View v) {
StatusBarNotification n =
(StatusBarNotification) mNotificationPeek.getNotificationView().getTag();
String pkg = n.getPackageName();
String tag = n.getTag();
int id = n.getId();
// Dismiss action confirmed, we need to remove the current notification.
mNotificationPeek
.onChildDismissed(NotificationHelper.getContentDescription(n), pkg, tag, id);
mNotificationPeek.setAnimating(false);
}
@Override
public void onBeginDrag(View v) {
mNotificationPeek.setAnimating(true);
}
@Override
public void onDragCancelled(View v) {
mNotificationPeek.setAnimating(false);
}
@Override
public void onAlphaChanged(float alpha) {
mNotificationPeek.updateNotificationTextAlpha(alpha);
}
@Override
public void onShowContentActionDetected() {
showNotificationContent();
}
@Override
public void onHideContentActionDetected() {
hideNotificationContent();
}
private void showNotificationContent() {
if (mContentShowing) {
// Content is already showing.
return;
}
mContentShowing = true;
StatusBarNotification selectedNotification =
(StatusBarNotification) mNotificationPeek.getNotificationView().getTag();
View contentView = PeekLayoutFactory
.createPeekLayout(getContext(), PeekLayoutFactory.LAYOUT_TYPE_CONTENT,
selectedNotification);
contentView.setId(R.id.notification_content);
RelativeLayout.LayoutParams params =
new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
params.addRule(RelativeLayout.ABOVE, R.id.notification_layout);
contentView.setLayoutParams(params);
// Animations.
LinearLayout contentTextLayout =
(LinearLayout) contentView.findViewById(R.id.content_layout);
contentTextLayout.setTranslationY(50);
contentView.setAlpha(0);
((ViewGroup)getParent()).addView(contentView);
contentView.animate().alpha(1f).setInterpolator(new DecelerateInterpolator()).start();
contentTextLayout.animate().translationY(0).setInterpolator(new DecelerateInterpolator())
.start();
// Send broadcast to NotificationPeekActivity and let it hide the other components
// when the content is displayed.
Intent intent =
new Intent(NotificationPeekActivity.NotificationPeekReceiver.ACTION_SHOW_CONTENT);
getContext().sendBroadcast(intent);
}
private void hideNotificationContent() {
if (!mContentShowing) {
// Content is already hidden.
return;
}
mContentShowing = false;
final ViewGroup peekView = (ViewGroup) getParent();
final View contentView = peekView.findViewById(R.id.notification_content);
LinearLayout contentTextLayout =
(LinearLayout) contentView.findViewById(R.id.content_layout);
// Animations.
contentTextLayout.animate().translationY(50).setInterpolator(new AccelerateInterpolator())
.start();
contentView.animate().alpha(0f).setInterpolator(new AccelerateInterpolator())
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
peekView.removeView(contentView);
}
}).start();
// Send broadcast to NotificationPeekActivity to let it show the components again.
Intent intent =
new Intent(NotificationPeekActivity.NotificationPeekReceiver.ACTION_HIDE_CONTENT);
getContext().sendBroadcast(intent);
}
}