[转载]Android代码优化工具——Android lint - 张兴业 - 博客园

mikel阅读(874)

[转载]Android代码优化工具——Android lint – 张兴业 – 博客园.

作为移动应用开发者,我们总希望发布的apk文件越小越好,不希望资源文件没有用到的图片资源也被打包进apk,不希望应用中使用了高 于minSdk的api,也不希望AndroidManifest文件存在异常,lint就能解决我们的这些问题。Android lint是在ADT 16提供的新工具,它是一个代码扫描工具,能够帮助我们识别代码结构存在的问题,主要包括:

 

1)布局性能(以前是 layoutopt工具,可以解决无用布局、嵌套太多、布局太多)

2)未使用到资源

3)不一致的数组大小

4)国际化问题(硬编码)

5)图标的问题(重复的图标,错误的大小)

6)可用性问题(如不指定的文本字段的输入型)

7)manifest文件的错误

 

    Android lint可以解决如上的问题,当然还有更多,具体的可以参考Android Lint ChecksAndroid官方也总结了lint能解决的问题,如下图。

 

    lint是命令工具,它已经完美的集成到了Eclipse中,我们可以方便的使用。通过lint,我们可以检测出每个问题的说明和问题的严重性,根据检测报告可以对程序作出改进。下面介绍下在Eclipse怎么使用lint。

 

lint的使用可以通过两个途径,Eclipse左上角的打钩的按钮或者选择项目->右键->Android Tools,如下图所示:

       

           图一                                           图二

 

lint工具简单实用,自动化分析,分析完成会给我们分析报告:

 

分析包括中会包括错误和警告,会给出具体的描述、类别、位置。上图是一个错误的描述,下图给出警告描述。

 


 

    Android lint是对android开发者很有帮助的一款工具,对于项目打包发布前优化代码、查找没用到的资源、查找错误等非常有帮助。作为开发者是必须掌握的工具之一,如果想了解更多可以参考lint

 

 

 

 

[转载]开发一款高端大气上档次的android应用需要必备的知识——记于2013年末 - 张兴业 - 博客园

mikel阅读(813)

[转载]开发一款高端大气上档次的android应用需要必备的知识——记于2013年末 – 张兴业 – 博客园.

Android入门还是很简单的,看两本书,翻阅几篇文章,搭建了开发环境就算入门了。可是怎样开发一款完备的Android应用呢,开发一款高端的android应用又需要那些知识呢,作者根据几年的开发经验做了一点总结,有不足之处也请读者补充。

 

一、网络开发技能

    开发的应用肯定会联网,在移动互联网时代,单机应用会越来越少。如果我们开发的应用缺少与服务器的交互,内容上不会丰富,更有可能的是我们无法控制到应 用,得不到用户及用户反馈。网络连接中用的最多的无非是Http或者Tcp。Android中http使用提供了三个包,我们常用的是 HttpClient、HttpURLConnection。网络上也有对http的封装包,例如volleyandroid-async-http,volley 使用的HttpURLConnection,android-async-http使用的HttpClient。虽然http的封装包使用起来都很简单, 但是我们也应该了解一下他们的区别,作者有一篇文章是介绍HttpClient、HttpURLConnection区别的,希望对您有帮助,AndroidHttp通信 HTTP Client与HttpURLConnection的区别

    volleyandroid-async-http都是非常简洁、伟大的http开发库,android-async-http有详细的开发文档,作者不做详细的说明。 Volley是Ficus Kirpatrick在Gooogle I/O 2013发布的一个处理和缓存网络请求的库,能使网络通信更快,更简单,更健壮;他没有使用文档,作者有几篇文章介绍了volley的使用。

Google I/O 2013 – Volley: Easy, Fast Networking for Android

网络通信框架Volley使用详细说明

Asynchronous HTTP Requests in Android Using Volley

Android UI开发第三十六篇——使用Volley加载图片列表

 

二、丰富的UI技能

    客户端开发不同于服务端,服务端只处理逻辑,客户端即处理逻辑又处理界面,而且界面又是多变的,不同的客户端,界面肯定不一样,相同的客户端,不同时期的界面也可能不一样,所以客户端开发者总感觉在修改界面,不是在改界面就是在改界面的路上大笑

    我们处在一个以“用户体验至上”的时代,产品经理经常会以此为理由修改已经确定的UI,为了应付多变的需求,我们必须储备尽可能多的UI处理技能。从最简 单的Button、TextView、EditText到高级点的Listiew、Tab、ViewPager,我们都应该掌握,我们还应该跟上时代掌握 ActionBar、Fragment等等,自定义View的技能也必不可少。作者有一个UI开发专栏,介绍到了很多常用UI知识,分享给大家。

Android UI开发专栏

 

三、保证应用安全技能

    应用安全是我们重点关注的,尤其涉及到支付相关应用。我们不希望自己的应用遭破解、也不希望用户被钓鱼、更不希望出现数据漏洞,那我们就需要提高应用安全技能。

    应用安全会涉及到代码安全、客户端与服务端通信安全、应用内部组件通信安全、数据库数据安全等等,作者也提供了一个专栏来介绍应用安全,内容还不够多,以后会再补充一些。作者也不是专业做安全的,难免有不足之处,也请读者谅解。

android应用安全

 

四、NDK技能,适当的使用so

    Android平台从诞生起,就已经支持C、C++开发。虽然Android的SDK基于Java实现,但这并不等同于“第三方应用只能使用Java”。 在Android SDK首次发布时,Google就宣称其虚拟机Dalvik支持JNI编程方式,也就是第三方应用完全可以通过JNI调用自己的C动态 库,即在Android平台上,”Java+C”的编程方式是一直都可以实现的。涉及到注重性能,或比较底层的程序都会使用C/C++开发,例如音视频编解码。有的应用会使用so文件,以保证应用安全。

    NDK全称是Native Development Kit。NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。官方关于NDK开发的文档相对较少,作者也总结了几篇文章,帮着初学者入门。

 

Android JNI入门

JNI专栏中包含了JNI入门、C调Java、Java调C、

 

    android开发中,使用到的知识不只是上面的四点,还会有数据库相关、Broadcast、Service等等,但是上面的四点在使用过程中更丰富、 多变;而数据库相关、Broadcast、Service等比较简单、单一,在每个应用中的使用方式都是一样的。在学习中我们更应该注重以上四点知识的积 累。有不足之处,望读者留言补充。

 

 

博主有幸成为2013年度博客之星的候选人之一,期待你的一票,谢谢您的支持。

投票猛击

http://vote.blog.csdn.net/blogstaritem/blogstar2013/xyz_lmn

[转载]Android 优化布局层次结构 - 张兴业 - 博客园

mikel阅读(860)

[转载]Android 优化布局层次结构 – 张兴业 – 博客园.

前面介绍过使用HierarchyViewer和Android lint来优化我们的程序,这一篇算是总结性的,借助一个小例子来说用怎么优化应用布局。这个例子是Android官网给出的,作者也当一把翻译。

    多数开发者可能会这样认为,使用基本的布局结构会产生高效的布局性能,其实这个想法是不完全正确的。我们每一个添加到应用的控件和布局,都需要初始化、布局、绘制,这些多是需要时间降低显示速度的。另外,嵌套多个使用layout_weight属性的LinearLayout实例会花费更大的代价,因为每一个子布局都要测量两次。如果这种布局使用在ListView或者GridView中,渲染时会更耗时。

    下面,我们根据一个布局示例使用HierarchyViewer和Android lint来检测优化布局结构。

 

使用HierchyViewer

    HierchyViewer需要你选择一个已连接的设备或者模拟器中的一个运行的程序,显示出布局的树结构。每个块上的红绿灯代表它的测量,布局,以及绘图性能,帮助你找出潜在的问题。有读者在读完Android UI 优化——使用HierarchyViewer工具后提出HierarchyViewer 没有显示出红绿黄灯和时间,这怎么解决。在tool目录启动HierarchyViewer确实没有相应的设置去显示,但是可以在eclipse中启动 HierarchyViewer去设置。Window->Open Perspective->others->hierarchyviewer。在Tree View点击三个圆圈的按钮,如图一:


                        图一

 

图一图二给出了显示绘制时间和不显示绘制时间的区别:

       

  图二                                                                             图三

    我们开始分析一个ListView的item布局,如图四,这个布局的左边显示了一幅图片,两个文字item放在右边。当布局被重复加载的时优化显得尤为重要。

                     图四

图四的布局文件在HierarcheyViewer中显示的层次结构如图五,选中LinearLayout会显示各种性能参数,如图六:

 

                         

                                 图五                                                                    图六        

 

     在图五中显示视图有三层结构,并且有些显示了红灯黄灯,这就需要我们优化,图六中也显示了绘制时间。

 

    上述布局性能较低的原因主要是由一个内嵌的LinearLayout所引起,为了提高性能,我们使用RelativeLayout,将该布局浅而广的扁平化结构代替为深而窄的树形结构,这样该布局变为一个2层的结构,修改后的布局结构如图七:

 

图七

     此时,绘制时间减少了,并且去掉了红灯、黄灯显示。

 

使用lint

Android代码优化——使用Android lint工具简单说明了lint的使用,在布局文件内运行Lint工具,可以找出那些可能要优化的布局结构。Lint工具代替Layoutopt工具,并且有更大的功能。如下是Lint的一些示例:

1、Use compound drawables,在LineraLayout布局中包含一个ImageView和一个TextView,可以使用compound drawable代替,性能会更好。

2、Merge root frame,如果root布局是FrameLayout,可以使用<merge/>代替,具体可参考Android抽象布局——include、merge 、ViewStub

3、Useless leaf,没有子布局的layout可以去掉

Useless parent ,一个布局不是ScrollView或者不是一个根布局,也没有背景,只有一个孩子节点,可以被删掉。

5、Deep layouts,布局若有太多内嵌,则性能很差。考虑使用RelativeLayout 以及GridLayout等扁平化布局代替。默认布局最大深度是10.

 

Android使用Lint请移步至Android代码优化——使用Android lint工具

 

 

 


再说些题外话,希望路过的各位支持,博主有幸成为2013年度博客之星的候选人,期待你的一票,谢谢您的支持。

投票猛击

http://vote.blog.csdn.net/blogstaritem/blogstar2013/xyz_lmn

[转载]【Android游戏开发之六】在SurfaceView中添加组件!!!!并且相互交互数据!!!! - 李华明Himi - 博客频道 - CSDN.NET

mikel阅读(764)

[转载]【Android游戏开发之六】在SurfaceView中添加组件!!!!并且相互交互数据!!!! – 李华明Himi – 博客频道 – CSDN.NET.

很多童鞋说我的代码运行后,点击home或者back后会程序异常,如果你也这样遇到过,那么你肯定没有仔细读完Himi的博文,第十九篇Himi专门写了关于这些错误的原因和解决方法,这里我在博客都补充说明下,省的童鞋们总疑惑这一块;请点击下面联系进入阅读:

【Android游戏开发十九】(必看篇)SurfaceView运行机制详解—剖析Back与Home按键及切入后台等异常处理!

 

      各位童鞋请你们注意:surfaceview中确实有 onDraw这个方法,但是surfaceview不会自己去调用!!!

  而我代码中的ondraw 也好 draw 也好,都是我自己定义的一个方法。。。放在线程中不断调用的,一定要注意!!

 

 

昨天圣诞节,没有出去,而是一天时间全部纠结在如何在SurfaceView中添加组件,例如添加常用的Button,TextView等等、一开始也想 着从网上找些资料看看有没有可参考的,但是发现搜到的结果仍是些童鞋对此很疑惑并且也在找寻答案,那么,这里就把圣诞节一天的成果来和各位童鞋分享;

 

1.因为我们的SurfaceView是个View对于添加的组件其实也是View,如果我们只是一味的想在SurfaceView中添加View组件其实是错误的思想,当然我一开始也是想着直接在SurfaceView中定义或者去使用组件,但是结果肯定是不成功的,因为View不能添加View!

 

2. 既然第一条肯定是错误的,那么我们就应该想到把我们的SurfaceView和组件都放在一个Layout里面,毕竟我们的的SurfaceView也是 一个view和其他组件一同放在我们的layout里,那么这样一来肯定就能完成在SurfaceView中添加组件的目的啦。下面先上截图、

 

 

 

大家看到中间白色区域就是我们的SurfaceView啦,最上方是组件TextView ,最下方是Button 、对的,要的就是这个效果!而不是像前面文章中多个Activity切换,这样都在一个界面中啦。哇哈哈啊。好、下面来看代码吧:

 

先放上Xml 代码:

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

&nbsp;

&nbsp;
&nbsp;

<button>

以上代码很简单,都是一些布局方式和各个组件一些属性及显示方式的设定,当然主要看如何对我们的SurfaceView如何注册在xml中的,那么每个组件都有id这样为了对后面其交互数据用到,因为我们要对每个组件操作,所以这里都索引了id方面从R文件中取出其对象。

那么,xml我们定义好了,看看代码中如何实现的,这里先说下Activity类中代码:

package com.himi;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener {
/** Called when the activity is first created. */
private Button button1, button2;
private TextView tv ;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);//隐去标题(应用的名字)
//此设定必须要写在setContentView之前,否则会有异常)
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main); //要先显示,然后再对其组件取出、处理操作
tv=(TextView)findViewById(R.id.textview);
button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(this);//这里是监听按键,因为本类使用了OnClickListener接口
button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(this);
/* 其实大家也可以不用本类使用接口,可以内部类来完成。
* 以下是不使用OnClickListener接口的绑定监听方式;
button2.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
//这里处理按键操作

}
});
*/
}
@Override
public void onClick(View v) {
if (v == button1) {
MySurfaceView.button_str = "button 1被触发";
tv.setText("button 1被触发");
} else if (v == button2) {
MySurfaceView.button_str = "button 2被触发";
tv.setText("button 2被触发");
}
}
}

该有的备注在代码后面都备注了,MySurfaceView.button_str,这个是自己的SurfaceView中定义的一个static 的变量用来交互数据用到;在那么下面就要看我们的SurfaceView,当在Xml注册需要注意什么了,我半天的时候都花在了这里!!!一定要引起注意,这也是在SurfaceView中并显示组件完成最重要的一步。

先分析:

1.SurfaceView类的创建和实现等等和之前都是一样的,该怎么去写还怎么去写,但是!构造函数一定要注意!

/*
* public MySurfaceView(Context context) { super(context); }//备注1(这里一定要引起注意,仔细看下文对备注1的解释 )
*/
public MySurfaceView(Context context, AttributeSet attrs) {//备注1}

这里解释下备注1:  这里有两个构造函数,当然我们用哪个都是可以的,但是在此时我们需要明确我们到底要使用哪个。

一个参数的构造函数:如果是new出来的此类实例肯定是没有问题,但是我们为了能在显示SurfaceView同时显示别的组件,所以把自定义的SurfaceView也当作组件注册在了main——xml中,所以这里需要注意,当在xml中注册的就必须在SurfaceView中使用这种含有两个参数的构造函数的方法, xml初始化的时候会调用两个参数的这个构造方法, (当时这个问题困扰了半天的研究时间,最后在一个群友的帮助下才发现是这里出了问题) 那么含有两个构造参数的方法里第二个参数指的自定义的组件的一些属性,就像长宽一样,你可以给组件属性,就是通过这个来传递的!

 

 

那么在SurfaceView 中并一同显示组件也就到底完结了,回顾下,一共分为3步,1.将我们的SurfaceView 作为一个组件view 和其他组件一同放置到布局中,当然布局的方式和显示的方式大家自己随自己喜欢定义! 2.在我们的SurfaceView中一定要使用两个构造函数的构造函数,一定!一定! 就这里有区别,别的还是该怎么处理就怎么处理,就是构造函数换了 3.交互数据,对其按键的绑定在 activity中完成,别把view绑定在咱们的SurfaceView中啊,否则报错- -、

 

这里说下为什么要在activity中去绑定按键处理 而不是在我们的surfaceview中去绑定:

 

 其实根据xml中定义button时的id 我们可以通过R.id 索引取到button,不管在activity中还是我们的surfaceview中都可以取到,但是!绑定button这一步如果在 surfaceview中去写就一定报错,原因我解释下;

我们在xml中定义我们的surfaceview 和 组件button、textview等等的时候 他们是同一级别的!!而不是把button包含在 surfaceview

里,所以虽然在surfaceview中可以根据id索引到button但绑定的时候是无法找到button的,只有我们的 activitysetContentView(R.layout.main); 显示的button,所以只能在显示它的activity中去绑定,这里需要注意下;

 

下面分享出源码:

 

源码下载地址: http://www.himigame.com/android-game/306.html

[转载]android ->在界面上使用URI编程 ----开发笔记1 - youxiachai - 博客园

mikel阅读(787)

[转载]android ->在界面上使用URI编程 —-开发笔记1 – youxiachai – 博客园.

导言

    做Android 开发有一段时间了,很多时候就是做些重复性的数据绑定,还有就是不够操作不够灵活,例如,我在某个界面要新增一个按钮,就需要发布一个新版本,就这么一个 按钮的话其实,可以完全由服务器控制,例如UC,凡客他们要更新首页,不可能为了更新一个首页特地开发一个新版本,那多傻啊,所以,观察了一下,想出了一 个可能解决的方案…

1.控制显示

  如何做到有服务器控制客户端的显示呢?

我们可以在客户端预留一些可能会用的例如UC的首页:

image

箭头标志的区域,是会根据不同情况而更新,而我现在就是要做出这样的效果.

如何控制显示?

我们知道,Android 找view是通过一系列ID 值找到相关的UI 那样,我们可以通过,在服务端,发送我们要修改的id.

1,是直接发送ID值还是发送一个具体路径?

这点,我毫无犹豫的选择了发送一个ui的路径,通过在客户端把这个URI进行转义,然后获得,相关的ID值.代码

/**
	 * 资源ID 的几种形式
	 * res = package:type/entry
	 * 1,res://com.achai@drawable/test_icon
	 * 2,res://drawable/test_icon
	 *(1) 不带具体包名
	 *entry = layout/main
	 *(2) 指定包名和类型实体
	 *com.achai@drawable/icon
	 * @param url
	 * @return
	 */
	public static int getResIdFromURL(String url){
		URI uri = URI.create(url);
		String scheme = uri.getScheme();
		String type = uri.getHost();
		String entry =	uri.getPath();
		entry = entry.replaceFirst("/", "");
		String packageName = uri.getUserInfo();
		if(ress == null)
			initRes();
		if(ress == null)
			return -1;
		//判断是否android资源URL
		if(!scheme.equals("res"))
			return -1;
		//1,判断是否是带包名的uri,并执行转换,获得资源ID
		if(packageName != null){
			return ress.getIdentifier(entry, type, packageName);
		}else{
			return ress.getIdentifier(entry, type, defPackage);
		}
	}

 

思路就如同代码那样,这样,我们的客户端就能够解析服务端发送过来要改哪个UI的了!接着就是修改值的事情了,这部分,以后继续!

2,控制监听

还是用uc作为例子:

image

在 UC的应用中心中,有个添加应用,这里就有个问题,我们如何监听我们新增的应用呢?

x

我翻阅android api的时候发现这么一行话

Tags

Unlike IDs, tags are not used to identify views. Tags are essentially an extra piece of information that can be associated with a view. They are most often used as a convenience to store data related to views in the views themselves rather than by putting them in a separate structure.

 

看到这里,我觉得就可以在这里做点文章了.

我们可以做一个tag 命令系统,然后,在这些新增应用的tag上打上一个标签命令,例如,UC就可能在这些应用上的tag 打上一个url 我们点击的时候,就会跳转到相关的应用.

根据这个思路敲下如下代码

	public void doViewClicked(View v){
		String url = v.getTag().toString().trim();
		if(v != null && url != null){
			//对view 中tag 进行解析
			doExecUrl(v, url);
		}
	}

	protected void doExecUrl(View view, String url) {
		try{
			if(url.indexOf('\n') > 0){
				String[] urls = url.split("\n");
				for(String u : urls){
					execUrl(view, u);
				}
			}else{
				execUrl(view, url);
			}
		}catch(RuntimeException ex){
			UserApp.curApp().showMessage("url 解析错误");
		}
	}

	private void execUrl(View view, String u) {
		URI execUri = URI.create(u);
		if(execUri == null)
			return;
		String prefix = execUri.getScheme();
		//执行相关的的命令
		if(prefix.equals("cmd")){
			execCmd(execUri);
		}else if(prefix.equals("act")){
			execAct(execUri);
		}

	}

	/**
	 * 执行命令操作
	 * @param u
	 */
	private void execCmd(URI u){
		String type = u.getHost();

		//监控 watch
		if(type.equals("watch")){
			//用于观察view 中的变量改变情况,晚些在实现
			return;
		}

		//结束当前view
		if(type.equals("finish")){
			theAct.finish();
			return;
		}

		//弹出提示
		if(type.equals("hint")){
			String msg = u.getFragment();
			if(msg != null){
				UserApp.showMessage(theAct, msg);
			}
			return;
		}
		//重新读取
		if(type.equals("reload")){
			return;
		}
		//设置指定id view 的值
		if(type.equals("setview")){
			return;
		}
		//设置显示某个view
		if(type.equals("showview")){
			return;
		}
	}

 

这样,我们可以在初始化view的时候,遍历所有view的元素,有tag命令就设置监听器!

	
	public void checkView(){

		ViewGroup vg = (ViewGroup) findViewById(R.id.line);
		int count = vg.getChildCount();
		for(int i=0; i < count; i ++){
			View child = vg.getChildAt(i);
			String tag = (String) child.getTag();
			if(tag != null){
				initTagCmd.setViewTagListenr(child);
			}
		}
	}

 

这样我们就可以很灵活的操作我们的UI 事件了!

k

可能有人会说效率问题?

效率的影响那是肯定会有的,但是,你想一下,一个view 官方推荐不要超过80个,一般而言也就10来个,遍历消耗的时间估计就算是htc g1(第一台android手机)那样的配置的手机都没问题,更何况是现在4核的android手机….

试一下效果:

image

这是一个开源的玩意…

  这个项目放在了github上,如果有朋友,想试一下可以到以下链接下载或者关注,提供一些建议,完善的话会慢慢来…

android_URI4Resource

[转载]android setTag (int key, Object tag)使用

mikel阅读(919)

[转载]android setTag (int key, Object tag)使用.

setTagAndroidview类中很有用的一个方法,可以用它来给空间附加一些信息,在很多场合下都得到妙用。

setTagObject tag)方法比较简单,这里主要谈一谈带两个参数的setTag方法。

官方的api文档中提到:“ The specified key should be an id declared in the resources of the application to ensure it is unique (see the ID resource type). Keys identified as belonging to the Android framework or not associated with any package will cause an IllegalArgumentExceptionto be thrown.”所以抛出IllegalArgumentException的原因就在于key不唯一,那么如何保证这种唯一性呢?定义一个final类型的int变量和硬编码一个值的方式都是行不通的。

 

privatestaticfinalint TAG_ONLINE_ID =1;
((Button) row.findViewById(R.id.btnPickContact)).setTag(TAG_ONLINE_ID,objContact.onlineid);
05-1820:29:38.044: ERROR/AndroidRuntime(5453): java.lang.IllegalArgumentException:The key must be an application-specific resource id. 05-1820:29:38.044: ERROR/AndroidRuntime(5453):     at android.view.View.setTag(View.java:7704) 05-1820:29:38.044: ERROR/AndroidRuntime(5453):     at com.mypkg.viewP.inflateRow(viewP.java:518)
如果只需要设置一个tag,那么直接调用setTag(Object tag)方法就可以轻松搞定,如果一定需要使用多个tag绑定,那么需要先在res/values/strings.xml中添加
<resources>
<item type="id" name="tag_first"></item>
<item type="id" name="tag_second"></item>
</resources>
使用的时候写成
imageView.setTag(R.id.tag_first,"Hello"); imageView.setTag(R.id.tag_second,"Success");
就可以了

[转载]android:tag与android:id的区别 - kaixinbingju的专栏 - 博客频道 - CSDN.NET

mikel阅读(960)

转载android:tag与android:id的区别 – kaixinbingju的专栏 – 博客频道 – CSDN.NET.

(1)tag的优势:只要不在同一个父控件中,tag可以有相同的名字。view.findViewWithTag(id)

(2)id的优势:查找速度不tag快。view.findViewById(id).

findViewById()函数其实有两种,一种是Activity类中findViewById()函数,另外一种是View类中定义的findViewById()函数.

