- 浏览: 637095 次
- 性别:
- 来自: 苏州
文章分类
最新评论
-
laj12347:
楼主太给力了
Eclipse设置、调优、使用 -
kunlyy:
楼主太给力了
Eclipse设置、调优、使用 -
knight_black_bob:
mark ~
Eclipse设置、调优、使用 -
hujunxiang:
好全好全~~~
Eclipse设置、调优、使用 -
bugyun:
楼主辛苦了
Eclipse设置、调优、使用
虽然android的源码也时不时的会去看,但大部分还是只能看懂部分。这里只把能完全看懂的源码上传了。
android.widget.AnalogClock
这个类比较简单,如果想要创建自己的View,可以从参考这个类开始。像TextView这种将近一万行的源码就太多了。还有一个比这个稍微难一点的是ImageView,也可以看那个类
不带布局的RadioGroup——NoLayoutRadioGroup
android提供的RadioGroup是一个LinearLayout,有时我们要在像TableLayout中的每个行使用一个RadioButton的话,RadioGroup就不太好用,所以参考RadioGroup实现了一个不带布局的RadioGroup.
android.widget.AnalogClock
这个类比较简单,如果想要创建自己的View,可以从参考这个类开始。像TextView这种将近一万行的源码就太多了。还有一个比这个稍微难一点的是ImageView,也可以看那个类
public class AnalogClock extends View { private Time mCalendar; /** 时针背景 */ private Drawable mHourHand; /** 分针背景 */ private Drawable mMinuteHand; /** 表盘背景 */ private Drawable mDial; /** 表盘宽度 */ private int mDialWidth; /** 表盘高度 */ private int mDialHeight; /** 是否添加到WindowManager中 */ private boolean mAttached; private final Handler mHandler = new Handler(); private float mMinutes; private float mHour; /** 时间是否改变了 */ private boolean mChanged; public AnalogClock(Context context) { this(context, null); } public AnalogClock(Context context, AttributeSet attrs) { this(context, attrs, 0); } public AnalogClock(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); Resources r = mContext.getResources(); TypedArray a = context.obtainStyledAttributes( attrs, com.android.internal.R.styleable.AnalogClock, defStyle, 0); mDial = a.getDrawable(com.android.internal.R.styleable.AnalogClock_dial); if (mDial == null) { mDial = r.getDrawable(com.android.internal.R.drawable.clock_dial); } mHourHand = a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_hour); if (mHourHand == null) { mHourHand = r.getDrawable(com.android.internal.R.drawable.clock_hand_hour); } mMinuteHand = a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_minute); if (mMinuteHand == null) { mMinuteHand = r.getDrawable(com.android.internal.R.drawable.clock_hand_minute); } mCalendar = new Time(); mDialWidth = mDial.getIntrinsicWidth(); mDialHeight = mDial.getIntrinsicHeight(); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); if (!mAttached) { mAttached = true; IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_TIME_TICK); filter.addAction(Intent.ACTION_TIME_CHANGED); filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); getContext().registerReceiver(mIntentReceiver, filter, null, mHandler); } // NOTE: It's safe to do these after registering the receiver since the receiver always runs // in the main thread, therefore the receiver can't run before this method returns. // The time zone may have changed while the receiver wasn't registered, so update the Time mCalendar = new Time(); // Make sure we update to the current time onTimeChanged(); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); if (mAttached) { getContext().unregisterReceiver(mIntentReceiver); mAttached = false; } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = MeasureSpec.getMode(widthMeasureSpec); // layout提供的可用Width int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); // layout提供的可用Height int heightSize = MeasureSpec.getSize(heightMeasureSpec); float hScale = 1.0f; float vScale = 1.0f; // 如果layout_width和layout_height是指定了值的 if (widthMode != MeasureSpec.UNSPECIFIED && widthSize < mDialWidth) { hScale = (float) widthSize / (float) mDialWidth; } if (heightMode != MeasureSpec.UNSPECIFIED && heightSize < mDialHeight) { vScale = (float )heightSize / (float) mDialHeight; } // 按照缩的比较小的缩放 float scale = Math.min(hScale, vScale); setMeasuredDimension(resolveSize((int) (mDialWidth * scale), widthMeasureSpec), resolveSize((int) (mDialHeight * scale), heightMeasureSpec)); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mChanged = true; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); boolean changed = mChanged; if (changed) { mChanged = false; } int availableWidth = mRight - mLeft; int availableHeight = mBottom - mTop; // 居中 int x = availableWidth / 2; int y = availableHeight / 2; final Drawable dial = mDial; int w = dial.getIntrinsicWidth(); int h = dial.getIntrinsicHeight(); boolean scaled = false; // 图片实际宽高比view的宽高大时,要对图片缩放 if (availableWidth < w || availableHeight < h) { scaled = true; float scale = Math.min((float) availableWidth / (float) w, (float) availableHeight / (float) h); canvas.save(); canvas.scale(scale, scale, x, y); } if (changed) { dial.setBounds(x - (w / 2), y - (h / 2), x + (w / 2), y + (h / 2)); } dial.draw(canvas); // 绘制时针 canvas.save(); canvas.rotate(mHour / 12.0f * 360.0f, x, y); final Drawable hourHand = mHourHand; if (changed) { w = hourHand.getIntrinsicWidth(); h = hourHand.getIntrinsicHeight(); hourHand.setBounds(x - (w / 2), y - (h / 2), x + (w / 2), y + (h / 2)); } hourHand.draw(canvas); canvas.restore(); // 绘制分针 canvas.save(); canvas.rotate(mMinutes / 60.0f * 360.0f, x, y); final Drawable minuteHand = mMinuteHand; if (changed) { w = minuteHand.getIntrinsicWidth(); h = minuteHand.getIntrinsicHeight(); minuteHand.setBounds(x - (w / 2), y - (h / 2), x + (w / 2), y + (h / 2)); } minuteHand.draw(canvas); canvas.restore(); // 结束 if (scaled) { canvas.restore(); } } private void onTimeChanged() { mCalendar.setToNow(); int hour = mCalendar.hour; int minute = mCalendar.minute; int second = mCalendar.second; mMinutes = minute + second / 60.0f; mHour = hour + mMinutes / 60.0f; mChanged = true; } private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)) { String tz = intent.getStringExtra("time-zone"); mCalendar = new Time(TimeZone.getTimeZone(tz).getID()); } onTimeChanged(); invalidate(); } }; }
不带布局的RadioGroup——NoLayoutRadioGroup
android提供的RadioGroup是一个LinearLayout,有时我们要在像TableLayout中的每个行使用一个RadioButton的话,RadioGroup就不太好用,所以参考RadioGroup实现了一个不带布局的RadioGroup.
/*** * 使用了这个类,RadioButton的OnCheckedChangeListener会被覆盖掉,所以 * 要使用监听器的话,使用这边的NonLayoutRadioGroup.OnCheckedChangeListener */ public class NonLayoutRadioGroup { public interface OnCheckedChangeListener { /*** * @param group 触发该事件的NonLayoutRadioGroup * @param view 触发该事件的RadioButton, 当调用clearCheck时,view的值为null */ public void onCheckedChanged(NonLayoutRadioGroup group, RadioButton view); } private List<RadioButton> mRadioButtons = new ArrayList<RadioButton>(); private RadioButton mCheckButton; private OnCheckedChangeListener mListener; private CompoundButton.OnCheckedChangeListener mCheckedListener = new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (!isChecked) { mCheckButton = null; return; } if (mCheckButton != null) { mCheckButton.setChecked(false); } setCheckedButton((RadioButton) buttonView); } }; public void addRadioButton(RadioButton button) { // 不能添加null // 为没有id的RadioButton生成一个Id if (button.getId() == View.NO_ID) { button.setId(button.hashCode()); } button.setOnCheckedChangeListener(null); if (button.isChecked()) { // 移除原来的 if (mCheckButton != null) { mCheckButton.setChecked(false); } setCheckedButton(button); } button.setOnCheckedChangeListener(mCheckedListener); mRadioButtons.add(button); } public void removeRadioButton(RadioButton button) { // 添加到这里面的移除时,才需要清除其OnCheckedChangeListener if (mRadioButtons.contains(button)) { button.setOnCheckedChangeListener(null); mRadioButtons.remove(button); } } public void setOnCheckedChangeListener(OnCheckedChangeListener listener) { mListener = listener; } public void check(RadioButton button) { // check原来选中的 if (button != null && mCheckButton == button) { return; } // 移除选中的 if (mCheckButton != null) { mCheckButton.setChecked(false); } // 设置选中的 if (button != null) { button.setChecked(true); } // 触发监听器 setCheckedButton(button); } public void clearCheck() { check(null); } public RadioButton getCheckedRadioButton() { return mCheckButton; } // //////////////////////////////////////////////// /*** * 设置选中的RadioButton */ private void setCheckedButton(RadioButton button) { mCheckButton = button; if (mListener != null) { if (button != null) { mListener.onCheckedChanged(this, button); } else { mListener.onCheckedChanged(this, null); } } } }
发表评论
-
Error: Cannot run program "sh": Launching failed
2014-02-20 21:05 3675**** Build of configuration De ... -
通过wifi来使用ADB[转]
2013-11-16 16:09 1499adb除了通过usb连接外,还可以通过tcp连接建立调试,在 ... -
Installation failed due to invalid APK file!
2013-11-16 15:42 8144今天在Eclipse里面测试Android的开发。 写好的代 ... -
QQ2013导致adb不能使用问题的修复[转]
2013-11-16 14:48 1613由于实在没法不用QQ,当QQ哭着闹着要升级到最新版的时候,手 ... -
adt安装慢解决
2013-06-08 14:29 4759安装adt的时候不管时在线安装还是下载下来了离线安装,都不见安 ... -
android 百度地图 wgs84和baidu09坐标转换
2012-11-14 23:35 17650wgs84: gps获取出来的坐标 ... -
hiero使用
2012-11-14 16:51 5135hiero是一个java小程序,能够帮助用户自定义.fnt ... -
分享一个日志类
2012-11-09 02:07 351/*** * <p> 封装日志api的调用 ... -
android相关工具收集
2012-07-30 09:33 1239常用 Java 静态代码分析工具的分析与比较 http://b ... -
proguard使用
2012-07-26 23:39 5327proguard的常见配置参数 -include {filen ... -
一张图让你明白android 九宫格工具使用
2012-07-07 16:13 2667... -
android sdk, adt等的下载
2012-06-28 21:38 16854一些小技巧 在eclipse中 ... -
ProgressBar定制
2011-12-07 09:04 4104ProgressBar的基本使用 可以参考这个:http:// ... -
Dialog定制
2011-11-18 14:47 7171定制dialog的方式 1. 可以通过Theme的方式,and ... -
Toast的使用
2011-10-31 16:12 6301Toast的基本原理其实就是将一个View添加到WindowM ... -
android 开发资料收集
2011-10-28 14:32 1712Android 解屏幕锁与点亮屏幕:键盘锁(KeyguardM ... -
android单元测试
2011-09-09 17:08 0android测试框架涉及的类的UML图 activity测 ... -
android.os包中一些类的使用
2011-09-08 15:09 23560android.os.Build Build.BOARD ... -
android游戏开发学习
2011-09-06 16:55 10968相关资源 2D中如何判断一点在另一个点的那个方位: http: ... -
android xml解析 - sax
2011-08-16 18:19 2363android 2.3 sdk提供的与sax解析相关的类和接口 ...
相关推荐
"Android源码阅读器"是一个专门为开发者设计的工具,帮助他们更有效地阅读和理解Android操作系统的源代码。这个压缩包可能包含了一个或多个应用程序或者工具,以图形化或者文本方式来呈现复杂的Android源码结构。...
使用Android Studio阅读整个Android源码
Android应用源码(精)记事本小程序,加注释,适合阅读.rar Android应用源码Android平台下通过HTTP协议实现断点续传下载.rar Android应用源码Hibernate4Android.rar Android应用源码http、udp、tcp网络交互组件.rar ...
Android应用源码13套安卓源码合集: android应用源码仿ireader书架.rar android应用源码动画效果 translate、scale、alpha、rotate 切换Activity动画.rar android应用源码可以报警的手电.rar android应用源码图片...
在本项目中,我们讨论的是一个名为"FTEReader-Android-master"的Android阅读应用程序的源码。这个应用专门设计用于提供本地和网络阅读体验,包含了一系列与Android开发相关的技术点,尤其是涉及到用户界面(UI)设计...
这篇文档将深入解析《Android应用源码电子书阅读器源码》这个项目,它是一个针对IT计算机专业学生的毕业设计示例,旨在帮助他们理解和实践Android应用程序的开发。在这个项目中,我们将探讨Android App的移动开发...
《Android小说阅读器CoolReader源码解析》 在Android应用开发领域,酷读器(CoolReader)是一款广受欢迎的小说阅读应用,它以其简洁的界面和丰富的功能深受用户喜爱。本文将深入探讨这款开源Android小说阅读器的...
《Android程序研发:深入解析CoolReader小说阅读器源码》 在移动设备上,阅读应用是用户日常使用的重要工具之一,而CoolReader是一款广受欢迎的免费电子书阅读器,尤其在Android平台上,它以其简洁的界面和强大的...
Android应用源码11套安卓源码合集: Android Gps日志记录程序源码.rar Android listview 滑动删除(具体效果360手机卫士后台通知).rar Android MP3播放器,带卡拉OK字幕.rar Android “遇见”android应用源码.rar ...
《Android应用源码电子书阅读器源码》是一款专为Android平台设计的源代码实现,旨在帮助开发者理解和学习Android应用程序的开发技术。该源码涵盖了Java编程语言的应用,以及Android SDK的相关组件和功能,是Android...
《Android 源码设计模式解析与实战》不仅分析了Android源代码的设计模式,更结合实例演示了如何使用这些设计模式。看这本书,既能学到如何分析、学习Android源代码,又能提高自己架构设计水平 《Android 源码设计...
Android应用源码30套安卓源码合集: andriod闹钟源代码.rar Android Gps日志记录程序源码.rar Android MP3播放器,带卡拉OK字幕.rar Android 个人记账程序源码.rar Android 仿Mac的Dock.rar Android 口袋微博服务器...
Android应用源码10套安卓源码合集: android应用源码DroidBrowser浏览器.rar android应用源码QQ_UI之分类菜单.rar android应用源码QQ的登录界面.rar android应用源码Socket的客户端通信.rar android应用源码tooxin图...
Android 源码源码在线访问,覆盖各版本,包括最新的Android L. 无需setup git, 无需费时下载。
下面我们将详细探讨Android源码学习的一些关键知识点。 首先,Android源码的分析通常从系统架构开始,它分为四个主要层次:Linux内核、硬件抽象层(HAL)、系统运行库层和应用程序框架层。这些层次构成了Android运行...
源码分析有助于开发者理解RSS订阅和解析的过程,以及如何在Android环境下构建一个功能完善的新闻阅读应用。以下是对该源码中涉及的关键知识点的详细说明: 1. **RSS(Really Simple Syndication)**: RSS是一种XML...
首先,要下载Android源码,你需要一个Linux环境,因为官方的构建工具链和文档主要针对这个平台。Ubuntu是最常见的选择,但其他基于Debian的发行版也可以。确保你的系统安装了必要的依赖项,如Git、Repo、Java JDK...
本项目提供的“android pdf阅读源码”是一个可运行的解决方案,专门针对Android设备设计,它能够处理PDF文档的显示、预览以及通过蓝牙进行打印的需求。 首先,我们要理解PDF(Portable Document Format)是一种广泛...