2016-07-29 15:44:42 baidu_25797177 阅读数 2898
  • 快速入门Android开发 视频 教程 android studio

    这是一门快速入门Android开发课程,顾名思义是让大家能快速入门Android开发。 学完能让你学会如下知识点: Android的发展历程 搭建Java开发环境 搭建Android开发环境 Android Studio基础使用方法 Android Studio创建项目 项目运行到模拟器 项目运行到真实手机 Android中常用控件 排查开发中的错误 Android中请求网络 常用Android开发命令 快速入门Gradle构建系统 项目实战:看美图 常用Android Studio使用技巧 项目签名打包 如何上架市场

    19223 人正在学习 去看看 任苹蜻

[Android]FloatingText仿点赞+1等效果

@Author GQ 20160729日  

自定义View,可以仿点赞往上飘+1的一个特效,或者点击加入
购物车商品抛物线特效。

FloatingText 是一个能够在任何控件之上执行漂浮效果动画的控件。

原文github地址

效果图

这里写图片描述

1. AndroidStudio使用

dependencies {

    compile 'com.ufreedom.uikit:FloatingTextLibrary:0.2.0'

}

2. 使用

FloatingText   floatingText = new FloatingText.FloatingTextBuilder(Activity)
    .textColor(Color.RED) // 漂浮字体的颜色
    .textSize(100)   // 浮字体的大小
    .textContent("+1000") // 浮字体的内容
    .offsetX(100) // FloatingText 相对其所贴附View的水平位移偏移量
    .offsetY(100) // FloatingText 相对其所贴附View的垂直位移偏移量
    .floatingAnimatorEffect(FloatingAnimator) // 漂浮动画
    .floatingPathEffect(FloatingPathEffect) // 漂浮的路径
    .build();

floatingText.attach2Window(); //将FloatingText贴附在Window上

//启动漂浮效果
floatingText.startFloating(View); // 传入一个View,FloatingText 就会相对于这个View执行漂浮效果
  • 自定义漂浮动画
    通过实现 FloatingAnimator 接口可以实现自定义漂浮动画,详情查看原github。

  • 自定义漂浮路径

    通过实现 FloatingPathEffect 和 FloatingPathAnimator 可以自定义路径动画

    FloatingPath 代表浮动路径

  • JAVA

// +1 向上移动效果
final View layoutTranslateFloating = findViewById(R.id.layoutTranslateView);
final View translateFloatingView = findViewById(R.id.translateView);
final FloatingText   translateFloatingText = new FloatingText.FloatingTextBuilder(MainActivity.this)
                .textColor(Color.RED)
                .textSize(100)
                .textContent("+1")
                .build();
        translateFloatingText.attach2Window();

        assert layoutTranslateFloating != null;
        layoutTranslateFloating.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                translateFloatingText.startFloating(translateFloatingView);
            }
        });


//+1 放大效果

View layoutScaleView = findViewById(R.id.layoutScaleView);
final View scaleView = findViewById(R.id.scaleView);
final FloatingText  scaleFloatingText = new FloatingText.FloatingTextBuilder(MainActivity.this)
                .textColor(Color.parseColor("#7ED321"))
                .textSize(100)
                .offsetY(-100)
                .floatingAnimatorEffect(new ScaleFloatingAnimator())
                .textContent("+1")
                .build();
        scaleFloatingText.attach2Window();

        assert scaleView != null;
        assert layoutScaleView != null;
        layoutScaleView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                scaleFloatingText.startFloating(scaleView);
            }
        });


//自定义 螺旋上升动画
final FloatingText  cubicFloatingText = new FloatingText.FloatingTextBuilder(MainActivity.this)
                .textColor(Color.RED)
                .textSize(100)
                .floatingAnimatorEffect(new CurvePathFloatingAnimator())
                .floatingPathEffect(new CurveFloatingPathEffect())
                .textContent("Hello! ")
                .build();
        cubicFloatingText.attach2Window();


        View layoutCurveView = findViewById(R.id.layoutCurveView);
        final View curveView = findViewById(R.id.curveView);
        assert curveView != null;
        assert layoutCurveView != null;
        layoutCurveView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                cubicFloatingText.startFloating(curveView);
            }
        });
  • XML
