转载请表明出处:http://blog.csdn.net/lmj623565791/article/details/39761281,本文出自:【张鸿洋的博客】

1、概述

前面已经写了关于检测手势识别的文章,如果不了解可以参考:Android 手势检测实战 打造支持缩放平移的图片预览效果(下)。首先本篇文章,将对之前博客的ZoomImageView代码进行些许的修改与改善,然后用到我们的本篇博客中去,实现仿微信的头像截取功能,当然了,个人觉得微信的截取头像功能貌似做得不太好,本篇博客准备去其糟粕,取其精华;最后还会见识到不一样的自定义控件的方式,也是在本人博客中首次出现,如果有兴趣可以读完本篇博客,希望可以启到抛砖引玉的效果。

2、效果分析

1、效果图:

我们来看看妹子的项链,嗯,妹子项链还是不错的~

2、效果分析

根据上面的效果,我们目测需要自定义两个控件,一个就是我们的可自由缩放移动的ImageView,一个就是那个白色的边框;然后一起放置到一个RelativeLayout中;最后对外公布一个裁剪的方法,返回一个Bitmap;

暂时的分析就这样,下面我们来写代码~

首先是白色框框那个自定义View,我们叫做ClipImageBorderView

3、ClipImageBorderView

分析下这个View,其实就是根据在屏幕中绘制一个正方形,正方形区域以外为半透明,绘制这个正方形需要与屏幕左右边距有个边距。

我们准备按如下图绘制:

按顺序在View的onDraw里面绘制上图中:1、2、3、4,四个半透明的区域,然后在中间正方形区域绘制一个正方形

下面看下代码:

  1. package com.zhy.view;
  2. import android.content.Context;
  3. import android.graphics.Canvas;
  4. import android.graphics.Color;
  5. import android.graphics.Paint;
  6. import android.graphics.Paint.Style;
  7. import android.util.AttributeSet;
  8. import android.util.TypedValue;
  9. import android.view.View;
  10. /**
  11. * @author zhy
  12. *
  13. */
  14. public class ClipImageBorderView extends View
  15. {
  16. /**
  17. * 水平方向与View的边距
  18. */
  19. private int mHorizontalPadding = 20;
  20. /**
  21. * 垂直方向与View的边距
  22. */
  23. private int mVerticalPadding;
  24. /**
  25. * 绘制的矩形的宽度
  26. */
  27. private int mWidth;
  28. /**
  29. * 边框的颜色,默认为白色
  30. */
  31. private int mBorderColor = Color.parseColor("#FFFFFF");
  32. /**
  33. * 边框的宽度 单位dp
  34. */
  35. private int mBorderWidth = 1;
  36. private Paint mPaint;
  37. public ClipImageBorderView(Context context)
  38. {
  39. this(context, null);
  40. }
  41. public ClipImageBorderView(Context context, AttributeSet attrs)
  42. {
  43. this(context, attrs, 0);
  44. }
  45. public ClipImageBorderView(Context context, AttributeSet attrs, int defStyle)
  46. {
  47. super(context, attrs, defStyle);
  48. // 计算padding的px
  49. mHorizontalPadding = (int) TypedValue.applyDimension(
  50. TypedValue.COMPLEX_UNIT_DIP, mHorizontalPadding, getResources()
  51. .getDisplayMetrics());
  52. mBorderWidth = (int) TypedValue.applyDimension(
  53. TypedValue.COMPLEX_UNIT_DIP, mBorderWidth, getResources()
  54. .getDisplayMetrics());
  55. mPaint = new Paint();
  56. mPaint.setAntiAlias(true);
  57. }
  58. @Override
  59. protected void onDraw(Canvas canvas)
  60. {
  61. super.onDraw(canvas);
  62. //计算矩形区域的宽度
  63. mWidth = getWidth() - 2 * mHorizontalPadding;
  64. //计算距离屏幕垂直边界 的边距
  65. mVerticalPadding = (getHeight() - mWidth) / 2;
  66. mPaint.setColor(Color.parseColor("#aa000000"));
  67. mPaint.setStyle(Style.FILL);
  68. // 绘制左边1
  69. canvas.drawRect(0, 0, mHorizontalPadding, getHeight(), mPaint);
  70. // 绘制右边2
  71. canvas.drawRect(getWidth() - mHorizontalPadding, 0, getWidth(),
  72. getHeight(), mPaint);
  73. // 绘制上边3
  74. canvas.drawRect(mHorizontalPadding, 0, getWidth() - mHorizontalPadding,
  75. mVerticalPadding, mPaint);
  76. // 绘制下边4
  77. canvas.drawRect(mHorizontalPadding, getHeight() - mVerticalPadding,
  78. getWidth() - mHorizontalPadding, getHeight(), mPaint);
  79. // 绘制外边框
  80. mPaint.setColor(mBorderColor);
  81. mPaint.setStrokeWidth(mBorderWidth);
  82. mPaint.setStyle(Style.STROKE);
  83. canvas.drawRect(mHorizontalPadding, mVerticalPadding, getWidth()
  84. - mHorizontalPadding, getHeight() - mVerticalPadding, mPaint);
  85. }
  86. }

