Android开发常见问题总结

Android开发常见问题总结-20xx年12月19日 ?

? 发布时间:2010-12-19 作者:Android开发网原创

随着开发Android平台的程序员不断增多,Android123每周末将总结国内外开发者论坛中的一些典型问题一起分析解答。20xx年12月19日我们从一些初级入门问题开始分类:

1. Q: 入门Android开发需要了解哪些知识?

A: 了解必要的Java基础知识比如Thread、Socket、File I/O,针对平台而言掌握Android特有的Activity、Service、Broadcast、ContentProvider、Handler、各种显示控件如Button、EditText等等。

2. Q: 开发Android使用哪个版本的SDK比较好?

A: 对于SDK版本,我们有两种选择,如果你开发技术比较高兼容的最全面可以考虑使用Android 1.5 API Level为3的,高版本API使用Java反射调用,如果你考虑较简单可以使用Android 2.0或更高版本,发布时和API兼容性无关的可以设置androidmanifest.xml中的minSDK版本来解决。

3. Q: Android开发用机,选择哪款比较好?

A: 对于公司采购,我们需要考虑比较周全,高中端以及不同分辨率的设备都要有,甚至平板、Ophone这些设备。目前公司从高端到低端推荐 Nexus S或Nexus One、Motorola Milestone、HTC Hero,平板选择Galaxy Tab我们的意思是选择专业的制造Android手机的大厂,这样做保证固件的版本升级速度。对于个人开发测试而言,建议使用高配置机型否则项目开发完后,可能自己的设备也淘汰了。

4. Q: 开发时固件版本问题

A: 对于固件版本而言Android开发网有两个问题要说,如果你追求固件升级速度使用谷歌自己的贴牌机型Nexus系列比较可靠,当然保证运行的可靠性建议使用英文版的官方固件,各种第三方固件并不是大多数人都是用的,可能因为提速或精简造成各种意料之外的问题,比如Android123曾经就测试过一款自制的ROM调试时产生很多莫名其妙的异常,刷回官方固件就很正常。

5. Q: Android手机需要越狱吗?

A: 对于Android平台而言越狱之后可能对于开发Java层应用帮助不大,同时在全球Android越狱的用户并不是很多,不像iPhone不越狱无法安装输入法,使用盗版软件等等,所以Android

Android开发常见问题总结

手机越狱不越狱

无所谓,同时越狱后开发的应用在非Root的手机上可能无法使用,所以对于开发者来说纯净接近官方的系统 兼容性和可靠性最大,并不是所有人买了手机都去那样折腾的。

6. Q: Android开发环境支持Win7系统吗?

A: 目前来看开发Android几乎任何平台都支持,比如WinXP、Win7、Mac OS X和主流的Linux发行版,只要你配置正确不会存在问题的。

7. Q: Android能用纯C/C++开发吗?

A: 目前截止到2.3系统来看,最终安装的文件仍然是apk格式,界面和系统大多数功能均使用Java开发,但是稍微高端的应用考虑到性能和安全性使用C/C++是必要的,C/C++最终编译的so文件就相当于Windows下的dll动态库,需要一个宿主去加载调用,我们通过Java的JNI去调用这些本地方法,目前从NDK的版本来看Google不断增强和开放C++在Android开发的用处,以保证和iPhone这种使用本地语言开发出来的软件体验度不能差距太大。

8. Q: Android开发者薪水如何?

A: 目前Google手机平台不断升温,Android程序员的薪水因技术差距可能比较大,同时按照增长来看开发者数量不断提高,从长远来讲开发者的数量不会太少,目前从2500-30000的都用,根据技术和不同地域而定,同时必要掌握NDK使用C++语言开发Android的程序员更有竞争力些,毕竟常规的J2ME、J2SE和J2EE程序员转到Android还是很快的对于入门而讲,但是整个Android系统很庞大,更新也比较快可能是入门简单提高和深入就很难了,如果你技术足够高,应该能提到Google的程序员来开发Android就差不多了。

9. Q: 相对而言Android、iPhone和Windows Phone他们之间哪个前景更好?

A: iPhone开发者在国外相对饱和,而国内仍然有很大的空缺,但是由于SDK自身的限制已经很多Mac OS内部的一些设计上的先天不足,所以很多Android上有的,在iPhone上不越狱使用第三方SDK是无法实现的,比如输入法和来电防火墙这些基本的应用,而Windows Phone 7目前比较绝了,微软的限制不亚于iPhone目前从界面和SDK来看表现一般,同时使用的Silverlight库知道的人比较好,相对来说在国内还有一定的需求,Android目前对于国内来说山寨机和平板这些产品还是有不错的发展空间。

10. Q: 有哪些好的Android开发书籍推荐?

A: 目前来看国内的一些书籍讲解的不是很好,很多书籍概念错误经历了n个版次,Android123推荐看SDK文档,学习SDK中的例子比如ApiDemos,接着直接看Android系统开源应用的代码,国内很多书大同小异基本上就是骗钱的,如果真想的想购买,建议买国内翻译过来的如果英文足够,直接看英文PDF原版比较好。

 