<FrameLayout
        android:id="@+id/layoutTranslateView"
        android:layout_width="234.4dp"
        android:layout_height="80dp"
        android:layout_alignParentLeft="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="50dp"
        >

        <TextView
            android:id="@+id/translateView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="20dp"
            android:text="Translate Floating"
            android:textColor="@android:color/white" />

    </FrameLayout>
2016-08-19 09:41:04 axiaoquan 阅读数 297
  • 快速入门Android开发 视频 教程 android studio

    这是一门快速入门Android开发课程,顾名思义是让大家能快速入门Android开发。 学完能让你学会如下知识点: Android的发展历程 搭建Java开发环境 搭建Android开发环境 Android Studio基础使用方法 Android Studio创建项目 项目运行到模拟器 项目运行到真实手机 Android中常用控件 排查开发中的错误 Android中请求网络 常用Android开发命令 快速入门Gradle构建系统 项目实战:看美图 常用Android Studio使用技巧 项目签名打包 如何上架市场

    19223 人正在学习 去看看 任苹蜻
2014-10-03 15:27:44 kan1kan5 阅读数 5917
  • 快速入门Android开发 视频 教程 android studio

    这是一门快速入门Android开发课程,顾名思义是让大家能快速入门Android开发。 学完能让你学会如下知识点: Android的发展历程 搭建Java开发环境 搭建Android开发环境 Android Studio基础使用方法 Android Studio创建项目 项目运行到模拟器 项目运行到真实手机 Android中常用控件 排查开发中的错误 Android中请求网络 常用Android开发命令 快速入门Gradle构建系统 项目实战:看美图 常用Android Studio使用技巧 项目签名打包 如何上架市场

    19223 人正在学习 去看看 任苹蜻

第一个动画文件btn_anim.xml
<?xml version="1.0" encoding="utf-8"?>

<set
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/decelerate_interpolator">
<!--位移动画    -->
    <translate
        android:fromXDelta="0.0"
        android:fromYDelta="0.0"
        android:toXDelta="0.0"
        android:toYDelta="-75.0"
        android:duration="750"
        android:fillBefore="true"
        android:fillAfter="true" />
<!--缩放动画    -->
<scale android:fromXScale="1.0" android:fromYScale="1.0" android:toXScale="1.05" android:toYScale="1.0" android:pivotX="50%" android:pivotY="50%" android:duration="350" android:fillBefore="true" android:fillAfter="true"/></set>

2-在res文件夹 anim文件夹下面,建立第二个文件layout_anim.xml):

<?xml version="1.0" encoding="utf-8"?>

<set
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/decelerate_interpolator">

    <scale
        android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:toXScale="0.95"
        android:toYScale="0.95"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="100"
        android:fillBefore="true"
        android:fillAfter="true"/>

</set>

3主activity 我是在fragment中使用,你就随意吧。

...
private ScrollView scrollView; // This is my container. Yours may be different
private Animation btnAnim;
private Animation layoutAnim;
...

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        // Getting context
        context = getActivity().getApplicationContext();

        btnAnim = AnimationUtils.loadAnimation(context, R.anim.btn_anim);
        btnAnim.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                layoutAnim = AnimationUtils.loadAnimation(context, R.anim.layout_anim);
                scrollView.startAnimation(layoutAnim);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });

        // create view
        View view = inflater.inflate(R.layout.fragment_browse_single, container, false);

        scrollView = (ScrollView) view.findViewById(R.id.scrollView);

        myButton = (Button) view.findViewById(R.id.myButton);
        myButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                btnZan.startAnimation(btnAnim);
            }
        });

        Log.i(TAG, "View created");
        return view;
    }




另一种demo做法。试用了线程。不推荐使用

public class applaudAnimation extends Activity implements OnClickListener {
 
    private Button button;
    private TextView textView;
    private android.view.animation.Animation animation;
 
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.animation);
 
        animation = AnimationUtils.loadAnimation(this,R.anim.applaud_animation);
        button = (Button) findViewById(R.id.bt);
        button.setOnClickListener(this);
        textView = (TextView) findViewById(R.id.animation);
    }
 
    @Override
    public void onClick(View v) {
        if (v == button) {
            textView.setVisibility(View.VISIBLE);
            textView.startAnimation(animation);
            new Handler().postDelayed(new Runnable() {
                public void run() {
                    textView.setVisibility(View.GONE);
                }
            }, 1000);
        }
 
    }
}