我们直接预设了一个水平方向的边距,根据边距计算出正方形的边长,接下来就是按照上图分别会1、2、3、4四个区域,最后就是绘制我们的正方形~~

代码还是很简单的~~我们的ClipImageBorderView就搞定了,我们决定来测试一下:

布局文件:

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:background="@drawable/a"   >
  6. <com.zhy.view.ClipImageBorderView
  7. android:id="@+id/id_clipImageLayout"
  8. android:layout_width="fill_parent"
  9. android:layout_height="fill_parent" />
  10. </RelativeLayout>

效果图:

故意放了个背景,没撒用,就是为了能看出效果,可以看到我们的框框绘制的还是蛮不错的~~嗯,这个框框距离屏幕左右两侧的距离应该抽取出来,嗯,后面再说~

4、ClipZoomImageView

我们准备对我们原先的ZoomImageView进行简单的修改,修改的地方:
1、在onGlobalLayout方法中,如果图片的宽或者高只要一个小于我们的正方形的边长,我们会直接把较小的尺寸放大至正方形的边长;如果图片的宽和高都大于我们的正方形的边长,我们仅仅把图片移动到我们屏幕的中央,不做缩放处理;

2、根据步骤1,我们会获得初始的缩放比例(默认为1.0f),然后SCALE_MID , 与 SCALE_MAX 分别为2倍和4倍的初始化缩放比例。

3、图片在移动过程中的边界检测完全根据正方形的区域,图片不会在移动过程中与正方形区域产生内边距

4、对外公布一个裁切的方法

