SeniorUI1005_搜索框动态效果

本文深入解析了使用PathMeasure、Path及Animation实现高级UI动画的方法,包括动画的不同阶段:开始、结束、无动作和搜索中。通过具体代码示例,展示了如何在SearchView组件中创建并控制这些动画状态。

SeniorUI_目录
SeniorUI1001_PathMeasure语法

一、Rendering

在这里插入图片描述

二、Principe

  • 利用Path、PathMeasure、Animation实现
  • 将动画 START,END,NONE,SEARCHING 四个不同的阶段
  • 利用状态和动画的值,取对应的Path,绘制

三、Core Code

public class SearchView extends View {
    private static final String TAG = "SearchView";

    private Paint mPaint;

    private Context mContext;

    private int mWidth,mHeight;

    private Path mPathCircle;

    private Path mPathSearch;

    private PathMeasure mMeasure;

    private ValueAnimator mValueAnimator;

    private long DEFAULT_DURATION =3000;

    private float mCurAnimValue;

    private SearchState mState = SearchState.NONE;

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

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

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

    public void init(Context context){
        this.mContext = context;
        initPaint();
        initPath();
        initAnimation();

    }
    public void initPaint(){
        mPaint = new Paint();
        mPaint.setDither(true);
        mPaint.setStrokeCap(Paint.Cap.ROUND);//设置笔头效果
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(3);
        mPaint.setStyle(Paint.Style.STROKE);
    }

    public void initPath(){
        mPathSearch = new Path();
        mPathCircle = new Path();

        mMeasure = new PathMeasure();

        // 注意,不要到360度,否则内部会自动优化,测量不能取到需要的数值
        RectF oval1 = new RectF(-50, -50, 50, 50);     // 放大镜圆环
        mPathSearch.addArc(oval1, 45, 359.9f);

        RectF oval2 = new RectF(-100, -100, 100, 100);   // 外部圆环
        mPathCircle.addArc(oval2, 45, -359.9f);

        float[] pos = new float[2];

        mMeasure.setPath(mPathCircle, false);        // 放大镜把手的位置
        mMeasure.getPosTan(0, pos, null);

        mPathSearch.lineTo(pos[0], pos[1]);         // 放大镜把手

        Log.d(TAG, "pos=" + pos[0] + ":" + pos[1]);

    }

    public void initAnimation(){
        mValueAnimator = ValueAnimator.ofFloat(0f,1.0f).setDuration(DEFAULT_DURATION);

        mValueAnimator.addUpdateListener(updateListener);

        mValueAnimator.addListener(animationListener);
    }
    private ValueAnimator.AnimatorUpdateListener updateListener = new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            mCurAnimValue = (float) animation.getAnimatedValue();
            invalidate();
        }
    };

    private Animator.AnimatorListener animationListener = new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {

        }

        @Override
        public void onAnimationEnd(Animator animation) {
            if(mState == SearchState.START){
                setState(SearchState.SEARCHING);
            }
        }

        @Override
        public void onAnimationCancel(Animator animation) {

        }

        @Override
        public void onAnimationRepeat(Animator animation) {

        }
    };
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Log.d(TAG,"onDraw");
        drawPath(canvas);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = w;
        mHeight = h;

    }

    private void drawPath(Canvas canvas) {
        canvas.translate(mWidth / 2, mHeight / 2);
        switch (mState){

            case NONE:
                canvas.drawPath(mPathSearch,mPaint);
                break;

            case START:
                mMeasure.setPath(mPathSearch,true);
                Path path = new Path();
                mMeasure.getSegment(mMeasure.getLength() * mCurAnimValue,mMeasure.getLength(),path, true);
                canvas.drawPath(path,mPaint);
                break;

            case SEARCHING:
                mMeasure.setPath(mPathCircle,true);
                Path pathSearch = new Path();
                mMeasure.getSegment(mMeasure.getLength()* mCurAnimValue -30,mMeasure.getLength()* mCurAnimValue,pathSearch,true);
                canvas.drawPath(pathSearch,mPaint);
                break;

            case END:
                mMeasure.setPath(mPathSearch,true);
                Path pathView = new Path();

                mMeasure.getSegment(0,mMeasure.getLength()* mCurAnimValue,pathView,true);
                canvas.drawPath(pathView,mPaint);
                break;
        }

    }


    public void setState(SearchState state){
        this.mState = state;
        startSearch();
    }

    public void startSearch(){
        switch (mState){
            case START:
                mValueAnimator.setRepeatCount(0);
                break;

            case SEARCHING:
                mValueAnimator.setRepeatCount(ValueAnimator.INFINITE);
                mValueAnimator.setRepeatMode(ValueAnimator.REVERSE);
                break;

            case END:
                mValueAnimator.setRepeatCount(0);
                break;
        }
        mValueAnimator.start();
    }
    public  enum SearchState {
        START,END,NONE,SEARCHING
    }
}

