用于保存两个浮点坐标x,y
float x,y;
PointF location
...
location=new PointF(x,y)
location=new PointF();
location.set(x,y);
存储绘制信息,决定如何绘制
...
boxPaint=new Paint();
boxPaint.setColor(Color.RED);
backgrounPaint=new Paint();
backgrounPaint.setColor(Color.BLACK);
canvas.drawPaint(backgrounPaint);
canvas.drawRect(left,top,right,bottom,boxPaint);
拥有需要的所有绘制操作
....
@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);
}
}
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
<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>
<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
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 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>
//从sunStart移动到skyHeight
ObjectAnimator.ofFloat(sun,"Y",sunStart,skyHeight);
//从当前位置向下移动200,回到初始位置再向上移动100
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(sun, "Y", 0, 200, -100,0);
设置动画时间
objectAnimator.setDuration(5000);
eg:
ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(sun,"y",sunStart,skyHeight).setDuration(2000);
objectAnimator.start();
注意:
在OnCreate()objectAnimator.start();是无效的,因为在OnCreate()中AnimationDrawable还没有完全的与ImageView绑定
//由慢变快
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 set=new AnimatorSet();
set.play(firstAnimation).with(nextAnimation).before(lastAnimation);
set.start();
使按钮按下和松开具有浮动效果,改变z值
<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为组件设置动画
将View像墨滴一样舒展开来
@Override
public 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勾股定理求斜边
共享元素交换,又称为hero transaction,可实现点击列表中的一张图片,令它以动画形式独立显示在一个新的activity/fragment中
@Override
protected 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)