一般我们在oncreate()方法中使用的(**view)findViewById(R.id.**)既是调用的Activity中的findViewById()函数,个函数是在寻找在xml中定义的指定id的对象.而在其他情况写出的***view.findViewById()中调用的是view类中的findViewById(),从一个view的child view中寻找指定id的对象,所以即使几个layout的XML文件中的View的id号相同的话,只要他们没有相同的父节点,或有相同的父亲节点,但不在父节点及以上节点调用findViewById通过id来查找他们就是没有问题。

既然Activity中的findViewById()是从R.java中寻找东西,那么我们就要杜绝相同名字的控件,在调用view中的findViewById()一定要想好父View是谁!即**view.findViewById()中的**view要找对,如果没有找对父View,返回基本都是null了。

在网上看见View.findViewById() 和 Activity.findViewById()执行效率不一样

通常我们使用Activity.findViewById()如:


    TextView tv_inner_1 = (TextView)this.findViewById(R.id.tv_inner_1);   
    TextView tv_inner_2 = (TextView)this.findViewById(R.id.tv_inner_2);  

View.findViewById() 如:


    View layout_outer = this.findViewById(R.id.layout_outer);   
    TextView tv_inner_1 = (TextView)layout_outer.findViewById(R.id.tv_inner_1);   
    TextView tv_inner_2 = (TextView)layout_outer.findViewById(R.id.tv_inner_2);  

他们都是针对下面同一个xml


    <LinearLayout>   
         <LinearLayout id="@+id/layout_outer">   
               <TextView id="@+id/tv_inner_1"/>   
               <TextView id="@+id/tv_inner_2"/>   
         </LinearLayout>   
    </LinearLayout> 

[转载]Android中继承View的研究(一) -- 一个小Demo

mikel阅读(1045)

.Android中继承View的研究(一) — 一个小Demo

Android中继承View的研究() — 一个小Demo

序:总想写下点东西出来,但是总是没有时间, 不是业务忙就是又有新的研究项目,最近有点时间,写点以前一直想写有一直没写的东西,供大家参考,但是终归是一家之言,仅供参考。本人的每次讲解都会提供 源代码下载,并且会最近会一直更新还请大家多多关注,有不对的地方欢迎指教。好了,不说题外话了,咱们开始研究。
 

一、         概述

 
对于一个手机的用户体验来说最重要的部分莫过于界面了,为此Android中提供了通过XML布局的方式来进行布局,各种布局方式和控件的使用就不多说了,如果有不会的可以参考下这个一个Demo让你掌握所有的控件。对于布局来说,个人感觉只用XML布局会有一定的局限性。所以就有了通过继承View以及其他控件来实现的Android布局。
就像HTML中有的人喜欢用css布局,有的人喜欢用table布局,众说纷纭,各执一词,但是个人感觉两个结合起来使用比较好,呵呵,就像Android中开发用自定义View和使用XML一样,使用两种方式结合开发,不失是一个利器。
 

二、一个使用自定义ViewDemo

 
MainActivity
import android.app.Activity;

import android.os.Bundle;

/**

* 使用自定义的View

* */

public class MainActivity extends Activity {

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(new HelloView(this));// 使用自定义的View

}
}

HelloView

import android.content.Context;

import android.view.View;

public class HelloView extends View {

/**

* 这个是我们要在Activity中初始化用的

* */

public HelloView(Context context){

super(context);

}
}
运行一下:
 

 
这个是不是看起来没有效果啊,哈哈,其实这个是系统默认的界面,也就是View默认的界面
 
我们来让他改变一下
 
View中写一个方法

/**

* 绘制View

* */

protected void onDraw(Canvas canvas){

canvas.drawColor(Color.BLUE);
}

运行试试看:

 
是不是非常神奇,由黑色变成蓝色了,哈哈,有点小小的成就感没啊>o<哈哈。
 
  博客地址搬迁通知:即日起本博将搬到个人独立博客思享

本文出自 “皓月繁星” 博客,请务必保留此出处http://lovewf.blog.51cto.com/1723922/723632

Android中继承View的研究(二) -- 绘图的基本知识

mikel阅读(913)

.Android中继承View的研究(二) — 绘图的基本知识

      既然使用onDraw可以绘制为蓝色背景,那我们是不是可以干一些坏事了,哈哈。。。。。

       不过干坏事之前要记得先学习学习graphics里面的一些知识。
 

