欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android實(shí)現(xiàn)點(diǎn)贊動(dòng)畫(huà)(27)

 更新時(shí)間:2017年02月01日 09:28:27   作者:逆世風(fēng)靈  
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)點(diǎn)贊動(dòng)畫(huà),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了Android使用入門(mén)第二十七篇點(diǎn)贊動(dòng)畫(huà)的具體代碼,供大家參考,具體內(nèi)容如下

MainActivity.java代碼:

package siso.likeanimation;

import android.graphics.Bitmap;
import android.graphics.PointF;
import android.graphics.drawable.BitmapDrawable;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
 private DivergeViewSecond mDivergeView;
 private Button mBtnStart;
 private ImageView mImageView;
 private ArrayList<Bitmap> mList;
 private int mIndex = 0;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 mBtnStart = (Button)findViewById(R.id.btnStart);
 mImageView = (ImageView)findViewById(R.id.iv_start);
 mList = new ArrayList<>();
 mList.add(((BitmapDrawable) ResourcesCompat.getDrawable(getResources(), R.drawable.ic_praise_sm1, null)).getBitmap());
 mList.add(((BitmapDrawable) ResourcesCompat.getDrawable(getResources(),R.drawable.ic_praise_sm2,null)).getBitmap());
 mList.add(((BitmapDrawable) ResourcesCompat.getDrawable(getResources(),R.drawable.ic_praise_sm3,null)).getBitmap());
 mList.add(((BitmapDrawable) ResourcesCompat.getDrawable(getResources(),R.drawable.ic_praise_sm4,null)).getBitmap());
 mList.add(((BitmapDrawable) ResourcesCompat.getDrawable(getResources(),R.drawable.ic_praise_sm5,null)).getBitmap());
 mList.add(((BitmapDrawable) ResourcesCompat.getDrawable(getResources(), R.drawable.ic_praise_sm6, null)).getBitmap());
 mBtnStart.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
  if(mIndex == 5){
   mIndex = 0 ;
  }
  mDivergeView.startDiverges(mIndex);
  mIndex ++;
//  if (mDivergeView.isRunning()) {
//   mDivergeView.stop();
//  } else {
//
//  }
  }
 });
 mDivergeView = (DivergeViewSecond) findViewById(R.id.divergeView);
 mDivergeView.post(new Runnable() {
  @Override
  public void run() {
  mDivergeView.setEndPoint(new PointF(mDivergeView.getMeasuredWidth()/2,0));
  mDivergeView.setDivergeViewProvider(new Provider());
  }
 });
// mDivergeView.start();
 }

 @Override
 protected void onDestroy() {
 super.onDestroy();
 if(mList != null){
  mList.clear();
  mList = null;
 }

 }

 class Provider implements DivergeViewSecond.DivergeViewProvider{

 @Override
 public Bitmap getBitmap(Object obj) {
  return mList == null ? null : mList.get((int)obj);
 }
 }
}

DivergeViewSecond.java代碼:

package siso.likeanimation;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;


public class DivergeViewSecond extends View implements Runnable{

 public static final float mDuration = 0.010F;
 public static final int mDefaultHeight = 100;
 protected static final long mQueenDuration = 200;

 protected final Random mRandom = new Random();

 protected ArrayList<DivergeInfo> mDivergeInfos;

 protected List<Object> mQueen;

 protected PointF mPtStart;
 protected PointF mPtEnd;

 protected ArrayList<DivergeInfo> mDeadPool = new ArrayList<>();

 private Paint mPaint;

// private static final int mDefaultWidth = 100;
// private static final int mAlphaOffset = 50;

 private DivergeViewProvider mDivergeViewProvider;

 private long mLastAddTime = 0;

 private Thread mThread;

 private boolean mRunning = true;

 private boolean mIsDrawing = false;

 public DivergeViewSecond(Context context) {
 this(context, null);
 }

 public DivergeViewSecond(Context context, AttributeSet attrs) {
 this(context, attrs, 0);
 }

 public DivergeViewSecond(Context context, AttributeSet attrs, int defStyleAttr) {
 super(context, attrs, defStyleAttr);
 init();
 }


