遇到的问题及其解决方案

1.简单的view旋转移动拖拽

PasterView

  1. public class PasterView extends LinearLayout {
  2. public ImageView mView;
  3. private ImageView mPushView;
  4. private ImageView mDeleteView;
  5. private float _1dp;
  6. private boolean mCenterInParent;
  7. private Drawable mImageDrawable, mPushImageDrawable, mDeleteImageDrawable;
  8. private float mImageHeight, mImageWidth, mPushImageHeight, mPushImageWidth, mDeleteImageHeight, mDeleteImageWidth;
  9. public int mLeft = 0, mTop = 0;
  10. private boolean mIconVisibility = true;
  11. /**
  12. * callback interface to be invoked when the delete icon has clicked
  13. */
  14. private OnPasterDeleteIconClickListener mOnPasterDeleteIconClickListener;
  15. /**
  16. * callback interface to be invoked when the image view has clicked
  17. */
  18. private OnImageViewClickListener mOnImageViewClickListener;
  19. public PasterView(Context context) {
  20. this(context, null, 0);
  21. }
  22. public PasterView(Context context, AttributeSet attrs) {
  23. this(context, attrs, 0);
  24. }
  25. public PasterView(Context context, AttributeSet attrs, int defStyle) {
  26. super(context, attrs, defStyle);
  27. this._1dp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, context.getResources().getDisplayMetrics());
  28. this.parseAttr(context, attrs);
  29. View mRoot = View.inflate(context, R.layout.test_image_view, null);
  30. addView(mRoot, -1, -1);
  31. mPushView = (ImageView) mRoot.findViewById(R.id.push_view);
  32. mView = (ImageView) mRoot.findViewById(R.id.view);
  33. mView.setTag(R.id.single_finger_view_scale, (float)1.0);
  34. mDeleteView = (ImageView) mRoot.findViewById(R.id.delete_view);
  35. mPushView.setOnTouchListener(new PushBtnTouchListener(mView, mDeleteView));
  36. WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
  37. mView.setOnTouchListener(new ViewOnTouchListener(mPushView, mDeleteView, wm.getDefaultDisplay().getWidth(), wm.getDefaultDisplay().getHeight()));
  38. mDeleteView.setOnClickListener(new OnClickListener() {
  39. @Override
  40. public void onClick(View v) {
  41. deletePasterImage();
  42. }
  43. });
  44. }
  45. public void showIconAndBorder() {
  46. if (null != mDeleteView) {
  47. mDeleteView.setVisibility(View.VISIBLE);
  48. }
  49. if (null != mPushView) {
  50. mPushView.setVisibility(View.VISIBLE);
  51. }
  52. if (null != mView) {
  53. mView.setBackgroundDrawable(getContext().getResources().getDrawable(R.drawable.paster_image_border));
  54. }
  55. mIconVisibility = true;
  56. }
  57. private void parseAttr(Context context, AttributeSet attrs) {
  58. if (null == attrs) return;
  59. TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PasterView);
  60. if (a != null) {
  61. int n = a.getIndexCount();
  62. for (int i = 0; i < n; i++) {
  63. int attr = a.getIndex(i);
  64. if (attr == R.styleable.PasterView_centerInParent) {
  65. this.mCenterInParent = a.getBoolean(attr, false);
  66. } else if (attr == R.styleable.PasterView_image) {
  67. this.mImageDrawable = a.getDrawable(attr);
  68. } else if (attr == R.styleable.PasterView_image_height) {
  69. this.mImageHeight = a.getDimension(attr, 200 * _1dp);
  70. } else if (attr == R.styleable.PasterView_image_width) {
  71. this.mImageWidth = a.getDimension(attr, 200 * _1dp);
  72. } else if (attr == R.styleable.PasterView_push_image) {
  73. this.mPushImageDrawable = a.getDrawable(attr);
  74. } else if (attr == R.styleable.PasterView_push_image_width) {
  75. this.mPushImageWidth = a.getDimension(attr, 50 * _1dp);
  76. } else if (attr == R.styleable.PasterView_push_image_height) {
  77. this.mPushImageHeight = a.getDimension(attr, 50 * _1dp);
  78. } else if (attr == R.styleable.PasterView_left) {
  79. this.mLeft = (int) a.getDimension(attr, 0 * _1dp);
  80. } else if (attr == R.styleable.PasterView_top) {
  81. this.mTop = (int) a.getDimension(attr, 0 * _1dp);
  82. } else if (attr == R.styleable.PasterView_delete_image) {
  83. this.mDeleteImageDrawable = a.getDrawable(attr);
  84. } else if (attr == R.styleable.PasterView_delete_image_width) {
  85. this.mDeleteImageWidth = a.getDimension(attr, 50 * _1dp);
  86. } else if (attr == R.styleable.PasterView_delete_image_height) {
  87. this.mDeleteImageHeight = a.getDimension(attr, 50 * _1dp);
  88. }
  89. }
  90. }
  91. }
  92. private void setViewToAttr(int pWidth, int pHeight) {
  93. if (null != mImageDrawable) {
  94. this.mView.setBackgroundDrawable(mImageDrawable);
  95. }
  96. if (null != mPushImageDrawable) {
  97. this.mPushView.setBackgroundDrawable(mPushImageDrawable);
  98. }
  99. if (null != mDeleteImageDrawable) {
  100. this.mDeleteView.setBackgroundDrawable(mDeleteImageDrawable);
  101. }
  102. FrameLayout.LayoutParams viewLP = (FrameLayout.LayoutParams) this.mView.getLayoutParams();
  103. viewLP.width = (int) mImageWidth;
  104. viewLP.height = (int) mImageHeight;
  105. int left = 0, top = 0;
  106. if (mCenterInParent) {
  107. left = pWidth / 2 - viewLP.width / 2;
  108. top = pHeight / 2 - viewLP.height / 2;
  109. } else {
  110. if (mLeft > 0) left = mLeft;
  111. if (mTop > 0) top = mTop;
  112. }
  113. viewLP.leftMargin = left;
  114. viewLP.topMargin = top;
  115. this.mView.setLayoutParams(viewLP);
  116. FrameLayout.LayoutParams pushViewLP = (FrameLayout.LayoutParams) mPushView.getLayoutParams();
  117. pushViewLP.width = (int) mPushImageWidth;
  118. pushViewLP.height = (int) mPushImageHeight;
  119. pushViewLP.leftMargin = (int) (viewLP.leftMargin + mImageWidth - mPushImageWidth / 2);
  120. pushViewLP.topMargin = (int) (viewLP.topMargin + mImageHeight - mPushImageHeight / 2);
  121. mPushView.setLayoutParams(pushViewLP);
  122. FrameLayout.LayoutParams deleteViewLP = (FrameLayout.LayoutParams) mDeleteView.getLayoutParams();
  123. deleteViewLP.width = (int) mDeleteImageWidth;
  124. deleteViewLP.height = (int) mDeleteImageHeight;
  125. deleteViewLP.leftMargin = (int) (viewLP.leftMargin - mDeleteImageWidth / 2);
  126. deleteViewLP.topMargin = (int) (viewLP.topMargin - mDeleteImageHeight / 2);
  127. mDeleteView.setLayoutParams(deleteViewLP);
  128. }
  129. @Override
  130. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  131. super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  132. setParamsForView(widthMeasureSpec, heightMeasureSpec);
  133. }
  134. private boolean hasSetParamsForView = false;
  135. private void setParamsForView(int widthMeasureSpec, int heightMeasureSpec) {
  136. ViewGroup.LayoutParams layoutParams = getLayoutParams();
  137. if (null != layoutParams && !hasSetParamsForView) {
  138. hasSetParamsForView = true;
  139. int width;
  140. if ((getLayoutParams().width == LayoutParams.MATCH_PARENT)) {
  141. width = MeasureSpec.getSize(widthMeasureSpec);
  142. } else {
  143. width = getLayoutParams().width;
  144. }
  145. int height;
  146. if ((getLayoutParams().height == LayoutParams.MATCH_PARENT)) {
  147. height = MeasureSpec.getSize(heightMeasureSpec);
  148. } else {
  149. height = getLayoutParams().height;
  150. }
  151. setViewToAttr(width, height);
  152. Log.d("tag", "width :" + width + " height :" + height);
  153. }
  154. }
  155. /**
  156. * Interface definition for a callback to be invoked when the delete icon has clicked.
  157. */
  158. public interface OnPasterDeleteIconClickListener {
  159. /***
  160. * callback method to be invoked when the delete icon has clicked
  161. */
  162. public void onDeleteIconClick(PasterView singleFingerView);
  163. }
  164. /**
  165. * Interface definition for a callback to be invoked when the image view has clicked
  166. */
  167. public interface OnImageViewClickListener {
  168. /**
  169. * callback method to be invoked when the image view has clicked
  170. */
  171. public void onImageViewClick(PasterView singleFingerView);
  172. }
  173. /**
  174. * call to delete the icon
  175. */
  176. public void deletePasterImage() {
  177. //if the delete icon clicked then notify listener if there is one
  178. if (mOnPasterDeleteIconClickListener != null) {
  179. mOnPasterDeleteIconClickListener.onDeleteIconClick(this);
  180. }
  181. }
  182. /**
  183. * call to change the index of imageview
  184. */
  185. public void changeViewIndexToTop() {
  186. //if the view clicked then notify listener if there is one
  187. if (mOnImageViewClickListener != null) {
  188. mOnImageViewClickListener.onImageViewClick(this);
  189. }
  190. }
  191. }

