问题描述
我目前正在使用消息传递应用程序,在这里我想向新用户显示动画飞行图标,例如Facebook实时浮动反应.任何人都可以启发我应遵循的程序或任何有用的库链接吗?
I'm currently working in a messaging application, where I want to show new user as animated flying icon like facebook live floating reactions. Can anybody enlighten which process I should follow or any helpful library link please?
我已经尝试浏览并检查了几个库链接,例如
I've already tried browsing and checked few library links like
推荐答案
我已经通过修改旧代码实现了这一点,所以这是我的解决方案.您可以更改表情符号的方向和数量,也可以使其在任何视图上方或下方飞行.
I have achieved this by modifying an old code So here is my solution. You can change the direction and number of emojis as well you can make it fly over or under any views.
主xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="top|left"
android:orientation="vertical">
<FrameLayout
android:id="@+id/animation_holder"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
主要活动
package com.example.hamidraza.flyinemojis;
import android.app.Activity;
import android.os.Bundle;
import android.view.ViewGroup;
import android.view.animation.Animation;
public class MainActivity extends Activity {
public void onCreate(Bundle savedState) {
super.onCreate(savedState);
setContentView(R.layout.activity_main);
emoji_one();
emoji_two();
emoji_three();
}
public void flyEmoji(final int resId) {
ZeroGravityAnimation animation = new ZeroGravityAnimation();
animation.setCount(1);
animation.setScalingFactor(0.2f);
animation.setOriginationDirection(Direction.BOTTOM);
animation.setDestinationDirection(Direction.TOP);
animation.setImage(resId);
animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
}
);
ViewGroup container = findViewById(R.id.animation_holder);
animation.play(this,container);
}
public void emoji_one() {
// You can change the number of emojis that will be flying on screen
for (int i = 0; i < 5; i++) {
flyEmoji(R.drawable.emojis1);
}
}
// You can change the number of emojis that will be flying on screen
public void emoji_two(){
for(int i=0;i<5;i++) {
flyEmoji(R.drawable.dabemoji);
}
}
// You can change the number of emojis that will be flying on screen
public void emoji_three(){
for(int i=0;i<5;i++) {
flyEmoji(R.drawable.heart);
}
}
// This method will be used if You want to fly your Emois Over any view
// public void flyObject(final int resId, final int duration, final Direction from, final Direction to, final float scale) {
//
// ZeroGravityAnimation animation = new ZeroGravityAnimation();
// animation.setCount(1);
// animation.setScalingFactor(scale);
// animation.setOriginationDirection(from);
// animation.setDestinationDirection(to);
// animation.setImage(resId);
// animation.setDuration(duration);
// animation.setAnimationListener(new Animation.AnimationListener() {
// @Override
// public void onAnimationStart(Animation animation) {
//
// }
//
// @Override
// public void onAnimationEnd(Animation animation) {
//
// flyObject(resId, duration, from, to, scale);
// }
//
// @Override
// public void onAnimationRepeat(Animation animation) {
//
// }
// });
//
// ViewGroup container = (ViewGroup) findViewById(R.id.animation_bigger_objects_holder);
// animation.play(this,container);
//
// }
//
}
ZeroGravityAnimation
package com.example.hamidraza.flyinemojis;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.FrameLayout;
public class ZeroGravityAnimation {
private static final int RANDOM_DURATION = -1;
private Direction mOriginationDirection = Direction.RANDOM;
private Direction mDestinationDirection = Direction.RANDOM;
private int mDuration = RANDOM_DURATION;
private int mCount = 1;
private int mImageResId;
private float mScalingFactor = 1f;
private Animation.AnimationListener mAnimationListener;
/**
* Sets the orignal direction. The animation will originate from the given direction.
*/
public ZeroGravityAnimation setOriginationDirection(Direction direction) {
this.mOriginationDirection = direction;
return this;
}
/**
* Sets the animation destination direction. The translate animation will proceed towards the given direction.
* @param direction
* @return
*/
public ZeroGravityAnimation setDestinationDirection(Direction direction) {
this.mDestinationDirection = direction;
return this;
}
/**
* Will take a random time duriation for the animation
* @return
*/
public ZeroGravityAnimation setRandomDuration() {
return setDuration(RANDOM_DURATION);
}
/**
* Sets the time duration in millseconds for animation to proceed.
* @param duration
* @return
*/
public ZeroGravityAnimation setDuration(int duration) {
this.mDuration = duration;
return this;
}
/**
* Sets the image reference id for drawing the image
* @param resId
* @return
*/
public ZeroGravityAnimation setImage(int resId) {
this.mImageResId = resId;
return this;
}
/**
* Sets the image scaling value.
* @param scale
* @return
*/
public ZeroGravityAnimation setScalingFactor(float scale) {
this.mScalingFactor = scale;
return this;
}
public ZeroGravityAnimation setAnimationListener(Animation.AnimationListener listener) {
this.mAnimationListener = listener;
return this;
}
public ZeroGravityAnimation setCount(int count) {
this.mCount = count;
return this;
}
/**
* Starts the Zero gravity animation by creating an OTT and attach it to th given ViewGroup
* @param activity
* @param ottParent
*/
public void play(Activity activity, ViewGroup ottParent) {
DirectionGenerator generator = new DirectionGenerator();
if(mCount > 0) {
for (int i = 0; i < mCount; i++) {
final int iDupe = i;
Direction origin = mOriginationDirection == Direction.RANDOM ? generator.getRandomDirection() : mOriginationDirection;
Direction destination = mDestinationDirection == Direction.RANDOM ? generator.getRandomDirection(origin) : mDestinationDirection;
int startingPoints[] = generator.getPointsInDirection(activity, origin);
int endPoints[] = generator.getPointsInDirection(activity,destination);
Bitmap bitmap = BitmapFactory.decodeResource(activity.getResources(), mImageResId);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, (int) (bitmap.getWidth() * mScalingFactor), (int) (bitmap.getHeight() * mScalingFactor), false);
switch (origin) {
case LEFT:
startingPoints[0] -= scaledBitmap.getWidth();
break;
case RIGHT:
startingPoints[0] += scaledBitmap.getWidth();
break;
case TOP:
startingPoints[1] -= scaledBitmap.getHeight();
break;
case BOTTOM:
startingPoints[1] += scaledBitmap.getHeight();
break;
}
switch (destination) {
case LEFT:
endPoints[0] -= scaledBitmap.getWidth();
break;
case RIGHT:
endPoints[0] += scaledBitmap.getWidth();
break;
case TOP:
endPoints[1] -= scaledBitmap.getHeight();
break;
case BOTTOM:
endPoints[1] += scaledBitmap.getHeight();
break;
}
final OverTheTopLayer layer = new OverTheTopLayer();
FrameLayout ottLayout = layer.with(activity)
.scale(mScalingFactor)
.attachTo(ottParent)
.setBitmap(scaledBitmap, startingPoints)
.create();
switch (origin) {
case LEFT:
}
int deltaX = endPoints[0] - startingPoints[0];
int deltaY = endPoints[1] - startingPoints[1];
int duration = mDuration;
if (duration == RANDOM_DURATION) {
duration = RandomUtil.generateRandomBetween(3500, 12500);
}
TranslateAnimation animation = new TranslateAnimation(0, deltaX, 0, deltaY);
animation.setDuration(duration);
animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
if (iDupe == 0) {
if (mAnimationListener != null) {
mAnimationListener.onAnimationStart(animation);
}
}
}
@Override
public void onAnimationEnd(Animation animation) {
layer.destroy();
if (iDupe == (mCount - 1)) {
if (mAnimationListener != null) {
mAnimationListener.onAnimationEnd(animation);
}
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
layer.applyAnimation(animation);
}
}
else {
Log.e(ZeroGravityAnimation.class.getSimpleName(),"Count was not provided, animation was not started");
}
}
/**
* Takes the content view as view parent for laying the animation objects and starts the animation.
* @param activity - activity on which the zero gravity animation should take place.
*/
public void play(Activity activity) {
play(activity,null);
}
}
RandomUtils Java类
package com.example.hamidraza.flyinemojis;
import java.util.Random;
public class RandomUtil {
/**
* Generates the random between two given integers.
*/
public static int generateRandomBetween(int start, int end) {
Random random = new Random();
int rand = random.nextInt(Integer.MAX_VALUE - 1) % end;
if (rand < start) {
rand = start;
}
return rand;
}
}
方向
package com.example.hamidraza.flyinemojis;
public enum Direction {
TOP, LEFT, RIGHT, BOTTOM,RANDOM
}
DirectionGeneretor
package com.example.hamidraza.flyinemojis;
import android.app.Activity;
import java.util.Random;
public class DirectionGenerator {
/**
* Gets the random pixel points in the given direction of the screen
* @param activity - activity from where you are referring the random value.
* @param direction - on among LEFT,RIGHT,TOP,BOTTOM,RANDOM
* @return a pixel point {x,y} in the given direction.
*/
public int[] getPointsInDirection(Activity activity, Direction direction) {
switch (direction) {
case LEFT:
return getRandomLeft(activity);
case RIGHT:
return getRandomRight(activity);
case BOTTOM:
return getRandomBottom(activity);
case TOP:
return getRandomTop(activity);
default:
Direction[] allDirections = new Direction[]{Direction.LEFT,Direction.TOP,Direction.BOTTOM,Direction.RIGHT};
int index = new Random().nextInt(allDirections.length);
return getPointsInDirection(activity, allDirections[index]);
}
}
/**
* Gets the random pixel points in the left direction of the screen. The value will be of {0,y} where y will be a random value.
* @param activity - activity from where you are referring the random value.
* @return a pixel point {x,y}.
*/
public int[] getRandomLeft(Activity activity) {
int x = 0;
int height = activity.getResources().getDisplayMetrics().heightPixels;
Random random = new Random();
int y = random.nextInt(height);
return new int[]{x, y};
}
/**
* Gets the random pixel points in the top direction of the screen. The value will be of {x,0} where x will be a random value.
* @param activity - activity from where you are referring the random value.
* @return a pixel point {x,y}.
*/
public int[] getRandomTop(Activity activity) {
int y = 0;
int width = activity.getResources().getDisplayMetrics().widthPixels;
Random random = new Random();
int x = random.nextInt(width);
return new int[]{x, y};
}
/**
* Gets the random pixel points in the right direction of the screen. The value will be of {screen_width,y} where y will be a random value.
* @param activity - activity from where you are referring the random value.
* @return a pixel point {x,y}.
*/
public int[] getRandomRight(Activity activity) {
int width = activity.getResources().getDisplayMetrics().widthPixels;
int height = activity.getResources().getDisplayMetrics().heightPixels;
int x = width ;
Random random = new Random();
int y = random.nextInt(height);
return new int[]{x, y};
}
/**
* Gets the random pixel points in the bottom direction of the screen. The value will be of {x,screen_height} where x will be a random value.
* @param activity - activity from where you are referring the random value.
* @return a pixel point {x,y}.
*/
public int[] getRandomBottom(Activity activity) {
int width = activity.getResources().getDisplayMetrics().widthPixels;
int height = activity.getResources().getDisplayMetrics().heightPixels;
int y = height ;
Random random = new Random();
int x = random.nextInt(width);
return new int[]{x, y};
}
/**
* Gets a random direction.
* @return one among LEFT,RIGHT,BOTTOM,TOP
*/
public Direction getRandomDirection() {
Direction[] allDirections = new Direction[]{Direction.LEFT,Direction.TOP,Direction.BOTTOM,Direction.RIGHT};
int index = new Random().nextInt(allDirections.length);
return (allDirections[index]);
}
/**
* Gets a random direction skipping the given direction.
* @param toSkip a direction which should not be returned by this method.
* @return one among LEFT,RIGHT,BOTTOM if TOP is provided as direction to skip,
* one among TOP,RIGHT,BOTTOM if LEFT is provided as direction to skip
* and so on.
*/
public Direction getRandomDirection(Direction toSkip) {
Direction[] allExceptionalDirections;
switch (toSkip) {
case LEFT:
allExceptionalDirections = new Direction[]{Direction.TOP,Direction.BOTTOM,Direction.RIGHT};
break;
case RIGHT:
allExceptionalDirections = new Direction[]{Direction.TOP,Direction.BOTTOM,Direction.LEFT};
break;
case BOTTOM:
allExceptionalDirections = new Direction[]{Direction.TOP,Direction.LEFT,Direction.RIGHT};
break;
case TOP:
allExceptionalDirections = new Direction[]{Direction.LEFT,Direction.BOTTOM,Direction.RIGHT};
break;
default:
allExceptionalDirections = new Direction[]{Direction.LEFT,Direction.TOP,Direction.BOTTOM,Direction.RIGHT};
}
int index = new Random().nextInt(allExceptionalDirections.length);
return (allExceptionalDirections[index]);
}
}
OverTheTopLayer 这将有助于使表情符号飞过某些视图
OverTheTopLayerThis will help to fly emojis over some views
package com.example.hamidraza.flyinemojis;
import android.app.Activity;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.widget.FrameLayout;
import android.widget.ImageView;
import java.lang.ref.WeakReference;
public class OverTheTopLayer {
public static class OverTheTopLayerException extends RuntimeException {
public OverTheTopLayerException(String msg) {
super(msg);
}
}
private WeakReference<Activity> mWeakActivity;
private WeakReference<ViewGroup> mWeakRootView;
private FrameLayout mCreatedOttLayer;
private float mScalingFactor = 1.0f;
private int[] mDrawLocation = {0, 0};
private Bitmap mBitmap;
public OverTheTopLayer() {
}
/**
* To create a layer on the top of activity
*/
public OverTheTopLayer with(Activity weakReferenceActivity) {
mWeakActivity = new WeakReference<Activity>(weakReferenceActivity);
return this;
}
/**
* Draws the image as per the drawable resource id on the given location pixels.
*/
public OverTheTopLayer generateBitmap(Resources resources, int drawableResId, float mScalingFactor, int[] location) {
if (location == null) {
location = new int[]{0, 0};
} else if (location.length != 2) {
throw new OverTheTopLayerException("Requires location as an array of length 2 - [x,y]");
}
Bitmap bitmap = BitmapFactory.decodeResource(resources, drawableResId);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, (int) (bitmap.getWidth() * mScalingFactor), (int) (bitmap.getHeight() * mScalingFactor), false);
this.mBitmap = scaledBitmap;
this.mDrawLocation = location;
return this;
}
public OverTheTopLayer setBitmap(Bitmap bitmap, int[] location) {
if (location == null) {
location = new int[]{0, 0};
} else if (location.length != 2) {
throw new OverTheTopLayerException("Requires location as an array of length 2 - [x,y]");
}
this.mBitmap = bitmap;
this.mDrawLocation = location;
return this;
}
/**
* Holds the scaling factor for the image.
*
* @param scale
* @return
*/
public OverTheTopLayer scale(float scale) {
if (scale <= 0) {
throw new OverTheTopLayerException("Scaling should be > 0");
}
this.mScalingFactor = scale;
return this;
}
/**
* Attach the OTT layer as the child of the given root view.
* @return
*/
public OverTheTopLayer attachTo(ViewGroup rootView) {
this.mWeakRootView = new WeakReference<ViewGroup>(rootView);
return this;
}
/**
* Creates an OTT.
* @return
*/
public FrameLayout create() {
if(mCreatedOttLayer != null) {
destroy();
}
if (mWeakActivity == null) {
throw new OverTheTopLayerException("Could not create the layer as not activity reference was provided.");
}
Activity activity = mWeakActivity.get();
if (activity != null) {
ViewGroup attachingView = null;
if (mWeakRootView != null && mWeakRootView.get() != null) {
attachingView = mWeakRootView.get();
} else {
attachingView = (ViewGroup) activity.findViewById(android.R.id.content);
}
ImageView imageView = new ImageView(activity);
imageView.setImageBitmap(mBitmap);
int minWidth = mBitmap.getWidth();
int minHeight = mBitmap.getHeight();
imageView.measure(View.MeasureSpec.makeMeasureSpec(minWidth, View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(minHeight, View.MeasureSpec.AT_MOST));
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) imageView.getLayoutParams();
if (params == null) {
params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT, Gravity.TOP);
imageView.setLayoutParams(params);
}
int xPosition = mDrawLocation[0];
int yPosition = mDrawLocation[1];
params.width = minWidth;
params.height = minHeight;
params.leftMargin = xPosition;
params.topMargin = yPosition;
imageView.setLayoutParams(params);
FrameLayout ottLayer = new FrameLayout(activity);
FrameLayout.LayoutParams topLayerParam = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT, Gravity.TOP);
ottLayer.setLayoutParams(topLayerParam);
ottLayer.addView(imageView);
attachingView.addView(ottLayer);
mCreatedOttLayer = ottLayer;
} else {
Log.e(OverTheTopLayer.class.getSimpleName(), "Could not create the layer. Reference to the activity was lost");
}
return mCreatedOttLayer;
}
/**
* Kills the OTT
*/
public void destroy() {
if (mWeakActivity == null) {
throw new OverTheTopLayerException("Could not create the layer as not activity reference was provided.");
}
Activity activity = mWeakActivity.get();
if (activity != null) {
ViewGroup attachingView = null;
if (mWeakRootView != null && mWeakRootView.get() != null) {
attachingView = mWeakRootView.get();
} else {
attachingView = (ViewGroup) activity.findViewById(android.R.id.content);
}
if (mCreatedOttLayer != null) {
attachingView.removeView(mCreatedOttLayer);
mCreatedOttLayer = null;
}
} else {
Log.e(OverTheTopLayer.class.getSimpleName(), "Could not destroy the layer as the layer was never created.");
}
}
/**
* Applies the animation to the image view present in OTT.
* @param animation
*/
public void applyAnimation(Animation animation) {
if(mCreatedOttLayer != null) {
ImageView drawnImageView = (ImageView) mCreatedOttLayer.getChildAt(0);
drawnImageView.startAnimation(animation);
}
}
}
这篇关于创建Facebook Live Reactions动画叠加的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!