第二篇:android开发总结

Android 图片平铺效果

方法一 XML方式平铺 首先,两个单词的中文意思分别是dither(抖动)和tileMode(平铺) 1,先来介绍tileMode(平铺) tileMode 属性就是用于定义背景的显示模式:

disabled

默认值,表示不使用平铺

clamp

复制边缘色彩

repeat

X、Y 轴进行重复图片显示,也就是我们说要说的平铺

mirror

在水平和垂直方向上使用交替镜像的方式重复图片的绘制 它的效果类似于 让背景小图不是拉伸而是多个重复(类似于将一张小图设置电脑桌面时的效果)

可绘制资源是指能够被绘制到屏幕上的图形的一般化概念,并且能够用诸如getDrawable(int)等API方法来获取这些资源,或者使用诸如android:drawable和android:icon属性把它们应用到另一个XML资源中。以下是几种不同的可绘制资源类型: 位图文件:

位图图形文件(.png、.jpg或.gif)。每个位图资源会创建一个BitmapDrawable对象。

Nine-Patch文件:

Nine-Patch文件是一个带有可拉伸区域的PNG文件,它允许图片基于内容进行尺寸的调整(.9.png)。每个Nine-Patch资源会创建一个NinePatchDrawable对象。

层列表:

层列表管理一个绘制资源数组。它们会按照数组的顺序进行描画,因此索引最大的元素被画在最上面,一个层列表会创建一个LayerDrawable对象。

状态列表:

状态列表是一个XML文件,文件中针对不同的状态定义了要引用的不同位图图形(例如,按钮被按下时,要使用的不同的图片)。一个状态列表会创建一个

StateListDrawable对象。

级别列表:

级别列表是一个定义可替代绘制资源的XML文件,每个资源都会给分配一个最大的数字值,一个状态列表会创建一个LevelListDrawable对象。

过渡绘制资源:

它是一个定义绘制资源的XML文件,文件中的绘制资源能够在两个绘制资源之间渐入渐出。一个XML文件会创建一个TransitionDrawable对象。

插图绘制资源:

它是一个定义绘制资源的XML文件,文件中的绘制资源能够按照指定的距离插入到另一个绘制资源中。当View对象需要绘制的背景比View的实际边框要小时,这个资源是有用的。

剪辑绘制资源:

它是一个定义绘制资源的XML文件,使用文件中的定义,基于绘制资源的当前级别值对另一个绘制资源进行剪辑。它会创建一个ClipDrawable对象。

缩放绘制资源:

它是一个定义绘制资源的XML文件,使用这个文件中的定义会基于当前的级别值来改变另一个绘制资源尺寸。它会创建一个ScaleDrawable对象。

形状绘制资源:

它是一个定义几何图形的XML文件,包括颜色和几何形状。它会创建一个

ShapeDrawable对象。

注意:在XML中,颜色资源也能够用于绘制资源。例如,在创建状态列表绘制资源时,android:drawable属性就可以引用一个颜色资源(如:android:drawable=”@color/green”)。

位图

Android支持三种格式的位图文件:.png(首选)、.jpg(次选)、.gif(不推荐使用)。 可以使用资源ID(文件名)直接引用位图文件,也可以在XML中创建一个别名资源。 注意:在编译期间,位图文件可以被aapt工具用无损图像压缩技术来自动的优化。例如,一个真彩色的PNG图片,不需要超过256色就可以用调试板给转换成8为的PNG图片。这样就会生成同等质量的图片,但却需要很少的内存。因此而要注意,放在这个目录镇南关的二进制图片能够在编译期间发生改变。如果计划用字节流来读取图片,以便把它转换成一个位图,就要把图片放到res/raw/文件夹镇南关,这样它们就不会被优化。

位图文件

这里的位图文件是指.png、.jpg、.gif格式文件。当把这些格式的文件保存在

res/drawable/目录时,Android会给这些文件创建一个绘制资源。

文件位置(FILE LOCATION):

res/drawable/filename.png(.png、.jpg或.gif)。

文件名用于资源ID。

编译资源的数据类型(COMPILED RESOURCE DATATYPE):

资源指向一个BitmapDrawable对象。

资源引用(RESOURCE REFERENCE):

在Java代码中:R.drawable.filename;

在XML中:@[package:]drawable/filename

列子(EXAMPLE):

把一个图片保存在res/drawable/muimage.png中,布局XML把这个图片应用于一个View对象:

<ImageView

android:layout_height="wrap_content"

android:layout_width="wrap_content"

android:src="@drawable/myimage"/>

应用程序在代码中用getDrawable()方法来获取Drawable对象:

Resources res=getResources();

Drawable drawable= res.getDrawable(R.drawable.myimage);

XML位图

XML位图是一个定义在XML中的资源,它指向一个位图文件。它是原始位图文件的一个别名。XML能够给位图指定额外的属性,如仿色和平铺。

注意:能够把<bitmap>元素作为<item>元素的子元素来使用。例如,在创建状态列表或层列表时,能够从<item>元素中排除android:drawable属性,并且在<item>元素内部嵌入一个<bitmap>元素来定义绘制项目。

文件位置(FILE LOCATION):

res/drawable/filename.xml

文件名被用作资源ID。

编译资源的数据类型(COMPILED RESOURCE DATATYPE):

资源指向一个BitmapDrawable对象。

资源引用(RESOURCE REFERENCE):

在Java代码中:R.drawable.filename

在XML中:@[package:]drawable/filename

语法(SYNTAX):

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

<bitmap

xmlns:android="/apk/res/android"

android:src="@[package:]drawable/drawable_resource"

android:antialias=["true" |"false"]

android:dither=["true" |"false"]

android:filter=["true" |"false"]

android:gravity=["top" |"bottom" |"left" | "right" |"center_vertical" | "fill_vertical" |"center_horizontal" |"fill_horizontal" | "center" |"fill" |"clip_vertical" |"clip_horizontal"] android:tileMode=["disabled" |"clamp" |"repeat" | "mirror"]/>

元素(ELEMENTS):

<bitmap>

用来定义位图资源和资源属性。

属性(ATTRIBUTES):

xmlns:android

字符串值,定义XML的命名空间,必须是

“/apk/res/android”。如果<bitmap>是根元素,那么这个属性就是必须的。当<bitmap>被嵌套在<item>内时,就不需要了。

android:src

绘制资源。必须的。它指向一个要绘制的资源。

android:antialias

布尔值。启用或禁用抗锯齿效果。

android:dither

布尔值。如果位图没有与屏幕相同的像素配置,这个属性会指示启用或禁用位图的仿色处理。

android:filter

布尔值,启用或禁用位图的过滤处理。在位图收缩或拉伸时,使用过滤处理让外观更平滑。

android:gravity

关键属性。定义位图的重心。如果位图比容器小,重心会指示绘制资源在容器中位置。

必须是下列常量值的组合(组合设定时使用”|”符号分离):

android开发总结

android开发总结

例子(EXAMPLE):

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

<bitmapxmlns:android="/apk/res/android"

android:src="@drawable/icon"

android:tileMode="repeat"/>

android开发总结

[html] view plaincopy

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

2. <LinearLayout

3. android:id="@+id/MainLayout"

4. xmlns:android="/apk/res/android"

5. android:layout_width="fill_parent"

6. android:layout_height="fill_parent"

7. android:orientation="vertical"

8. android:background="@drawable/backrepeat"

9. >

backrepeat.xml

[html] view plaincopy

1. <bitmap

2. xmlns:android="/apk/res/android"

3. android:src="@drawable/repeatimg"

4. android:tileMode="repeat"

5. android:dither="true" />

代码方式:

[java] view plaincopy

1. Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon

);

2. BitmapDrawable bd = new BitmapDrawable(bitmap);

3. bd.setTileModeXY(TileMode.REPEAT , TileMode.REPEAT );

4. bd.setDither(true

android开发总结

);

5. view.setBackgroundDrawable(bd);

2,再来解释下 dither(抖动)

Dither(图像的抖动处理,当每个颜色值以低于8位表示时,对应图像做抖动处理可以实现在可显示颜色总数比较低(比如256色)时还保持较好的显示效果: Dither on Wikipedia

方法二 系统API实现

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pic);

//bitmap = Bitmap.createBitmap(100, 20, Config.ARGB_8888);

BitmapDrawable drawable = new BitmapDrawable(bitmap);

drawable.setTileModeXY(TileMode.REPEAT , TileMode.REPEAT );

drawable.setDither(true);

view.setBackgroundDrawable(drawable);

方法三 自己画出来

22 public static Bitmap createRepeater(int width, Bitmap src){

23 int count = (width + src.getWidth() - 1) / src.getWidth();

24

25 Bitmap bitmap = Bitmap.createBitmap(width, src.getHeight(), Config.ARGB_8888); 26 Canvas canvas = new Canvas(bitmap);

27

28 for(int idx = 0; idx < count; ++ idx){

29 canvas.drawBitmap(src, idx * src.getWidth(), 0, null);

30 }

31

32 return bitmap;

Android强制设置横屏或竖屏 全屏

在Activity的onCreate方法中的setContentView(myview)调用之前添加下面代码 requestWindowFeature(Window.FEATURE_NO_TITLE);//隐藏标题

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//设置全屏

横屏

按照下面代码示例修改Activity的onResume方法

@Override

protected void onResume() {

/**

* 设置为横屏

*/

if(getRequestedOrientation()!=ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE){

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

}

super.onResume();

}

或者在配置文件中对Activity节点添加android:screenOrientation属性(landscape是横向,

portrait是纵向)

android:launchMode="singleTask"

android:screenOrientation="portrait">

要设置成竖屏设置成 SCREEN_ORIENTATION_PORTRAIT

// ----------------

常亮

view.setKeepScreenOn(true)

不加任何旋转屏幕的处理代码的时候,旋转屏幕将会导致系统把当前activity关闭,重新打开。

如果只是简单的界面调整,我们可以阻止此问题的发生,屏幕旋转而自己调整屏幕的元素重构。

首先我们需要修改AndroidManifest.xml文件:

<activity android:name=".Magazine">

</activity>

//修改为:

<activity android:name=".Magazine"

android:configChanges="orientation|keyboard">

</activity>

这样是让程序能够响应旋转屏幕的事件。

然后重写onConfigurationChanged方法:

@Override

public void onConfigurationChanged(Configuration newConfig) {

// TODO Auto-generated method stub

super.onConfigurationChanged(newConfig);

Log.v(" == onConfigurationChanged");

processLayout();

}

//----------------------------

在我们用Android开发过程中,会碰到Activity在切换到后台或布局从横屏LANDSCAPE切换

到PORTRAIT,会重新切换Activity会触发一次onCreate方法。

在Android开发中这种情况视可以避免的,我们可以在androidmanifest.xml中的activit元素加入这个属性 android:configChanges="orientation|keyboardHidden" 就能有效避免oncreat方法的重复加载,

androidmanifest.xml内容如下:红色字体为添加部分

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

<manifest xmlns:android=""

package="com.demo"

android:versionCode="1"

android:versionName="1.0">

<application android:icon="@drawable/icon" android:label="@string/app_name">

<activity android:name=".DemoGPS"

android:configChanges="orientation|keyboardHidden"

android:label="@string/app_name">

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

<uses-library android:name="com.google.android.maps" />

</application>

<uses-sdk android:minSdkVersion="7" />

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

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

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

</manifest>

同时在Activity的Java文件中重载onConfigurationChanged(Configuration newConfig)这个方法,这样就不会在布局切换或窗口切换时重载等方法。代码如下:

@Override

public void onConfigurationChanged(Configuration newConfig)

{

super.onConfigurationChanged(newConfig);

if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)

{

//land

}

else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)

{

//port

}

}

//------------------------------------------------------

关于Android中Activity的横竖屏切换问题可以通过AndroidManifest.xml文件中的Activity来配置:

android:screenOrientation=["unspecified" | "user" | "behind" |

"landscape" | "portrait" |

"sensor" | "nonsensor"]

screenOrientation 用来指定Activity的在设备上显示的方向,每个值代表如下含义: "unspecified" 默认值 由系统来判断显示方向.判定的策略是和设备相关的,所以不同的设备会有

不同的显示方向.

"landscape" 横屏显示(宽比高要长)

"portrait" 竖屏显示(高比宽要长)

用户当前首选的方向 "user"

"behind" 和该Activity下面的那个Activity的方向一致(在Activity堆栈中的)

android开发总结

Android应用资源---绘制资源类型(Drawable) 可绘制资源是指能够被绘制到屏幕上的图形的一般化概念,并且能够用诸如

getDrawable(int)等API方法来获取这些资源,或者使用诸如android:drawable和

android:icon属性把它们应用到另一个XML资源中。以下是几种不同的可绘制资源类型:

位图文件:

位图图形文件(.png、.jpg或.gif)。每个位图资源会创建一个BitmapDrawable对象。

Nine-Patch文件:

Nine-Patch文件是一个带有可拉伸区域的PNG文件,它允许图片基于内容进行尺寸的调整(.9.png)。每个Nine-Patch资源会创建一个NinePatchDrawable对象。

层列表:

层列表管理一个绘制资源数组。它们会按照数组的顺序进行描画,因此索引最大的元素被画在最上面,一个层列表会创建一个LayerDrawable对象。

状态列表:

状态列表是一个XML文件,文件中针对不同的状态定义了要引用的不同位图图形(例如,按钮被按下时,要使用的不同的图片)。一个状态列表会创建一个

StateListDrawable对象。

级别列表:

级别列表是一个定义可替代绘制资源的XML文件,每个资源都会给分配一个最大的数字值,一个状态列表会创建一个LevelListDrawable对象。

过渡绘制资源:

它是一个定义绘制资源的XML文件,文件中的绘制资源能够在两个绘制资源之间渐入渐出。一个XML文件会创建一个TransitionDrawable对象。

插图绘制资源:

它是一个定义绘制资源的XML文件,文件中的绘制资源能够按照指定的距离插入到另一个绘制资源中。当View对象需要绘制的背景比View的实际边框要小时,这个资源是有用的。

剪辑绘制资源:

它是一个定义绘制资源的XML文件,使用文件中的定义,基于绘制资源的当前级别值对另一个绘制资源进行剪辑。它会创建一个ClipDrawable对象。

缩放绘制资源:

它是一个定义绘制资源的XML文件,使用这个文件中的定义会基于当前的级别值来改变另一个绘制资源尺寸。它会创建一个ScaleDrawable对象。

形状绘制资源:

它是一个定义几何图形的XML文件,包括颜色和几何形状。它会创建一个

ShapeDrawable对象。

注意:在XML中,颜色资源也能够用于绘制资源。例如,在创建状态列表绘制资源时,android:drawable属性就可以引用一个颜色资源(如:android:drawable=”@color/green”)。

位图

Android支持三种格式的位图文件:.png(首选)、.jpg(次选)、.gif(不推荐使用)。 可以使用资源ID(文件名)直接引用位图文件,也可以在XML中创建一个别名资源。 注意:在编译期间,位图文件可以被aapt工具用无损图像压缩技术来自动的优化。例如,一个真彩色的PNG图片,不需要超过256色就可以用调试板给转换成8为的PNG图片。这样就会生成同等质量的图片,但却需要很少的内存。因此而要注意,放在这个目录镇南关的二进制图片能够在编译期间发生改变。如果计划用字节流来读取图片,以便把它转换成一个位图,就要把图片放到res/raw/文件夹镇南关,这样它们就不会被优化。

位图文件

这里的位图文件是指.png、.jpg、.gif格式文件。当把这些格式的文件保存在

res/drawable/目录时,Android会给这些文件创建一个绘制资源。

文件位置(FILE LOCATION):

res/drawable/filename.png(.png、.jpg或.gif)。

文件名用于资源ID。

编译资源的数据类型(COMPILED RESOURCE DATATYPE):

资源指向一个BitmapDrawable对象。

资源引用(RESOURCE REFERENCE):

在Java代码中:R.drawable.filename;

在XML中:@[package:]drawable/filename

列子(EXAMPLE):

把一个图片保存在res/drawable/muimage.png中,布局XML把这个图片应用于一个View对象:

<ImageView

android:layout_height="wrap_content"

android:layout_width="wrap_content"

android:src="@drawable/myimage"/>

应用程序在代码中用getDrawable()方法来获取Drawable对象:

Resources res=getResources();

Drawable drawable= res.getDrawable(R.drawable.myimage);

XML位图

XML位图是一个定义在XML中的资源,它指向一个位图文件。它是原始位图文件的一个别名。XML能够给位图指定额外的属性,如仿色和平铺。

注意:能够把<bitmap>元素作为<item>元素的子元素来使用。例如,在创建状态列表或层列表时,能够从<item>元素中排除android:drawable属性,并且在<item>元素内部嵌入一个<bitmap>元素来定义绘制项目。

文件位置(FILE LOCATION):

res/drawable/filename.xml

文件名被用作资源ID。

编译资源的数据类型(COMPILED RESOURCE DATATYPE):

资源指向一个BitmapDrawable对象。

资源引用(RESOURCE REFERENCE):

在Java代码中:R.drawable.filename

在XML中:@[package:]drawable/filename

语法(SYNTAX):

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

<bitmap

xmlns:android="/apk/res/android"

android:src="@[package:]drawable/drawable_resource"

android:antialias=["true" |"false"]

android:dither=["true" |"false"]

android:filter=["true" |"false"]

android:gravity=["top" |"bottom" |"left" | "right" |"center_vertical" | "fill_vertical" |"center_horizontal" |"fill_horizontal" | "center" |"fill" |"clip_vertical" |"clip_horizontal"] android:tileMode=["disabled" |"clamp" |"repeat" | "mirror"]/>

元素(ELEMENTS):

<bitmap>

用来定义位图资源和资源属性。

属性(ATTRIBUTES):

xmlns:android

字符串值,定义XML的命名空间,必须是

“/apk/res/android”。如果<bitmap>是根元素,那么这个属性就是必须的。当<bitmap>被嵌套在<item>内时,就不需要了。

android:src

绘制资源。必须的。它指向一个要绘制的资源。

android:antialias

布尔值。启用或禁用抗锯齿效果。

android:dither

布尔值。如果位图没有与屏幕相同的像素配置,这个属性会指示启用或禁用位图的仿色处理。

android:filter

布尔值,启用或禁用位图的过滤处理。在位图收缩或拉伸时,使用过滤处理让外观更平滑。

android:gravity

关键属性。定义位图的重心。如果位图比容器小,重心会指示绘制资源在容器中位置。

必须是下列常量值的组合(组合设定时使用”|”符号分离):

android开发总结

android开发总结

例子(EXAMPLE):

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

<bitmapxmlns:android="/apk/res/android"

android:src="@drawable/icon"

android:tileMode="repeat"/>

Android自定义Button按钮显示样式

现在的用户对APP的外观看得很重要,如果APP内所有元件都用Android默认样式写,估计下面评论里就有一堆在骂UI丑的。今天学习自定义Button按钮样式。Button样式修改的是Button的背景(Background)属性。

首先写一个定义Button样式的XML文件:

新建Android XML文件,类型选Drawable,根结点选selector,文件名就buton_style吧。

程序自动给我们刚刚建的文件里加了selector结点,我们只需要在selector结点里写上三种状态时显示的背景图片(按下、获取焦点,正常)。

代码如下:

Xml代码

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

<item android:state_pressed="true" android:drawable="@drawable/play_press" /> <item android:state_focused="true" android:drawable="@drawable/play_press" /> <item android:drawable="@drawable/play" />

</selector>

我这里获取焦点跟点击时显示的是同一张图片,必须严格照上面的顺序写,不可倒。 接下来只要在布局时写Button控件时应用到Button的Background属性即可。

Xml代码

<Button android:id="@+id/button1"

android:layout_width="wrap_content" android:layout_height="wrap_content"

android:background="@drawable/button_style"

></Button>

最终效果图:

再加上一种自定义样式方法,上面的是用图片,其实我们可以直接通过定义xml文件来实现不同的样式:

在上面的源代码基础上,只需要修改button_style文件,同样三种状态分开定义: Xml代码

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

<item android:state_pressed="true">

<shape>

<gradient android:startColor="#0d76e1" android:endColor="#0d76e1"

android:angle="270" />

<stroke android:width="1dip" android:color="#f403c9" />

<corners android:radius="2dp" />

<padding android:left="10dp" android:top="10dp"

android:right="10dp" android:bottom="10dp" />

</shape>

</item>

<item android:state_focused="true">

<shape>

<gradient android:startColor="#ffc2b7" android:endColor="#ffc2b7"

android:angle="270" />

<stroke android:width="1dip" android:color="#f403c9" />

<corners android:radius="2dp" />

<padding android:left="10dp" android:top="10dp"

android:right="10dp" android:bottom="10dp" />

</shape>

</item>

<item>

<shape>

<gradient android:startColor="#000000" android:endColor="#ffffff"

android:angle="180" />

<stroke android:width="1dip" android:color="#f403c9" />

<corners android:radius="5dip" />

<padding android:left="10dp" android:top="10dp"

android:right="10dp" android:bottom="10dp" />

</shape>

</item>

</selector>

gradient 主体渐变 startColor开始颜色,endColor结束颜色 ,angle开始渐变的角度(值只能为90的倍数,0时为左到右渐变,90时为下到上渐变,依次逆时针类推)

stroke 边框 width 边框宽度,color 边框颜色

corners 圆角 radius 半径,0为直角

padding text值的相对位置

Android之自定义Adapter的ListView

在开发中,我们经常使用到ListView这个控件。的API也提供了许多创建ListView适配器的快捷方式。例如ArrayAdapter、SimpleAdapter和SimpleCursorAdapter等。但你是否发现,如果采用这些系统自带的适配器,对于事件的响应只能局限在一个行单位。假设一行里面有一个按钮和一个图片控件,它们之间的响应操作是不一样的。若采用系统自带的适配器,就不能精确到每个控件的响应事件。这时,我们一般采取自定义适配器来实现这个比较精确地请求。

ListView的创建,一般要具备两大元素:

1)数据集,即要映射的字符串、图片信息之类。

2)适配器,实现把要映射的字符串、图片信息映射成视图(如Textview、Image等组件),再添加到ListView中。

下面是一个实操例子:

实现细节:

1、创建数据集,一般定义如下

private List<Map<String, Object>> listItems;

元素添加方式:

Map<String, Object> map = new HashMap<String, Object>();

map.put("image", imgeIDs[i]); //图片资源

map.put("title", "物品名称:"); //物品标题

map.put("info", goodsNames[i]); //物品名称

map.put("detail", goodsDetails[i]); //物品详情

listItems.add(map); //添加一项

2、创建适配器

public class ListViewAdapter extends BaseAdapter{........} //自定义的适配器一般继承BaseAdapter类

listViewAdapter = new ListViewAdapter(this, listItems);

3、给ListView设置适配器

listView.setAdapter(listViewAdapter);

4、这里还有个关键点,如何把list_item.xml布局作为一个视图,添加到listView中:

LayoutInflater listContainer; //视图容器工厂

listContainer = LayoutInflater.from(context); //创建视图容器工厂并设置上下文 convertView = listContainer.inflate(R.layout.list_item, null); //创建list_item.xml布局文件的视图

实例视图如下:

android开发总结

android开发总结

android开发总结

android开发总结

android开发总结

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

2. <LinearLayout xmlns:"/apk/res/android"

3. :orientation="vertical"

4. :layout_width="fill_parent"

5. :layout_height="fill_parent">

6.

7. <!-- 结算 -->

8. <LinearLayout:gravity="center_horizontal"

9. :orientation="horizontal" android:layout_width="fill_parent"

10. :layout_height="wrap_content">

11. <TextView:text="结算: "

12. :layout_width="wrap_content"

13. :layout_height="wrap_content"

14. :textColor="#FFFFFFFF"

15. :textSize="20px"/>

16. <ImageButton:id="@+id/imgbt_sum"

17. :layout_width="40px"

18. :layout_height="40px"

19. :background = "@drawable/shopping" />

20. </LinearLayout>

21.

22. <TextView:text="商品列表: "

23. :layout_width="wrap_content"

24. :layout_height="wrap_content"

25. :textColor="#FFFFFFFF" />

26.

27. <!-- 商品列表 -->

28. <ListView:id="@+id/list_goods"

29. :layout_width="fill_parent"

30. :layout_height="wrap_content" />

31.

32. </LinearLayout>

列表项布局文件list_item.xml

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

2. <LinearLayout xmlns:"/apk/res/android"

3. :orientation="horizontal" android:layout_width="fill_parent"

4. :layout_height="fill_parent">

5.

6. <!-- 商品图片 -->

7. <ImageView:id="@+id/imageItem"

8. :layout_width="wrap_content"

9. :layout_height="wrap_content"

10. :layout_margin="5px"/>

11.

12. <!-- 商品信息 -->

13. <LinearLayout:orientation="vertical"

14. :layout_width="wrap_content"

15. :layout_height="wrap_content">

16.

17. <TextView:id="@+id/titleItem"

18. :layout_width="wrap_content"

19. :layout_height="wrap_content"

20. :textColor="#FFFFFFFF"

21. :textSize="13px" />

22. <TextView:id="@+id/infoItem"

23. :layout_width="wrap_content"

24. :layout_height="wrap_content"

25. :textColor="#FFFFFFFF"

26. :textSize="22px" />

27. </LinearLayout>

28.

29. <!-- 购买和商品详情 -->

30. <LinearLayout:gravity="right"

31. :orientation="horizontal" android:layout_width="fill_parent"

32. :layout_height="wrap_content">

33. <CheckBox:id="@+id/checkItem"

34. :layout_width="wrap_content"

35. :layout_height="wrap_content"

36. :layout_margin="5px"/>

37. <Button:id="@+id/detailItem"

38. :layout_width="wrap_content"

39. :layout_height="wrap_content"

40. :layout_margin="5px"/>

41. </LinearLayout>

42. </LinearLayout>

2)代码,主代码:

1. package

2.

3. import java.util.ArrayList;

4. import java.util.HashMap;

5. import java.util.List;

6. import java.util.Map;

7.

8. import

9. import

10. import

11. import

12. import

13. import

14. import

15. import

16. import

17.

18. public class MyListView extends Activity {

19.

20. private ListView listView;

21. private ImageButton imgbt_sum;

22. private ListViewAdapter listViewAdapter;

23. private List<Map<String, Object>> listItems;

24. private Integer[] imgeIDs = {R.drawable.cake,

25. R.drawable.gift, R.drawable.letter,

26. R.drawable.love, R.drawable.mouse,

27. R.drawable.music};

28. private String[] goodsNames = {"蛋糕", "礼物",

29. "邮票", "爱心", "鼠标", "音乐CD"};

30. private String[] goodsDetails = {

31. "蛋糕:好好吃。",

32. "礼物:礼轻情重。",

33. "邮票:环游世界。",

34. "爱心:世界都有爱。",

35. "鼠标:反应敏捷。",

36. "音乐CD:酷我音乐。"};

37.

38. /** Called when the activity is first created. */

39. @Override

40. public void onCreate(Bundle savedInstanceState) {

41. super.onCreate(savedInstanceState);

42. setContentView(R.layout.main);

43.

44. listView = (ListView)findViewById(R.id.list_goods);

45. imgbt_sum = (ImageButton) findViewById(R.id.imgbt_sum);

46. imgbt_sum.setOnClickListener(new ClickEvent());

47. listItems = getListItems();

48. listViewAdapter = new ListViewAdapter(this, listItems); //创建适配

49. listView.setAdapter(listViewAdapter);

50. }

51.

52. /**

53. * 初始化商品信息

54. */

55. private List<Map<String, Object>> getListItems() {

56. List<Map<String, Object>> listItems = new ArrayList<Map<String, Obje

ct>>();

57. for(int i = 0; i < goodsNames.length; i++) {

58. Map<String, Object> map = new HashMap<String, Object>();

59. map.put("image", imgeIDs[i]); //图片资源

60. map.put("title", "物品名称:"); //物品标题

61. map.put("info", goodsNames[i]); //物品名称

62. map.put("detail", goodsDetails[i]); //物品详情

63. listItems.add(map);

64. }

65. return listItems;

66. }

67.

68. class ClickEvent implements OnClickListener{

69.

android开发总结

70. @Override

71. public void onClick(View v) {

72. // TODO Auto-generated method stub

73. String goodsList = "";

74. for(int i = 0; i < listItems.size(); i++) {

75. goodsList += listViewAdapter.hasChecked(i)? goodsNames[i] +

" ": "";

76. }

77. new AlertDialog.Builder(MyListView.this)

78. .setTitle("购物清单:")

79. .setMessage("你好,你选择了如下商品:\n" + goodsList)

80. .setPositiveButton("确定", null)

81. .show(); 82. }

83.

84. }

85. }

