(六十六)Android打造形形色色的进度条 (转载自:http://blog.csdn.net/lmj623565791/article/details/43371299)

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

1、概述

最近需要用进度条,秉着不重复造轮子的原则,上github上搜索了一番,看了几个觉得比较好看的ProgressBar,比如:daimajia的等。简单看了下代码,基本都是继承自View,彻彻底底的自定义了一个进度条。盯着那绚丽滚动条,忽然觉得,为什么要通过View去写一个滚动条,系统已经提供了ProgressBar以及属于它的特性,我们没必要重新去构建一个,但是系统的又比较丑,不同版本变现还不一定一样。那么得出我们的目标:改变系统ProgressBar的样子。

  对没错,我们没有必要去从0打造一个ProgressBar,人家虽然长的不好看,但是特性以及稳定性还是刚刚的,我们只需要为其整下容就ok了。

说到整容,大家都知道我们的控件是通过onDraw()画出来的,那么我们只需要去覆盖它的onDraw()方法,自己写下就ok 。

对了,我创建了一个微信公众号,欢迎关注,左边栏目上扫一扫即可。

  接下来,我们贴下效果图:

2、效果图

1、横向的进度条

2、圆形的进度条

没错,这就是我们的进度条效果,横向的模仿了daimajia的进度条样子。不过我们继承子ProgressBar,简单的为其整个容,代码清晰易懂 。为什么说,易懂呢?

横向那个进度条,大家会drawLine()和drawText()吧,那么通过getWidth()拿到控件的宽度,再通过getProgress()拿到进度,按比例控制绘制线的长短,字的位置还不是分分钟的事。

github源码地址Android-ProgressBarWidthNumber欢迎大家star or fork 。

3、实现

横向的滚动条绘制肯定需要一些属性,比如已/未到达进度的颜色、宽度,文本的颜色、大小等。 
本来呢,我是想通过系统ProgressBar的progressDrawable,从里面提取一些属性完成绘制需要的参数的。但是,最终呢,反而让代码变得复杂。所以最终还是改用自定义属性。 说道自定义属性,大家应该已经不陌生了。

1、HorizontalProgressBarWithNumber

1、自定义属性

values/attr_progress_bar.xml:

[html] view plaincopy

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3. <declare-styleable name="HorizontalProgressBarWithNumber">
  4. <attr name="progress_unreached_color" format="color" />
  5. <attr name="progress_reached_color" format="color" />
  6. <attr name="progress_reached_bar_height" format="dimension" />
  7. <attr name="progress_unreached_bar_height" format="dimension" />
  8. <attr name="progress_text_size" format="dimension" />
  9. <attr name="progress_text_color" format="color" />
  10. <attr name="progress_text_offset" format="dimension" />
  11. <attr name="progress_text_visibility" format="enum">
  12. <enum name="visible" value="0" />
  13. <enum name="invisible" value="1" />
  14. </attr>
  15. </declare-styleable>
  16. <declare-styleable name="RoundProgressBarWidthNumber">
  17. <attr name="radius" format="dimension" />
  18. </declare-styleable>
  19. </resources>

2、构造中获取

[java] view plaincopy

  1. public class HorizontalProgressBarWithNumber extends ProgressBar
  2. {
  3. private static final int DEFAULT_TEXT_SIZE = 10;
  4. private static final int DEFAULT_TEXT_COLOR = 0XFFFC00D1;
  5. private static final int DEFAULT_COLOR_UNREACHED_COLOR = 0xFFd3d6da;
  6. private static final int DEFAULT_HEIGHT_REACHED_PROGRESS_BAR = 2;
  7. private static final int DEFAULT_HEIGHT_UNREACHED_PROGRESS_BAR = 2;
  8. private static final int DEFAULT_SIZE_TEXT_OFFSET = 10;
  9. /**
  10. * painter of all drawing things
  11. */
  12. protected Paint mPaint = new Paint();
  13. /**
  14. * color of progress number
  15. */
  16. protected int mTextColor = DEFAULT_TEXT_COLOR;
  17. /**
  18. * size of text (sp)
  19. */
  20. protected int mTextSize = sp2px(DEFAULT_TEXT_SIZE);
  21. /**
  22. * offset of draw progress
  23. */
  24. protected int mTextOffset = dp2px(DEFAULT_SIZE_TEXT_OFFSET);
  25. /**
  26. * height of reached progress bar
  27. */
  28. protected int mReachedProgressBarHeight = dp2px(DEFAULT_HEIGHT_REACHED_PROGRESS_BAR);
  29. /**
  30. * color of reached bar
  31. */
  32. protected int mReachedBarColor = DEFAULT_TEXT_COLOR;
  33. /**
  34. * color of unreached bar
  35. */
  36. protected int mUnReachedBarColor = DEFAULT_COLOR_UNREACHED_COLOR;
  37. /**
  38. * height of unreached progress bar
  39. */
  40. protected int mUnReachedProgressBarHeight = dp2px(DEFAULT_HEIGHT_UNREACHED_PROGRESS_BAR);
  41. /**
  42. * view width except padding
  43. */
  44. protected int mRealWidth;
  45. protected boolean mIfDrawText = true;
  46. protected static final int VISIBLE = 0;
  47. public HorizontalProgressBarWithNumber(Context context, AttributeSet attrs)
  48. {
  49. this(context, attrs, 0);
  50. }
  51. public HorizontalProgressBarWithNumber(Context context, AttributeSet attrs,
  52. int defStyle)
  53. {
  54. super(context, attrs, defStyle);
  55. setHorizontalScrollBarEnabled(true);
  56. obtainStyledAttributes(attrs);
  57. mPaint.setTextSize(mTextSize);
  58. mPaint.setColor(mTextColor);
  59. }
  60. /**
  61. * get the styled attributes
  62. *
  63. * @param attrs
  64. */
  65. private void obtainStyledAttributes(AttributeSet attrs)
  66. {
  67. // init values from custom attributes
  68. final TypedArray attributes = getContext().obtainStyledAttributes(
  69. attrs, R.styleable.HorizontalProgressBarWithNumber);
  70. mTextColor = attributes
  71. .getColor(
  72. R.styleable.HorizontalProgressBarWithNumber_progress_text_color,
  73. DEFAULT_TEXT_COLOR);
  74. mTextSize = (int) attributes.getDimension(
  75. R.styleable.HorizontalProgressBarWithNumber_progress_text_size,
  76. mTextSize);
  77. mReachedBarColor = attributes
  78. .getColor(
  79. R.styleable.HorizontalProgressBarWithNumber_progress_reached_color,
  80. mTextColor);
  81. mUnReachedBarColor = attributes
  82. .getColor(
  83. R.styleable.HorizontalProgressBarWithNumber_progress_unreached_color,
  84. DEFAULT_COLOR_UNREACHED_COLOR);
  85. mReachedProgressBarHeight = (int) attributes
  86. .getDimension(
  87. R.styleable.HorizontalProgressBarWithNumber_progress_reached_bar_height,
  88. mReachedProgressBarHeight);
  89. mUnReachedProgressBarHeight = (int) attributes
  90. .getDimension(
  91. R.styleable.HorizontalProgressBarWithNumber_progress_unreached_bar_height,
  92. mUnReachedProgressBarHeight);
  93. mTextOffset = (int) attributes
  94. .getDimension(
  95. R.styleable.HorizontalProgressBarWithNumber_progress_text_offset,
  96. mTextOffset);
  97. int textVisible = attributes
  98. .getInt(R.styleable.HorizontalProgressBarWithNumber_progress_text_visibility,
  99. VISIBLE);
  100. if (textVisible != VISIBLE)
  101. {
  102. mIfDrawText = false;
  103. }
  104. attributes.recycle();
  105. }

嗯,看起来代码挺长,其实都是在获取自定义属性,没什么技术含量。

3、onMeasure

刚才不是出onDraw里面写写就行了么,为什么要改onMeasure呢,主要是因为我们所有的属性比如进度条宽度让用户自定义了,所以我们的测量也得稍微变下。

[java] view plaincopy

  1. @Override
  2. protected synchronized void onMeasure(int widthMeasureSpec,
  3. int heightMeasureSpec)
  4. {
  5. int heightMode = MeasureSpec.getMode(heightMeasureSpec);
  6. if (heightMode != MeasureSpec.EXACTLY)
  7. {
  8. float textHeight = (mPaint.descent() + mPaint.ascent());
  9. int exceptHeight = (int) (getPaddingTop() + getPaddingBottom() + Math
  10. .max(Math.max(mReachedProgressBarHeight,
  11. mUnReachedProgressBarHeight), Math.abs(textHeight)));
  12. heightMeasureSpec = MeasureSpec.makeMeasureSpec(exceptHeight,
  13. MeasureSpec.EXACTLY);
  14. }
  15. super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  16. }

宽度我们不变,所以的自定义属性不涉及宽度,高度呢,只考虑不是EXACTLY的情况(用户明确指定了,我们就不管了),根据padding和进度条宽度算出自己想要的,如果非EXACTLY下,我们进行exceptHeight封装,传入给控件进行测量高度。

测量完,就到我们的onDraw了~~~

4、onDraw

[java] view plaincopy

  1. @Override
  2. protected synchronized void onDraw(Canvas canvas)
  3. {
  4. canvas.save();
  5. //画笔平移到指定paddingLeft, getHeight() / 2位置,注意以后坐标都为以此为0,0
  6. canvas.translate(getPaddingLeft(), getHeight() / 2);
  7. boolean noNeedBg = false;
  8. //当前进度和总值的比例
  9. float radio = getProgress() * 1.0f / getMax();
  10. //已到达的宽度
  11. float progressPosX = (int) (mRealWidth * radio);
  12. //绘制的文本
  13. String text = getProgress() + "%";
  14. //拿到字体的宽度和高度
  15. float textWidth = mPaint.measureText(text);
  16. float textHeight = (mPaint.descent() + mPaint.ascent()) / 2;
  17. //如果到达最后,则未到达的进度条不需要绘制
  18. if (progressPosX + textWidth > mRealWidth)
  19. {
  20. progressPosX = mRealWidth - textWidth;
  21. noNeedBg = true;
  22. }
  23. // 绘制已到达的进度
  24. float endX = progressPosX - mTextOffset / 2;
  25. if (endX > 0)
  26. {
  27. mPaint.setColor(mReachedBarColor);
  28. mPaint.setStrokeWidth(mReachedProgressBarHeight);
  29. canvas.drawLine(0, 0, endX, 0, mPaint);
  30. }
  31. // 绘制文本
  32. if (mIfDrawText)
  33. {
  34. mPaint.setColor(mTextColor);
  35. canvas.drawText(text, progressPosX, -textHeight, mPaint);
  36. }
  37. // 绘制未到达的进度条
  38. if (!noNeedBg)
  39. {
  40. float start = progressPosX + mTextOffset / 2 + textWidth;
  41. mPaint.setColor(mUnReachedBarColor);
  42. mPaint.setStrokeWidth(mUnReachedProgressBarHeight);
  43. canvas.drawLine(start, 0, mRealWidth, 0, mPaint);
  44. }
  45. canvas.restore();
  46. }
  47. @Override
  48. protected void onSizeChanged(int w, int h, int oldw, int oldh)
  49. {
  50. super.onSizeChanged(w, h, oldw, oldh);
  51. mRealWidth = w - getPaddingRight() - getPaddingLeft();
  52. }

其实核心方法就是onDraw了,但是呢,onDraw也很简单,绘制线、绘制文本、绘制线,结束。

还有两个简单的辅助方法:

[java] view plaincopy

  1. /**
  2. * dp 2 px
  3. *
  4. * @param dpVal
  5. */
  6. protected int dp2px(int dpVal)
  7. {
  8. return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
  9. dpVal, getResources().getDisplayMetrics());
  10. }
  11. /**
  12. * sp 2 px
  13. *
  14. * @param spVal
  15. * @return
  16. */
  17. protected int sp2px(int spVal)
  18. {
  19. return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
  20. spVal, getResources().getDisplayMetrics());
  21. }

