欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android自定義View實(shí)現(xiàn)QQ消息氣泡

 更新時(shí)間:2022年08月17日 10:25:12   作者:z真真  
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)QQ消息氣泡,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了Android自定義View實(shí)現(xiàn)QQ消息氣泡的具體代碼,供大家參考,具體內(nèi)容如下

效果圖:

原理:

控件源碼:

public class DragView extends View {

? ? private int defaultZoomSize = 8;
? ? //初始化圓的大小
? ? private int initRadius;
? ? //圓1的圓心位置
? ? private PointF center1;
? ? private PointF center2;

? ? private PointF point1;
? ? private PointF point2;
? ? private PointF point3;
? ? private PointF point4;

? ? private int mWidth;
? ? private int mHeight;

? ? private float realZoomSize;
? ? private float currentRadius;
? ? private float minRadiusScale = 1 / 2f;


? ? private Paint paint;
? ? private Path path;
? ? private Bitmap bitmap;

? ? @DragStatus
? ? private int mDragStatus;


? ? public DragView(Context context) {
? ? ? ? this(context, null);
? ? }

? ? public DragView(Context context, @Nullable AttributeSet attrs) {
? ? ? ? this(context, attrs, 0);
? ? }

? ? public DragView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
? ? ? ? super(context, attrs, defStyleAttr);

? ? ? ? paint = new Paint();
? ? ? ? paint.setColor(Color.BLUE);
? ? ? ? paint.setStyle(Paint.Style.FILL);
? ? ? ? paint.setStrokeWidth(4);
? ? ? ? paint.setAntiAlias(true);

? ? ? ? path = new Path();
? ? ? ? center1 = new PointF();
? ? ? ? center2 = new PointF();
? ? ? ? point1 = new PointF();
? ? ? ? point2 = new PointF();
? ? ? ? point3 = new PointF();
? ? ? ? point4 = new PointF();

? ? ? ? bitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.icon_pot);
? ? ? ? initRadius = Math.min(bitmap.getWidth(), bitmap.getHeight()) / 2;
? ? ? ? Log.e("zhen", "解析bitmap: " + bitmap.getWidth() + " * " + bitmap.getHeight() + " * " + initRadius);
? ? }

? ? @Override
? ? protected void onSizeChanged(int w, int h, int oldw, int oldh) {
? ? ? ? super.onSizeChanged(w, h, oldw, oldh);
? ? ? ? mWidth = w;
? ? ? ? mHeight = h;
? ? ? ? center1.set(mWidth / 2, mHeight / 2);
? ? ? ? Log.d("zhen", "圓心位置:x" + center1.x + " y: " + center1.y);
? ? }

? ? private boolean isSelected = false;