 /**
 * Loop
 */
 @Override
 public void run() {

 while(mRunning){

  if(mDivergeViewProvider == null){
  continue;
  }

  if(mQueen == null){
  continue;
  }

  if(mIsDrawing){
  //如果正在繪制,不要處理數(shù)據(jù)
  continue;
  }

  if(mDivergeInfos == null){
  continue;
  }

  dealQueen();

  if(mDivergeInfos.size() == 0){
  continue;
  }

  dealDiverge();

  mIsDrawing = true;

  postInvalidate();

 }

 //停止
 release();
 }

 private void dealDiverge(){
 for (int i = 0; i < mDivergeInfos.size(); i++) {
  DivergeInfo divergeInfo = mDivergeInfos.get(i);

  float timeLeft = 1.0F - divergeInfo.mDuration;

  divergeInfo.mDuration += mDuration;

  float x, y;

  //二次貝塞爾
  float time1 = timeLeft * timeLeft;
  float time2 = 2 * timeLeft * divergeInfo.mDuration;
  float time3 = divergeInfo.mDuration * divergeInfo.mDuration;
  x = time1 * (mPtStart.x)
   + time2 * (divergeInfo.mBreakPoint.x)
   + time3 * (divergeInfo.mEndPoint.x);

  divergeInfo.mX = x;

  y = time1 * (mPtStart.y)
   + time2 * (divergeInfo.mBreakPoint.y)
   + time3 * (divergeInfo.mEndPoint.y);

  divergeInfo.mY = y;

  if (divergeInfo.mY <= divergeInfo.mEndPoint.y) {
  mDivergeInfos.remove(i);
  mDeadPool.add(divergeInfo);
  i--;
  continue;
  }
 }
 }

 private void dealQueen(){
 long now = System.currentTimeMillis();
 if(mQueen.size() > 0 && now - mLastAddTime > mQueenDuration){
  mLastAddTime = System.currentTimeMillis();
  DivergeInfo divergeInfo = null;
  if(mDeadPool.size() > 0){
  //死池里面有空閑的divergeNode
  divergeInfo = mDeadPool.get(0);
  mDeadPool.remove(0);
  }
  if(divergeInfo == null){
  divergeInfo = createDivergeNode(mQueen.get(0));
  }
  divergeInfo.reset();
  divergeInfo.mType = mQueen.get(0);
  mDivergeInfos.add(divergeInfo);
  mQueen.remove(0);
 }
 }

 public interface DivergeViewProvider{
 public Bitmap getBitmap(Object obj);
 }