一、基础预备知识

1Canvas–画板
              Canvas是一个大大的画板,这个画板有多大,就看Android系统能支持多大的Canvas了,以后慢慢就会体会到这个Canvas到底有多大,不过原理上:Canvas是无穷大的
 
       2Paint–画笔
              有画板没有画笔怎么能行了,没错Paint就是画笔。掌管Android王国中的所有画笔,只要和Canvas打交道,没有画笔是万万不行的。。。。。。
 
       3Color–颜色
              在这个设计的世界里,没有颜色掌管各种颜色怎么行呢,所以这里定义了各种常用的颜色,嘎嘎,还提供了灵活的Color.parseColor(String str);函数这个函数太强大了,哈哈,解析Alpha颜色和普通的颜色。
       4Bitmap–位图
              没有图片的世界是悲惨的,这个类可以掌管天下的pngjpg图片,不过貌似Androidpng支持比jpg好。呵呵,这个我们在下回研究,我们会使用三种方法获得Drawable文件夹下的图片
 

二、开始涂鸦

准备好了吗??我们开始涂鸦了……………..
/**

* 绘制View

* */

protected void onDraw(Canvas canvas){

canvas.drawColor(Color.WHITE);
}

我们先绘制画板为白色,然后先使用一下画笔哈哈.......

/**

* 定义一个画笔

* */
Paint paint;

/**

* 初始化画笔

* */

public void intiPaint(){

paint = new Paint();

// 设置画笔

paint.setColor(Color.GREEN); // 绿色画笔

paint.setAntiAlias(true); // 打开抗锯齿

paint.setTextSize(15); // 设置字体大小
}

/**

* 绘制View

* */

protected void onDraw(Canvas canvas){

canvas.drawColor(Color.WHITE);

canvas.drawText("我的第一次使用画笔--繁星皓月", 20, 20, paint);
}
 
             

本文出自 “皓月繁星” 博客,请务必保留此出处http://lovewf.blog.51cto.com/1723922/723669

[转载] Android中自定义View的研究(三) -- 获得Bitmap的三种方法

mikel阅读(861)

. Android中自定义View的研究(三) — 获得Bitmap的三种方法

    是不是开始摩拳擦掌了,哈哈,有感觉了吧,有感觉了就加油,开始下一步学习,一步一步始终会学到东西,这章不解释,上面有完整注释
 

一、使用BitmapFactory解析图片

// --&gt; 使用BitmapFactory解析图片

public void myUseBitmapFactory(Canvas canvas){

// 定义画笔

Paint paint = new Paint();

// 获取资源流

Resources rec = getResources();

InputStream in = rec.openRawResource(R.drawable.haha);

// 设置图片

Bitmap bitmap =BitmapFactory.decodeStream(in);

// 绘制图片

canvas.drawBitmap(bitmap, 0,20, paint);
}

使用BitmapDrawable解析图片

// --&gt; 使用BitmapDrawable解析图片

public void myUseBitmapDrawable(Canvas canvas){

// 定义画笔

Paint paint = new Paint();

// 获得资源

Resources rec = getResources();

// BitmapDrawable

BitmapDrawable bitmapDrawable = (BitmapDrawable) rec.getDrawable(R.drawable.haha);

// 得到Bitmap

Bitmap bitmap = bitmapDrawable.getBitmap();

// 在画板上绘制图片

canvas.drawBitmap(bitmap, 20,120,paint);
}

用InputStream和BitmapDrawable绘制

// --&gt; 使用InputStream和BitmapDrawable解析图片

public void myUseInputStreamandBitmapDrawable(Canvas canvas){

// 定义画笔

Paint paint = new Paint();

// 获得资源

Resources rec = getResources();

// InputStream得到资源流

InputStream in = rec.openRawResource(R.drawable.haha);

// BitmapDrawable 解析数据流

BitmapDrawable bitmapDrawable = new BitmapDrawable(in);

// 得到图片

Bitmap bitmap = bitmapDrawable.getBitmap();

// 绘制图片

canvas.drawBitmap(bitmap, 100, 100,paint);
}

 

本文出自 “皓月繁星” 博客,请务必保留此出处http://lovewf.blog.51cto.com/1723922/724114