转载至我的个人博客:自定义视图中绘制一个图形

PointF

用于保存两个浮点坐标x,y

float x,y;PointF location...location=new PointF(x,y)location=new PointF();location.set(x,y);

Paint

存储绘制信息,决定如何绘制

...boxPaint=new Paint();boxPaint.setColor(Color.RED);backgrounPaint=new Paint();backgrounPaint.setColor(Color.BLACK);canvas.drawPaint(backgrounPaint);canvas.drawRect(left,top,right,bottom,boxPaint);

Canvas

拥有需要的所有绘制操作

....@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    //绘制自定义视图的背景色    canvas.drawPaint(backgrounPaint);    for(Boxer boxer:boxers){        float left=Math.min(boxer.getOrigiin().x,boxer.getCurrent().x);        float right=Math.max(boxer.getOrigiin().x,boxer.getCurrent().x);        float top=Math.min(boxer.getOrigiin().y,boxer.getCurrent().y);        float bottom=Math.max(boxer.getOrigiin().y,boxer.getCurrent().y);        //画出一个矩形        canvas.drawRect(left,top,right,bottom,boxPaint);    }}

实例:绘制一个矩形

Boxer.class

import android.graphics.PointF;public class Boxer {    private PointF origiin;    private PointF current;    public Boxer(PointF origiin){        this.origiin=origiin;        this.current=origiin;    }    public void setCurrent(PointF current){        this.current=current;    }    public PointF getCurrent() {        return current;    }    public PointF getOrigiin() {        return origiin;    }}

BoxVieWer.class

import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.PointF;import android.support.annotation.Nullable;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;import java.util.ArrayList;import java.util.List;public class BoxVieWer extends View {    private static final String TAG=BoxVieWer.class.getSimpleName();    private Boxer boxer;    private List boxers;    private Paint boxPaint;    private Paint backgrounPaint;    public BoxVieWer(Context context) {        super(context);    }    public BoxVieWer(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);        boxers=new ArrayList<>();        boxPaint=new Paint();        boxPaint.setColor(Color.RED);        backgrounPaint=new Paint();        backgrounPaint.setColor(Color.BLACK);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        PointF pointF=new PointF(event.getX(),event.getY());        switch(event.getAction()){            case MotionEvent.ACTION_DOWN:                boxer=new Boxer(pointF);                boxers.add(boxer);                break;            case MotionEvent.ACTION_MOVE:                if(boxer!=null){                    boxer.setCurrent(pointF);                    invalidate();                }                break;            case MotionEvent.ACTION_UP:                boxer=null;                break;            case MotionEvent.ACTION_CANCEL:                boxer=null;                break;        }        return true;    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        canvas.drawPaint(backgrounPaint);        for(Boxer boxer:boxers){            float left=Math.min(boxer.getOrigiin().x,boxer.getCurrent().x);;            float right=Math.max(boxer.getOrigiin().x,boxer.getCurrent().x);            float top=Math.min(boxer.getOrigiin().y,boxer.getCurrent().y);            float bottom=Math.max(boxer.getOrigiin().y,boxer.getCurrent().y);            canvas.drawRect(left,top,right,bottom,boxPaint);        }    }}

ViewerActivity.class

import android.os.Bundle;import android.support.annotation.Nullable;import android.support.v7.app.AppCompatActivity;import io.githubs.grooters.luffy.R;public class ViewerActivity extends AppCompatActivity {    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.view_drawer);    }}

view_drawer.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent">    <luffy_viewer.BoxVieWer        android:layout_width="match_parent"        android:layout_height="match_parent" />LinearLayout>

Drawable

Selector

<?xml version="1.0" encoding="utf-8" ?>    <selector xmlns:android="http://schemas.android.com/apk/res/android">                <item android:drawable="@drawable/pic1" />                <item android:state_window_focused="false" android:drawable="@drawable/pic1" />                <item android:state_focused="true" android:state_pressed="true"            android:drawable="@drawable/pic2" />                <item android:state_focused="false" android:state_pressed="true"            android:drawable="@drawable/pic3" />                <item android:state_selected="true" android:drawable="@drawable/pic4" />                <item android:state_focused="true" android:drawable="@drawable/pic5" />    selector>