好了,到此我们的横向进度就结束了,是不是很简单~~如果你是自定义View,你还得考虑progress的更新,考虑状态的销毁与恢复等等复杂的东西。

接下来看我们的RoundProgressBarWidthNumber圆形的进度条。

2、RoundProgressBarWidthNumber

圆形的进度条和横向的进度条基本变量都是一致的,于是我就让RoundProgressBarWidthNumber extends HorizontalProgressBarWithNumber 了。

然后需要改变的就是测量和onDraw了:

完整代码:

[java] view plaincopy

  1. package com.zhy.view;
  2. import android.content.Context;
  3. import android.content.res.TypedArray;
  4. import android.graphics.Canvas;
  5. import android.graphics.Paint.Cap;
  6. import android.graphics.Paint.Style;
  7. import android.graphics.RectF;
  8. import android.util.AttributeSet;
  9. import com.zhy.library.view.R;
  10. public class RoundProgressBarWidthNumber extends
  11. HorizontalProgressBarWithNumber {
  12. /**
  13. * mRadius of view
  14. */
  15. private int mRadius = dp2px(30);
  16. public RoundProgressBarWidthNumber(Context context) {
  17. this(context, null);
  18. }
  19. public RoundProgressBarWidthNumber(Context context, AttributeSet attrs) {
  20. super(context, attrs);
  21. mReachedProgressBarHeight = (int) (mUnReachedProgressBarHeight * 2.5f);
  22. TypedArray ta = context.obtainStyledAttributes(attrs,
  23. R.styleable.RoundProgressBarWidthNumber);
  24. mRadius = (int) ta.getDimension(
  25. R.styleable.RoundProgressBarWidthNumber_radius, mRadius);
  26. ta.recycle();
  27. mTextSize = sp2px(14);
  28. mPaint.setStyle(Style.STROKE);
  29. mPaint.setAntiAlias(true);
  30. mPaint.setDither(true);
  31. mPaint.setStrokeCap(Cap.ROUND);
  32. }
  33. @Override
  34. protected synchronized void onMeasure(int widthMeasureSpec,
  35. int heightMeasureSpec) {
  36. int heightMode = MeasureSpec.getMode(heightMeasureSpec);
  37. int widthMode = MeasureSpec.getMode(widthMeasureSpec);
  38. int paintWidth = Math.max(mReachedProgressBarHeight,
  39. mUnReachedProgressBarHeight);
  40. if (heightMode != MeasureSpec.EXACTLY) {
  41. int exceptHeight = (int) (getPaddingTop() + getPaddingBottom()
  42. + mRadius * 2 + paintWidth);
  43. heightMeasureSpec = MeasureSpec.makeMeasureSpec(exceptHeight,
  44. MeasureSpec.EXACTLY);
  45. }
  46. if (widthMode != MeasureSpec.EXACTLY) {
  47. int exceptWidth = (int) (getPaddingLeft() + getPaddingRight()
  48. + mRadius * 2 + paintWidth);
  49. widthMeasureSpec = MeasureSpec.makeMeasureSpec(exceptWidth,
  50. MeasureSpec.EXACTLY);
  51. }
  52. super.onMeasure(heightMeasureSpec, heightMeasureSpec);
  53. }
  54. @Override
  55. protected synchronized void onDraw(Canvas canvas) {
  56. String text = getProgress() + "%";
  57. // mPaint.getTextBounds(text, 0, text.length(), mTextBound);
  58. float textWidth = mPaint.measureText(text);
  59. float textHeight = (mPaint.descent() + mPaint.ascent()) / 2;
  60. canvas.save();
  61. canvas.translate(getPaddingLeft(), getPaddingTop());
  62. mPaint.setStyle(Style.STROKE);
  63. // draw unreaded bar
  64. mPaint.setColor(mUnReachedBarColor);
  65. mPaint.setStrokeWidth(mUnReachedProgressBarHeight);
  66. canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);
  67. // draw reached bar
  68. mPaint.setColor(mReachedBarColor);
  69. mPaint.setStrokeWidth(mReachedProgressBarHeight);
  70. float sweepAngle = getProgress() * 1.0f / getMax() * 360;
  71. canvas.drawArc(new RectF(0, 0, mRadius * 2, mRadius * 2), 0,
  72. sweepAngle, false, mPaint);
  73. // draw text
  74. mPaint.setStyle(Style.FILL);
  75. canvas.drawText(text, mRadius - textWidth / 2, mRadius - textHeight,
  76. mPaint);
  77. canvas.restore();
  78. }
  79. }

首先获取它的专有属性mRadius,然后根据此属性去测量,测量完成绘制;

绘制的过程呢?

先绘制一个细一点的圆,然后绘制一个粗一点的弧度,二者叠在一起就行。文本呢,绘制在中间~~~总体,没什么代码量。

好了,两个进度条就到这了,是不是发现简单很多。总体设计上,存在些问题,如果抽取一个BaseProgressBar用于获取公共的属性;然后不同样子的进度条继承分别实现自己的测量和样子,这样结构可能会清晰些~~~

4、使用

布局文件

[html] view plaincopy

  1. <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. xmlns:zhy="http://schemas.android.com/apk/res-auto"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent" >
  6. <LinearLayout
  7. android:layout_width="match_parent"
  8. android:layout_height="match_parent"
  9. android:orientation="vertical"
  10. android:padding="25dp" >
  11. <com.zhy.view.HorizontalProgressBarWithNumber
  12. android:id="@+id/id_progressbar01"
  13. android:layout_width="match_parent"
  14. android:layout_height="wrap_content"
  15. android:layout_marginTop="50dip"
  16. android:padding="5dp" />
  17. <com.zhy.view.HorizontalProgressBarWithNumber
  18. android:layout_width="match_parent"
  19. android:layout_height="wrap_content"
  20. android:layout_marginTop="50dip"
  21. android:padding="5dp"
  22. android:progress="50"
  23. zhy:progress_text_color="#ffF53B03"
  24. zhy:progress_unreached_color="#ffF7C6B7" />
  25. <com.zhy.view.RoundProgressBarWidthNumber
  26. android:id="@+id/id_progress02"
  27. android:layout_width="match_parent"
  28. android:layout_height="wrap_content"
  29. android:layout_marginTop="50dip"
  30. android:padding="5dp"
  31. android:progress="30" />
  32. <com.zhy.view.RoundProgressBarWidthNumber
  33. android:layout_width="match_parent"
  34. android:layout_height="wrap_content"
  35. android:layout_marginTop="50dip"
  36. android:padding="5dp"
  37. android:progress="50"
  38. zhy:progress_reached_bar_height="20dp"
  39. zhy:progress_text_color="#ffF53B03"
  40. zhy:radius="60dp" />
  41. </LinearLayout>
  42. </ScrollView>

MainActivity

[java] view plaincopy

  1. package com.zhy.sample.progressbar;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.os.Handler;
  5. import com.zhy.annotation.Log;
  6. import com.zhy.view.HorizontalProgressBarWithNumber;
  7. public class MainActivity extends Activity {
  8. private HorizontalProgressBarWithNumber mProgressBar;
  9. private static final int MSG_PROGRESS_UPDATE = 0x110;
  10. private Handler mHandler = new Handler() {
  11. @Log
  12. public void handleMessage(android.os.Message msg) {
  13. int progress = mProgressBar.getProgress();
  14. mProgressBar.setProgress(++progress);
  15. if (progress >= 100) {
  16. mHandler.removeMessages(MSG_PROGRESS_UPDATE);
  17. }
  18. mHandler.sendEmptyMessageDelayed(MSG_PROGRESS_UPDATE, 100);
  19. };
  20. };
  21. @Log
  22. @Override
  23. protected void onCreate(Bundle savedInstanceState) {
  24. super.onCreate(savedInstanceState);
  25. setContentView(R.layout.activity_main);
  26. mProgressBar = (HorizontalProgressBarWithNumber) findViewById(R.id.id_progressbar01);
  27. mHandler.sendEmptyMessage(MSG_PROGRESS_UPDATE);
  28. }
  29. }

