Android 点赞飘心

[unity]代码批量修改图片、文本文件的AssetBundle的Name 当项目工程内有大量文件,需要打包成AssetBundle的时候,一个一个打包是一件非常麻烦的事情。 批量修改AssetBundle的Name并对AssetBundle包 进行批量 打包。 批量修改项目工程文件的图片、文本文件的AssetBundle 1.批量建立AssetBundle 1.1修改文件的.meta文件的文本内容 来自参考资料1 打开对应文本、图片文件的.meta的 文件,如下所示。 fileFormatVersion: 2 guid: 6c1c2f4... 阅读详情

一、依赖

compile 'com.wx.goodview:goodview:1.0.0'

二、布局

<wangyanyong.packag.com.dianzan.DivergeViewSecond
    android:id="@+id/divergeView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"/>
<ImageView
    android:id="@+id/iv_start"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginRight="10dp"
    android:layout_alignParentBottom="true"
    android:layout_alignParentRight="true"/>

三、代码  DivergeViewSecond 

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;

/*
* 实现弹幕所需要的类
* 
* */
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 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){
                //如果正在绘制,不要处理数据
                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);
        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);//默认起始高度
        }
        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;
        }
    }
}

MainActivity
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.ImageView;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private DivergeViewSecond mDivergeView;
    private ImageView mImageView;
    private List<Bitmap> mList=new ArrayList<Bitmap>();
    private int mIndex = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mImageView =findViewById(R.id.iv_start);
        mList = new ArrayList<>();
        mList.add(((BitmapDrawable) ResourcesCompat.getDrawable(getResources(), R.drawable.raw_1499933215, null)).getBitmap());
        mList.add(((BitmapDrawable) ResourcesCompat.getDrawable(getResources(),R.drawable.raw_1499933215,null)).getBitmap());
        mList.add(((BitmapDrawable) ResourcesCompat.getDrawable(getResources(),R.drawable.raw_1499933215,null)).getBitmap());
        mList.add(((BitmapDrawable) ResourcesCompat.getDrawable(getResources(),R.drawable.raw_1499933215,null)).getBitmap());
        mList.add(((BitmapDrawable) ResourcesCompat.getDrawable(getResources(),R.drawable.raw_1499933215,null)).getBitmap());
        mList.add(((BitmapDrawable) ResourcesCompat.getDrawable(getResources(), R.drawable.raw_1499933215, null)).getBitmap());
        mList.add(((BitmapDrawable) ResourcesCompat.getDrawable(getResources(), R.drawable.raw_1499933215, null)).getBitmap());
        mList.add(((BitmapDrawable) ResourcesCompat.getDrawable(getResources(), R.drawable.raw_1499933215, null)).getBitmap());
        //mList.add(((BitmapDrawable) ResourcesCompat.getDrawable(getResources(), R.drawable.a10, null)).getBitmap());
        mImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(mIndex == 8){
                    mIndex = 0 ;
                }
                mDivergeView.startDiverges(mIndex);
                mIndex ++;
            }
        });
        mDivergeView =findViewById(R.id.divergeView);
        mDivergeView.post(new Runnable() {
            @Override
            public void run() {
                mDivergeView.setEndPoint(new PointF(mDivergeView.getMeasuredWidth()/2,0));
                mDivergeView.setDivergeViewProvider(new Provider());
            }
        });
    }
    @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);
        }
    }
}



点赞飘心+贝塞尔曲线+直播界面 立即下载

相关推荐

Android 仿某直播点赞飘爱心

Android 仿某平台直播点赞飘爱心效果,本人采用的是Android Studio3.0.1和Gradle4.1版本的工具

vue点赞飘心(实测可用)

点赞飘心的组件,拿来即用

大大大大冬瓜 2450

Android点击屏幕,在点击位置绘制桃心

Android点击屏幕,在点击的位置绘制一颗桃心,注释已经写的很清楚了

Android仿直播特效之点赞飘心