? ? @Override
? ? public boolean onTouchEvent(MotionEvent event) {
? ? ? ? float x = event.getX();
? ? ? ? float y = event.getY();
? ? ? ? switch (event.getAction()) {
? ? ? ? ? ? case MotionEvent.ACTION_DOWN:
? ? ? ? ? ? ? ? if (Math.sqrt(Math.pow(x - center1.x, 2) + Math.pow(y - center1.y, 2)) < initRadius
? ? ? ? ? ? ? ? ? ? ? ? && mDragStatus == DragStatus.NORMAL) {
? ? ? ? ? ? ? ? ? ? inAnimation = false;
? ? ? ? ? ? ? ? ? ? isSelected = true;
? ? ? ? ? ? ? ? ? ? Log.e("zhen", "選中狀態(tài)");
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case MotionEvent.ACTION_MOVE:
? ? ? ? ? ? ? ? if (isSelected) {
// ? ? ? ? ? ? ? ? ? ?Log.d("zhen", "拖動(dòng)距離: " + dragDistance);
? ? ? ? ? ? ? ? ? ? if (mDragStatus != DragStatus.DRAG_BACK && mDragStatus != DragStatus.DRAG_TO) {
? ? ? ? ? ? ? ? ? ? ? ? mDragStatus = DragStatus.DRAG_MOVE;
? ? ? ? ? ? ? ? ? ? ? ? center2.set(x, y);
? ? ? ? ? ? ? ? ? ? ? ? float dragDistance = (float) (Math.sqrt(Math.pow(center2.x - center1.x, 2)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? + Math.pow(center2.y - center1.y, 2)));
? ? ? ? ? ? ? ? ? ? ? ? //多少倍圓的大小
? ? ? ? ? ? ? ? ? ? ? ? realZoomSize = dragDistance / initRadius;
? ? ? ? ? ? ? ? ? ? ? ? invalidate();
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case MotionEvent.ACTION_UP:
? ? ? ? ? ? ? ? if (isSelected) {
? ? ? ? ? ? ? ? ? ? if (realZoomSize <= defaultZoomSize) {
? ? ? ? ? ? ? ? ? ? ? ? //回彈,改變center2.x, center2.y直到等于center1.x, center1.y
? ? ? ? ? ? ? ? ? ? ? ? doAnimation(DragStatus.DRAG_BACK, center2, center1);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? isSelected = false;
? ? ? ? ? ? ? ? break;
? ? ? ? }
? ? ? ? return true;
? ? }


? ? @Override
? ? protected void onDraw(Canvas canvas) {
? ? ? ? super.onDraw(canvas);
? ? ? ? //圓的半徑改變
? ? ? ? currentRadius = initRadius * (1 + (minRadiusScale - 1) / defaultZoomSize * realZoomSize);
? ? ? ? if (realZoomSize > defaultZoomSize) {
? ? ? ? ? ? //圓縮小為一半,去往目的地,就應(yīng)該消失了
? ? ? ? ? ? doAnimation(DragStatus.DRAG_TO, center1, center2);
? ? ? ? }
? ? ? ? //中間矩形
// ? ? ? ?paint.setColor(Color.BLACK);
? ? ? ? float angle = (float) Math.atan((center2.y - center1.y) / (center2.x - center1.x));

? ? ? ? float sinValue;
? ? ? ? float cosValue;
? ? ? ? float controlX;
? ? ? ? float controlY;
? ? ? ? sinValue = (float) Math.abs((currentRadius * Math.sin(angle)));
? ? ? ? cosValue = (float) Math.abs((currentRadius * Math.cos(angle)));
? ? ? ? controlX = (center1.x + center2.x) / 2;
? ? ? ? controlY = (center1.y + center2.y) / 2;
? ? ? ? point1.set(center1.x - sinValue, center1.y - cosValue);
? ? ? ? point2.set(center1.x + sinValue, center1.y + cosValue);
? ? ? ? point3.set(center2.x - sinValue, center2.y - cosValue);
? ? ? ? point4.set(center2.x + sinValue, center2.y + cosValue);

? ? ? ? path.reset();
? ? ? ? switch (mDragStatus) {
? ? ? ? ? ? case DragStatus.NORMAL:
? ? ? ? ? ? ? ? currentRadius = initRadius;
? ? ? ? ? ? ? ? //原始圖片
? ? ? ? ? ? ? ? canvas.drawBitmap(bitmap, center1.x - initRadius, center1.y - initRadius, paint);
? ? ? ? ? ? ? ? //起始位置的圓
// ? ? ? ? ? ? ? ?paint.setColor(Color.RED);
// ? ? ? ? ? ? ? ?canvas.drawCircle(center1.x, center1.y, currentRadius, paint);
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case DragStatus.DRAG_MOVE:
? ? ? ? ? ? ? ? //拖動(dòng)過(guò)程中
? ? ? ? ? ? ? ? path.moveTo(point1.x, point1.y);
? ? ? ? ? ? ? ? path.lineTo(point2.x, point2.y);
? ? ? ? ? ? ? ? path.quadTo(controlX, controlY, point4.x, point4.y);
? ? ? ? ? ? ? ? path.lineTo(point3.x, point3.y);
? ? ? ? ? ? ? ? path.quadTo(controlX, controlY, point1.x, point1.y);
? ? ? ? ? ? ? ? canvas.drawPath(path, paint);
? ? ? ? ? ? ? ? //起始位置的圓
? ? ? ? ? ? ? ? paint.setColor(Color.RED);
? ? ? ? ? ? ? ? canvas.drawCircle(center1.x, center1.y, currentRadius, paint);
? ? ? ? ? ? ? ? //結(jié)束位置的圓
// ? ? ? ? ? ? ? ?paint.setColor(Color.BLUE);
// ? ? ? ? ? ? ? ?canvas.drawCircle(center2.x, center2.y, currentRadius, paint);
? ? ? ? ? ? ? ? //原始圖片
? ? ? ? ? ? ? ? canvas.drawBitmap(bitmap, center2.x - initRadius, center2.y - initRadius, paint);
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case DragStatus.DRAG_BACK:
? ? ? ? ? ? ? ? //改變center2.x, center2.y直到等于center1.x, center1.y
? ? ? ? ? ? ? ? path.reset();
? ? ? ? ? ? ? ? path.moveTo(point1.x, point1.y);
? ? ? ? ? ? ? ? path.quadTo(center2.x, center2.y, point2.x, point2.y);
? ? ? ? ? ? ? ? canvas.drawPath(path, paint);
? ? ? ? ? ? ? ? //起始位置的圓
// ? ? ? ? ? ? ? ?paint.setColor(Color.RED);
// ? ? ? ? ? ? ? ?canvas.drawCircle(center1.x, center1.y, currentRadius, paint);
? ? ? ? ? ? ? ? //原始圖片
? ? ? ? ? ? ? ? canvas.drawBitmap(bitmap, center1.x - initRadius, center1.y - initRadius, paint);
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case DragStatus.DRAG_TO:
? ? ? ? ? ? ? ? //改變center1.x, center1.y,直到等于center2.x, center2.y
? ? ? ? ? ? ? ? path.reset();
? ? ? ? ? ? ? ? path.moveTo(point3.x, point3.y);
? ? ? ? ? ? ? ? path.quadTo(center1.x, center1.y, point4.x, point4.y);
? ? ? ? ? ? ? ? canvas.drawPath(path, paint);
// ? ? ? ? ? ? ? ?//起始位置的圓
// ? ? ? ? ? ? ? ?paint.setColor(Color.RED);
// ? ? ? ? ? ? ? ?canvas.drawCircle(center1.x, center1.y, currentRadius, paint);
// ? ? ? ? ? ? ? ?//結(jié)束位置的圓
// ? ? ? ? ? ? ? ?paint.setColor(Color.BLUE);
// ? ? ? ? ? ? ? ?canvas.drawCircle(center2.x, center2.y, currentRadius, paint);
? ? ? ? ? ? ? ? //原始圖片
? ? ? ? ? ? ? ? canvas.drawBitmap(bitmap, center2.x - initRadius, center2.y - initRadius, paint);
? ? ? ? ? ? ? ? break;
? ? ? ? }
// ? ? ? ?Log.d("zhen", "dragStatus: " + mDragStatus + " 圓1:" + center1 + " 圓2:" + center2 + " 半徑: " + currentRadius);
// ? ? ? ?Log.w("zhen", "dragStatus: " + mDragStatus + " point3:" + point3 + " point4" + point4 + " sinValue " + sinValue + " cosValue " + cosValue);
? ? ? ? Log.w("zhen", "dragStatus: " + mDragStatus + " 圓1:" + center1 + " 圓2:" + center2 + " 半徑: " + currentRadius);

? ? }

? ? int i = 0;
? ? private boolean inAnimation = false;

? ? private void doAnimation(int dragStatus, final PointF startPoint, final PointF endPoint) {
? ? ? ? if (inAnimation) return;
? ? ? ? inAnimation = true;
? ? ? ? final int step = 10;
? ? ? ? final float stepx = (endPoint.x - startPoint.x) / step;
? ? ? ? final float stepy = (endPoint.y - startPoint.y) / step;
? ? ? ? i = 1;
? ? ? ? mDragStatus = dragStatus;
? ? ? ? Log.d("zhen", "dragStatus: " + mDragStatus + " startPoint:" + startPoint
? ? ? ? ? ? ? ? + " endPoint:" + endPoint + " stepx: " + stepy + " stepx: " + stepy);
? ? ? ? new Thread(new Runnable() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? while (i <= step) {
? ? ? ? ? ? ? ? ? ? startPoint.x += stepx;
? ? ? ? ? ? ? ? ? ? startPoint.y += stepy;
? ? ? ? ? ? ? ? ? ? postInvalidate();
? ? ? ? ? ? ? ? ? ? i++;
? ? ? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? ? ? Thread.sleep(50);
? ? ? ? ? ? ? ? ? ? } catch (InterruptedException e) {
? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? mDragStatus = DragStatus.NORMAL;
? ? ? ? ? ? ? ? invalidate();

? ? ? ? ? ? ? ? Log.e("zhen", "恢復(fù)為可拖動(dòng)狀態(tài)");
? ? ? ? ? ? }
? ? ? ? }).start();
? ? }


? ? @IntDef({DragStatus.DRAG_MOVE, DragStatus.DRAG_TO, DragStatus.DRAG_BACK})
? ? public @interface DragStatus {
? ? ? ? int NORMAL = 0;
? ? ? ? //拖動(dòng)中
? ? ? ? int DRAG_MOVE = 1;
? ? ? ? //
? ? ? ? int DRAG_TO = 2;
? ? ? ? //回彈
? ? ? ? int DRAG_BACK = 3;
? ? }

}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論