Skip to content

Instantly share code, notes, and snippets.

@cbedoy
Created September 12, 2014 03:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cbedoy/1492d7e75df24bc32c5b to your computer and use it in GitHub Desktop.
Save cbedoy/1492d7e75df24bc32c5b to your computer and use it in GitHub Desktop.
import android.content.Context;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.PaintDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RoundRectShape;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.LinearLayout;
import com.facebook.rebound.Spring;
import com.facebook.rebound.SpringConfig;
import com.facebook.rebound.SpringListener;
import com.facebook.rebound.SpringSystem;
import org.pademobile.service.ImageService;
import org.telegram.android.AndroidUtilities;
import org.telegram.android.MessagesController;
import org.telegram.messenger.R;
import org.telegram.messenger.TLRPC;
import org.telegram.messenger.Utilities;
import org.telegram.ui.Views.BackupImageView;
/**
* Created by admin on 9/9/14.
*/
public class BubbleView extends LinearLayout
{
private BackupImageView backupImageView;
private TLRPC.TL_dialog mDialog;
private WindowManager mWindowManager;
private View mContent;
private int[] mPos = {ImageService.getInstance(null).getDialogWidth(), ImageService.getInstance(null).getActionBarSize()*2};
private boolean mbMoved;
private boolean mbExpanded;
private Bundle bundle;
public BubbleView(Context context)
{
super(context);
}
private void initView()
{
backupImageView = new BackupImageView(getContext());
backupImageView.setLayoutParams(new LinearLayout.LayoutParams(AndroidUtilities.dp(48), AndroidUtilities.dp(48)));
setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
addView(backupImageView);
setOrientation(VERTICAL);
mWindowManager = (WindowManager) getContext().getSystemService(getContext().WINDOW_SERVICE);
ChatBubbleView chatBubbleView = new ChatBubbleView(bundle);
mContent = chatBubbleView.createView(getContext());
mContent.setPivotX(0);
mContent.setPivotY(0);
mContent.setScaleX(0.0f);
mContent.setScaleY(0.0f);
mContent.setAlpha(0.0f);
addView(mContent, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0, 1));
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = mPos[0];
params.y = mPos[1];
params.dimAmount = 0.6f;
SpringSystem system = SpringSystem.create();
SpringConfig springConfig = new SpringConfig(200, 20);
final BubbleView self = this;
final Spring contentSpring = system.createSpring();
contentSpring.setSpringConfig(springConfig);
contentSpring.setCurrentValue(0.0);
contentSpring.addListener(new SpringListener() {
@Override
public void onSpringUpdate(Spring spring) {
//Log.d(TAG, "hardware acc = " + mContent.isHardwareAccelerated() + ", layer type = " + mContent.getLayerType());
float value = (float) spring.getCurrentValue();
float clampedValue = Math.min(Math.max(value, 0.0f), 1.0f);
mContent.setScaleX(value);
mContent.setScaleY(value);
mContent.setAlpha(clampedValue);
}
@Override
public void onSpringAtRest(Spring spring) {
mContent.setLayerType(View.LAYER_TYPE_NONE, null);
}
@Override
public void onSpringActivate(Spring spring) {
mContent.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
@Override
public void onSpringEndStateChange(Spring spring) {
}
});
final Spring bubbleSpring = system.createSpring();
bubbleSpring.setSpringConfig(springConfig);
bubbleSpring.setCurrentValue(1.0);
bubbleSpring.addListener(new SpringListener() {
@Override
public void onSpringUpdate(Spring spring) {
float value = (float) spring.getCurrentValue();
params.x = (int) (mPos[0] * value);
params.y = (int) (mPos[1] * value);
mWindowManager.updateViewLayout(self, params);
if (spring.isOvershooting() && contentSpring.isAtRest()) {
contentSpring.setEndValue(1.0);
}
}
@Override
public void onSpringAtRest(Spring spring) {
if (spring.currentValueIsApproximately(1.0)) {
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
mWindowManager.updateViewLayout(self, params);
}
}
@Override
public void onSpringActivate(Spring spring) {
}
@Override
public void onSpringEndStateChange(Spring spring) {
}
});
setOnTouchListener(new View.OnTouchListener() {
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
@Override
public boolean onTouch(View v, MotionEvent event)
{
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mbMoved = false;
initialX = params.x;
initialY = params.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
return true;
case MotionEvent.ACTION_UP:
if (mbMoved) return true;
if (!mbExpanded) {
self.getLocationOnScreen(mPos);
mPos[1] += 50;
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.height = WindowManager.LayoutParams.MATCH_PARENT;
params.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
params.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
bubbleSpring.setEndValue(0.0);
} else {
params.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
params.flags &= ~WindowManager.LayoutParams.FLAG_DIM_BEHIND;
bubbleSpring.setEndValue(1.0);
contentSpring.setEndValue(0.0);
}
mbExpanded = !mbExpanded;
mWindowManager.updateViewLayout(self, params);
return true;
case MotionEvent.ACTION_MOVE:
int deltaX = (int) (event.getRawX() - initialTouchX);
int deltaY = (int) (event.getRawY() - initialTouchY);
params.x = initialX + deltaX;
params.y = initialY + deltaY;
if (deltaX * deltaX + deltaY * deltaY >= 30) {
mbMoved = true;
mWindowManager.updateViewLayout(self, params);
}
return true;
}
return false;
}
});
mWindowManager.addView(this, params);
}
public void setDialog(TLRPC.TL_dialog dialog)
{
mDialog = dialog;
TLRPC.User user = null;
TLRPC.Chat chat = null;
TLRPC.EncryptedChat encryptedChat = null;
int lower_id = (int) mDialog.id;
int high_id = (int) (mDialog.id >> 32);
if (lower_id != 0)
{
if (high_id == 1)
{
chat = MessagesController.getInstance().chats.get(lower_id);
}
else
{
if (lower_id < 0)
{
chat = MessagesController.getInstance().chats.get(-lower_id);
}
else
{
user = MessagesController.getInstance().users.get(lower_id);
}
}
} else
{
encryptedChat = MessagesController.getInstance().encryptedChats.get(high_id);
if (encryptedChat != null)
{
user = MessagesController.getInstance().users.get(encryptedChat.user_id);
}
}
int placeHolderId = 0;
TLRPC.FileLocation photo = null;
if (user != null)
{
if (user.photo != null)
{
photo = user.photo.photo_small;
}
placeHolderId = Utilities.getUserAvatarForId(user.id);
} else if (chat != null)
{
if (chat.photo != null)
{
photo = chat.photo.photo_small;
}
placeHolderId = Utilities.getGroupAvatarForId(chat.id);
}
bundle = new Bundle();
if (lower_id != 0) {
if (high_id == 1) {
bundle.putInt("chatId", lower_id);
} else {
if (lower_id < 0) {
bundle.putInt("chatId", -lower_id);
} else {
bundle.putInt("userId", lower_id);
}
}
} else {
bundle.putInt("encId", high_id);
}
initView();
backupImageView.setImage(photo, "50_50", placeHolderId);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment