ArrayList.toArray(T[] a) 的说明 - Leon的专栏 - 博客频道 - CSDN.NET

mikel阅读(981)

ArrayList.toArray(T[] a) 的说明首先说明,下面是从jdk api 文档中看到的,这里只记录下午无特别的事情,就想着研究下常用的java 源码,在这之前肯定要先看下jdk api 文档,心里有对这些实现的认识,看到了ArrayList ,其中的一个方法 toArray(T[]a), 这个方法是将一个链表转换成数组,在知道这个方法之前,一直自己用循环的方法转换成数组。在知道这个方

来源: ArrayList.toArray(T[] a) 的说明 – Leon的专栏 – 博客频道 – CSDN.NET

首先说明,下面是从jdk api 文档中看到的,这里只记录

下午无特别的事情,就想着研究下常用的Java 源码,在这之前肯定要先看下jdk api 文档,心里有对这些实现的认识,看到了ArrayList ,其中的一个方法 toArray(T[]a), 这个方法是将一个链表转换成数组,在知道这个方法之前,一直自己用循环的方法转换成数组。

在知道这个方法之后,

用的第一版

String[] desc = new String[]{};
list.toArray(desc);
output(desc);

显然,经过测试这样并不能完成任务,desc 是空的,就有了下面的版本

String[] desc = new String[]{};
desc = list.toArray(desc);
output(desc);

这样也可以完成任务,当时总觉着有些问题,也没多想,反正只要完成想要的结果就可以了。

直到今天,看到文档

原来如果desc 不足以容纳list 时,会产生一个新的数组,之前的desc 不变,所以第一版中desc 初始化为空的数组,肯定不能容纳任何元素,故产生新的数据返回,output 时还是之前的空。

这也是第二版可以将返回的数组重新赋值给desc ,output 时也就能获得正确的结果;

如果写到这就完了,那岂不是不当于没写

今天看文档才知道的,必须要有用,
思来想去,只要desc 可以容纳toArray 之后的元素不就可以了,于是有了下面的版本:

String[] desc = new String[list.size()];
list.toArray(desc);
output(desc);

这下看着舒服多了,看代码就知道要实现什么目的,还是要多看文档,官方文档是最好的资料,加油,没事就来折腾文档与源码

ensureCapacity(int minCapacity)

这个方法保证会产生最少 minCapacity 个空间,但是不保证就是这么多,
如果现有容量已经大于minCapacity, 则不做处理
否则方法首先做的是:将现在有的容量扩展1.5 倍,之后再将新的容量与minCapacity 比较,取较大值

get/set 方法

  1. get 先验证下标值,再取值
  2. set 方法会返回被覆盖的元素值,也就是说添加替换新元素时,

FloatMath.sqrt 方法找不到 不支持 解决办法 - huahuahua333686的博客 - 博客频道 - CSDN.NET

mikel阅读(1510)

FloatMath.sqrt()11Error:(95, 30) 错误: 找不到符号符号: 方法 sqrt(float)位置: 类 FloatMath123123解决办法:改为 (float)Math.sqrt()

来源: FloatMath.sqrt 方法找不到 不支持 解决办法 – huahuahua333686的博客 – 博客频道 – CSDN.NET

FloatMath.sqrt()
Error:(95, 30) 错误: 找不到符号
符号:   方法 sqrt(float)
位置: 类 FloatMath

解决办法:改为 (float)Math.sqrt()

ImageLoader must be init with configuration before using 错误解决方法 - 博客频道 - CSDN.NET

mikel阅读(1656)

来源: ImageLoader must be init with configuration before using 错误解决方法 – 博客频道 – CSDN.NET

最近开发过程中用到了开源项目Android-Universal-Image-Loader

程序开发之前在CSDN的文章里看到的有Android-Universal-Image-Loader这么个好东西 ,用起来非常的方便,大家可以看Demo,里面有详细的介绍。

Android-Universal-Image-Loader 在使用的过程中碰到了一些问题。当时完全是按照官方的Demo来搭建的,但是始终程序运行不起来,会报以下错误:

java.lang.RuntimeException: ImageLoader must be init with configuration before using

字面意思是在使用前要初始化

只要加一句话:

imageLoader.init(ImageLoaderConfiguration.createDefault(MainActivity.this));

ps: 经小伙伴们提醒,官方demo中的初始化方法是在application类中调用的

Android:NineGridLayout — 仿微信朋友圈和QQ空间的九宫格图片展示自定义控件 - HMYANG314的专栏 - 博客频道 - CSDN.NET

mikel阅读(1921)

NineGridLayout一个仿微信朋友圈和QQ空间的九宫格图片展示自定义控件。一、介绍 1、当只有1张图时,可以自己定制图片宽高,也可以使用默认九宫格的宽高; 2、当只有4张图时,以2*2的方式显示; 3、除以上两种情况下,都是按照3列方式显示,但这时有一些细节: a、如果只有9张图,当然是以3*3的方式

来源: Android:NineGridLayout — 仿微信朋友圈和QQ空间的九宫格图片展示自定义控件 – HMYANG314的专栏 – 博客频道 – CSDN.NET

 转载请注明出处:http://blog.csdn.net/hmyang314/article/details/51415396

NineGridLayout

一个仿微信朋友圈和QQ空间的九宫格图片展示自定义控件。

GitHub:https://github.com/HMY314/NineGridLayout

一、介绍

    1、当只有1张图时,可以自己定制图片宽高,也可以使用默认九宫格的宽高;
    2、当只有4张图时,以2*2的方式显示;
    3、除以上两种情况下,都是按照3列方式显示,但这时有一些细节:
        a、如果只有9张图,当然是以3*3的方式显示;
        b、如果超过9张图,可以设置是否全部显示。
            如果设置不完全显示,则按照3*3的方式显示,但是在第9张图上会有一个带“+”号的数字,
            代表还有几张没有显示,这里是模仿了QQ空间图片超出9张的显示方式;
            如果设置全部显示,理所当然的将所有图片都显示出来。
    4、图片被按下时,会有一个变暗的效果,这也是模仿微信朋友圈的效果。

二、使用方法

1、核心类是NineGridLayout,继承自ViewGroup的抽象类,所以我们实际项目使用需要继承它,并要实现3个方法,如下:

  1. public abstract class NineGridLayout extends ViewGroup {
  2.     //******************************其他代码省略**************************
  3.         /**
  4.          * 显示一张图片
  5.          * @param imageView
  6.          * @param url
  7.          * @param parentWidth 父控件宽度
  8.          * @return true 代表按照九宫格默认大小显示,false 代表按照自定义宽高显示
  9.          */
  10.         protected abstract boolean displayOneImage(RatioImageView imageView, String url, int parentWidth);
  11.         protected abstract void displayImage(RatioImageView imageView, String url);
  12.         /**
  13.          * 点击图片时执行
  14.          */
  15.         protected abstract void onClickImage(int position, String url, List<String> urlList);
  16.     }

2、我这里用NineGridTestLayout继承NineGridLayout实现,displayOneImage()与displayImage()中的参数都是显示图片需要的,我这里用的是ImageLoader显示图片,当然你也可以用其他的。

  1. public class NineGridTestLayout extends NineGridLayout {
  2.      protected static final int MAX_W_H_RATIO = 3;
  3.      public NineGridTestLayout(Context context) {
  4.          super(context);
  5.      }
  6.      public NineGridTestLayout(Context context, AttributeSet attrs) {
  7.          super(context, attrs);
  8.      }
  9.      @Override
  10.      protected boolean displayOneImage(final RatioImageView imageView, String url, final int parentWidth) {
  11.         //这里是只显示一张图片的情况,显示图片的宽高可以根据实际图片大小自由定制,parentWidth 为该layout的宽度
  12.          ImageLoader.getInstance().displayImage(imageView, url, ImageLoaderUtil.getPhotoImageOption(), new ImageLoadingListener() {
  13.              @Override
  14.              public void onLoadingStarted(String imageUri, View view) {
  15.              }
  16.              @Override
  17.              public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
  18.              }
  19.              @Override
  20.              public void onLoadingComplete(String imageUri, View view, Bitmap bitmap) {
  21.                  int w = bitmap.getWidth();
  22.                  int h = bitmap.getHeight();
  23.                  int newW;
  24.                  int newH;
  25.                  if (h > w * MAX_W_H_RATIO) {//h:w = 5:3
  26.                      newW = parentWidth / 2;
  27.                      newH = newW * 5 / 3;
  28.                  } else if (h < w) {//h:w = 2:3
  29.                      newW = parentWidth * 2 / 3;
  30.                      newH = newW * 2 / 3;
  31.                  } else {//newH:h = newW :w
  32.                      newW = parentWidth / 2;
  33.                      newH = h * newW / w;
  34.                  }
  35.                  setOneImageLayoutParams(imageView, newW, newH);
  36.              }
  37.              @Override
  38.              public void onLoadingCancelled(String imageUri, View view) {
  39.              }
  40.          });
  41.          return false;// true 代表按照九宫格默认大小显示(此时不要调用setOneImageLayoutParams);false 代表按照自定义宽高显示。
  42.      }
  43.      @Override
  44.      protected void displayImage(RatioImageView imageView, String url) {
  45.          ImageLoaderUtil.getImageLoader(mContext).displayImage(url, imageView, ImageLoaderUtil.getPhotoImageOption());
  46.      }
  47.      @Override
  48.      protected void onClickImage(int i, String url, List<String> urlList) {
  49.          Toast.makeText(mContext, “点击了图片” + url, Toast.LENGTH_SHORT).show();
  50.      }
  51. }

3、在xml中实现

  1. <com.hmy.ninegridlayout.view.NineGridTestLayout xmlns:app=“http://schemas.Android.com/apk/res-auto”
  2.     Android:id=“@+id/layout_nine_grid”
  3.     android:layout_width=“match_parent”
  4.     android:layout_height=“wrap_content”
  5.     android:layout_marginTop=“8dp”
  6.     app:sapcing=“4dp” />

app:sapcing是设置九宫格中图片之间的间隔。

4、使用:

  1. public List<String> urlList = new ArrayList<>();//图片url
  2. NineGridTestLayout layout = (NineGridTestLayout) view.findViewById(R.id.layout_nine_grid);
  3. layout.setIsShowAll(false); //当传入的图片数超过9张时,是否全部显示
  4. layout.setSpacing(5); //动态设置图片之间的间隔
  5. layout.setUrlList(urlList); //最后再设置图片url

 

三、核心类

NineGridLayout.java

  1. /**
  2.  * 描述:
  3.  * 作者:HMY
  4.  * 时间:2016/5/10
  5.  */
  6. public abstract class NineGridLayout extends ViewGroup {
  7.     private static final float DEFUALT_SPACING = 3f;
  8.     private static final int MAX_COUNT = 9;
  9.     protected Context mContext;
  10.     private float mSpacing = DEFUALT_SPACING;
  11.     private int mColumns;
  12.     private int mRows;
  13.     private int mTotalWidth;
  14.     private int mSingleWidth;
  15.     private boolean mIsShowAll = false;
  16.     private boolean mIsFirst = true;
  17.     private List<String> mUrlList = new ArrayList<>();
  18.     public NineGridLayout(Context context) {
  19.         super(context);
  20.         init(context);
  21.     }
  22.     public NineGridLayout(Context context, AttributeSet attrs) {
  23.         super(context, attrs);
  24.         TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.NineGridLayout);
  25.         mSpacing = typedArray.getDimension(R.styleable.NineGridLayout_sapcing, DEFUALT_SPACING);
  26.         typedArray.recycle();
  27.         init(context);
  28.     }
  29.     private void init(Context context) {
  30.         mContext = context;
  31.         if (getListSize(mUrlList) == 0) {
  32.             setVisibility(GONE);
  33.         }
  34.     }
  35.     @Override
  36.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  37.         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  38.     }
  39.     @Override
  40.     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
  41.         mTotalWidth = right – left;
  42.         mSingleWidth = (int) ((mTotalWidth – mSpacing * (3 – 1)) / 3);
  43.         if (mIsFirst) {
  44.             notifyDataSetChanged();
  45.             mIsFirst = false;
  46.         }
  47.     }
  48.     /**
  49.      * 设置间隔
  50.      *
  51.      * @param spacing
  52.      */
  53.     public void setSpacing(float spacing) {
  54.         mSpacing = spacing;
  55.     }
  56.     /**
  57.      * 设置是否显示所有图片(超过最大数时)
  58.      *
  59.      * @param isShowAll
  60.      */
  61.     public void setIsShowAll(boolean isShowAll) {
  62.         mIsShowAll = isShowAll;
  63.     }
  64.     public void setUrlList(List<String> urlList) {
  65.         if (getListSize(urlList) == 0) {
  66.             setVisibility(GONE);
  67.             return;
  68.         }
  69.         setVisibility(VISIBLE);
  70.         mUrlList.clear();
  71.         mUrlList.addAll(urlList);
  72.         if (!mIsFirst) {
  73.             notifyDataSetChanged();
  74.         }
  75.     }
  76.     public void notifyDataSetChanged() {
  77.         removeAllViews();
  78.         int size = getListSize(mUrlList);
  79.         if (size > 0) {
  80.             setVisibility(VISIBLE);
  81.         } else {
  82.             setVisibility(GONE);
  83.         }
  84.         if (size == 1) {
  85.             String url = mUrlList.get(0);
  86.             RatioImageView imageView = createImageView(0, url);
  87.             //避免在ListView中一张图未加载成功时,布局高度受其他item影响
  88.             LayoutParams params = getLayoutParams();
  89.             params.height = mSingleWidth;
  90.             setLayoutParams(params);
  91.             imageView.layout(00, mSingleWidth, mSingleWidth);
  92.             boolean isShowDefualt = displayOneImage(imageView, url, mTotalWidth);
  93.             if (isShowDefualt) {
  94.                 layoutImageView(imageView, 0, url, false);
  95.             } else {
  96.                 addView(imageView);
  97.             }
  98.             return;
  99.         }
  100.         generateChildrenLayout(size);
  101.         layoutParams();
  102.         for (int i = 0; i < size; i++) {
  103.             String url = mUrlList.get(i);
  104.             RatioImageView imageView;
  105.             if (!mIsShowAll) {
  106.                 if (i < MAX_COUNT – 1) {
  107.                     imageView = createImageView(i, url);
  108.                     layoutImageView(imageView, i, url, false);
  109.                 } else { //第9张时
  110.                     if (size <= MAX_COUNT) {//刚好第9张
  111.                         imageView = createImageView(i, url);
  112.                         layoutImageView(imageView, i, url, false);
  113.                     } else {//超过9张
  114.                         imageView = createImageView(i, url);
  115.                         layoutImageView(imageView, i, url, true);
  116.                         break;
  117.                     }
  118.                 }
  119.             } else {
  120.                 imageView = createImageView(i, url);
  121.                 layoutImageView(imageView, i, url, false);
  122.             }
  123.         }
  124.     }
  125.     private void layoutParams() {
  126.         int singleHeight = mSingleWidth;
  127.         //根据子view数量确定高度
  128.         LayoutParams params = getLayoutParams();
  129.         params.height = (int) (singleHeight * mRows + mSpacing * (mRows – 1));
  130.         setLayoutParams(params);
  131.     }
  132.     private RatioImageView createImageView(final int i, final String url) {
  133.         RatioImageView imageView = new RatioImageView(mContext);
  134.         imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
  135.         imageView.setOnClickListener(new OnClickListener() {
  136.             @Override
  137.             public void onClick(View v) {
  138.                 onClickImage(i, url, mUrlList);
  139.             }
  140.         });
  141.         return imageView;
  142.     }
  143.     /**
  144.      * @param imageView
  145.      * @param url
  146.      * @param showNumFlag 是否在最大值的图片上显示还有未显示的图片张数
  147.      */
  148.     private void layoutImageView(RatioImageView imageView, int i, String url, boolean showNumFlag) {
  149.         final int singleWidth = (int) ((mTotalWidth – mSpacing * (3 – 1)) / 3);
  150.         int singleHeight = singleWidth;
  151.         int[] position = findPosition(i);
  152.         int left = (int) ((singleWidth + mSpacing) * position[1]);
  153.         int top = (int) ((singleHeight + mSpacing) * position[0]);
  154.         int right = left + singleWidth;
  155.         int bottom = top + singleHeight;
  156.         imageView.layout(left, top, right, bottom);
  157.         addView(imageView);
  158.         if (showNumFlag) {//添加超过最大显示数量的文本
  159.             int overCount = getListSize(mUrlList) – MAX_COUNT;
  160.             if (overCount > 0) {
  161.                 float textSize = 30;
  162.                 final TextView textView = new TextView(mContext);
  163.                 textView.setText(“+” + String.valueOf(overCount));
  164.                 textView.setTextColor(Color.WHITE);
  165.                 textView.setPadding(0, singleHeight / 2 – getFontHeight(textSize), 00);
  166.                 textView.setTextSize(textSize);
  167.                 textView.setGravity(Gravity.CENTER);
  168.                 textView.setBackgroundColor(Color.BLACK);
  169.                 textView.getBackground().setAlpha(120);
  170.                 textView.layout(left, top, right, bottom);
  171.                 addView(textView);
  172.             }
  173.         }
  174.         displayImage(imageView, url);
  175.     }
  176.     private int[] findPosition(int childNum) {
  177.         int[] position = new int[2];
  178.         for (int i = 0; i < mRows; i++) {
  179.             for (int j = 0; j < mColumns; j++) {
  180.                 if ((i * mColumns + j) == childNum) {
  181.                     position[0] = i;//行
  182.                     position[1] = j;//列
  183.                     break;
  184.                 }
  185.             }
  186.         }
  187.         return position;
  188.     }
  189.     /**
  190.      * 根据图片个数确定行列数量
  191.      *
  192.      * @param length
  193.      */
  194.     private void generateChildrenLayout(int length) {
  195.         if (length <= 3) {
  196.             mRows = 1;
  197.             mColumns = length;
  198.         } else if (length <= 6) {
  199.             mRows = 2;
  200.             mColumns = 3;
  201.             if (length == 4) {
  202.                 mColumns = 2;
  203.             }
  204.         } else {
  205.             mColumns = 3;
  206.             if (mIsShowAll) {
  207.                 mRows = length / 3;
  208.                 int b = length % 3;
  209.                 if (b > 0) {
  210.                     mRows++;
  211.                 }
  212.             } else {
  213.                 mRows = 3;
  214.             }
  215.         }
  216.     }
  217.     protected void setOneImageLayoutParams(RatioImageView imageView, int width, int height) {
  218.         imageView.setLayoutParams(new LayoutParams(width, height));
  219.         imageView.layout(00, width, height);
  220.         LayoutParams params = getLayoutParams();
  221. //        params.width = width;
  222.         params.height = height;
  223.         setLayoutParams(params);
  224.     }
  225.     private int getListSize(List<String> list) {
  226.         if (list == null || list.size() == 0) {
  227.             return 0;
  228.         }
  229.         return list.size();
  230.     }
  231.     private int getFontHeight(float fontSize) {
  232.         Paint paint = new Paint();
  233.         paint.setTextSize(fontSize);
  234.         Paint.FontMetrics fm = paint.getFontMetrics();
  235.         return (int) Math.ceil(fm.descent – fm.ascent);
  236.     }
  237.     /**
  238.      * @param imageView
  239.      * @param url
  240.      * @param parentWidth 父控件宽度
  241.      * @return true 代表按照九宫格默认大小显示,false 代表按照自定义宽高显示
  242.      */
  243.     protected abstract boolean displayOneImage(RatioImageView imageView, String url, int parentWidth);
  244.     protected abstract void displayImage(RatioImageView imageView, String url);
  245.     protected abstract void onClickImage(int position, String url, List<String> urlList);
  246. }

 

RatioImageView.Java

该类有两个功能:

1、是用于ImageView被按下时有变暗效果

2、ImageView的宽高根据设置的比例动态适配高度,如在xml中设置 app:ratio=”2″ ,ImageView的高度根据其宽度改变,但始终是宽的2倍,该功能在该项目中没有使用。

  1. /**
  2.  * 根据宽高比例自动计算高度ImageView
  3.  * Created by HMY on 2016/4/21.
  4.  */
  5. public class RatioImageView extends ImageView {
  6.     /**
  7.      * 宽高比例
  8.      */
  9.     private float mRatio = 0f;
  10.     public RatioImageView(Context context, AttributeSet attrs, int defStyleAttr) {
  11.         super(context, attrs, defStyleAttr);
  12.     }
  13.     public RatioImageView(Context context, AttributeSet attrs) {
  14.         super(context, attrs);
  15.         TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RatioImageView);
  16.         mRatio = typedArray.getFloat(R.styleable.RatioImageView_ratio, 0f);
  17.         typedArray.recycle();
  18.     }
  19.     public RatioImageView(Context context) {
  20.         super(context);
  21.     }
  22.     /**
  23.      * 设置ImageView的宽高比
  24.      *
  25.      * @param ratio
  26.      */
  27.     public void setRatio(float ratio) {
  28.         mRatio = ratio;
  29.     }
  30.     @Override
  31.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  32.         int width = MeasureSpec.getSize(widthMeasureSpec);
  33.         if (mRatio != 0) {
  34.             float height = width / mRatio;
  35.             heightMeasureSpec = MeasureSpec.makeMeasureSpec((int) height, MeasureSpec.EXACTLY);
  36.         }
  37.         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  38.     }
  39.     @Override
  40.     public boolean onTouchEvent(MotionEvent event) {
  41.         switch (event.getAction()) {
  42.             case MotionEvent.ACTION_DOWN:
  43.                 Drawable drawable = getDrawable();
  44.                 if (drawable != null) {
  45.                     drawable.mutate().setColorFilter(Color.GRAY,
  46.                             PorterDuff.Mode.MULTIPLY);
  47.                 }
  48.                 break;
  49.             case MotionEvent.ACTION_MOVE:
  50.                 break;
  51.             case MotionEvent.ACTION_CANCEL:
  52.             case MotionEvent.ACTION_UP:
  53.                 Drawable drawableUp = getDrawable();
  54.                 if (drawableUp != null) {
  55.                     drawableUp.mutate().clearColorFilter();
  56.                 }
  57.                 break;
  58.         }
  59.         return super.onTouchEvent(event);
  60.     }
  61. }

代码可在我的GitHub上下载,地址:https://github.com/HMY314/NineGridLayout

 

效果图

    

Fragment的广播消息接收

mikel阅读(1742)

这种方式不用在配置文件加东西,我比较喜欢。

广播注册,可以写在Activity(onCreate),也可以写在Fragment(onActivityCreated)里。

LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(getActivity());
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.intent.action.CART_BROADCAST");//建议把它写一个公共的变量,这里方便阅读就不写了。
BroadcastReceiver mItemViewListClickReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent){
                System.out.println("OK");
            }
 };
 broadcastManager.registerReceiver(mItemViewListClickReceiver, intentFilter);
 
发送广播
 

Intent intent = new Intent("android.intent.action.CART_BROADCAST");
LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent);

Android 如何获取当前Activity实例对象? - fuchenxuan blog - 博客频道 - CSDN.NET

mikel阅读(1817)

Android 获取当前Activity实例对象? 在项目开发中,遇到这么个情景,Activity是第三方部门的jar包,而我们需要当前界面用户输入的值 并且校验,jar包里面 并没有提供支持,然而这个jar包牵扯跨部门众多,更新困难。在短时间内只能靠我们自己 想办法获取当前屏幕的Activity 实例 对象,然后获取的View 遍历 到自己需要的值。以上都是废话,直接看需求~。获取当前屏幕A

来源: Android 如何获取当前Activity实例对象? – fuchenxuan blog – 博客频道 – CSDN.NET

Android 如何获取当前Activity实例对象?

在项目开发中,遇到这么个情景,Activity是第三方部门的jar包,而我们需要当前界面用户输入的值 并且校验,jar包里面 并没有提供支持,然而这个jar包牵扯跨部门众多,更新困难。在短时间内只能靠我们自己 想办法获取当前屏幕的Activity 实例 对象,然后获取的View 遍历 到自己需要的值。

以上都是废话,直接看需求~。

获取当前屏幕Activity实例对象

网上很多说使用获取Task 名称,利用ActivityManager的runingtask 代码如下:
记得在加AndroidManifest.xml中增加权限

<uses-permission Android:name="android.permission.GET_TASKS"/>


ActivityManager activityManager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningTaskInfo> forGroundActivity = activityManager.getRunningTasks(1);
        RunningTaskInfo currentActivity;
        currentActivity = forGroundActivity.get(0);
        String activityName = currentActivity.topActivity.getClassName();

可以看到代码,这样并不能获取到Activity 对象。

ActivityLifecycleCallbacks 是什么?

见名知意,Activity生命周期回调,Application通过此接口提供了一套回调方法,用于让开发者对Activity的生命周期事件进行集中处理。
但是这个要求API 14+ (Android 4.0+)以上使用,幸好我们这个最低支持,满足需求。

ActivityLifecycleCallbacks 怎么使用?

重写Application的onCreate()方法,或在Application的无参构造方法内,调用Application.registerActivityLifecycleCallbacks()方法,并实现ActivityLifecycleCallbacks接口

public void onCreate() {  
  super.onCreate();  
  this.registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {  

    @Override  
    public void onActivityStopped(Activity activity) {  
        Logger.v(activity, "onActivityStopped");  
    }  

    @Override  
    public void onActivityStarted(Activity activity) {  
        Logger.v(activity, "onActivityStarted");  
    }  

    @Override  
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {  
        Logger.v(activity, "onActivitySaveInstanceState");  
    }  

    @Override  
    public void onActivityResumed(Activity activity) {  
        Logger.v(activity, "onActivityResumed");  
    }  

    @Override  
    public void onActivityPaused(Activity activity) {  
        Logger.v(activity, "onActivityPaused");  
    }  

    @Override  
    public void onActivityDestroyed(Activity activity) {  
        Logger.v(activity, "onActivityDestroyed");  
    }  

    @Override  
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {  
        Logger.v(activity, "onActivityCreated");  
    }  
  });  
}; 

这样就能获取到activity的对象了。之前知道还有其他方法可以获取对象,没记住现在已经忘记了。如有大神发现,麻烦告诉小弟。~~谢谢

ActivityLifecycleCallbacks 为什么?

我们查看Application的源码,发现原来 ActivityLifecycleCallbacks 就是Application的内部类。