部分代码:

  1. /**
  2. * 水平方向与View的边距
  3. */
  4. private int mHorizontalPadding = 20;
  5. /**
  6. * 垂直方向与View的边距
  7. */
  8. private int mVerticalPadding;
  9. @Override
  10. public void onGlobalLayout()
  11. {
  12. if (once)
  13. {
  14. Drawable d = getDrawable();
  15. if (d == null)
  16. return;
  17. Log.e(TAG, d.getIntrinsicWidth() + " , " + d.getIntrinsicHeight());
  18. // 计算padding的px
  19. mHorizontalPadding = (int) TypedValue.applyDimension(
  20. TypedValue.COMPLEX_UNIT_DIP, mHorizontalPadding,
  21. getResources().getDisplayMetrics());
  22. // 垂直方向的边距
  23. mVerticalPadding = (getHeight() - (getWidth() - 2 * mHorizontalPadding)) / 2;
  24. int width = getWidth();
  25. int height = getHeight();
  26. // 拿到图片的宽和高
  27. int dw = d.getIntrinsicWidth();
  28. int dh = d.getIntrinsicHeight();
  29. float scale = 1.0f;
  30. if (dw < getWidth() - mHorizontalPadding * 2
  31. && dh > getHeight() - mVerticalPadding * 2)
  32. {
  33. scale = (getWidth() * 1.0f - mHorizontalPadding * 2) / dw;
  34. }
  35. if (dh < getHeight() - mVerticalPadding * 2
  36. && dw > getWidth() - mHorizontalPadding * 2)
  37. {
  38. scale = (getHeight() * 1.0f - mVerticalPadding * 2) / dh;
  39. }
  40. if (dw < getWidth() - mHorizontalPadding * 2
  41. && dh < getHeight() - mVerticalPadding * 2)
  42. {
  43. float scaleW = (getWidth() * 1.0f - mHorizontalPadding * 2)
  44. / dw;
  45. float scaleH = (getHeight() * 1.0f - mVerticalPadding * 2) / dh;
  46. scale = Math.max(scaleW, scaleH);
  47. }
  48. initScale = scale;
  49. SCALE_MID = initScale * 2;
  50. SCALE_MAX = initScale * 4;
  51. Log.e(TAG, "initScale = " + initScale);
  52. mScaleMatrix.postTranslate((width - dw) / 2, (height - dh) / 2);
  53. mScaleMatrix.postScale(scale, scale, getWidth() / 2,
  54. getHeight() / 2);
  55. // 图片移动至屏幕中心
  56. setImageMatrix(mScaleMatrix);
  57. once = false;
  58. }
  59. }
  60. /**
  61. * 剪切图片,返回剪切后的bitmap对象
  62. *
  63. * @return
  64. */
  65. public Bitmap clip()
  66. {
  67. Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(),
  68. Bitmap.Config.ARGB_8888);
  69. Canvas canvas = new Canvas(bitmap);
  70. draw(canvas);
  71. return Bitmap.createBitmap(bitmap, mHorizontalPadding,
  72. mVerticalPadding, getWidth() - 2 * mHorizontalPadding,
  73. getWidth() - 2 * mHorizontalPadding);
  74. }
  75. /**
  76. * 边界检测
  77. */
  78. private void checkBorder()
  79. {
  80. RectF rect = getMatrixRectF();
  81. float deltaX = 0;
  82. float deltaY = 0;
  83. int width = getWidth();
  84. int height = getHeight();
  85. // 如果宽或高大于屏幕,则控制范围
  86. if (rect.width() >= width - 2 * mHorizontalPadding)
  87. {
  88. if (rect.left > mHorizontalPadding)
  89. {
  90. deltaX = -rect.left + mHorizontalPadding;
  91. }
  92. if (rect.right < width - mHorizontalPadding)
  93. {
  94. deltaX = width - mHorizontalPadding - rect.right;
  95. }
  96. }
  97. if (rect.height() >= height - 2 * mVerticalPadding)
  98. {
  99. if (rect.top > mVerticalPadding)
  100. {
  101. deltaY = -rect.top + mVerticalPadding;
  102. }
  103. if (rect.bottom < height - mVerticalPadding)
  104. {
  105. deltaY = height - mVerticalPadding - rect.bottom;
  106. }
  107. }
  108. mScaleMatrix.postTranslate(deltaX, deltaY);
  109. }

这里贴出了改变的代码,完整的代码就不贴了,太长了,如果大家学习过前面的博客应该也会比较熟悉,若没有也没事,后面会提供源码。

贴代码的目的,第一让大家看下我们改变了哪些;第二,我想暴露出我们代码中的问题,我们设置了一个这样的变量:mHorizontalPadding = 20;这个是手动和ClipImageBorderView里面的成员变量mHorizontalPadding 写的一致,也就是说这个变量,两个自定义的View都需要使用且需要相同的值,目前我们的做法,写死且每个View各自定义一个。这种做法不用说,肯定不好,即使抽取成自定义属性,两个View都需要进行抽取,且用户在使用的时候,还需要设置为一样的值,总觉得有点强人所难~~

5、不一样的自定义控件

现在我们考虑下:易用性。目前为止,其实我们的效果已经实现了,但是需要用户这么写布局文件:

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:background="#aaaaaa" >
  6. <com.zhy.view.ZoomImageView
  7. android:id="@+id/id_zoomImageView"
  8. android:layout_width="fill_parent"
  9. android:layout_height="fill_parent"
  10. android:scaleType="matrix"
  11. android:src="@drawable/a" />
  12. <com.zhy.view.ClipImageView
  13. android:layout_width="fill_parent"
  14. android:layout_height="fill_parent" />
  15. </RelativeLayout>

然后这两个类中都有一个mHorizontalPadding变量,且值一样,上面也说过,即使抽取成自定义变量,也需要在布局文件中每个View中各写一次。so, we need change . 这样的耦合度太夸张了,且使用起来蹩脚。

于是乎,我决定把这两个控件想办法整到一起,用户使用时只需要声明一个控件:

