这篇文章中我们比较了DraggableFlagView和BezierDemo两个项目的区别,提到将对其中一个做源码分析,那么我们就来分析BezierDemo的源码吧,因为这个项目的源码最简单,可以更直接的去分析核心的东西。但是效果还是DraggableFlagView好些。我尽量讲的详细些,满足更多的初学者。这篇文章主要分析拉伸效果的实现。
源码结构
BezierDemo只有两个java文件

其中MainActivity.java是程序界面,而BezierView.java是实现了粘连拉伸效果的类。
MainActivity.java
package github.chenupt.bezier;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
activity_main.xml
这里有个疑问:为啥BezierView控件的layout_width和layout_height为match_parent。 这是因为这个代码很粗糙,哈哈。
?
好了,从上面的activity可以看出,所有的功能都是BezierView控件实现的,因此我们直接转向BezierView.java
先贴代码
package github.chenupt.bezier;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.AnimationDrawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
/**
* Created by chenupt@gmail.com on 11/20/14.
* Description : custom layout to draw bezier
*/
public class BezierView extends FrameLayout {
// 默认定点圆半径
public static final float DEFAULT_RADIUS = 20;
private Paint paint;
private Path path;
// 手势坐标
float x = 300;
float y = 300;
// 锚点坐标
float anchorX = 200;
float anchorY = 300;
// 起点坐标
float startX = 100;
float startY = 100;
// 定点圆半径
float radius = DEFAULT_RADIUS;
// 判断动画是否开始
boolean isAnimStart;
// 判断是否开始拖动
boolean isTouch;
ImageView exploredImageView;
ImageView tipImageView;
public BezierView(Context context) {
super(context);
init();
}
public BezierView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public BezierView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init(){
path = new Path();
paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setStrokeWidth(2);
paint.setColor(Color.RED);
LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
exploredImageView = new ImageView(getContext());
exploredImageView.setLayoutParams(params);
exploredImageView.setImageResource(R.drawable.tip_anim);
exploredImageView.setVisibility(View.INVISIBLE);
tipImageView = new ImageView(getContext());
tipImageView.setLayoutParams(params);
tipImageView.setImageResource(R.drawable.skin_tips_newmessage_ninetynine);
addView(tipImageView);
addView(exploredImageView);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
exploredImageView.setX(startX - exploredImageView.getWidth()/2);
exploredImageView.setY(startY - exploredImageView.getHeight()/2);
tipImageView.setX(startX - tipImageView.getWidth()/2);
tipImageView.setY(startY - tipImageView.getHeight()/2);
super.onLayout(changed, left, top, right, botto