Point

  1. public class Point {
  2. public float x;
  3. public float y;
  4. public Point(float x, float y) {
  5. this.x = x;
  6. this.y = y;
  7. }
  8. @Override
  9. public String toString() {
  10. return "x: " + x + ",y: " + y;
  11. }
  12. }

PushBtnTouchListener

  1. import android.view.MotionEvent;
  2. import android.view.View;
  3. import android.widget.FrameLayout;
  4. import com.warpath.pasterview.R;
  5. class PushBtnTouchListener implements View.OnTouchListener {
  6. Point pushPoint;
  7. int lastImgWidth;
  8. int lastImgHeight;
  9. int lastImgLeft;
  10. int lastImgTop;
  11. int lastImgAngle;
  12. double lastComAngle;
  13. int pushImgWidth;
  14. int pushImgHeight;
  15. int deleteImageWidth;
  16. int deleteImageHeight;
  17. int lastPushBtnLeft;
  18. int lastPushBtnTop;
  19. int lastDeleteBtnLeft;
  20. int lastDeleteBtnTop;
  21. private View mView;
  22. private View mDeleteView;
  23. private Point mViewCenter;
  24. private static final double PI = 3.14159265359;
  25. public PushBtnTouchListener(View mView, View mDeleteView) {
  26. this.mView = mView;
  27. this.mDeleteView = mDeleteView;
  28. }
  29. private FrameLayout.LayoutParams pushBtnLP;
  30. private FrameLayout.LayoutParams imgLP;
  31. private FrameLayout.LayoutParams deleteBtnLP;
  32. float lastX = -1;
  33. float lastY = -1;
  34. @Override
  35. public boolean onTouch(View pushView, MotionEvent event) {
  36. switch (event.getAction() & MotionEvent.ACTION_MASK) {
  37. // 主点按下
  38. case MotionEvent.ACTION_DOWN:
  39. pushBtnLP = (FrameLayout.LayoutParams) pushView.getLayoutParams();
  40. imgLP = (FrameLayout.LayoutParams) mView.getLayoutParams();
  41. deleteBtnLP = (FrameLayout.LayoutParams) mDeleteView.getLayoutParams();
  42. pushPoint = getPushPoint(pushBtnLP, event);
  43. lastImgWidth = imgLP.width;
  44. lastImgHeight = imgLP.height;
  45. lastImgLeft = imgLP.leftMargin;
  46. lastImgTop = imgLP.topMargin;
  47. lastImgAngle = (int) mView.getRotation();
  48. lastPushBtnLeft = pushBtnLP.leftMargin;
  49. lastPushBtnTop = pushBtnLP.topMargin;
  50. lastDeleteBtnLeft = deleteBtnLP.leftMargin;
  51. lastDeleteBtnTop = deleteBtnLP.topMargin;
  52. deleteImageWidth = deleteBtnLP.width;
  53. deleteImageHeight = deleteBtnLP.height;
  54. pushImgWidth = pushBtnLP.width;
  55. pushImgHeight = pushBtnLP.height;
  56. lastX = event.getRawX();
  57. lastY = event.getRawY();
  58. refreshImageCenter();
  59. break;
  60. // 副点按下
  61. case MotionEvent.ACTION_POINTER_DOWN:
  62. break;
  63. case MotionEvent.ACTION_UP: {
  64. break;
  65. }
  66. case MotionEvent.ACTION_POINTER_UP:
  67. break;
  68. case MotionEvent.ACTION_MOVE:
  69. float rawX = event.getRawX();
  70. float rawY = event.getRawY();
  71. if (lastX != -1) {
  72. if (Math.abs(rawX - lastX) < 5 && Math.abs(rawY - lastY) < 5) {
  73. return false;
  74. }
  75. }
  76. lastX = rawX;
  77. lastY = rawY;
  78. Point O = mViewCenter, A = pushPoint, B = getPushPoint(pushBtnLP, event);
  79. float dOA = getDistance(O, A);
  80. float dOB = getDistance(O, B);
  81. float f = dOB / dOA;
  82. int newWidth = (int) (lastImgWidth * f);
  83. int newHeight = (int) (lastImgHeight * f);
  84. mView.setTag(R.id.single_finger_view_scale, f);
  85. imgLP.leftMargin = lastImgLeft - ((newWidth - lastImgWidth) / 2);
  86. imgLP.topMargin = lastImgTop - ((newHeight - lastImgHeight) / 2);
  87. imgLP.width = newWidth;
  88. imgLP.height = newHeight;
  89. mView.setLayoutParams(imgLP);
  90. float fz = (((A.x - O.x) * (B.x - O.x)) + ((A.y - O.y) * (B.y - O.y)));
  91. float fm = dOA * dOB;
  92. double comAngle = (180 * Math.acos(fz / fm) / PI);
  93. if (Double.isNaN(comAngle)) {
  94. comAngle = (lastComAngle < 90 || lastComAngle > 270) ? 0 : 180;
  95. } else if ((B.y - O.y) * (A.x - O.x) < (A.y - O.y) * (B.x - O.x)) {
  96. comAngle = 360 - comAngle;
  97. }
  98. lastComAngle = comAngle;
  99. float angle = (float) (lastImgAngle + comAngle);
  100. angle = angle % 360;
  101. mView.setRotation(angle);
  102. Point imageRB = new Point(mView.getLeft() + mView.getWidth(), mView.getTop() + mView.getHeight());
  103. Point anglePoint = getAnglePoint(O, imageRB, angle);
  104. Point deleteAnglePoint = getAnglePoint1(O , imageRB, angle);
  105. pushBtnLP.leftMargin = (int) (anglePoint.x - pushImgWidth / 2);
  106. pushBtnLP.topMargin = (int) (anglePoint.y - pushImgHeight / 2);
  107. pushView.setLayoutParams(pushBtnLP);
  108. deleteBtnLP.leftMargin = (int) (deleteAnglePoint.x - deleteImageWidth / 2);
  109. deleteBtnLP.topMargin = (int) (deleteAnglePoint.y - deleteImageHeight / 2);
  110. mDeleteView.setLayoutParams(deleteBtnLP);
  111. break;
  112. }
  113. return false;
  114. }
  115. private void refreshImageCenter() {
  116. int x = mView.getLeft() + mView.getWidth() / 2;
  117. int y = mView.getTop() + mView.getHeight() / 2;
  118. mViewCenter = new Point(x, y);
  119. }
  120. private Point getPushPoint(FrameLayout.LayoutParams lp, MotionEvent event) {
  121. return new Point(lp.leftMargin + (int) event.getX(), lp.topMargin + (int) event.getY());
  122. }
  123. private float getDistance(Point a, Point b) {
  124. float v = ((a.x - b.x) * (a.x - b.x)) + ((a.y - b.y) * (a.y - b.y));
  125. return ((int) (Math.sqrt(v) * 100)) / 100f;
  126. }
  127. private Point getAnglePoint(Point O, Point A, float angle) {
  128. int x, y;
  129. float dOA = getDistance(O, A);
  130. double p1 = angle * PI / 180f;
  131. double p2 = Math.acos((A.x - O.x) / dOA);
  132. x = (int) (O.x + dOA * Math.cos(p1 + p2));
  133. double p3 = Math.acos((A.x - O.x) / dOA);
  134. y = (int) (O.y + dOA * Math.sin(p1 + p3));
  135. return new Point(x, y);
  136. }
  137. private Point getAnglePoint1(Point O, Point A, float angle) {
  138. int x, y;
  139. float dOA = getDistance(O, A);
  140. double p1 = angle * PI / 180f;
  141. double p2 = Math.acos((A.x - O.x) / dOA);
  142. x = (int) (O.x - dOA * Math.cos(p1 + p2));
  143. double p3 = Math.acos((A.x - O.x) / dOA);
  144. y = (int) (O.y - dOA * Math.sin(p1 + p3));
  145. return new Point(x, y);
  146. }
  147. }

