遇到的问题及其解决方案
1.简单的view旋转移动拖拽
PasterView
public class PasterView extends LinearLayout {public ImageView mView;private ImageView mPushView;private ImageView mDeleteView;private float _1dp;private boolean mCenterInParent;private Drawable mImageDrawable, mPushImageDrawable, mDeleteImageDrawable;private float mImageHeight, mImageWidth, mPushImageHeight, mPushImageWidth, mDeleteImageHeight, mDeleteImageWidth;public int mLeft = 0, mTop = 0;private boolean mIconVisibility = true;/*** callback interface to be invoked when the delete icon has clicked*/private OnPasterDeleteIconClickListener mOnPasterDeleteIconClickListener;/*** callback interface to be invoked when the image view has clicked*/private OnImageViewClickListener mOnImageViewClickListener;public PasterView(Context context) {this(context, null, 0);}public PasterView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public PasterView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);this._1dp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, context.getResources().getDisplayMetrics());this.parseAttr(context, attrs);View mRoot = View.inflate(context, R.layout.test_image_view, null);addView(mRoot, -1, -1);mPushView = (ImageView) mRoot.findViewById(R.id.push_view);mView = (ImageView) mRoot.findViewById(R.id.view);mView.setTag(R.id.single_finger_view_scale, (float)1.0);mDeleteView = (ImageView) mRoot.findViewById(R.id.delete_view);mPushView.setOnTouchListener(new PushBtnTouchListener(mView, mDeleteView));WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);mView.setOnTouchListener(new ViewOnTouchListener(mPushView, mDeleteView, wm.getDefaultDisplay().getWidth(), wm.getDefaultDisplay().getHeight()));mDeleteView.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {deletePasterImage();}});}public void showIconAndBorder() {if (null != mDeleteView) {mDeleteView.setVisibility(View.VISIBLE);}if (null != mPushView) {mPushView.setVisibility(View.VISIBLE);}if (null != mView) {mView.setBackgroundDrawable(getContext().getResources().getDrawable(R.drawable.paster_image_border));}mIconVisibility = true;}private void parseAttr(Context context, AttributeSet attrs) {if (null == attrs) return;TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PasterView);if (a != null) {int n = a.getIndexCount();for (int i = 0; i < n; i++) {int attr = a.getIndex(i);if (attr == R.styleable.PasterView_centerInParent) {this.mCenterInParent = a.getBoolean(attr, false);} else if (attr == R.styleable.PasterView_image) {this.mImageDrawable = a.getDrawable(attr);} else if (attr == R.styleable.PasterView_image_height) {this.mImageHeight = a.getDimension(attr, 200 * _1dp);} else if (attr == R.styleable.PasterView_image_width) {this.mImageWidth = a.getDimension(attr, 200 * _1dp);} else if (attr == R.styleable.PasterView_push_image) {this.mPushImageDrawable = a.getDrawable(attr);} else if (attr == R.styleable.PasterView_push_image_width) {this.mPushImageWidth = a.getDimension(attr, 50 * _1dp);} else if (attr == R.styleable.PasterView_push_image_height) {this.mPushImageHeight = a.getDimension(attr, 50 * _1dp);} else if (attr == R.styleable.PasterView_left) {this.mLeft = (int) a.getDimension(attr, 0 * _1dp);} else if (attr == R.styleable.PasterView_top) {this.mTop = (int) a.getDimension(attr, 0 * _1dp);} else if (attr == R.styleable.PasterView_delete_image) {this.mDeleteImageDrawable = a.getDrawable(attr);} else if (attr == R.styleable.PasterView_delete_image_width) {this.mDeleteImageWidth = a.getDimension(attr, 50 * _1dp);} else if (attr == R.styleable.PasterView_delete_image_height) {this.mDeleteImageHeight = a.getDimension(attr, 50 * _1dp);}}}}private void setViewToAttr(int pWidth, int pHeight) {if (null != mImageDrawable) {this.mView.setBackgroundDrawable(mImageDrawable);}if (null != mPushImageDrawable) {this.mPushView.setBackgroundDrawable(mPushImageDrawable);}if (null != mDeleteImageDrawable) {this.mDeleteView.setBackgroundDrawable(mDeleteImageDrawable);}FrameLayout.LayoutParams viewLP = (FrameLayout.LayoutParams) this.mView.getLayoutParams();viewLP.width = (int) mImageWidth;viewLP.height = (int) mImageHeight;int left = 0, top = 0;if (mCenterInParent) {left = pWidth / 2 - viewLP.width / 2;top = pHeight / 2 - viewLP.height / 2;} else {if (mLeft > 0) left = mLeft;if (mTop > 0) top = mTop;}viewLP.leftMargin = left;viewLP.topMargin = top;this.mView.setLayoutParams(viewLP);FrameLayout.LayoutParams pushViewLP = (FrameLayout.LayoutParams) mPushView.getLayoutParams();pushViewLP.width = (int) mPushImageWidth;pushViewLP.height = (int) mPushImageHeight;pushViewLP.leftMargin = (int) (viewLP.leftMargin + mImageWidth - mPushImageWidth / 2);pushViewLP.topMargin = (int) (viewLP.topMargin + mImageHeight - mPushImageHeight / 2);mPushView.setLayoutParams(pushViewLP);FrameLayout.LayoutParams deleteViewLP = (FrameLayout.LayoutParams) mDeleteView.getLayoutParams();deleteViewLP.width = (int) mDeleteImageWidth;deleteViewLP.height = (int) mDeleteImageHeight;deleteViewLP.leftMargin = (int) (viewLP.leftMargin - mDeleteImageWidth / 2);deleteViewLP.topMargin = (int) (viewLP.topMargin - mDeleteImageHeight / 2);mDeleteView.setLayoutParams(deleteViewLP);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);setParamsForView(widthMeasureSpec, heightMeasureSpec);}private boolean hasSetParamsForView = false;private void setParamsForView(int widthMeasureSpec, int heightMeasureSpec) {ViewGroup.LayoutParams layoutParams = getLayoutParams();if (null != layoutParams && !hasSetParamsForView) {hasSetParamsForView = true;int width;if ((getLayoutParams().width == LayoutParams.MATCH_PARENT)) {width = MeasureSpec.getSize(widthMeasureSpec);} else {width = getLayoutParams().width;}int height;if ((getLayoutParams().height == LayoutParams.MATCH_PARENT)) {height = MeasureSpec.getSize(heightMeasureSpec);} else {height = getLayoutParams().height;}setViewToAttr(width, height);Log.d("tag", "width :" + width + " height :" + height);}}/*** Interface definition for a callback to be invoked when the delete icon has clicked.*/public interface OnPasterDeleteIconClickListener {/**** callback method to be invoked when the delete icon has clicked*/public void onDeleteIconClick(PasterView singleFingerView);}/*** Interface definition for a callback to be invoked when the image view has clicked*/public interface OnImageViewClickListener {/*** callback method to be invoked when the image view has clicked*/public void onImageViewClick(PasterView singleFingerView);}/*** call to delete the icon*/public void deletePasterImage() {//if the delete icon clicked then notify listener if there is oneif (mOnPasterDeleteIconClickListener != null) {mOnPasterDeleteIconClickListener.onDeleteIconClick(this);}}/*** call to change the index of imageview*/public void changeViewIndexToTop() {//if the view clicked then notify listener if there is oneif (mOnImageViewClickListener != null) {mOnImageViewClickListener.onImageViewClick(this);}}}
Point
public class Point {public float x;public float y;public Point(float x, float y) {this.x = x;this.y = y;}@Overridepublic String toString() {return "x: " + x + ",y: " + y;}}
PushBtnTouchListener
import android.view.MotionEvent;import android.view.View;import android.widget.FrameLayout;import com.warpath.pasterview.R;class PushBtnTouchListener implements View.OnTouchListener {Point pushPoint;int lastImgWidth;int lastImgHeight;int lastImgLeft;int lastImgTop;int lastImgAngle;double lastComAngle;int pushImgWidth;int pushImgHeight;int deleteImageWidth;int deleteImageHeight;int lastPushBtnLeft;int lastPushBtnTop;int lastDeleteBtnLeft;int lastDeleteBtnTop;private View mView;private View mDeleteView;private Point mViewCenter;private static final double PI = 3.14159265359;public PushBtnTouchListener(View mView, View mDeleteView) {this.mView = mView;this.mDeleteView = mDeleteView;}private FrameLayout.LayoutParams pushBtnLP;private FrameLayout.LayoutParams imgLP;private FrameLayout.LayoutParams deleteBtnLP;float lastX = -1;float lastY = -1;@Overridepublic boolean onTouch(View pushView, MotionEvent event) {switch (event.getAction() & MotionEvent.ACTION_MASK) {// 主点按下case MotionEvent.ACTION_DOWN:pushBtnLP = (FrameLayout.LayoutParams) pushView.getLayoutParams();imgLP = (FrameLayout.LayoutParams) mView.getLayoutParams();deleteBtnLP = (FrameLayout.LayoutParams) mDeleteView.getLayoutParams();pushPoint = getPushPoint(pushBtnLP, event);lastImgWidth = imgLP.width;lastImgHeight = imgLP.height;lastImgLeft = imgLP.leftMargin;lastImgTop = imgLP.topMargin;lastImgAngle = (int) mView.getRotation();lastPushBtnLeft = pushBtnLP.leftMargin;lastPushBtnTop = pushBtnLP.topMargin;lastDeleteBtnLeft = deleteBtnLP.leftMargin;lastDeleteBtnTop = deleteBtnLP.topMargin;deleteImageWidth = deleteBtnLP.width;deleteImageHeight = deleteBtnLP.height;pushImgWidth = pushBtnLP.width;pushImgHeight = pushBtnLP.height;lastX = event.getRawX();lastY = event.getRawY();refreshImageCenter();break;// 副点按下case MotionEvent.ACTION_POINTER_DOWN:break;case MotionEvent.ACTION_UP: {break;}case MotionEvent.ACTION_POINTER_UP:break;case MotionEvent.ACTION_MOVE:float rawX = event.getRawX();float rawY = event.getRawY();if (lastX != -1) {if (Math.abs(rawX - lastX) < 5 && Math.abs(rawY - lastY) < 5) {return false;}}lastX = rawX;lastY = rawY;Point O = mViewCenter, A = pushPoint, B = getPushPoint(pushBtnLP, event);float dOA = getDistance(O, A);float dOB = getDistance(O, B);float f = dOB / dOA;int newWidth = (int) (lastImgWidth * f);int newHeight = (int) (lastImgHeight * f);mView.setTag(R.id.single_finger_view_scale, f);imgLP.leftMargin = lastImgLeft - ((newWidth - lastImgWidth) / 2);imgLP.topMargin = lastImgTop - ((newHeight - lastImgHeight) / 2);imgLP.width = newWidth;imgLP.height = newHeight;mView.setLayoutParams(imgLP);float fz = (((A.x - O.x) * (B.x - O.x)) + ((A.y - O.y) * (B.y - O.y)));float fm = dOA * dOB;double comAngle = (180 * Math.acos(fz / fm) / PI);if (Double.isNaN(comAngle)) {comAngle = (lastComAngle < 90 || lastComAngle > 270) ? 0 : 180;} else if ((B.y - O.y) * (A.x - O.x) < (A.y - O.y) * (B.x - O.x)) {comAngle = 360 - comAngle;}lastComAngle = comAngle;float angle = (float) (lastImgAngle + comAngle);angle = angle % 360;mView.setRotation(angle);Point imageRB = new Point(mView.getLeft() + mView.getWidth(), mView.getTop() + mView.getHeight());Point anglePoint = getAnglePoint(O, imageRB, angle);Point deleteAnglePoint = getAnglePoint1(O , imageRB, angle);pushBtnLP.leftMargin = (int) (anglePoint.x - pushImgWidth / 2);pushBtnLP.topMargin = (int) (anglePoint.y - pushImgHeight / 2);pushView.setLayoutParams(pushBtnLP);deleteBtnLP.leftMargin = (int) (deleteAnglePoint.x - deleteImageWidth / 2);deleteBtnLP.topMargin = (int) (deleteAnglePoint.y - deleteImageHeight / 2);mDeleteView.setLayoutParams(deleteBtnLP);break;}return false;}private void refreshImageCenter() {int x = mView.getLeft() + mView.getWidth() / 2;int y = mView.getTop() + mView.getHeight() / 2;mViewCenter = new Point(x, y);}private Point getPushPoint(FrameLayout.LayoutParams lp, MotionEvent event) {return new Point(lp.leftMargin + (int) event.getX(), lp.topMargin + (int) event.getY());}private float getDistance(Point a, Point b) {float v = ((a.x - b.x) * (a.x - b.x)) + ((a.y - b.y) * (a.y - b.y));return ((int) (Math.sqrt(v) * 100)) / 100f;}private Point getAnglePoint(Point O, Point A, float angle) {int x, y;float dOA = getDistance(O, A);double p1 = angle * PI / 180f;double p2 = Math.acos((A.x - O.x) / dOA);x = (int) (O.x + dOA * Math.cos(p1 + p2));double p3 = Math.acos((A.x - O.x) / dOA);y = (int) (O.y + dOA * Math.sin(p1 + p3));return new Point(x, y);}private Point getAnglePoint1(Point O, Point A, float angle) {int x, y;float dOA = getDistance(O, A);double p1 = angle * PI / 180f;double p2 = Math.acos((A.x - O.x) / dOA);x = (int) (O.x - dOA * Math.cos(p1 + p2));double p3 = Math.acos((A.x - O.x) / dOA);y = (int) (O.y - dOA * Math.sin(p1 + p3));return new Point(x, y);}}
ViewOnTouchListener
import android.view.MotionEvent;import android.view.View;import android.widget.FrameLayout;public class ViewOnTouchListener implements View.OnTouchListener {Point pushPoint;int lastImgLeft;int lastImgTop;int lastImgRight;int lastImgBottom;FrameLayout.LayoutParams viewLP;FrameLayout.LayoutParams pushBtnLP;FrameLayout.LayoutParams deleteBtnLP;int lastPushBtnLeft;int lastPushBtnTop;int lastDeleteBtnLeft;int lastDeleteBtnTop;private View mPushView;private View mDeleteView;int maxX;int maxY;float moveX;float moveY;public ViewOnTouchListener(View mPushView, View mDeleteView, int maxX, int maxY) {this.mPushView = mPushView;this.mDeleteView = mDeleteView;this.maxX = maxX;this.maxY = maxY;}@Overridepublic boolean onTouch(View view, MotionEvent event) {switch (event.getAction() & MotionEvent.ACTION_MASK) {case MotionEvent.ACTION_DOWN:mPushView.setVisibility(View.VISIBLE);mDeleteView.setVisibility(View.VISIBLE);if (null == viewLP) {viewLP = (FrameLayout.LayoutParams) view.getLayoutParams();}if (null == pushBtnLP) {pushBtnLP = (FrameLayout.LayoutParams) mPushView.getLayoutParams();}if (null == deleteBtnLP) {deleteBtnLP = (FrameLayout.LayoutParams) mDeleteView.getLayoutParams();}pushPoint = getRawPoint(event);lastImgLeft = viewLP.leftMargin;lastImgTop = viewLP.topMargin;lastImgRight = viewLP.rightMargin;lastImgBottom = viewLP.bottomMargin;lastPushBtnLeft = pushBtnLP.leftMargin;lastPushBtnTop = pushBtnLP.topMargin;lastDeleteBtnLeft = deleteBtnLP.leftMargin;lastDeleteBtnTop = deleteBtnLP.topMargin;return true;case MotionEvent.ACTION_MOVE:Point newPoint = getRawPoint(event);moveX = newPoint.x - pushPoint.x;moveY = newPoint.y - pushPoint.y;if (lastImgLeft + moveX <= 0 - viewLP.width/2) {return true;} else if (lastImgLeft + viewLP.width + moveX > maxX + viewLP.width/2) {return true;}if (lastImgTop + moveY <= 0 - viewLP.height/2) {return true;} else if (lastImgTop + viewLP.height + moveY > maxY + viewLP.height/2) {return true;}viewLP.leftMargin = (int) (lastImgLeft + moveX);viewLP.topMargin = (int) (lastImgTop + moveY);view.setLayoutParams(viewLP);pushBtnLP.leftMargin = (int) (lastPushBtnLeft + moveX);pushBtnLP.topMargin = (int) (lastPushBtnTop + moveY);mPushView.setLayoutParams(pushBtnLP);deleteBtnLP.leftMargin = (int) (lastDeleteBtnLeft + moveX);deleteBtnLP.topMargin = (int) (lastDeleteBtnTop + moveY);mDeleteView.setLayoutParams(deleteBtnLP);break;}return false;}private Point getRawPoint(MotionEvent event) {return new Point((int) event.getRawX(), (int) event.getRawY());}}
2.Git配置多个SSH key
ssh-add ~/.ssh/id_rsa_two
ssh-agent bash