最后,本篇博客的目的呢?就是为了说下,类似ProgressBar这样的控件,如果你只是想去改变显示的样子,完全没必要从0去创建,复写onDraw即可,当然是个人观点,提出供大家参考。

源码点击下载

时间: 2024-10-20 09:43:48

(六十六)Android打造形形色色的进度条 (转载自:http://blog.csdn.net/lmj623565791/article/details/43371299)的相关文章

(二十)Android中处理崩溃异常(转载:http://blog.csdn.net/liuhe688/article/details/6584143)

大家都知道,现在安装Android系统的手机版本和设备千差万别,在模拟器上运行良好的程序安装到某款手机上说不定就出现崩溃的现象,开发者个人不可能购买所有设备逐个调试,所以在程序发布出去之后,如果出现了崩溃现象,开发者应该及时获取在该设备上导致崩溃的信息,这对于下一个版本的bug修复帮助极大,所以今天就来介绍一下如何在程序崩溃的情况下收集相关的设备参数信息和具体的异常信息,并发送这些信息到服务器供开发者分析和调试程序. 我们先建立一个crash项目,项目结构如图: 在MainActivity.ja

Android 打造形形色色的进度条 实现可以如此简单

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/43371299 ,本文出自:[张鸿洋的博客] 1.概述 最近需要用进度条,秉着不重复造轮子的原则,上github上搜索了一番,看了几个觉得比较好看的ProgressBar,比如:daimajia的等.简单看了下代码,基本都是继承自View,彻彻底底的自定义了一个进度条.盯着那绚丽滚动条,忽然觉得,为什么要通过View去写一个滚动条,系统已经提供了ProgressBar以及属于它的

Android音频系统之音频框架(转http://blog.csdn.net/uiop78uiop78/article/details/8796492)

1.1 音频框架 转载请注明,From LXS, http://blog.csdn.net/uiop78uiop78/article/details/8796492 Android的音频系统在很长一段时间内都是外界诟病的焦点.的确,早期的Android系统在音频处理上相比于IOS有一定的差距,这也是很多专业的 音乐播放软件开发商没有推出Android平台产品的一个重要原因.但这并不代表它的音频框架一无是处,相反,基于Linux系统的Android平台有 很多值得我们学习的地方. 1.1.1 Li

(六十二)Activity的启动模式(转载自http://blog.csdn.net/android_tutor/article/details/6310015)

本文转自: http://marshal.easymorse.com/archives/2950. 写的非常好,分享给大家!!! 在多Activity开发中,有可能是自己应用之间的Activity跳转,或者夹带其他应用的可复用Activity.可能会希望跳转到原来某个Activity实例,而不是产生大量重复的Activity. 这需要为Activity配置特定的加载模式,而不是使用默认的加载模式. 加载模式分类及在哪里配置 Activity有四种加载模式: standard singleTop

快速掌握 Android Studio 中 Gradle 的使用方法 [转http://blog.csdn.net/feelang/article/details/41783317]

Gradle是可以用于Android开发的新一代的 Build System, 也是 Android Studio默认的build工具. Gradle脚本是基于一种JVM语言 -- Groovy,再加上DSL(领域特定语言)组成的. 因为Groovy是JVM语言,所以可以使用大部分的Java语言库.所谓DSL就是专门针对Android开发的插件,比如标准Gradle之外的一些新的方法(Method).闭包(Closure)等. 由于Gradle的语法足够简洁,而且可以使用大部分的java包,当之

第十八章 并发登录人数控制——《跟我学Shiro》(http://blog.csdn.net/lhacker/article/details/19334305)

第十八章 并发登录人数控制——<跟我学Shiro> 博客分类: 跟我学Shiro 跟我学Shiro 目录贴:跟我学Shiro目录贴 在某些项目中可能会遇到如每个账户同时只能有一个人登录或几个人同时登录,如果同时有多人登录:要么不让后者登录:要么踢出前者登录(强制退出).比如spring security就直接提供了相应的功能:Shiro的话没有提供默认实现,不过可以很容易的在Shiro中加入这个功能. 示例代码基于<第十六章 综合实例>完成,通过Shiro Filter机制扩展Ki

Android APK反编译详解(附图) (转至 http://blog.csdn.net/ithomer/article/details/6727581)

本文Android反编译教程,测试环境: Win7 Ultimate x64 Ubuntu 12.04 x86_x64 反编译工具包 下载 (2012-10-10更新) 一.Apk反编译得到Java源代码 下载上述反编译工具包,打开apk2java目录下的dex2jar-0.0.9.9文件夹,内含apk反编译成java源码工具,以及源码查看工具. apk反编译工具dex2jar,是将apk中的classes.dex转化成jar文件 源码查看工具jdgui,是一个反编译工具,可以直接查看反编译后的

android 自定义照相机Camera黑屏 (转至 http://blog.csdn.net/chuchu521/article/details/8089058)

对于一些手机,像HTC,当自定义Camera时,调用Camera.Parameters的 parameters.setPreviewSize(width, height)方法时,如果width和height为奇数情况下,则会出现黑屏现象,解决办法可参考SDK提供的ApiDemos中关于Camera的 例子: List<Size> sizes = parameters.getSupportedPreviewSizes(); Size optimalSize = getOptimalPreview

Android 利用cursor来进行排序(转至http://blog.csdn.net/yangzongquan/article/details/6547860)

主要思路是:override move系列的方法,让cursor以自己想要的顺序来移动,从而达到对cursor排序的目的.比如数组A0里有 4(0),3(1),1(2),2(3),括号内为位置,排序后用数据记录A1:1(2),2(3),3(1),4(0).要访问第一个元素,则访问 A1[0]得到1(2),根据(2)找到在A0中的实际位置2,即1(2).参考了下系统的CursorWrapper和AbstractCursor代 码实现,另外有时间可以顺带了解下MatrixCursor. packag