怎么做呢,我们使用组合的思想来自定义控件,我们再声明一个控件,继承子RelativeLayout,然后在这个自定义RelativeLayout中通过代码添加这两个自定义的布局,并且设置一些公用的属性,具体我们就开始行动。

1、ClipImageLayout

我们自定义一个RelativeLayout叫做ClipImageLayout,用于放置我们的两个自定义View,并且由ClipImageLayout进行设置边距,然后传给它内部的两个View,这样的话,跟用户交互的就一个ClipImageLayout,用户只需要设置一次边距即可。

完整的ClipImageLayout代码:

  1. package com.zhy.view;
  2. import android.content.Context;
  3. import android.graphics.Bitmap;
  4. import android.util.AttributeSet;
  5. import android.util.TypedValue;
  6. import android.widget.RelativeLayout;
  7. import com.zhy.clippic.R;
  8. /**
  9. * zhy
  10. * @author zhy
  11. *
  12. */
  13. public class ClipImageLayout extends RelativeLayout
  14. {
  15. private ClipZoomImageView mZoomImageView;
  16. private ClipImageBorderView mClipImageView;
  17. /**
  18. * 这里测试,直接写死了大小,真正使用过程中,可以提取为自定义属性
  19. */
  20. private int mHorizontalPadding = 20;
  21. public ClipImageLayout(Context context, AttributeSet attrs)
  22. {
  23. super(context, attrs);
  24. mZoomImageView = new ClipZoomImageView(context);
  25. mClipImageView = new ClipImageBorderView(context);
  26. android.view.ViewGroup.LayoutParams lp = new LayoutParams(
  27. android.view.ViewGroup.LayoutParams.MATCH_PARENT,
  28. android.view.ViewGroup.LayoutParams.MATCH_PARENT);
  29. /**
  30. * 这里测试,直接写死了图片,真正使用过程中,可以提取为自定义属性
  31. */
  32. mZoomImageView.setImageDrawable(getResources().getDrawable(
  33. R.drawable.a));
  34. this.addView(mZoomImageView, lp);
  35. this.addView(mClipImageView, lp);
  36. // 计算padding的px
  37. mHorizontalPadding = (int) TypedValue.applyDimension(
  38. TypedValue.COMPLEX_UNIT_DIP, mHorizontalPadding, getResources()
  39. .getDisplayMetrics());
  40. mZoomImageView.setHorizontalPadding(mHorizontalPadding);
  41. mClipImageView.setHorizontalPadding(mHorizontalPadding);
  42. }
  43. /**
  44. * 对外公布设置边距的方法,单位为dp
  45. *
  46. * @param mHorizontalPadding
  47. */
  48. public void setHorizontalPadding(int mHorizontalPadding)
  49. {
  50. this.mHorizontalPadding = mHorizontalPadding;
  51. }
  52. /**
  53. * 裁切图片
  54. *
  55. * @return
  56. */
  57. public Bitmap clip()
  58. {
  59. return mZoomImageView.clip();
  60. }
  61. }

可以看到,现在用户需要使用头像裁切功能只需要声明下ClipImageLayout即可,完全避免了上述我们描述的问题,我们对用户屏蔽了两个真正实现的类。这个也是自定义控件的一种方式,希望可以借此抛砖引玉,大家能够更加合理的设计出自己的控件~~

好了,我们的ClipImageLayout搞定以后,下面看下如何使用~

6、用法

1、布局文件

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:background="#aaaaaa"   >
  6. <com.zhy.view.ClipImageLayout
  7. android:id="@+id/id_clipImageLayout"
  8. android:layout_width="fill_parent"
  9. android:layout_height="fill_parent" />
  10. </RelativeLayout>