animation.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#ffffff" >
 
    <Button
        android:id="@+id/bt"
        android:layout_width="40dip"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:text="赞"
        android:textColor="#000000"
        android:textSize="18dip" />
 
    <TextView
        android:id="@+id/animation"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:text="+1"
        android:textColor="#FF0000"
        android:textSize="18dip"
        android:visibility="gone" />
 
</RelativeLayout>

  

applaud_animation.xml
<?xml version="1.0" encoding="utf-8"?>
  <translate
    android:fromXDelta="0"
    android:toXDelta="0"
    android:fromYDelta="0"
    android:toYDelta="-50"
    android:duration="1000"/>
   
  <alpha
    android:fromAlpha="1.0"
    android:toAlpha="0.3"
    android:duration="1000"/>
</set>
2017-09-14 16:12:28 lzan13 阅读数 932
  • 快速入门Android开发 视频 教程 android studio

    这是一门快速入门Android开发课程,顾名思义是让大家能快速入门Android开发。 学完能让你学会如下知识点: Android的发展历程 搭建Java开发环境 搭建Android开发环境 Android Studio基础使用方法 Android Studio创建项目 项目运行到模拟器 项目运行到真实手机 Android中常用控件 排查开发中的错误 Android中请求网络 常用Android开发命令 快速入门Gradle构建系统 项目实战:看美图 常用Android Studio使用技巧 项目签名打包 如何上架市场

    19223 人正在学习 去看看 任苹蜻


绘制点在爱心的图片


package com.example.administrator.testbeisaier.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;


import com.example.administrator.testbeisaier.R;


import java.util.Random;


/**
 * Created by Administrator on 2017/8/29 0029.
 */
public class FavourHeartView extends View{
    Paint mPaint ;
    int mHeight,mWidth;
    Bitmap  bitmap= BitmapFactory.decodeResource(getResources(),R.drawable.anim_heart_border);


    public FavourHeartView(Context context) {
        super(context);
        initPaint();
    }




    private void initPaint() {
        mPaint=new Paint();
        Log.e("zjun","initPaint");
        mPaint.setAntiAlias(true);
        Random random=new Random();
        int color= Color.rgb(random.nextInt(255),random.nextInt(255),random.nextInt(255));
        mPaint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP));
        Log.e("zjun","...");
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        Log.e("zjun","onMeasure");
        mWidth=bitmap.getWidth();
        mHeight=bitmap.getHeight();
        setMeasuredDimension(mWidth,mHeight);
    }
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        Log.e("zjun11","w:"+w+" h:"+h);
        super.onSizeChanged(w, h, oldw, oldh);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        Log.e("zjun","onDraw");
        super.onDraw(canvas);
        Matrix matrix=new Matrix();
        if(bitmap!=null){
            canvas.drawBitmap(bitmap,matrix,mPaint);
        }
        if(bitmap!=null&&!bitmap.isRecycled()){   //回收bitmap;
            bitmap.recycle();
        }
        if(isDrawFinishListenr!=null){
            isDrawFinishListenr.isDrawFinish(true);
        }
    }


    IsDrawFinishListenr isDrawFinishListenr;


    public  interface  IsDrawFinishListenr{
        void isDrawFinish(boolean isDrawFinish);
    }


    public void setOnDrawFinishListenr(IsDrawFinishListenr isDrawFinishListenr){
        this.isDrawFinishListenr=isDrawFinishListenr;
    }

}


  添加爱心然后让其执行动画

package com.example.administrator.testbeisaier.view;


import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;


import com.example.administrator.testbeisaier.R;


import java.util.Random;


/**
 * Created by Administrator on 2017/8/29 0029.
 */
public class FavourLayout extends RelativeLayout {
    int mWidth,mHeight;
    private LayoutParams layoutParams;




    public FavourLayout(Context context) {
        super(context);
    }