ViewOnTouchListener

  1. import android.view.MotionEvent;
  2. import android.view.View;
  3. import android.widget.FrameLayout;
  4. public class ViewOnTouchListener implements View.OnTouchListener {
  5. Point pushPoint;
  6. int lastImgLeft;
  7. int lastImgTop;
  8. int lastImgRight;
  9. int lastImgBottom;
  10. FrameLayout.LayoutParams viewLP;
  11. FrameLayout.LayoutParams pushBtnLP;
  12. FrameLayout.LayoutParams deleteBtnLP;
  13. int lastPushBtnLeft;
  14. int lastPushBtnTop;
  15. int lastDeleteBtnLeft;
  16. int lastDeleteBtnTop;
  17. private View mPushView;
  18. private View mDeleteView;
  19. int maxX;
  20. int maxY;
  21. float moveX;
  22. float moveY;
  23. public ViewOnTouchListener(View mPushView, View mDeleteView, int maxX, int maxY) {
  24. this.mPushView = mPushView;
  25. this.mDeleteView = mDeleteView;
  26. this.maxX = maxX;
  27. this.maxY = maxY;
  28. }
  29. @Override
  30. public boolean onTouch(View view, MotionEvent event) {
  31. switch (event.getAction() & MotionEvent.ACTION_MASK) {
  32. case MotionEvent.ACTION_DOWN:
  33. mPushView.setVisibility(View.VISIBLE);
  34. mDeleteView.setVisibility(View.VISIBLE);
  35. if (null == viewLP) {
  36. viewLP = (FrameLayout.LayoutParams) view.getLayoutParams();
  37. }
  38. if (null == pushBtnLP) {
  39. pushBtnLP = (FrameLayout.LayoutParams) mPushView.getLayoutParams();
  40. }
  41. if (null == deleteBtnLP) {
  42. deleteBtnLP = (FrameLayout.LayoutParams) mDeleteView.getLayoutParams();
  43. }
  44. pushPoint = getRawPoint(event);
  45. lastImgLeft = viewLP.leftMargin;
  46. lastImgTop = viewLP.topMargin;
  47. lastImgRight = viewLP.rightMargin;
  48. lastImgBottom = viewLP.bottomMargin;
  49. lastPushBtnLeft = pushBtnLP.leftMargin;
  50. lastPushBtnTop = pushBtnLP.topMargin;
  51. lastDeleteBtnLeft = deleteBtnLP.leftMargin;
  52. lastDeleteBtnTop = deleteBtnLP.topMargin;
  53. return true;
  54. case MotionEvent.ACTION_MOVE:
  55. Point newPoint = getRawPoint(event);
  56. moveX = newPoint.x - pushPoint.x;
  57. moveY = newPoint.y - pushPoint.y;
  58. if (lastImgLeft + moveX <= 0 - viewLP.width/2) {
  59. return true;
  60. } else if (lastImgLeft + viewLP.width + moveX > maxX + viewLP.width/2) {
  61. return true;
  62. }
  63. if (lastImgTop + moveY <= 0 - viewLP.height/2) {
  64. return true;
  65. } else if (lastImgTop + viewLP.height + moveY > maxY + viewLP.height/2) {
  66. return true;
  67. }
  68. viewLP.leftMargin = (int) (lastImgLeft + moveX);
  69. viewLP.topMargin = (int) (lastImgTop + moveY);
  70. view.setLayoutParams(viewLP);
  71. pushBtnLP.leftMargin = (int) (lastPushBtnLeft + moveX);
  72. pushBtnLP.topMargin = (int) (lastPushBtnTop + moveY);
  73. mPushView.setLayoutParams(pushBtnLP);
  74. deleteBtnLP.leftMargin = (int) (lastDeleteBtnLeft + moveX);
  75. deleteBtnLP.topMargin = (int) (lastDeleteBtnTop + moveY);
  76. mDeleteView.setLayoutParams(deleteBtnLP);
  77. break;
  78. }
  79. return false;
  80. }
  81. private Point getRawPoint(MotionEvent event) {
  82. return new Point((int) event.getRawX(), (int) event.getRawY());
  83. }
  84. }

ezgif-1124892373.gif

2.Git配置多个SSH key

ssh-add ~/.ssh/id_rsa_two
ssh-agent bash