2、MainActivity

  1. package com.zhy.clippic;
  2. import java.io.ByteArrayOutputStream;
  3. import android.app.Activity;
  4. import android.content.Intent;
  5. import android.graphics.Bitmap;
  6. import android.os.Bundle;
  7. import android.view.Menu;
  8. import android.view.MenuItem;
  9. import com.zhy.view.ClipImageLayout;
  10. public class MainActivity extends Activity
  11. {
  12. private ClipImageLayout mClipImageLayout;
  13. @Override
  14. protected void onCreate(Bundle savedInstanceState)
  15. {
  16. super.onCreate(savedInstanceState);
  17. setContentView(R.layout.activity_main);
  18. mClipImageLayout = (ClipImageLayout) findViewById(R.id.id_clipImageLayout);
  19. }
  20. @Override
  21. public boolean onCreateOptionsMenu(Menu menu)
  22. {
  23. getMenuInflater().inflate(R.menu.main, menu);
  24. return true;
  25. }
  26. @Override
  27. public boolean onOptionsItemSelected(MenuItem item)
  28. {
  29. switch (item.getItemId())
  30. {
  31. case R.id.id_action_clip:
  32. Bitmap bitmap = mClipImageLayout.clip();
  33. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  34. bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
  35. byte[] datas = baos.toByteArray();
  36. Intent intent = new Intent(this, ShowImageActivity.class);
  37. intent.putExtra("bitmap", datas);
  38. startActivity(intent);
  39. break;
  40. }
  41. return super.onOptionsItemSelected(item);
  42. }
  43. }

我们在menu里面体检了一个裁切的按钮,点击后把裁切好的图片传递给我们的ShowImageActivity

看一下眼menu的xml

  1. <menu xmlns:android="http://schemas.android.com/apk/res/android" >
  2. <item
  3. android:id="@+id/id_action_clip"
  4. android:icon="@drawable/actionbar_clip_icon"
  5. android:showAsAction="always|withText"
  6. android:title="裁切"/>
  7. </menu>

3、ShowImageActivity

  1. package com.zhy.clippic;
  2. import android.app.Activity;
  3. import android.graphics.Bitmap;
  4. import android.graphics.BitmapFactory;
  5. import android.os.Bundle;
  6. import android.widget.ImageView;
  7. public class ShowImageActivity extends Activity
  8. {
  9. private ImageView mImageView;
  10. @Override
  11. protected void onCreate(Bundle savedInstanceState)
  12. {
  13. super.onCreate(savedInstanceState);
  14. setContentView(R.layout.show);
  15. mImageView = (ImageView) findViewById(R.id.id_showImage);
  16. byte[] b = getIntent().getByteArrayExtra("bitmap");
  17. Bitmap bitmap = BitmapFactory.decodeByteArray(b, 0, b.length);
  18. if (bitmap != null)
  19. {
  20. mImageView.setImageBitmap(bitmap);
  21. }
  22. }
  23. }

layout/show.xml

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:background="#ffffff" >
  6. <ImageView
  7. android:id="@+id/id_showImage"
  8. android:layout_width="wrap_content"
  9. android:layout_height="wrap_content"
  10. android:layout_centerInParent="true"
  11. android:src="@drawable/tbug"
  12. />
  13. </RelativeLayout>

好了,到此我们的 高仿微信头像截取功能 就已经结束了~~希望大家可以从本篇博客中可以领悟到something~

最后我们把ClipImageLayout里面的mHorizontalPadding设置为50,贴个静态效果图~

ok ~~

源码点击下载