1. package

2.

3. import java.util.List;

4. import java.util.Map;

5.

6. import

7. import

8. import

9. import

10. import

11. import

12. import

13. import

14. import

15. import

16. import

17. import

18. import

19.

20. public class ListViewAdapter extends BaseAdapter {

21. private Context context; //运行上下文

22. private List<Map<String, Object>> listItems; //商品信息集合

23. private LayoutInflater listContainer; //视图容器

24. private boolean[] hasChecked; //记录商品选中状态

25. public final class ListItemView{ //自定义控件集合

26. public ImageView image;

27. public TextView title;

28. public TextView info;

29. public CheckBox check;

30. public Button detail;

31. }

32.

33.

34. public ListViewAdapter(Context context, List<Map<String, Object>> listIt

ems) {

35. this.context = context;

36. listContainer = LayoutInflater.from(context); //创建视图容器并设置上

下文

37. this.listItems = listItems;

38. hasChecked = new boolean[getCount()];

39. }

40.

41. public int getCount() {

42. // TODO Auto-generated method stub

43. return listItems.size();

44. }

45.

46. public Object getItem(int arg0) {

47. // TODO Auto-generated method stub

48. return null;

49. }

50.

51. public long getItemId(int arg0) {

52. // TODO Auto-generated method stub

53. return 0;

54. }

55.

56. /**

57. * 记录勾选了哪个物品

58. * @param checkedID 选中的物品序号

59. */

60. private void checkedChange(int checkedID) {

61. hasChecked[checkedID] = !hasChecked[checkedID];

62. }

63.

64. /**

65. * 判断物品是否选择

66. * @param checkedID 物品序号

67. * @return 返回是否选中状态

68. */

69. public boolean hasChecked(int checkedID) {

70. return hasChecked[checkedID];

71. }

72.

73. /**

74. * 显示物品详情

75. * @param clickID

76. */

77. private void showDetailInfo(int clickID) {

78. new AlertDialog.Builder(context)

79. .setTitle("物品详情:" + listItems.get(clickID).get("info"))

80. .setMessage(listItems.get(clickID).get("detail").toString())

81. .setPositiveButton("确定", null)

82. .show();

83. }

84.

85.

86. /**

87. * ListView Item设置

88. */

89. public View getView(int position, View convertView, ViewGroup parent) {

90. // TODO Auto-generated method stub

91. Log.e("method", "getView");

92. final int selectID = position;

93. //自定义视图

94. ListItemView listItemView = null;

95. if (convertView == null) {

96. listItemView = new ListItemView();

97. //获取list_item布局文件的视图

98. convertView = listContainer.inflate(R.layout.list_item, null);

99. //获取控件对象

100. listItemView.image = (ImageView)convertView.findViewById(R.id.i

mageItem);

101. listItemView.title = (TextView)convertView.findViewById(R.id.ti

tleItem);

102. listItemView.info = (TextView)convertView.findViewById(R.id.inf

oItem);

103. listItemView.detail= (Button)convertView.findViewById(R.id.deta

ilItem);

104. listItemView.check = (CheckBox)convertView.findViewById(R.id.ch

eckItem);

105. //设置控件集到convertView

106. convertView.setTag(listItemView);

107. }else {

108. listItemView = (ListItemView)convertView.getTag();

109. }

110. // Log.e("image", (String) listItems.get(position).get("title")); //

测试

111. // Log.e("image", (String) listItems.get(position).get("info")); 112.

113. //设置文字和图片

114. listItemView.image.setBackgroundResource((Integer) listItems.get(

115. position).get("image"));

116. listItemView.title.setText((String) listItems.get(position) 117. .get("title"));

118. listItemView.info.setText((String) listItems.get(position).get("inf

o"));

119. listItemView.detail.setText("商品详情");

120. //注册按钮点击时间爱你

121. listItemView.detail.setOnClickListener(new View.OnClickListener() {

122. @Override

123. public void onClick(View v) {

124. //显示物品详情

125. showDetailInfo(selectID);

126. }

127. });

128. // 注册多选框状态事件处理

129. listItemView.check

130. .setOnCheckedChangeListener(new CheckBox.OnCheckedChangeLis

tener() {

131. @Override

132. public void onCheckedChanged(CompoundButton buttonView,

133. boolean isChecked) {

134. //记录物品选中状态

135. checkedChange(selectID);

136. }

137. });

138.

139. return convertView;

140. }

141. }

至于,如何实现系统自带的适配器,如ArrayAdapter、SimpleAdapter和SimpleCursorAdapter等,有机会再补充。

相关推荐