四、Demo

SearchView

【EI复现】基于深度强化学习的微能源网能量管理与优化策略研究(Python代码实现)内容概要:本文围绕“基于深度强化学习的微能源网能量管理与优化策略”展开研究,重点利用深度Q网络(DQN)等深度强化学习算法对微能源网中的能量调度进行建模与优化,旨在应对可再生能源出力波动、负荷变化及运行成本等问题。文中结合Python代码实现,构建了包含光伏、储能、负荷等元素的微能源网模型,通过强化学习智能体动态决策能量分配策略,实现经济性、稳定性和能效的多重优化目标,并可能与其他优化算法进行对比分析以验证有效性。研究属于电力系统与人工智能交叉领域,具有较强的工程应用背景和学术参考价值。; 适合人群:具备一定Python编程基础和机器学习基础知识,从事电力系统、能源互联网、智能优化等相关方向的研究生、科研人员及工程技术人员。; 使用场景及目标:①学习如何将深度强化学习应用于微能源网的能量管理;②掌握DQN等算法在实际能源系统调度中的建模与实现方法;③为相关课题研究或项目开发提供代码参考和技术思路。; 阅读建议:建议读者结合提供的Python代码进行实践操作,理解环境建模、状态空间、动作空间及奖励函数的设计逻辑,同时可扩展学习其他强化学习算法在能源系统中的应用。
皮肤烧伤识别作为医学与智能技术交叉的前沿课题,近年来在深度学习方法推动下取得了显著进展。该技术体系借助卷积神经网络等先进模型,实现了对烧伤区域特征的高效提取与分类判别,为临床诊疗决策提供了重要参考依据。本研究项目系统整合了算法设计、数据处理及模型部署等关键环节,形成了一套完整的可操作性方案。 在技术实现层面,首先需要构建具有代表性的烧伤图像数据库,涵盖不同损伤程度及愈合阶段的临床样本。通过对原始图像进行标准化校正、对比度增强等预处理操作,有效提升后续特征学习的稳定性。网络架构设计需充分考虑皮肤病变的区域特性,通过多层卷积与池化操作的组合,逐步抽象出具有判别力的烧伤特征表示。 模型优化过程中采用自适应学习率调整策略,结合交叉熵损失函数与梯度下降算法,确保参数收敛的稳定性。为防止过拟合现象,引入数据扩增技术与正则化约束,增强模型的泛化能力。性能验证阶段采用精确率、召回率等多维度指标,在独立测试集上全面评估模型对不同烧伤类型的识别效能。 经过充分验证的识别系统可集成至医疗诊断平台,通过规范化接口实现与现有医疗设备的无缝对接。实际部署前需进行多中心临床验证,确保系统在不同操作环境下的稳定表现。该技术方案的实施将显著缩短烧伤评估时间,为临床医师提供客观量化的辅助诊断依据,进而优化治疗方案制定流程。 本项目的突出特点在于将理论研究与工程实践有机结合,既包含前沿的深度学习算法探索,又提供了完整的产业化实施路径。通过模块化的设计思路,使得医疗专业人员能够快速掌握核心技术方法,推动智能诊断技术在烧伤外科领域的实际应用。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值