Android 高仿微信头像截取 打造不一样的自定义控件的更多相关文章

  1. 安卓高仿QQ头像截取升级版

    观看此篇文章前,请先阅读上篇文章:高仿QQ头像截取: 本篇之所以为升级版,是在截取头像界面添加了与qq类似的阴影层(裁剪区域以外的部分),且看效果图:   为了适应大家不同需求,这次打了两个包,及上图 ...

  2. 高仿QQ头像截取

    花费了半天时间,把 仿QQ头像截取的方法整理了下,并制作了一个demo以供大家参考,基本上实现了qq中我的资料界面上(包括背景透明化,上滑标题栏显示,下拉隐藏等)的大致效果,先上图看效果吧: 支持的功 ...

  3. Android 高仿微信6.0主界面 带你玩转切换图标变色

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/41087219,本文出自:[张鸿洋的博客] 1.概述 学习Android少不了模仿 ...

  4. Android 高仿微信语音聊天页面高斯模糊效果

    目前的应用市场上,使用毛玻璃效果的APP随处可见,比如用过微信语音聊天的人可以发现,语音聊天页面就使用了高斯模糊效果. 先看下效果图: 仔细观察上图,我们可以发现,背景图以用户头像为模板,对其进行了高 ...

  5. Android高仿微信(一)——如何消除启动时的白屏

    默认情况下,APP启动时会先把屏幕刷成白色,然后才绘制第一个Activity中的View,这两个步骤之间的延迟会造成启动后先看到白屏(时间大概为1秒左右).时间不长,但是我们也看到,一般的APP时不存 ...

  6. Android 高仿微信实时聊天 基于百度云推送

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38799363 ,本文出自:[张鸿洋的博客] 一直在仿微信界面,今天终于有幸利用百 ...

  7. android高仿微信拍照、多选、预览、删除(去除相片)相冊功能

    先声明授人与鱼不如授人与渔,仅仅能提供一个思路,当然须要源代码的同学能够私下有偿问我要源代码:QQ:508181017 工作了将近三年时间了,一直没正儿八经的研究系统自带的相冊和拍照,这回来个高仿微信 ...

  8. Android 高仿微信即时聊天 百度云为基础的推

    转载请注明出处:http://blog.csdn.net/lmj623565791/article/details/38799363 ,本文出自:[张鸿洋的博客] 一直在仿微信界面,今天最终有幸利用百 ...

  9. Android 高仿微信支付键盘

    现在很多app的支付.输入密码功能,都已经开始使用自定义数字键盘,不仅更加方便.其效果着实精致. 下面带着大家学习下,如何高仿微信的数字键盘,可以拿来直接用在自身的项目中. 先看下效果图: 1. 自定 ...

随机推荐

  1. Append加载动态轮播

    前几天遇到了些小麻烦,不过很快就解决了.之所以要记下来是因为作为一名前端的程序员,要理解页面的加载顺序是最重要的.要不然自己写程序意外的出现bug~~ 刚开始写利用Append的时候,利用火狐的fir ...

  2. Word01-从正文处开始插入页码

    一份正式的文档应该由以下几部分组成:封面.目录.摘要.正文…… 现在要求前三页不需要插入页码,从正文部分插入页码为第一页,原文档如下: 步骤: 第一步:将光标移动到摘要页的末尾,选择页面部局--> ...

  3. 服务 Service 基本介绍

    Activity public class MainActivity extends ListActivity {     private boolean flag;//是否开启线程     publ ...

  4. 附加数据库报错:无法打开物理文件 XXX.mdf",操作系统错误 5:"5(拒绝访问。)"

    今天在附加数据库的时候出现如图报错信息: 无法打开物理文件 XXX.mdf",操作系统错误 5:"5(拒绝访问.)"错信息如图:(是不是远程服务器数据库附加出现只读那个情 ...

  5. 不用标准库实现memmove,借助一个缓冲区temp,即使src和dest所指的内存有重叠也能正确拷贝

    void *mymemmove(void *dest,const void *src,size_t count) { char temp[count]; int i; char *d=(char *) ...

  6. git使用笔记(三)(图文说明) 图解提交更改内容的不同方式,涉及代码

    此步之前的工作和示例请参考以下帖子: git使用笔记(一)Git的下载与配置 git使用笔记(二) 如何把GitHub上项目同步到本地 -------------------------------- ...

  7. 校门外的树 - Grids2808

    校门外的树 问题描述: 某校大门外长度为 L 的马路上有一排树,每两棵相邻的树之间的间隔都是1 米.我们 可以把马路看成一个数轴,马路的一端在数轴0 的位置,另一端在L 的位置:数轴上的每 个整数点, ...

  8. “#ifdef __cplusplus extern "C" { #endif”的定义

    平时我们在linux c平台开发的时候,引用了一些Cpp或者C的代码库,发现一些头文件有如下代码条件编译. #ifdef __cplusplus extern "C" { #end ...

  9. RF学习过程中遇到的问题

    1.写了一个打开浏览器的用例,执行用例时报需要对应的浏览器驱动,此时应下载对应的浏览器驱动,把该执行文件放到python的安装根目录下,再执行用例就成功了 2.日志不见的问题:需要杀进程

  10. 较优H圈matlab实现

    大家好,我是小鸭酱,博客地址为:http://www.cnblogs.com/xiaoyajiang %解决完备图中的较优H圈 clc clear w = [ inf 6 1 8 3 1 ;...   ...