    public FavourLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        Log.e("zjun,","onSizeChanged...");
        mHeight=h;
        mWidth=w;
        Log.e("zjun","w:"+w+" h:"+h);
        layoutParams =new LayoutParams(w,h);
        layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
        setLayoutParams(layoutParams);
    }


    public  void addView(){          //在外面的触发事件,例如点赞
        Log.e("zjun","addV");
       final FavourHeartView  favourHeartView= new FavourHeartView(getContext());
        favourHeartView.setOnDrawFinishListenr(new FavourHeartView.IsDrawFinishListenr() {
            @Override
            public void isDrawFinish(boolean isDrawFinish) {
                if(isDrawFinish){
                    addBSEAnimator(favourHeartView);
                }
            }
        });
        addView(favourHeartView);
        addAlpaAnimator(favourHeartView);


    }
    private void addAlpaAnimator(final  View favourHeartView){
        ObjectAnimator animator=ObjectAnimator.ofFloat(favourHeartView,"alpha",1.0f,0.1f).setDuration(2000);
        animator.start();
    }


    private void addBSEAnimator(final  View favourHeartView) {
        ValueAnimator animator =  getBezierValueAnimator(favourHeartView);
        animator.start();
        animator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animator) {


            }


            @Override
            public void onAnimationEnd(Animator animator) {
//因为不停的add 导致子view数量只增不减,所以在view动画结束后remove掉
                removeView(favourHeartView);
            }


            @Override
            public void onAnimationCancel(Animator animator) {


            }


            @Override
            public void onAnimationRepeat(Animator animator) {


            }
        });


    }
    private ValueAnimator getBezierValueAnimator(View favourHeartView) {


        //初始化一个贝塞尔计算器- - 传入两个控制点
        BezierEvaluator evaluator = new BezierEvaluator(getPointF(2), getPointF(1));
        //这里最好画个图 理解一下 传入了起点 和 终点
        ValueAnimator animator = ValueAnimator.ofObject(evaluator, new PointF((mWidth - favourHeartView.getWidth()) / 2, mHeight - favourHeartView.getHeight()), new PointF((mWidth - favourHeartView.getWidth()) / 2, 0));
        animator.addUpdateListener(new BezierListener(favourHeartView));
        animator.setDuration(2000);
        return animator;
    }


    /**
     * 获取中间的两个 点
     *
     * @param scale
     */
    private PointF getPointF(int scale) {
        Random random = new Random();
        PointF pointF = new PointF();
        pointF.x = random.nextInt((mWidth - 100));//减去100 是为了控制 x轴活动范围,看效果 随意~~
        //再Y轴上 为了确保第二个点 在第一个点之上,我把Y分成了上下两半 这样动画效果好一些  也可以用其他方法
        pointF.y = random.nextInt((mHeight - 100)) / scale;
        return pointF;
    }


    /**
     *三杰曲线获取点
     */


    public class BezierEvaluator implements TypeEvaluator<PointF> {
        private PointF pointF1;
        private PointF pointF2;
        public BezierEvaluator(PointF pointF1,PointF pointF2){
            this.pointF1 = pointF1;
            this.pointF2 = pointF2;
        }
        @Override
        public PointF evaluate(float time, PointF startValue,
                               PointF endValue) {


            float timeLeft = 1.0f - time;
            PointF point = new PointF();//结果


            point.x = timeLeft * timeLeft * timeLeft * (startValue.x)
                    + 3 * timeLeft * timeLeft * time * (pointF1.x)
                    + 3 * timeLeft * time * time * (pointF2.x)
                    + time * time * time * (endValue.x);


            point.y = timeLeft * timeLeft * timeLeft * (startValue.y)
                    + 3 * timeLeft * timeLeft * time * (pointF1.y)
                    + 3 * timeLeft * time * time * (pointF2.y)
                    + time * time * time * (endValue.y);
            return point;
        }
    }


    private class BezierListener implements ValueAnimator.AnimatorUpdateListener {


        private View target;


        public BezierListener(View target) {
            this.target = target;
        }


        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            //这里获取到贝塞尔曲线计算出来的的x y值 赋值给view 这样就能让爱心随着曲线走啦
            PointF pointF = (PointF) animation.getAnimatedValue();
            Log.e("zjun","pointF.x:"+pointF.x+"  pointF.y"+pointF.y);
            target.setX(pointF.x);
            target.setY(pointF.y);
            // 这里顺便做一个alpha动画
//            target.setAlpha(1 - animation.getAnimatedFraction());
        }
    }




}