 private void init(){
 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
 }

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
 //不需要支持wrap_content

 }

 @Override
 protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
 super.onLayout(changed, left, top, right, bottom);

 }

 public void setDivergeViewProvider(DivergeViewProvider divergeViewProvider){
 mDivergeViewProvider = divergeViewProvider;
 }

 public PointF getStartPoint(){
 return mPtStart;
 }

 public boolean isRunning(){
 return mRunning;
 }

 public void startDiverges(Object obj){

 if(mDivergeInfos == null){
  mDivergeInfos = new ArrayList<>(30);
 }

 if(mQueen == null){
  mQueen = Collections.synchronizedList(new ArrayList<>(30));
 }

 mQueen.add(obj);
// for(Object obj : objs) {
//  mQueen.add(obj);
// }

 if(mThread == null) {
  mThread = new Thread(this);
  mThread.start();
 }
 }

 public void stop(){
 if(mDivergeInfos != null){
  mDivergeInfos.clear();
 }

 if(mQueen != null){
  mQueen.clear();
 }

 if(mDeadPool != null){
  mDeadPool.clear();
 }

 }

 public void release(){
 stop();
 mPtEnd = null;
 mPtStart = null;
 mDivergeInfos = null;
 mQueen = null;
 mDeadPool = null;
 }

 public void setStartPoint(PointF point){
 mPtStart = point;
 }

 public void setEndPoint(PointF point){
 mPtEnd = point;
 }

 @Override
 protected void onDetachedFromWindow() {
 super.onDetachedFromWindow();
 mRunning = false;
 }

 @Override
 protected void onDraw(Canvas canvas) {

 if(mRunning && mDivergeViewProvider != null && mDivergeInfos != null){
  for(DivergeInfo divergeInfo : mDivergeInfos){
  mPaint.setAlpha((int)(255 * divergeInfo.mY / mPtStart.y));
  canvas.drawBitmap(mDivergeViewProvider.getBitmap(divergeInfo.mType),
   divergeInfo.mX,
   divergeInfo.mY,
   mPaint);
  }
 }
 mIsDrawing = false;
 }


 private PointF getBreakPointF(int scale1, int scale2) {

 PointF pointF = new PointF();
 pointF.x = mRandom.nextInt((getMeasuredWidth() - getPaddingRight() + getPaddingLeft()) / scale1) + getMeasuredWidth() / scale2;
 pointF.y = mRandom.nextInt((getMeasuredHeight() - getPaddingBottom() + getPaddingTop()) / scale1) + getMeasuredHeight() / scale2;
 return pointF;
 }

 protected DivergeInfo createDivergeNode(Object type){
 PointF endPoint = mPtEnd;
 if(endPoint == null){
  endPoint = new PointF(mRandom.nextInt(getMeasuredWidth()),0);
 }
// int height = mDivergeViewProvider == null ? mDefaultHeight : mDivergeViewProvider.getBitmap(type).getHeight();
 if(mPtStart == null) {
  mPtStart = new PointF(getMeasuredWidth() / 2, getMeasuredHeight() - mDefaultHeight);//默認(rèn)起始高度
 }
 return new DivergeInfo(
  mPtStart.x,
  mPtStart.y,
  getBreakPointF(2, 3),
  endPoint,
  type);
 }

 public class DivergeInfo {
 public float mDuration;
 public PointF mBreakPoint;
 public PointF mEndPoint;
 public float mX;
 public float mY;
 public Object mType;
 public float mStartX;
 public float mStartY;
 public DivergeInfo(float x, float y, PointF breakPoint, PointF endPoint, Object type){
  mDuration = 0.0f;
  mEndPoint = endPoint;
  mX = x;
  mY = y;
  mStartX = x;
  mStartY = y;
  mBreakPoint = breakPoint;
  mType = type;
 }

 public void reset(){
  mDuration = 0.0f;
  mX = mStartX;
  mY = mStartY;
 }
 }
}

activity_main.xml內(nèi)容:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:paddingBottom="@dimen/activity_vertical_margin"
 android:paddingLeft="@dimen/activity_horizontal_margin"
 android:paddingRight="@dimen/activity_horizontal_margin"
 android:paddingTop="@dimen/activity_vertical_margin"
 tools:context="siso.likeanimation.MainActivity">

 <Button
 android:id="@+id/btnStart"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:text="開(kāi)始"/>

 <siso.likeanimation.DivergeViewSecond
 android:id="@+id/divergeView"
 android:layout_alignParentBottom="true"
 android:layout_alignParentRight="true"
 android:layout_width="130dp"
 android:layout_height="300dp"/>
 <ImageView
 android:id="@+id/iv_start"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginRight="10dp"
 android:layout_alignParentBottom="true"
 android:layout_alignParentRight="true"
 android:background="@drawable/ic_praise_sm6"/>
</RelativeLayout>