Shape

  • <?xml version="1.0" encoding="utf-8"?><shape    xmlns:android="http://schemas.android.com/apk/res/android"    android:shape="oval"    android:useLevel="false">    <stroke        android:color="@color/colorAccent"        android:width="1dp"/>    <size        android:width="20dp"        android:height="20dp"/>shape>

  • 矩形
  •     android:shape="rectangle"

  • 线
  •     android:shape="line"

  • 实心
  •     <solid android:color="@color/colorAccent"/>

    Selector与Shape结合使用

    以下代码摘抄自互联网

    <?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android">                        <item android:state_window_focused="false">        <shape android:shape="rectangle">                        <corners android:radius="5dp" />                        <solid android:color="@color/white" />                        <stroke android:width="1dp" android:color="@color/blue" />        shape>    item>        <item android:state_pressed="true">        <shape android:shape="rectangle">                        <corners android:radius="5dp" />                        <solid android:color="@color/white" />                        <stroke android:width="1dp" android:color="@color/green" />        shape>    item>selector>

    属性动画

    ObjectAnimator

  • onFloat
  • //从sunStart移动到skyHeightObjectAnimator.ofFloat(sun,"Y",sunStart,skyHeight);//从当前位置向下移动200,回到初始位置再向上移动100ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(sun, "Y", 0, 200, -100,0);

  • setDuration
  • 设置动画时间

    objectAnimator.setDuration(5000);

    eg:

    ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(sun,"y",sunStart,skyHeight).setDuration(2000);objectAnimator.start();

    注意:

    在OnCreate()objectAnimator.start();是无效的,因为在OnCreate()中AnimationDrawable还没有完全的与ImageView绑定

    TimeInterpolator

    //由慢变快objectAnimator.setInterpolator(new  AccelerateInterpolator());//由快变慢objectAnimator.setInterpolator(new  DecelerateInterpolator());

    颜色渐变

    int first=getResources().getColor(R.color.colorPrimary,getTheme());int second=getResources().getColor(R.color.colorAccent,getTheme());int last=getResources().getColor(R.color.black,getTheme());ObjectAnimator skyAnimation = ObjectAnimator.ofInt(sky,"backgroundColor",first,second,last);skyAnimation.setDuration(5000);skyAnimation.setEvaluator(new ArgbEvaluator());skyAnimation.start();

    AnimatorSet

    可将动画放在一起播放动画集

    AnimatorSet set=new AnimatorSet();set.play(firstAnimation).with(nextAnimation).before(lastAnimation);set.start();

    state list AnimatorSet

    使按钮按下和松开具有浮动效果,改变z值

    <?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android">    <item android:state_pressed="true">        <objectAnimator            android:propertyName="translationZ"            android:duration="100"            android:valueTo="10dp"            android:valueType="floatType"/>    item>    <item android:state_pressed="false">        <objectAnimator            android:propertyName="translationZ"            android:duration="100"            android:valueTo="0dp"            android:valueType="floatType"/>    item>selector>

    将以上xml文件放入animator文件夹

    然后通过android:stateListAnimator为组件设置动画

    circular revel

    将View像墨滴一样舒展开来

    @Overridepublic void onClick(View view) {    // 获取FloatingActionButton的中心点的坐标    int centerX = (view.getLeft() + view.getRight()) / 2;    int centerY = (view.getTop() + view.getBottom()) / 2;    Log.i(TAG,"centerX:"+centerX);    // 获取扩散的半径    float finalRadius = (float) Math.hypot((double) centerX, (double) centerY);    // 定义揭露动画    Animator mCircularReveal = ViewAnimationUtils.createCircularReveal(revelView, centerX, centerY, 0, finalRadius);    // 设置动画持续时间,并开始动画    mCircularReveal.setDuration(4000).start();}

    其中view为触发组件,revelView为需要揭露出来地新地View,Math.hypot勾股定理求斜边

    shared element transition

    共享元素交换,又称为hero transaction,可实现点击列表中的一张图片,令它以动画形式独立显示在一个新的activity/fragment中

    @Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);    setContentView(R.layout.activity_animationer);    final ImageView sun=findViewById(R.id.sunImage);    Button tranButton=findViewById(R.id.button_animation);    tranButton.setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View view) {            Intent intent=new Intent(AnimatioNer.this,ImagerActivity.class);            ViewCompat.setTransitionName(sun,"image");            ActivityOptionsCompat optionsCompat=ActivityOptionsCompat.makeSceneTransitionAnimation(AnimatioNer.this,sun,"image");            AnimatioNer.this.startActivity(intent,optionsCompat.toBundle());        }    });}

    getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)

    必须写在setContentView前

    ViewCompat.setTransitionName(View view, String transictionName )

    view为需要共享的资源,这里是图片sun,transictionName的字符串要和布局(原布局和共享布局)中组件transitionName属性值一样,eg:

    <ImageView    android:id="@+id/sunImage"    android:layout_gravity="center"    android:background="@drawable/sun"    android:transitionName="image"    android:layout_width="50dp"    android:layout_height="50dp"/>

    由于共享布局是共享主布局的sunImage图片,所以共享布局中也必须由图片控件,并带有transitionName=”image”属性

    optionsCompat=ActivityOptionsCompat.makeSceneTransitionAnimation(Activity activity,View view,String transictionName)

    更多相关文章

    1. Android(安卓)开发笔记 动画效果 --Animation
    2. Android(安卓)动画显示文字与bitmap的BadgeView
    3. Android(安卓)自定义dialog出入场动画
    4. Android手动画柱状图的例子
    5. Android中的矢量动画
    6. Activity切换动画无效(android:windowIsTranslucent)影响(androi
    7. android开机动画
    8. Android(安卓)集成百度地图实现设备定位
    9. Android(安卓)属性动画(Property Animation) 完全解析 (上)

    随机推荐

    1. typing模块
    2. 血洗多线程,抱得 offer 归
    3. 深入了解Nginx
    4. 手把手教linux驱动11-linux设备驱动统一
    5. 互联网和互联网的组成
    6. 第4部分- Linux ARM汇编首个程序
    7. 第7部分- Linux ARM汇编 X86和ARM64部分
    8. 网络架构及其演变过程
    9. 第9部分- Linux ARM汇编 语法
    10. 第6部分- Linux ARM汇编 指令集概要