public class Application extends ContextWrapper implements ComponentCallbacks2 {
    private ArrayList<ComponentCallbacks> mComponentCallbacks =
            new ArrayList<ComponentCallbacks>();
    private ArrayList<ActivityLifecycleCallbacks> mActivityLifecycleCallbacks =
            new ArrayList<ActivityLifecycleCallbacks>();
    private ArrayList<OnProvideAssistDataListener> mAssistCallbacks = null;
    /** @hide */
    public LoadedApk mLoadedApk;
    public interface ActivityLifecycleCallbacks {
        void onActivityCreated(Activity activity, Bundle savedInstanceState);
        void onActivityStarted(Activity activity);
        void onActivityResumed(Activity activity);
        void onActivityPaused(Activity activity);
        void onActivityStopped(Activity activity);
        void onActivitySaveInstanceState(Activity activity, Bundle outState);
        void onActivityDestroyed(Activity activity);
    }

再来看是怎么回调的,这是内部API

// —————— Internal API ——————

  /**
     * @hide
     */
    /* package */ final void attach(Context context) {
        attachBaseContext(context);
        mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
    }
       //调用onActivityCreated
    /* package */ void dispatchActivityCreated(Activity activity, Bundle savedInstanceState) {
        Object[] callbacks = collectActivityLifecycleCallbacks();
        if (callbacks != null) {
            for (int i=0; i<callbacks.length; i++) {
                ((ActivityLifecycleCallbacks)callbacks[i]).onActivityCreated(activity,
                        savedInstanceState);
            }
        }
    }
    //调用onActivityStarted
    /* package */ void dispatchActivityStarted(Activity activity) {
        Object[] callbacks = collectActivityLifecycleCallbacks();
        if (callbacks != null) {
            for (int i=0; i<callbacks.length; i++) {
                ((ActivityLifecycleCallbacks)callbacks[i]).onActivityStarted(activity);
            }
        }
    }

其他应用

我们还可以利用ActivityLifecycleCallbacks 做一些数据埋点,统计之类的应用,对其统一做处理。这样对减少Activity的代码入侵。尽量简化和模块化的注入生命周期方法。

水平有限,若有错漏,欢迎指正,批评,如需转载,请注明出处–http://blog.csdn.net/vfush,谢谢!

Android调用摄像头拍照(兼容7.0) - Errol's Blog - 博客频道 - CSDN.NET

mikel阅读(1288)

Android调用摄像头拍照(兼容7.0)

来源: Android调用摄像头拍照(兼容7.0) – Errol’s Blog – 博客频道 – CSDN.NET

demo

先从一个简单的demo了解Android拍照

xml代码

<button></button>

一个 Button和一个 ImageView。Button是用于打 开摄像头进行拍照的,而 ImageView则是用于将拍到的图片显示出来

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
public static final int TAKE_PHOTO = 1;
public static final int CROP_PHOTO = 2;
private Button takePhoto;
private ImageView picture;
private Uri imageUri;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

takePhoto = (Button) findViewById(R.id.take_photo);
picture = (ImageView) findViewById(R.id.picture);

takePhoto.setOnClickListener(this);
}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.take_photo:
File outputImage = new File(Environment.getExternalStorageDirectory(),
"tempImage" + ".jpg");
try {
if (outputImage.exists()) {
outputImage.delete();
}
outputImage.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
imageUri = Uri.fromFile(outputImage);
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, TAKE_PHOTO);
break;
}
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case TAKE_PHOTO:
if (resultCode == RESULT_OK) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(imageUri, "image/*");
intent.putExtra("scale", true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, CROP_PHOTO); // 启动裁剪程序
}
break;
case CROP_PHOTO:
if (resultCode == RESULT_OK) {
try {
Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver()
.openInputStream(imageUri));
picture.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
break;
}
}
}

给button按钮增加点击事件,调用摄像头

1、首先这里创建了一个 File对象,用于存储摄像头拍下的图片,这里我们把图片命名为 tempImage.jpg ,并 将 它 存 放 在 手 机 SD 卡 的 根 目 录 下 , 调 用 Environment 的 getExternalStorageDirectory()方法获取到的就是手机 SD 卡的根目录
2、然后再调用 Uri 的 fromFile()方法将 File 对象转换成 Uri对象,这个 Uri对象标识着 tempImage.jpg 这张图片 的唯一地址
3、接着构建出一个Intent对象,并将这个Intent的action指定为Android.media.action. IMAGE_CAPTURE,再调用 Intent的 putExtra()方法指定图片的输出地址,这里填入刚刚得 到的 Uri 对象,最后调用 startActivityForResult()来启动活动
4、由于我们使用的是一个隐式 Intent,系统会找出能够响应这个 Intent的活动去启动,这样照相机程序就会被打开,拍下的 照片将会输出到 tempImage.jpg中
5、我们是使用 startActivityForResult()来启动活动的,因此拍完照后会有结果返回 到 onActivityResult()方法中。
6、如果发现拍照成功,则会再次构建出一个 Intent对象,并把它 的 action指定为 com.android.camera.action.CROP,这个 Intent是用于对拍出的照片进行裁剪的,因为摄像头拍出的照片都比较大,而我们可能只希望截取其中的一小部分然后给这个 Intent设置上一些必要的属性,并再次调用 startActivityForResult()来启动裁剪程序。裁剪后 的照片同样会输出到 tempImage.jpg中
7、裁剪操作完成之后,程序又会回调到 onActivityResult()方法中,这个时候我们就可以调 用 BitmapFactory的 decodeStream()方法将 output_image.jpg这张照片解析成 Bitmap对象,然 后把它设置到 ImageView中显示

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.choosepictest" android:versionCode="1" android:versionName="1.0" > <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> …… </manifest> 
  • 1
  • 1

由于这个项目涉及到了向SD卡中写数据的操作,因此我们还需要在AndroidManifest.xml 中声明权限

剪裁