運(yùn)行結(jié)果如圖:

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Kotlin面向?qū)ο笾R(shí)點(diǎn)講解

    Kotlin面向?qū)ο笾R(shí)點(diǎn)講解

    面向?qū)ο缶幊掏ㄟ^(guò)對(duì)事物的抽象,大大的簡(jiǎn)化了程序的開(kāi)發(fā)難度。我們常用的編程語(yǔ)言:Java、C++、Python都屬于面向?qū)ο缶幊獭otlin與java類(lèi)似,也是一種面向?qū)ο缶幊陶Z(yǔ)言。本文從面向?qū)ο笕齻€(gè)基本特征:封裝、繼承、多態(tài),來(lái)闡述一下Kotlin中的面向?qū)ο缶幊?/div> 2022-12-12
  • 如何在Android Studio下進(jìn)行NDK開(kāi)發(fā)

    如何在Android Studio下進(jìn)行NDK開(kāi)發(fā)

    這篇文章主要介紹了如何在Android Studio下進(jìn)行NDK開(kāi)發(fā),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • 分享五種Android常用布局方式

    分享五種Android常用布局方式

    Android布局是應(yīng)用界面開(kāi)發(fā)的重要一環(huán),在Android中,共有五種布局方式,分別是:FrameLayout(框架布 局),LinearLayout (線性布局),AbsoluteLayout(絕對(duì)布局),RelativeLayout(相對(duì)布局),TableLayout(表格布局),小編通過(guò)本文逐一給大家詳解
    2015-11-11
  • Android實(shí)現(xiàn)仿今日頭條點(diǎn)贊動(dòng)畫(huà)效果實(shí)例

    Android實(shí)現(xiàn)仿今日頭條點(diǎn)贊動(dòng)畫(huà)效果實(shí)例

    我想看到今日頭條的點(diǎn)贊效果,應(yīng)該都覺(jué)得很絢麗吧,下面這篇文章主要給大家介紹了關(guān)于Android實(shí)現(xiàn)仿今日頭條點(diǎn)贊動(dòng)畫(huà)效果的相關(guān)資料,文中通過(guò)示例代價(jià)介紹的非常詳細(xì),需要的朋友可以參考下
    2022-02-02
  • Android利用MediaRecorder實(shí)現(xiàn)錄音功能

    Android利用MediaRecorder實(shí)現(xiàn)錄音功能

    這篇文章主要為大家詳細(xì)介紹了Android利用MediaRecorder實(shí)現(xiàn)錄音功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Android Vitamio和ExoPlayer兩種播放器優(yōu)劣分析

    Android Vitamio和ExoPlayer兩種播放器優(yōu)劣分析

    Vitamio和ExoPlayer都是用于安卓平臺(tái)的視頻播放器庫(kù),它們各有優(yōu)缺點(diǎn),具體使用哪一個(gè),需要根據(jù)你的實(shí)際需求、開(kāi)發(fā)經(jīng)驗(yàn)、項(xiàng)目規(guī)模等多個(gè)因素綜合考慮
    2023-04-04
  • Android使用Intent的Action和Data屬性實(shí)現(xiàn)點(diǎn)擊按鈕跳轉(zhuǎn)到撥打電話和發(fā)送短信界面

    Android使用Intent的Action和Data屬性實(shí)現(xiàn)點(diǎn)擊按鈕跳轉(zhuǎn)到撥打電話和發(fā)送短信界面

    這篇文章主要介紹了Android中使用Intent的Action和Data屬性實(shí)現(xiàn)點(diǎn)擊按鈕跳轉(zhuǎn)到撥打電話和發(fā)送短信,需要的朋友可以參考下
    2020-01-01
  • Android實(shí)現(xiàn)俄羅斯方塊

    Android實(shí)現(xiàn)俄羅斯方塊

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)俄羅斯方塊游戲 ,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • flutter自定義InheritedProvider實(shí)現(xiàn)狀態(tài)管理詳解

    flutter自定義InheritedProvider實(shí)現(xiàn)狀態(tài)管理詳解

    這篇文章主要為大家介紹了flutter自定義InheritedProvider實(shí)現(xiàn)狀態(tài)管理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • Android實(shí)現(xiàn)調(diào)用系統(tǒng)圖庫(kù)與相機(jī)設(shè)置頭像并保存在本地及服務(wù)器

    Android實(shí)現(xiàn)調(diào)用系統(tǒng)圖庫(kù)與相機(jī)設(shè)置頭像并保存在本地及服務(wù)器

    這篇文章主要介紹了Android實(shí)現(xiàn)調(diào)用系統(tǒng)圖庫(kù)與相機(jī)設(shè)置頭像并保存在本地及服務(wù)器 ,需要的朋友可以參考下
    2017-03-03

最新評(píng)論