一、概述 老规矩先上图 好了,基本就是这个样子,录完的视频用格式工厂转换完就这个样子了,将就看吧 二、定义我们自己的Layout /** * @author 刘洋巴金 * @date 2017-4-27 * * 定义我们自己的布局 * */ public class LoveLayout extends RelativeLayout{ private Context

刘洋巴金的专栏 1万+

安卓飘心动画

安卓的自定义开发飘心动画,不采用安卓的动画类,而是自定义实现。

Android仿直播特效之点赞飘心效果

主要为大家详细介绍了Android实现点赞飘心效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

android 飘心动画(直播点赞)效果

前段时间在写直播的时候,需要观众在看直播的时候点赞的效果,在此参照了腾讯大神写的点赞(飘心动画效果)。下面是效果图:1.自定义飘心动画的属性在attrs.xml 中增加自定义的属性<!-- 飘心动画自定义的属性 --> <declare-styleable name="HeartLayout"> <attr name="initX" format="dimension"/>

android_小路的博客 1万+

android实现直播点赞飘心动画效果

主要为大家详细介绍了android实现直播点赞飘心动画效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

android点赞动画仿twritter,Android仿直播特效之点赞飘心效果

本文实例为大家分享了Android实现点赞飘心效果的具体代码,供大家参考,具体内容如下一、概述老规矩先上图好了,基本就是这个样子,录完的视频用格式工厂转换完就这个样子了,将就看吧二、定义我们自己的Layout/*** @author 刘洋巴金* @date 2017-4-27** 定义我们自己的布局* */public class LoveLayout extends RelativeLayout...

weixin_42349769的博客 396

oracle rac 成本及架构,Oracle Extended RAC 架构实战

Extended-RAC,是RAC技术的一种扩展增强。Extended-RAC是通过专用光纤(或租用裸光纤)加DWDM(波分设备)设备将两个不同楼栋/同城甚至异地机房进行相连,将数据库主机、存储分别放置于不同机房,利用存储复制/ASM Mirror等技术进行数据复制进行搭建的一种远距离集群架构。Extended RAC需要将不同楼栋/同城甚至异地机房通过专用光纤(或租用裸光纤)加DWDM(光纤复用...

weixin_33812391的博客 2453

AI人工智能领域多模态大模型的数字孪生应用

本文旨在系统性地介绍多模态大模型在数字孪生领域的最新应用进展,探讨其技术原理、实现方法和应用价值。内容范围涵盖从基础概念到前沿技术,从理论分析到实践案例。文章首先介绍多模态大模型和数字孪生的基本概念,然后深入分析两者的结合点,接着通过具体案例展示应用实践,最后探讨未来发展趋势和挑战。多模态大模型:能够同时处理和融合多种数据模态(如文本、图像、视频、音频等)的大型人工智能模型数字孪生:物理实体或系统的虚拟副本,通过实时数据同步实现虚实交互跨模态融合:将不同数据模态的信息进行有效整合和关联的技术。

AI云原生与云计算技术学院 1325

C语言文本文件实现局部修改

前言:以往进行文件操作时,都是以链表(变量)作为用户所见数据与文件数据之间的桥梁。用户改变数据时,先改变链表(变量)中的数据,然后直接将整个链表重新写入文件,以做到“实时同步”,非正常退出程序一般数据也不会丢失。但是数据量很大时,微小的改动就要重写整个文件,浪费很多计算资源。但是在控制台程序中,没有C语言做不到的事,只有C语言不擅长的事。下面介绍一下文本文件的局部修改(覆盖写入)。当然,不进行覆盖...

kafmws的博客 5万+

数据质量管理的一些思考

背景 在近期的项目当中,我们为客户落地实施了数据资产平台。随后,在数据平台中接入了客户子公司的一个业务系统的明细数据。客户希望在我们的数据平台上通过数据探索和数据分析,来挖掘一些业务价值和业务创新点。 当我们拿到数据开始进行一些初步探索的时候,发现导入平台的数据质量存在一定的问题:例如一些用于数据分析的关键字段的值为空、一些本应该有主从关系的数据对应不上、数据分类混乱等。这些问题直接影响到了对...

IDEAL Garden 1万+

修改文本文件

修改文本文件是指对文本文件进行编辑或修改的过程。你可以使用文本编辑器(如 Notepad 或 TextEdit)或其他编辑工具来修改文本文件。只要打开文件,就可以对其进行修改并保存。 ...

weixin_35749440的博客 244

AI赋能软件测试:从冒烟测试到全流程智能化的效率革命

软件测试是确保软件质量的关键环节,其核心原理是通过预设用例验证系统功能是否符合预期。传统测试方法依赖人工编写和维护脚本,面临维护成本高、适应性差等挑战。随着人工智能技术的发展,特别是自然语言处理和计算机视觉的成熟,AI为测试领域带来了新的技术价值。通过让AI理解应用界面和业务逻辑,可以实现测试用例的智能生成、自主执行和结果分析,显著提升测试效率和覆盖率。在实际应用场景中,AI驱动的冒烟测试能够动态适应UI变化,自动分析失败日志,将测试人员从重复劳动中解放出来,专注于更复杂的质量策略设计。本文基于AI在冒烟测

weixin_28841265的博客 306

ESXI 7 :创建统信V20_1050d服务器系统虚拟机

记录一下在 X86 架构创建统信V20_1050d 虚拟机遇到的问题。已遇到的问题有①:常规服务器环境下网络连接失败重点:按照桌面版本,有问题处理简单。

guyuelin123的博客 1967

java 改写文本文件_java往文本文件中写入信息并修改

题目要求:1.可以往一个文本文档中写入员工信息:name,id和详情2.可以更改namepackage FanCQ.Xue.practice;import java.io.*;import java.util.Scanner;/** @author XueWeiWei* @date 2019/3/31 20:13*/public class Xue_RW {public static void m...

weixin_32801929的博客 443

EBSD数据转ABAQUS的inp文件实操指南

晶体塑性有限元模拟中,如何将材料微观组织表征数据转化为可计算的有限元模型,是连接实验与仿真的关键环节。EBSD技术能够获取材料表面的晶体取向、晶粒形貌和晶界分布信息,但这类数据需要经过格式解析、欧拉角转换、网格生成等步骤,才能被ABAQUS等有限元软件读取。通过将扫描点坐标映射为节点、按像素邻域生成单元,并将Bunge约定欧拉角变换为局部坐标系方向余弦,用户可以准确构建包含真实微观结构的inp文件模型。这一流程广泛应用于金属材料形变、织构演化及应力集中分析等研究场景,有效提升仿真结果与实验的一致性。围绕数据

weixin_42509513的博客 310

修改和删除文本文件指定内容

此篇文章是我关于在Python下使用文本文件后,记录相关文本读写、修改、删除、显示操作。

m0_62490926的博客 3766

ESP32-S3双模CMSIS-DAP调试器:USB+WiFi无线调试方案

CMSIS-DAP是ARM生态中标准化的嵌入式调试协议接口,广泛用于Keil、IAR、STM32CubeIDE等开发环境。其核心原理是通过SWD/JTAG物理层实现目标芯片寄存器访问、内存读写与断点控制,依赖确定性时序和低延迟通信。传统DAPLink调试器受限于USB线缆束缚,而WiFi-USB-DAPLink项目将完整CMSIS-DAP v2协议栈移植至ESP32-S3平台,同时支持USB CDC直连与WiFi TCP远程通道,兼顾实时性与网络化部署能力。该方案无需主机驱动、兼容主流IDE,并支持多机并发

weixin_31185473的博客 368

智能硬件产品 App 全球发布 第 1 章:全球 App 发布战略设计

本章阐述智能硬件 App 全球发布战略,涵盖市场分析、竞争格局、用户画像及资源配置。通过制定可执行的全球化推广路径,整合地区法规合规、渠道分发策略与营销活动设计,助力团队快速进入主流商店并确立品牌影响力。同时构建可量化的 KPI 监控体系,指导项目进度追踪与效果复盘,确保产品迭代持续优化,降低运营总成本。

moton2017的博客 156

修改一个文本文件的方法

目前作个项目,需要实现一个功能,就是要修改一个文本文件中的前面几行的数据,按一般的做法如下: using System; using System.Collections.Generic; using System.Text; using System.IO; namespace ReadLine { class Program { stati...

weixin_30492601的博客 86

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

java往文本文件中写入信息并修改

题目要求: 1.可以往一个文本文档中写入员工信息:name,id和详情 2.可以更改name package FanCQ.Xue.practice;import java.io.*;import java.util.Scanner;/* * @author XueWeiWei * @date 2019/3/31 20:13 */public class Xue_RW { publ...

weixin_30955617的博客 322

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

如何修改MyEclipse中项目的文本文件编码

窗口--首选项--工作空间,如下图 当然,也可以给单个工程修改编码,右键属性--资源,即可修改文本文件编码

sxlzll的专栏 836

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

在解决乱码问题是,如何修改文本文件的编码类型。

我们可以将这个文本文件用微软的记事本打开,右键-->打开方式-->记事本 打开后,另存为-->这是会让你选择编码类型--->选择自己所需要的编码类型就可以了 -->是否覆盖--->是 这样修改编码是为了解决有时候,因为编码类型的不一至而导致的乱码问题。

1671
上一篇: 弹幕opendanmaku.DanmakuView+节操播放器JCVideoPlayerStandard的实现
下一篇: Android 简单实现点赞功能
彦4212
博客等级 码龄9年 17粉丝 39原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值