图片显示

针对7.0做修改

Android升级到7.0后对权限又做了一个更新即不允许出现以file://的形式调用隐式APP,需要用共享文件的形式:content:// URI

其余代码不变,仅java代码进行了修改如下

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
public static final int PHOTO_REQUEST_CAREMA = 1;// 拍照
public static final int CROP_PHOTO = 2;
private Button takePhoto;
private ImageView picture;
private Uri imageUri;

public static File tempFile;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

takePhoto = (Button) findViewById(R.id.take_photo);
picture = (ImageView) findViewById(R.id.picture);

takePhoto.setOnClickListener(this);
}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.take_photo:
openCamera(this);
break;
}
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case PHOTO_REQUEST_CAREMA:
if (resultCode == RESULT_OK) {
Intent intent = new Intent(“com.android.camera.action.CROP”);
intent.setDataAndType(imageUri, “image/*”);
intent.putExtra(“scale”, true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, CROP_PHOTO); // 启动裁剪程序
}
break;
case CROP_PHOTO:
if (resultCode == RESULT_OK) {
try {
Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver()
.openInputStream(imageUri));
picture.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
break;
}
}

public void openCamera(Activity activity) {
//獲取系統版本
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
// 激活相机
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// 判断存储卡是否可以用,可用进行存储
if (hasSdcard()) {
SimpleDateFormat timeStampFormat = new SimpleDateFormat(
“yyyy_MM_dd_HH_mm_ss”);
String filename = timeStampFormat.format(new Date());
tempFile = new File(Environment.getExternalStorageDirectory(),
filename + “.jpg”);
if (currentapiVersion < 24) { // 从文件中创建uri imageUri = Uri.fromFile(tempFile); intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); } else { //兼容android7.0 使用共享文件的形式 ContentValues contentValues = new ContentValues(1); contentValues.put(MediaStore.Images.Media.DATA, tempFile.getAbsolutePath()); //检查是否有存储权限,以免崩溃 if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { //申请WRITE_EXTERNAL_STORAGE权限 Toast.makeText(this,"请开启存储权限",Toast.LENGTH_SHORT).show(); return; } imageUri = activity.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues); intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); } } // 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_CAREMA activity.startActivityForResult(intent, PHOTO_REQUEST_CAREMA); } /* * 判断sdcard是否被挂载 */ public static boolean hasSdcard() { return Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED); } } [/code] *需要注意的是安装在手机上的app,需要检查下是否开启了存储权限 调取系统相册 [code] Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("image/*"); startActivityForResult(intent, CROP_PHOTO); [/code] 这里请求码为CROP_PHOTO,因此对上边的CROP_PHOTO做些改造 [code] @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case TAKE_PHOTO: ... break; case CROP_PHOTO: if (resultCode == RESULT_OK) { try { if(data != null) { Uri uri = data.getData(); imageUri = uri; } Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver() .openInputStream(imageUri)); picture.setImageBitmap(bitmap); } catch (FileNotFoundException e) { e.printStackTrace(); } } break; default: super.onActivityResult(requestCode, resultCode, data); break; } } [/code] 关于android权限相关只是可以查看文后的更多文章

Android百度地图开发之显示当前位置地图 - zhengyikuangge的博客 - 博客频道 - CSDN.NET

mikel阅读(1172)

来源: Android百度地图开发之显示当前位置地图 – zhengyikuangge的博客 – 博客频道 – CSDN.NET

步骤:

1、获取当前的经纬度
2、显示地图
3、改变地图中心的经纬度


1、获取当前的经纬度
请参考网址:
http://blog.csdn.net/zhengyikuangge/article/details/51921549


2、显示地图
请参考网址:
http://blog.csdn.net/zhengyikuangge/article/details/51945053


3、改变地图中心的经纬度:
参考代码(只提供Java代码,其他代码与第2个网址中的相同):

package com.example.baidumaptest;

import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.Toast;

import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.model.LatLng;

public class MainActivity extends Activity {
private LocationManager locationManager;
private String provider;
MapView mapView;
BaiduMap baiduMap;
boolean ifFrist = true;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SDKInitializer.initialize(getApplicationContext());
setContentView(R.layout.activity_main);
mapView = (MapView) findViewById(R.id.map_view);
// 获取baiduMap对象
baiduMap = mapView.getMap();
// 设置可改变地图位置
baiduMap.setMyLocationEnabled(true);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
List list = locationManager.getProviders(true);
if (list.contains(LocationManager.GPS_PROVIDER)) {
provider = LocationManager.GPS_PROVIDER;
} else if (list.contains(LocationManager.NETWORK_PROVIDER)) {
provider = LocationManager.NETWORK_PROVIDER;

} else {
Toast.makeText(this, "当前不能提供位置信息", Toast.LENGTH_LONG).show();
return;
}
Location location = locationManager.getLastKnownLocation(provider);
if (location != null) {
navigateTo(location);
}
locationManager.requestLocationUpdates(provider, 5000, 1,
locationListener);

}

private void navigateTo(Location location) {
// 按照经纬度确定地图位置
if (ifFrist) {
LatLng ll = new LatLng(location.getLatitude(),
location.getLongitude());
MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll);
// 移动到某经纬度
baiduMap.animateMapStatus(update);
update = MapStatusUpdateFactory.zoomBy(5f);
// 放大
baiduMap.animateMapStatus(update);

ifFrist = false;
}
// 显示个人位置图标
MyLocationData.Builder builder = new MyLocationData.Builder();
builder.latitude(location.getLatitude());
builder.longitude(location.getLongitude());
MyLocationData data = builder.build();
baiduMap.setMyLocationData(data);
}