2017-07-02 17:21:05 XIAIBIANCHENG 阅读数 1091
  • 快速入门Android开发 视频 教程 android studio

    这是一门快速入门Android开发课程,顾名思义是让大家能快速入门Android开发。 学完能让你学会如下知识点: Android的发展历程 搭建Java开发环境 搭建Android开发环境 Android Studio基础使用方法 Android Studio创建项目 项目运行到模拟器 项目运行到真实手机 Android中常用控件 排查开发中的错误 Android中请求网络 常用Android开发命令 快速入门Gradle构建系统 项目实战:看美图 常用Android Studio使用技巧 项目签名打包 如何上架市场

    19223 人正在学习 去看看 任苹蜻

闲来无事研究了下qq的点赞功能,qq点赞后会随机生成不同颜色的图片,生成方式如下:

 //生成不同颜色的点赞图片
    private Bitmap generateRandomColorBitmap(){
        int w,h;
        w=h=dip2px(this,20);
        Bitmap dst= Bitmap.createBitmap(w,h, Bitmap.Config.ARGB_8888);
        Bitmap src=BitmapFactory.decodeResource(getResources(),R.mipmap.pql).copy(Bitmap.Config.ARGB_8888, true);;

        Canvas dstCanvas=new Canvas(dst);
        Canvas srcCanvas=new Canvas(src);

        Paint rectPaint=new Paint();
        rectPaint.setStyle(Paint.Style.FILL);
        rectPaint.setColor(randomColors[getRandom(0,5)]);
        dstCanvas.drawRect(0,0,w,h,rectPaint);

        Paint p=new Paint();
        p.setStyle(Paint.Style.FILL);
        p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        srcCanvas.drawBitmap(dst,0,0,p);
        dst.recycle();
        return src;
    }

然后运动的轨迹是曲线的,可以用三次贝塞尔曲线生成轨迹路线代码如下:

/**
         * 三次贝塞尔曲线计算公式
         * B(t) = P0 * (1-t)^3 + 3 * P1 * t * (1-t)^2 + 3 * P2 * t^2 * (1-t) + P3 * t^3, t ∈ [0,1]
         * @param t  曲线长度比例
         * @param p0 起始点
         * @param p1 控制点1
         * @param p2 控制点2
         * @param p3 终止点
         * @return t对应的点
         */
        private  PointF CalculateBezierPointForCubic(float t, PointF p0, PointF p1, PointF p2, PointF p3) {
            PointF point = new PointF();
            float temp = 1 - t;
            point.x = p0.x * temp * temp * temp + 3 * p1.x * t * temp * temp + 3 * p2.x * t * t * temp + p3.x * t * t * t;
            point.y = p0.y * temp * temp * temp + 3 * p1.y * t * temp * temp + 3 * p2.y * t * t * temp + p3.y * t * t * t;
            return point;
        }

运行动过程当中的变化可以用属性动画实现代码如下:

 public void setScale(float v){
            img.setScaleY(v);
            img.setScaleX(v);
        }

        public void setPosition(float v){

            //计算位置的变化
            PointF p=CalculateBezierPointForCubic(v,p0,p1,p2,p3);
            img.setX(p.x);
            img.setY(p.y);
        }

        public void setAlpha(float v){
            img.setAlpha(v);
        }

        public void startAnimator(){
            set.playTogether(ObjectAnimator.ofFloat(this,"scale",0.4f,1.3f,1.0f));
            set.playTogether(ObjectAnimator.ofFloat(this,"position",0.0f,1.0f));
            set.playTogether(ObjectAnimator.ofFloat(this,"alpha",0.0f,1.0f,0.0f));
            set.setInterpolator(new LinearInterpolator());
            set.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {}
                @Override
                public void onAnimationEnd(Animator animation) {
                    parentView.removeView(img);
                    moveImages.remove(AnimaImageView.this);
                }
                @Override
                public void onAnimationCancel(Animator animation) {}
                @Override
                public void onAnimationRepeat(Animator animation) {}
            });
            set.setDuration(2000);
            set.start();
        }

最终效果:



完整代码:

https://github.com/XIAIBIANCHENG/qqthumb

Android 点赞

阅读数 395

android实现点赞动画

阅读数 4147

没有更多推荐了,返回首页