LocationListener locationListener = new LocationListener() {

@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub

}

@Override
public void onProviderEnabled(String arg0) {
// TODO Auto-generated method stub

}

@Override
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub

}

@Override
public void onLocationChanged(Location arg0) {
// TODO Auto-generated method stub
// 位置改变则重新定位并显示地图
navigateTo(arg0);
}
};

@Override
protected void onDestroy() {
// 释放资源
super.onDestroy();
if (locationManager != null) {
locationManager.removeUpdates(locationListener);
}

mapView.onDestroy();

baiduMap.setMyLocationEnabled(false);

}

}

参考代码下载地址:
http://download.csdn.net/detail/zhengyikuangge/9579595

在Fragment中集成百度地图 - liliwei2658的博客 - 博客频道 - CSDN.NET

mikel阅读(1481)

1.下载百度地图SDK,下面是官方下载地址:http://developer.baidu.com/map/index.php?title=Androidsdk/sdkandev-download2.根据http://lbsyun.baidu.com/index.php?title=Androidsdk/guide/buildproject中开发指南完成密匙申请、环境配置及发布,  确保

来源: 在Fragment中集成百度地图 – liliwei2658的博客 – 博客频道 – CSDN.NET

1.下载百度地图SDK,下面是官方下载地址:

http://developer.baidu.com/map/index.PHP?title=Androidsdk/sdkandev-download

2.根据http://lbsyun.baidu.com/index.php?title=androidsdk/guide/buildproject中开发指南完成密匙申请、环境配置及发布,

确保.so及jar文件版本的一致性,并且将其放置在相应位置

3.完成Hello BaiduMap中以下两个步骤:在application中添加开发密钥    添加所需权限

4.在Fragment布局xml文件中添加地图控件:

<!--?xml version="1.0" encoding="utf-8"?-->

注意!!!:在这一步中有可能报错:

The following classes could not be instantiated:

com.baidu.mapapi.map.MapView (Open Class, Show Exception, Clear Cache)

Tip: Use View.isInEditMode() in your custom views to skip code or show sample data when shown in the IDE……

不必在意,这个不影响后续工作,编译是可以通过的!

5.接下来就是在Java代码中实现了:

public class MyFragment extends Fragment {
MapView mMapView = null;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
//在使用SDK各组件之前初始化context信息,传入ApplicationContext
//注意该方法要再setContentView方法之前实现
SDKInitializer.initialize(getActivity().getApplicationContext());
View view = inflater.inflate(R.layout.task_layout, container, false);
mMapView = (MapView)view.findViewById(R.id.bmapView);
return view;
}

@Override
public void onResume() {
super.onResume();
//在Fragment执行onResume时执行mMapView. onResume (),实现地图生命周期管理
mMapView.onResume();
}

@Override
public void onPause() {
super.onPause();
//在<span style="font-family: 微软雅黑, 'Microsoft YaHei', sans-serif;">Fragment</span>执行onPause时执行mMapView. onPause (),实现地图生命周期管理
mMapView.onPause();
}

@Override
public void onDestroy() {
super.onDestroy();
//在Fragment执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
mMapView.onDestroy();
}
}

到此为止,运行以下看看效果吧~

转载请注明出处http://write.blog.csdn.NET/postedit?ref=toolbar&ticket=ST-104229-Pccqap1iFIc1gpOpBGtt-passport.csdn.Net

谢谢~

百度地图SDK 已经定位到城市,但是用location.getCity()获取到的是NULL问题解决 - 梦想的天空 - 博客频道 - CSDN.NET

mikel阅读(1666)

变量的声明:    String city = null;  //当前所在的城市    String addr = null; //当前所在地点在MyLocationListenner implements BDLocationListener 类中获取城市名:public class MyLocationListenner implements BDLocationListene

来源: 百度地图SDK 已经定位到城市,但是用location.getCity()获取到的是NULL问题解决 – 梦想的天空 – 博客频道 – CSDN.NET

变量的声明:
String city = null;  //当前所在的城市
String addr = null; //当前所在地点
在MyLocationListenner implements BDLocationListener 类中获取城市名:

public class MyLocationListenner implements BDLocationListener {

@Override
public void onReceiveLocation(BDLocation location) {
// map view 销毁后不在处理新接收的位置
if (location == null || mMapView == null)
return;
MyLocationData locData = new MyLocationData.Builder()
.accuracy(location.getRadius())
// 此处设置开发者获取到的方向信息,顺时针0-360
.direction(100).latitude(location.getLatitude())
.longitude(location.getLongitude()).build();
mBaiduMap.setMyLocationData(locData);
if (isFirstLoc) {
isFirstLoc = false;
LatLng ll = new LatLng(location.getLatitude(),
location.getLongitude());
MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(ll);
mBaiduMap.animateMapStatus(u);
}
try {
city=location.getCity();
addr=location.getAddrStr();
Toast.makeText(baidu_map.this, city+addr, 1).show(); //吐司出来的是NULL??
} catch (Exception e) {
int err = location.getLocType();
Toast.makeText(baidu_map.this, err, 1).show();
}

}

如红色部分,这样一直无法获取到地址信息,提示为NULL,
需要在红色部分上面加入:
LocationClientOption option = new LocationClientOption();
option.setIsNeedAddress(true);
mLocClient.setLocOption(option);
这样就可以了,不过有几秒钟的定位给时间,