(一)Activity页面切换的效果
先介绍下左右滑动切换Activity,对于复杂的手势原理一样,具体后述。
主要原理为监控触屏事件和手势事件,在触屏事件处理函数中调用手势事件处理函数,表示用户触屏后是否有手势操作,有则进行手势事件处理,大致分为四步
1、需要继承OnGestureListener和OnDoubleTapListener,如下:
public class ViewSnsActivity extends Activity implements OnTouchListener, OnGestureListener
这两个类分别是触屏监听器和手势监控器,具体可查看OnTouchListener和OnGestureListener
2、在添加mGestureDetector的定义,并在ViewSnsActivity的onCreate函数中加入其页面布局的setOnTouchListener事件
GestureDetector mGestureDetector;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_sns_activity);
mGestureDetector = new GestureDetector((OnGestureListener) this);
LinearLayout viewSnsLayout = (LinearLayout)findViewById(R.id.viewSnsLayout);
viewSnsLayout.setOnTouchListener(this);
viewSnsLayout.setLongClickable(true);
}
mGestureDetector为手势监听对象,下面的OnFling就是为其实现,用来处理手势的
viewSnsLayout.setOnTouchListener(this);表示viewSnsLayout这个layout的触屏事件由下面的OnTouch处理
3、重载onFling函数
private int verticalMinDistance = 20;
private int minVelocity = 0;
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if (e1.getX() - e2.getX() > verticalMinDistance && Math.abs(velocityX) > minVelocity) {
// 切换Activity
// Intent intent = new Intent(ViewSnsActivity.this, UpdateStatusActivity.class);
// startActivity(intent);
Toast.makeText(this, "向左手势", Toast.LENGTH_SHORT).show();
} else if (e2.getX() - e1.getX() > verticalMinDistance && Math.abs(velocityX) > minVelocity) {
// 切换Activity
// Intent intent = new Intent(ViewSnsActivity.this, UpdateStatusActivity.class);
// startActivity(intent);
Toast.makeText(this, "向右手势", Toast.LENGTH_SHORT).show();
}
return false;
}
OnFling的四个参数意思分别为
说的更简单点就是,鼠标手势相当于一个向量(当然有可能手势是曲线),e1为向量的起点,e2为向量的终点,velocityX为向量水平方向的速度,velocityY为向量垂直方向的速度
if (e1.getX() - e2.getX() > verticalMinDistance && Math.abs(velocityX) > minVelocity)
则上面的语句能知道啥意思了吧,就是说向量的水平长度必须大于verticalMinDistance,并且水平方向速度大于minVelocity
从而我们可以如此判断手势是否满足一定的条件从而进行相应响应,也可以根据这个写出更复杂的手势判断。
4、重载onTouch函数
在2中我们定义了viewSnsLayout的touch事件处理,下面我们来实现,直接调用手势的处理函数
public boolean onTouch(View v, MotionEvent event) {
return mGestureDetector.onTouchEvent(event);
}
查看GestureDetector类的onTouchEvent的源码就能知道,进入该函数后会进入case MotionEvent.ACTION_UP这个路径,从而调用onFling函数
如果需要设置activity切换效果,在startActivity(intent);之后添加
overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right);即可,可修改相应参数,可参考http://www.iteye.com/topic/1116472
其他:
关于activity添加ScrollView后或是外部为RelativeLayout时onFling不起作用,无法滑动问题见http://trinea.iteye.com/blog/1213815
Android 2.0之后有了overridePendingTransition(),其中里面两个参数,一个是前一个activity的退出两一个activity的进入,
Java代码
1. @Override public void onCreate(BundlesavedInstanceState) {
2. super.onCreate(savedInstanceState); 3.
4. setContentView(R.layout.SplashScreen); 5.
6. new Handler().postDelayed(new Runnable() {
7. @Override
8. public void run() {
9. Intent mainIntent = newIntent(SplashScreen.this, AndroidNews.class);
10. SplashScreen.this.startActivity(mainIntent);
11. SplashScreen.this.finish(); 12.
13. overridePendingTransition(R.anim.mainfadein,
14. R.anim.splashfadeout);
15. }
16.}, 3000);
}
上面的代码只是闪屏的一部分。
Java代码
1. getWindow ().setWindowAnimations ( int );
这可没有上个好但是也可以 。
实现淡入淡出的效果
Java代码
1. overridePendingTransition(Android.R.anim.fade_in,android.R.anim
.fade_out);
由左向右滑入的效果
Java代码
1. overridePendingTransition(Android.R.anim.slide_in_left,android.
R.anim.slide_out_right); 实现zoomin和zoomout,即类似iphone的进入和退出时的效果
Java代码
1. overridePendingTransition(R.anim.zoomin,R.anim.zoomout);
新建zoomin.xml文件
Xml代码
1. version="1.0"encoding="utf-8"?>
2.
3. xmlns:Android="http://schemas.android.com/apk/res/android"
4. Android:interpolator="@android:anim/decelerate_interpolator">
5. Android:fromYScale="2.0"android:toYScale="1.0"
6. Android:pivotX="50%p"android:pivotY="50%p"
7. Android:duration="@android:integer/config_mediumAnimTime"/> 新建zoomout.xml文件
Xml代码
1. version="1.0"encoding="utf-8"?>
2.
3. xmlns:Android="http://schemas.android.com/apk/res/android"
4. Android:interpolator="@android:anim/decelerate_interpolator"
5. Android:zAdjustment="top">
6.
7. Android:fromYScale="1.0"android:toYScale=".5"
8. Android:pivotX="50%p"android:pivotY="50%p"
9. Android:duration="@android:integer/config_mediumAnimTime"/>
10.
11.Android:duration="@android:integer/config_mediumAnimTime"/>
12.
(二)android 菜单动画
先请注意,这里的菜单并不是按机器上的MENU出现在那种菜单,而是基于
Android SDK 提供的android.view.animation.TranslateAnimation(extends
android.view.animation.Animation)类实例后附加到一个Layout上使之产生的有动画出现和隐藏效果的菜单。
原理:Layout(菜单)从屏幕内(挨着屏幕边沿,其实并非一定,视需要的初态和末态而定)动态的移动到屏幕外(在外面可以挨着边沿,也可以离远点,这个无所谓了),这样就可以达到动态菜单的效果了。但
是由于Animation的一些奇怪特性(setFill**() 函数的作用效果,这个在我使用的某几个Animation当中出现了没有想明白的效果),就暂不理会这个东西了,所以使得我们还需要用上XML属性android:visibility。当Layout(菜单)显示的时候,设置android:visibility="visible",当Layout(菜单)隐藏的时候,设置android:visibility="gone",这里android:visibility可以有3个值,"visible"为可见,"invisible"为不可见但占空间,"gone"为不可见且不占空间(所谓的占不占空间,这个可以自己写个XML来试试就明白了)。
Class TranslateAnimation的使用:Animation有两种定义方法,一种是用Java code,一种是用XML,这里只介绍用code来定义(因为用 XML来定义的那种我没用过。。嘿嘿。。)。多的不说,看代码。
这里是TranslateAnimationMenu.java(我在里面还另加入了ScaleAnimation
产生的动画,各位朋友可以照着SDK以及程序效果来理解):
packagecom.TranslateAnimation.Menu;
importandroid.app.Activity; import android.os.Bundle; import android.view.View;import android.view.View.OnClickListener; importandroid.view.animation.Animation; importandroid.view.animation.TranslateAnimation; import android.widget.Button; importandroid.widget.LinearLayout;
public classTranslateAnimationMenu extends Activity { /** Called when the activity is first created. */
//TranslateAnimation showAction,hideAction;
Animation showAction, hideAction;
LinearLayout menu; Button button;
boolean menuShowed;
@Override
public void onCreate(BundlesavedInstanceState)
{ super.onCreate(savedInstanceState); setContentView(R.layout.main); menu = (LinearLayout) findViewById(R.id.menu);
button = (Button)findViewById(R.id.button); //这里是TranslateAnimation动画 showAction = newTranslateAnimation(
Animation.RELATIVE_TO_SELF,0.0f,Animation.RELATIVE_TO_SELF,
0.0f,Animation.RELATIVE_TO_SELF, -1.0f, Animation.RELATIVE_TO_SELF, 0.0f);
// 这里是ScaleAnimation动画
//showAction = newScaleAnimation(
// 1.0f, 1.0f, 0.0f, 1.0f,Animation.RELATIVE_TO_SELF, 0.0f,
// Animation.RELATIVE_TO_SELF, 0.0f);showAction.setDuration(500);
// 这里是TranslateAnimation动画
hideAction= new TranslateAnimation( Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF,0.0f, Animation.RELATIVE_TO_SELF, -1.0f); //这里是ScaleAnimation动画
//hideAction = newScaleAnimation(
// 1.0f, 1.0f, 1.0f, 0.0f,
Animation.RELATIVE_TO_SELF,0.0f, Animation.RELATIVE_TO_SELF,
0.0f);
hideAction.setDuration(500); menuShowed =false; menu.setVisibility(View.GONE);
button.setOnClickListener(newOnClickListener() {
@Override
public void onClick(View v) { // TODO Auto-generated method stub if (menuShowed) { menuShowed = false; menu.startAnimation(hideAction);
menu.setVisibility(View.GONE);
}
else { menuShowed = true; menu.startAnimation(showAction);
menu.setVisibility(View.VISIBLE);
}
}
});
}
}
这里是main.xml:
xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"> android:layout_height="100px"android:layout_width="fill_parent" android:layout_alignParentTop="true"android:background="#ffffff"> android:layout_height="fill_parent"android:text="I am a menu" android:gravity="center" />
Android基于TranslateAnimation的动画动态菜单
android布局属性
文章分类:移动开发
第一类:属性值为true或false
android:layout_centerHrizontal 水平居中 android:layout_centerVertical 垂直居中 android:layout_centerInparent 相对于父元素完全居中 android:layout_alignParentBottom 贴紧父元素的下边缘 android:layout_alignParentLeft 贴紧父元素的左边缘 android:layout_alignParentRight 贴紧父元素的右边缘 android:layout_alignParentTop 贴紧父元素的上边缘
android:layout_alignWithParentIfMissing 如果对应的兄弟元素找
不到的话就以父元素做参照物
第二类:属性值必须为id的引用名“@id/id-name” android:layout_below 在某元素的下方 android:layout_above 在某元素的的上方 android:layout_toLeftOf 在某元素的左边
android:layout_toRightOf 在某元素的右边
android:layout_alignTop 本元素的上边缘和某元素的的上边缘对齐 android:layout_alignLeft本元素的左边缘和某元素的的左边缘对齐 android:layout_alignBottom本元素的下边缘和某元素的的下边缘对齐
android:layout_alignRight本元素的右边缘和某元素的的右边缘对齐
第三类:属性值为具体的像素值,如30dip,40px android:layout_marginBottom 离某元素底边缘的距离 android:layout_marginLeft 离某元素左边缘的距离 android:layout_marginRight 离某元素右边缘的距离 android:layout_marginTop 离某元素上边缘的距离 EditText的android:hint
设置EditText为空时输入框内的提示信息。
android:gravity
android:gravity属性是对该view 内容的限定.比如一个button 上面的
text. 你可以设置该text 在view的靠左,靠右等位置.以button为例,
android:gravity="right"则button上面的文字靠右 android:layout_gravity
android:layout_gravity是用来设置该view相对与起父view 的位置.比如一个button 在linearlayout里,你想把该button放在靠左、靠右等位置就可以通过该属性设置.以button为例,android:layout_gravity="right"则button 靠右
android:layout_alignParentRight
使当前控件的右端和父控件的右端对齐。这里属性值只能为true或false,默认false。
android:scaleType: android:scaleType是控制图片如何resized/moved来匹对ImageView的size。
ImageView.ScaleType /android:scaleType值的意义区别:
CENTER /center 按图片的原来size居中显示,当图片长/宽超过View的长/
宽,则截取图片的居中部分显示
CENTER_CROP / centerCrop 按比例扩大图片的size居中显示,使得图片长(宽)
等于或大于View的长(宽)
CENTER_INSIDE /centerInside 将图片的内容完整居中显示,通过按比例缩小或原来的size使得图片长/宽等于或小于View的长/宽
FIT_CENTER / fitCenter 把图片按比例扩大/缩小到View的宽度,居中显示
FIT_END / fitEnd 把图片按比例扩大/缩小到View的宽度,显示在View
的下部分位置
FIT_START / fitStart 把图片按比例扩大/缩小到View的宽度,显示在View
的上部分位置
FIT_XY / fitXY 把图片•不按比例扩大/缩小到View的大小显示
MATRIX / matrix 用矩阵来绘制,动态缩小放大图片来显示。
** 要注意一点,Drawable文件夹里面的图片命名是不能大写的。
2010-10-28
android翻页
:
之前看到不少翻页,不过人家没有分享出代码来,我也一直没有搞出来.
想了好久,实现原理并不是那么的难,怎么实现就比较难了.
当然像3D现实模拟分页的难度是比较大的.
平面的分页,简单点说就是用三张片,模拟分页时可见区, 这里我弄了一个View,里面有翻页的效果.
OnDraw中;
最底一张是将要显示的,先画出来,
接着画原来那张,放中间,叠为这张片要翻页的过程中慢慢消失,一点一点被拉出去,
最后一张就是最上面的,为什么要用这张片呢?当页面被翻起后,一个角消失了, 就比如第二张不显示的部分,那这部分,就是第三张了,再覆盖第二张上面,形成一种看似翻书的.效果.
然后第二张(假设从左边开始被翻起,左边先消失),左边缘再画出一条线,当然这条线要粗点,然后设置颜色渐变,还要透明的,就有一种阴影的效果.
我开始一直想,像这样的,不难实现啊,当然只限于矩形的,叠为当时没有想到如何处理第二张消失部分为一个三角形.
可以通过Rect来设置一个Bitmap,的宽度.
Rect rect = new Rect(mWidth, 0,width, height);
canvas.drawBitmap(image2, null,rect, paint2);
mWidth就是左边消失部分的宽度.通过不断改变这个值,然后再刷新View就可以
看到一种滚动的效果.第二张片左边慢慢消失, width,height为画面目的宽高.
然后可以添加一个第三张片,也用同样的方法设置了它显示的宽,高,
通过上面Rect的处理,看到一般的效果.比较常见的是从一个角开始,然后慢慢
的卷起来,而不是像上面平行的,(上面只能看到平行的效果.)
这里就涉及到了一个角,就是三角形如何产生的问题,这个问题台扰了好久.今天想到办法了.就是用Path去画多边形.一个矩形,减去一个多边形,就剩下一个三角形了.
先讨论上面那种效果的处理方式:
首先是View:的OnDraw方法.
Java代码
1. width =getWidth();
2. height =getHeight();
3. //画最底下一张将要显示的图片
4. Rect rect = newRect(0, 0, width, height); 5. canvas.drawBitmap(image1, null, rect, paint1);
6. //画上面卷起的那张.实现平行翻页效果.
7. rect = newRect(mWidth, 0, width, height);
8. canvas.drawBitmap(image2,null, rect, paint2);
9. //当然之后再处理卷起边缘阴影,模糊等效果,这里省略了.还有图片
Image1,image2自己准备了
10.然后就是手势,没有手势,翻页显得很呆板.
11.这个View实现OnGestureListener,自然有一些方法要覆盖的.
12.其它方法随便了,有返回值的给它一个True,主要是
13.public booleanonFling(MotionEvent e1, MotionEvent e2, fl oat velocityX, float velocityY)这个方法,比较有用.
14.myHandler.removeMessage(0);/../我觉得要先移除上一次翻页的动作,然后会马上从上一次运行中停止,而立即向当前需要的方向变化.
15.if(e1.getX() - e2.getX() >0){
16. turnLeft(5);//向左翻
17.}else if(e2.getX() -e1.getX() > 0){
18. turnRight(5);//向右翻
19.}
20.两个方法差不多,也可以合并,传入正负值.
21.delta = speed;参数就是上面的5,作为变化速度.
22.myHandler.sendEmptyMessage(0);
23.普通的View要Handler来更新.之前试过了,以为在View直接Invalidate 可以.
24.虽然没有提示非UI线程的问题,但是循环了多次只看到OnDraw执行一次而以.
25.public voidhandleMessage(Message message){
26. invalidate();
27. mWidth += delta;//变化第二张图片的宽.
28. if(delta > 0){//向右滚动
29. if(mWidth < width){//当第二张图片的左侧空白超过了画布的宽 时停止
30. sendEmptyMessage(0);
31. }
32.}else{//向左滚动
33.if(mWidth > 0){
34. sendEmptyMessage(0);
35.} 36.}
37.} 38.
39.然后在XML里用这个View,最后Activity里SetContentView就OK了
/
40. 41.android:id="@+id/pageView1" 42.android:layout_gravity="center" 43.android:layout_marginTop="5px" 44.android:layout_width="fill_parent" 45.android:layout_height="fill_parent"/> 46. 47.由于使用XML,所以构造方法必须要有,带两个参数的. 48.public PageView(Contextcontext, AttributeSet attrs){ 49. super(context, attrs); 50. initView(); 51.} 52.InitView: 53.private void initView(){ 54. image1 =Bitmap.createBitmap(BitmapFactory.decodeResource (getResources(),R.drawable.aac)); 55. image2 =Bitmap.createBitmap(BitmapFactory.decodeResource (getResources(),R.drawable.q1)); 56. image3 =Bitmap.createBitmap(BitmapFactory.decodeResource (getResources(),R.drawable.q2)); 57. 58. myHandler = new MyHandler(); 59. gestureDetector = new GestureDetector(this); 60. mShader = new LinearGradient(10,250,250, 250, 61. new int[]{Color.RED, Color.GREEN, Color.BLUE}, 62. null, Shader.TileMode.MIRROR); 63. paint1 = new Paint(); 64. paint1.setFlags(Paint.ANTI_ALIAS_FLAG); //去除插刺 65. paint2 = new Paint(paint1); 66. paint3 = new Paint(paint2); 67. paint3.setColor(0x45111111); 68. //paint.setShader(mShader);//其间颜色会有变化. 69. paint3.setStrokeWidth(12); 70. paint4 = new Paint(paint2); 71. paint4.setColor(0xff111111); 72. paint4.setShader(mShader);//其间颜色会有变化. 73. paint4.setStrokeWidth(12); 74. } 75. 76.代码就到这里了.关于三角形卷动翻页,代码没有写完整,(第三张图片还没有弄,也没有阴影),先不写了,而且似乎也不止我这样一种写法的,网上看到的翻页还有其它的,比如我见到一个,OnDraw里得到画布的高,然后一行一行描述,并逐行递减宽度,这样造成一个三角形,速度也不那么地慢. 还可接受. 77. 78.来些图片. 79.page-15.png到page-16.png,宽度越来越小了. 80.page-12.png到page-14.png是三角形的,里面具体操作复杂一些,当前差上面那张遮罩.以后再完善了. 81.android中颜色对应的值 82.文章分类:移动开发 83. < ?xml version="1.0"encoding="utf-8" ?> < resources> < color name="white">#FFFFFF< /color>< !--白色 --> < color name="ivory">#FFFFF0< /color>< !--象牙色 --> < color name="lightyellow">#FFFFE0< /color> < color name="yellow">#FFFF00< /color>< !--黄色 --> < color name="snow">#FFFAFA< /color>< !--雪白色 --> < color name="floralwhite">#FFFAF0< /color> < color name="lemonchiffon">#FFFACD< /color> < color name="cornsilk">#FFF8DC< /color>< !--米绸色 --> < color name="seashell">#FFF5EE< /color>< !--海贝色 --> < color name="lavenderblush">#FFF0F5< /color> < color name="papayawhip">#FFEFD5< /color>< !--番木色 --> < color name="blanchedalmond">#FFEBCD< /color> < color name="mistyrose">#FFE4E1< /color>< !--浅玫瑰色--> < color name="bisque">#FFE4C4< /color>< !--桔黄色 --> < colorname="moccasin">#FFE4B5< /color>< !--鹿皮色 --> < color name="navajowhite">#FFDEAD< /color>< !--纳瓦白 --> < color name="peachpuff">#FFDAB9< /color>< !--桃色 --> < color name="gold">#FFD700< /color>< !--金色 --> < color name="pink">#FFC0CB< /color>< !--粉红色 --> < color name="lightpink">#FFB6C1< /color>< !--亮粉红色--> < color name="orange">#FFA500< /color>< !--橙色 --> < color name="lightsalmon">#FFA07A< /color> < color name="darkorange">#FF8C00< /color>< !--暗桔黄色--> < color name="coral">#FF7F50< /color>< !--珊瑚色 --> < color name="hotpink">#FF69B4< /color>< !--热粉红色--> < color name="tomato">#FF6347< /color>< !--西红柿色--> < color name="orangered">#FF4500< /color>< !--红橙色 --> < color name="deeppink">#FF1493< /color>< !--深粉红色--> < color name="fuchsia">#FF00FF< /color>< !--紫红色 --> < color name="magenta">#FF00FF< /color>< !--红紫色 --> < color name="red">#FF0000< /color>< !--红色 --> < color name="oldlace">#FDF5E6< /color>< !--老花色 --> < color name="lightgoldenrodyellow">#FAFAD2< !--亮金黄色 --> < color name="linen">#FAF0E6< /color>< !--亚麻色 --> < color name="antiquewhite">#FAEBD7< /color> < color name="salmon">#FA8072< /color>< !--鲜肉色 --> < color name="ghostwhite">#F8F8FF< /color>< !--幽灵白 --> < colorname="mintcream">#F5FFFA< /color>< !--薄荷色 --> < color name="whitesmoke">#F5F5F5< /color>< !--烟白色 --> < color name="beige">#F5F5DC< /color>< !--米色 --> < color name="wheat">#F5DEB3< /color>< !--浅黄色 --> < color name="sandybrown">#F4A460< /color>< !--沙褐色 --> < color name="azure">#F0FFFF< /color>< !--天蓝色 --> < color name="honeydew">#F0FFF0< /color>< !--蜜色 --> < color name="aliceblue">#F0F8FF< /color>< !--艾利斯兰--> < color name="khaki">#F0E68C< /color>< !--黄褐色 --> < color name="lightcoral">#F08080< /color>< !--亮珊瑚色--> < color name="palegoldenrod">#EEE8AA< /color> < color name="violet">#EE82EE< /color>< !--紫罗兰色--> < color name="darksalmon">#E9967A< /color>< !--暗肉色 --> < color name="lavender">#E6E6FA< /color>< !--淡紫色 --> < color name="lightcyan">#E0FFFF< /color>< !--亮青色 --> < color name="burlywood">#DEB887< /color>< !--实木色 --> < color name="plum">#DDA0DD< /color>< !--洋李色 --> < color name="gainsboro">#DCDCDC< /color>< !--淡灰色 --> < color name="crimson">#DC143C< /color>< !--暗深红色--> < color name="palevioletred">#DB7093< /color> < color name="goldenrod">#DAA520< /color>< !--金麒麟色--> < colorname="orchid">#DA70D6< /color>< !--淡紫色 --> < colorname="thistle">#D8BFD8< /color>< !--蓟色 --> < color name="lightgray">#D3D3D3< /color>< !--亮灰色 --> < color name="lightgrey">#D3D3D3< /color>< !--亮灰色 --> < color name="tan">#D2B48C< /color>< !--茶色 --> < color name="chocolate">#D2691E< /color>< !--巧可力色--> < color name="peru">#CD853F< /color>< !--秘鲁色 --> < color name="indianred">#CD5C5C< /color>< !--印第安红--> < color name="mediumvioletred">#C71585< !--中紫罗兰色 --> < color name="silver">#C0C0C0< /color>< !--银色 --> < color name="darkkhaki">#BDB76B< /color>< !--暗黄褐色 < color name="rosybrown">#BC8F8F< /color>< !--褐玫瑰红--> < color name="mediumorchid">#BA55D3< /color> < color name="darkgoldenrod">#B8860B< /color> < color name="firebrick">#B22222< /color>< !--火砖色 --> < color name="powderblue">#B0E0E6< /color>< !--粉蓝色 --> < color name="lightsteelblue">#B0C4DE< /color> < color name="paleturquoise">#AFEEEE< /color> < color name="greenyellow">#ADFF2F< /color> < color name="lightblue">#ADD8E6< /color>< !--亮蓝色 --> < color name="darkgray">#A9A9A9< !--暗灰色 --> < color name="darkgrey">#A9A9A9< /color>< !--暗灰色 --> < colorname="brown">#A52A2A< /color>< !--褐色 --> < color name="sienna">#A0522D< /color>< !--赭色 --> < color name="darkorchid">#9932CC< /color>< !--暗紫色 --> < color name="palegreen">#98FB98< /color>< !--苍绿色 --> < color name="darkviolet">#9400D3< /color>< !--暗紫罗兰色--> < color name="mediumpurple">#9370DB< /color> < color name="lightgreen">#90EE90< /color>< !--亮绿色 --> < color name="darkseagreen">#8FBC8F< /color> < color name="saddlebrown">#8B4513< /color> < color name="darkmagenta">#8B008B< /color> < color name="darkred">#8B0000< /color>< !--暗红色 --> < color name="blueviolet">#8A2BE2< /color>< !--紫罗兰蓝色 < color name="lightskyblue">#87CEFA< /color> < color name="skyblue">#87CEEB< /color>< !--天蓝色 --> < color name="gray">#808080< /color>< !--灰色 --> < color name="grey">#808080< /color>< !--灰色 --> < color name="olive">#808000< /color>< !--橄榄色 --> < color name="purple">#800080< /color>< !--紫色 --> < color name="maroon">#800000< /color>< !--粟色 --> < color name="aquamarine">#7FFFD4< /color>< !--碧绿色 --> < color name="chartreuse">#7FFF00< /color>< !--黄绿色 --> < colorname="lawngreen">#7CFC00< /color>< !--草绿色 --> < color name="mediumslateblue">#7B68EE< /color> < color name="lightslategray">#778899< /color> < color name="lightslategrey">#778899< /color> < color name="slategray">#708090< /color>< !--灰石色 --> < color name="slategrey">#708090< /color>< !--灰石色 --> < color name="olivedrab">#6B8E23< /color>< !--深绿褐色--> < color name="slateblue">#6A5ACD< /color>< !--石蓝色 --> < color name="dimgray">#696969< /color>< !--暗灰色 --> < color name="dimgrey">#696969< /color>< !--暗灰色 --> < color name="mediumaquamarine">#66CDAA< !--中绿色 --> < color name="cornflowerblue">#6495ED< /color> < color name="cadetblue">#5F9EA0< /color>< !--军兰色 --> < color name="darkolivegreen">#556B2F< /color> < color name="mediumturquoise">#48D1CC< !--中绿宝石 --> < color name="darkslateblue">#483D8B< /color> < color name="steelblue">#4682B4< /color>< !--钢兰色 --> < color name="royalblue">#4169E1< /color>< !--皇家蓝 --> < color name="turquoise">#40E0D0< /color>< !--青绿色 --> < colorname="mediumseagreen">#3CB371< /color>< !--中海蓝 --> < colorname="limegreen">#32CD32< /color>< !--橙绿色 --> < color name="darkslategray">#2F4F4F< /color> < color name="darkslategrey">#2F4F4F< /color> < color name="seagreen">#2E8B57< /color>< !--海绿色 --> < color name="forestgreen">#228B22< /color> < color name="lightseagreen">#20B2AA< /color> < color name="dodgerblue">#1E90FF< /color>< !--闪兰色 --> < color name="midnightblue">#191970< /color> < color name="aqua">#00FFFF< /color>< !--浅绿色 --> < color name="cyan">#00FFFF< /color>< !--青色 --> < color name="springgreen">#00FF7F< /color> < color name="lime">#00FF00< /color>< !--酸橙色 --> < color name="mediumspringgreen">#00FA9A< !--中春绿色 --> < color name="darkturquoise">#00CED1< /color> < color name="deepskyblue">#00BFFF< /color> < color name="darkcyan">#008B8B< /color>< !--暗青色 --> < color name="teal">#008080< /color>< !--水鸭色 --> < color name="green">#008000< /color>< !--绿色 --> < color name="darkgreen">#006400< /color>< !--暗绿色 --> < color name="blue">#0000FF< /color>< !--蓝色 --> < colorname="mediumblue">#0000CD< /color>< !--中兰色 --> < colorname="darkblue">#00008B< /color>< !--暗蓝色 --> < colorname="navy">#000080< /color>< !--海军色 --> < color name="black">#000000< /color>< !--黑色 --> < /resources> android ListView详解 在 android开发中ListView是比较常用的组件,它以列表的形式展示具体内容,并且能够根据数据的长度自适应显示。抽空把对 ListView 的使用做了整理,并写了个小例子,如下图。 列表的显示需要三个元素: 1.ListVeiw 用来展示列表的View。 2.适配器 用来把数据映射到ListView 上的中介。 3.数据 具体的将被映射的字符串,图片,或者基本组件。 根据列表的适配器类型,列表分为三种,ArrayAdapter,SimpleAdapter和 SimpleCur sorAdapter 其中以 ArrayAdapter 最为简单,只能展示一行字。SimpleAdapter有最好的扩充性,可以自定义出各种效果。SimpleCursorAdapter可以认为是 SimpleAdapter 对数据库的简单结合,可以方面的把数据库的内容以列表的形式展示出来。 我们从最简单的 ListView 开始: print? 01 /** 02 * @author allin 03 * 04 */ 05 public class MyListView extends Activity { 06 07 private ListView listView; 08 //private List 09 @Override 10 public void onCreate(Bundle savedInstanceState){ 11 super.onCreate(savedInstanceState); 12 13 listView = new ListView(this); 14 listView.setAdapter(new ArrayAdapter 15 setContentView(listView); 16 } 17 18 19 20 private List 21 22 List 23 data.add("测试数据1"); 24 data.add("测试数据2"); 25 data.add("测试数据3"); 26 data.add("测试数据4"); 28 return data; 29 } 30 } 上面代码使用了 ArrayAdapter(Context context, int textViewResourceId,List ()完成适配的最后工作。运行后的现实结构如下图: SimpleCursorAdapter sdk 的解释是这样的:An easy adapter to map columns from a cursor to T extViews orImageViews defined in an XML file. You can specify which colu mns you want,which views you want to display the columns, and the XML file that defines the appearance of theseviews。简单的说就是方便把从游标得到的数据进行列表显示,并可以把指定的列映射到对应的TextView 中。 下面的程序是从电话簿中把联系人显示到类表中。先在通讯录中添加一个联系人作为数据库的数据。然后获得一个指向数据库的Cursor并且定义一个布局文件(当然也可以使用系统自带的)。 view source print? 01 /** 02 * @author allin 03 * 04 */ 05 public class MyListView2 extends Activity { 07 private ListView listView; 08 //private List 09 @Override 10 public void onCreate(Bundle savedInstanceState){ 11 super.onCreate(savedInstanceState); 13 listView = new ListView(this); Cursor cursor =getContentResolver().query(People.CONTENT_URI, 15 null, null, null, null); 16 startManagingCursor(cursor); 18 ListAdapter listAdapter = new SimpleCursorAdapter(this,android.R.layout.simple_expandable_list_item_1, 19 cursor, 20 new String[]{People.NAME}, 21 new int[]{android.R.id.text1}); 23 listView.setAdapter(listAdapter); 24 setContentView(listView); 25 } Cursor cursor =getContentResolver().query(People.CONTENT_URI, null, null, null, null);先获得一个指向系统通讯录数据库的 Cursor对象获得数据来源。 startManagingCursor(cursor);我们将获得的 Cursor对象交由Activity管理,这样C ursor的生命周期和Activity便能够自动同步,省去自己手动管理 Cursor。 SimpleCursorAdapter 构造函数前面 3 个参数和 ArrayAdapter 是一样的,最后两个参数:一个包含数据库的列的 String 型数组,一个包含布局文件中对应组件id 的 int型数组。其作用是自动的将String型数组所表示的每一列数据映射到布局文件对应id的组件上。上面的代码,将NAME列的数据一次映射到布局文件的 id 为text1 的组件上。 注意:需要在 AndroidManifest.xml 中如权限: 运行后效果如下图: SimpleAdapter simpleAdapter 的扩展性最好,可以定义各种各样的布局出来,可以放上 ImageView(图片),还可以放上Button(按钮),CheckBox(复选框)等等。下面的代码都直接继承了 ListActivity,ListActivity 和普通的Activity没有太大的差别,不同就是对显示ListView 做了许多优化,方面显示而已。下面的程序是实现一个带有图片的类表。首先需要定义好一个用来显示每一个列内容的xml vlist.xml view source print? 01 version="1.0" encoding="utf-8"?> 02xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="horizontal" 03android:layout_width="fill_parent" 04android:layout_height="fill_parent"> 07 08 android:layout_width="wrap_content" 09 android:layout_height="wrap_content" 10 android:layout_margin="5px"/> 11 12 13 android:layout_width="wrap_content" 14 android:layout_height="wrap_content"> 15 16 17 android:layout_width="wrap_content" 18 android:layout_height="wrap_content" 19 android:textColor="#FFFFFFFF" 20 android:textSize="22px" /> 21 22 android:layout_width="wrap_content" 23 android:layout_height="wrap_content" 24 android:textColor="#FFFFFFFF" 25 android:textSize="13px" /> 26 27 30 下面是实现代码: view source print? 01 /** 02 * @author allin 03 * 04 */ 05 public class MyListView3 extends ListActivity { 08 // privateList 09 @Override 10 public void onCreate(BundlesavedInstanceState) { 11 super.onCreate(savedInstanceState); SimpleAdapter adapter = 13 new SimpleAdapter(this,getData(),R.layout.vlist, 14 new String[]{"title","info","img"}, 15 new int[]{R.id.title,R.id.info,R.id.img}); 16 setListAdapter(adapter); 17 } 18 19 private List 20 new ArrayList 22 Map 23 map.put("title", "G1"); 24 map.put("info", "google 1"); 25 map.put("img", R.drawable.i1); 26 list.add(map); 27 28 map = new HashMap 29 map.put("title", "G2"); 30 map.put("info", "google 2"); 31 map.put("img", R.drawable.i2); 32 list.add(map); 33 34 map = new HashMap 35 map.put("title", "G3"); 36 map.put("info", "google 3"); 37 map.put("img", R.drawable.i3); 38 list.add(map); 39 40 return list; 41 } 42 } 使用 simpleAdapter 的数据用一般都是 HashMap 构成的 List,list 的每一节对应ListVi ew 的每一行。HashMap的每个键值数据映射到布局文件中对应 id 的组件上。因为系统没有对应的布局文件可用,我们可以自己定义一个布局vlist.xml。下面做适配,new 一个 S impleAdapter 参数一次是:this,布局文件(vlist.xml),HashMap 的 title 和 info, img。布局文件的组件id,title,info,img。布局文件的各组件分别映射到HashMap的各元素上,完成适配。运行效果如下图: 有按钮的 ListView 但是有时候,列表不光会用来做显示用,我们同样可以在在上面添加按钮。添加按钮首先要写一个有按钮的 xml 文件,然后自然会想到用上面的方法定义一个适配器,然后将数据映射到布局文件上。但是事实并非这样,因为按钮是无法映射的,即使你成功的用布局文件显示出了按钮也无法添加按钮的响应,这时就要研究一下ListView 是如何现实的了,而且必须要重写一个类继承 BaseAdapter。下面的示例将显示一个按钮和一个图片,两行字如果单击按钮将删除此按钮的所在行。并告诉你 ListView 究竟是如何工作的。效果如下: vlist2.xml view source print? 01 version="1.0" encoding="utf-8"?> 02 xmlns:android="http://schemas.android.com/apk/res/android" 03 android:orientation="horizontal" android:layout_width="fill_parent 04 " 05 android:layout_height="fill_parent"> 06 07 08 09 android:layout_width="wrap_content" 10 android:layout_height="wrap_content" 11 android:layout_margin="5px"/> 12 13 15 android:layout_height="wrap_content"> 16 17 18 android:layout_width="wrap_content" 19 android:layout_height="wrap_content" 20 android:textColor="#FFFFFFFF" 21 android:textSize="22px" /> 22 23 android:layout_width="wrap_content" 24 android:layout_height="wrap_content" 25 android:textColor="#FFFFFFFF" 26 android:textSize="13px" /> 27 28 29 30 31 32 android:layout_width="wrap_content" 33 android:layout_height="wrap_content" 34 android:text="@string/s_view_btn" 35 android:layout_gravity="bottom|right" /> 36 程序代码: view source print? 001 /** 002 * @author allin 003 * 004 */ 005 public class MyListView4 extends ListActivity { 008 private List 010 @Override 011 public void onCreate(BundlesavedInstanceState) { 012 super.onCreate(savedInstanceState); 013 mData = getData(); 014 MyAdapter adapter = new MyAdapter(this); 015 setListAdapter(adapter); 016 } 017 018 private List 019 List 020 021 Map 022 map.put("title","G1"); 023 map.put("info","google 1"); 024 map.put("img",R.drawable.i1); 025 list.add(map); 026 027 map = new HashMap 028 map.put("title","G2"); 029 map.put("info","google 2"); 030 map.put("img",R.drawable.i2); 031 list.add(map); 032 033 map = new HashMap 034 map.put("title", "G3"); 035 map.put("info","google 3"); 036 map.put("img",R.drawable.i3); 037 list.add(map); 038 039 return list; 040 } 041 042 // ListView 中某项被选中后的逻辑 043 @Override 044 protected void onListItemClick(ListView l, Viewv, intposition, longid) { 045 Log.v("MyListView4-click", 046 (String)mData.get(position).get("title")); 047 } 048 049 /** 050 * listview中点击按键弹出对话框 051 */ 052 public void showInfo(){ 053 new AlertDialog.Builder(this) 054 .setTitle("我的listview") 055 .setMessage("介绍...") .setPositiveButton("确定", 056 new DialogInterface.OnClickListener(){ 057 @Override 058 public void onClick(DialogInterface dialog,intwhich) { 059 } 060 }) 061 .show(); 062 067 public final class ViewHolder{ 068 public ImageView img; 069 public TextView title; 070 public TextView info; 071 public Button viewBtn; } 072 075 public class MyAdapter extends BaseAdapter{ 076 077 private LayoutInflater mInflater; 080 public MyAdapter(Context context){ 081 this.mInflater =LayoutInflater.from(context); 082 } 083 @Override 084 public int getCount() { 085 // TODO Auto-generated methodstub 086 return mData.size(); 087 } 088 089 @Override 090 public Object getItem(int arg0) { 091 // TODO Auto-generated methodstub 092 return null; 093 } 094 095 @Override 096 public long getItemId(int arg0) { 097 // TODO Auto-generated methodstub 098 return 0; 099 } 100 101 @Override 102 public View getView(int position, View convertView, ViewGroup parent) { 103 104 ViewHolder holder = null; 105 if (convertView ==null) { 107 holder=new ViewHolder(); 109 convertView = mInflater.inflate(R.layout.vlist2,null); 110 holder.img =(ImageView)convertView.findViewById(R.id.img); 111 holder.title =(TextView)convertView.findViewById(R.id.title); 112 holder.info =(TextView)convertView.findViewById(R.id.info); 113 holder.viewBtn =(Button)convertView.findViewById(R.id.view_btn); 114 convertView.setTag(holder); 115 116 }else { 117 118 holder = (ViewHolder)convertView.getTag(); 119 } 120 12holder.img.setBackgroundResource((Integer)mData.get(position).ge 2 t("img")); 123 holder.title.setText((String)mData.get(position).get("title")); 124 holder.info.setText((String)mData.get(position).get("info")); 125 126 holder.viewBtn.setOnClickListener(new View.OnClickListener() { 127 128 @Override 129 public void onClick(View v) { 130 showInfo(); 131 } 132 }); 133 134 135 return convertView; 136 } 137 下面将对上述代码,做详细的解释,listView在开始绘制的时候,系统首先调用getC ount()函数,根据他的返回值得到listView的长度(这也是为什么在开始的第一张图特别的标出列表长度),然后根据这个长度,调用 getView()逐一绘制每一行。如果你的g etCount()返回值是0的话,列表将不显示同样return 1,就只显示一行。 系统显示列表时,首先实例化一个适配器(这里将实例化自定义的适配器)。当手动完成适配时,必须手动映射数据,这需要重写getView()方法。系统在绘制列表的每一行的时候将调用此方法。getView()有三个参数,position 表示将显示的是第几行,covert View 是从布局文件中 inflate 来的布局。我们用LayoutInflater 的方法将定义好的 vlist 2.xml 文件提取成 View 实例用来显示。然后将 xml 文件中的各个组件实例化(简单的 fi ndViewById()方法)。这样便可以将数据对应到各个组件上了。但是按钮为了响应点击事件,需要为它添加点击监听器,这样就能捕获点击事件。至此一个自定义的 listView 就完成了,现在让我们回过头从新审视这个过程。系统要绘制ListView了,他首先获得要绘制的这个列表的长度,然后开始绘制第一行,怎么绘制呢?调用 getView()函数。在这个函数里面首先获得一个View(实际上是一个 ViewGroup),然后再实例并设置各个组件,显示之。好了,绘制完这一行了。那 再绘制下一行,直到绘完为止。在实际的运行过程中会发现listView 的每一行没有焦点了,这是因为 Button 抢夺了listView的焦点,只要布局文件中将 Button设置为没有焦点就OK了。Android API Demo研究(2) 文章分类:移动开发 1. Forwarding 这个实现很简单,就是启动新的 Activity 或者 Service 后,增加一个finish() 语句就可以了,这个语句会主动将当前 activity从历史stack中清除,这样back 操作就不会打开当前activity。 做这个实验的时候,发现开发 Android 程序需要注意的一点小问题:增加新的activity 时,不能只增加一个 class,一定要记得要在 manifest 文件中增加该activity 的描述。(这个简单的功能,未来 google 应该给增加吧) “android:name 中的点”意义:首先 manifest 会有一个默认指定的 package 属性,比如指定为"com.android.sample",如果我们增加的 activity 的实现也在这个 package 下,则android:name 为实现的类名,这个类名前加不加点都没有关系,都会自动找到该实现,比如实现为forwardtarget,则 android:name 写成 forwardtarget 或者.forwardtarget 都可以。唯一有区别的是,如果 activity 的实现是在默认包的子包里面,则前面这个点就尤为重 要,比如 activity 的实现是com.android.sample.app.forwardtarget,则 android:name 必须写成.app.forwardtarget 或者 com.android.sample.app.forwardtarget。如果只写 app.forwardtarget,通常编辑器就会提示该类找不到,但不巧的是,你恰好有一个类是 app.forwardtarget,那你只有等着运行时报错吧。 所以建议养成习惯只要是默认 package 下面的类,无论是否是在子包里面,前面都要加上一个点,现在当前实现是在默认package 下。 2.Persistent 这里的持久化其实就是本地配置文件的读写,实现方法是通过 Activity.getPreferences(int)获取 SharedPreferences对象,然后操作配置文件的读写,值得注意的是以下几点: 1)Activity.getPreferences(int mode)等价于 Content.getSharedPreferences(String filename,int mode),这里面的 filename 就是当前class 的名称,例如在 PersistentTest 类中调用 getPreferences(0),等价于调用 getPreferences("PersistentTest",0)。如 不想用 class name 做文件名,可以直接调用 getSharedPreferences 方法,自己指定配置文件的名称。 2)mode 值的定义: MODE_PRIVATE = 0,表示当前配置文件为私有文件,只有当前的应用可以访问。 MODE_WORLD_READABLE = 1,表示当前配置文件可以被其他应用读取。 MODE_WORLD_WRITEABLE = 2,表示当前配置文件可以被其他应用写入。 如果配置文件又想被人读又想被写人,怎么办呢,呵呵,当然是 MODE_WORLD_READABLE&MODE_WORLD_WRITEABLE,真的怀疑设计 android 的人以前是做C/C++的。 3) SharedPreferences 是个很有意思的实现,读取数据的时候,直接用 get 方法就可以了,可是写数据的时候,没用给 set 方法,呵呵,第一次用这个类一定会以为只能读不能写。如果要写数据的话,需要用editor()方法(为什么不是 getEditor()呢?看来设计的人一定是做 C/C++的)获取 SharedPreferences.Editor 类,然后用这个类的 put方法写文件。为什么要 这样做呢?好久没有看设计模式了,不知道他采用是哪种高级模式,等以后有时间,看看它的实现再做研究吧。 4) 在这个实现中,读文件是放在 onResume()中,写文件是在 onPause()中,为什么要这么做呢,看字面意思,好像只有恢复和暂停的时候才会被执行,那程序第一次创建的时候会读文件吗?来让我们看看Activity 的生命周期,就会发现这么做的巧妙之处: 文章分类:移动开发 1. Custom Dialog Android 支持自定义窗口的风格: 1)首先在资源里面建立style 的 value; example: drawable/filled_box.xml > PS:关于Styles的学习,可以参见: http://code.google.com/android/reference/available-resources.html#stylesandthemes 2)设置当前activity的属性,两种方式:1.在manifest文件中给指定的activity 增加属性 android:theme="@android:style/Theme.CustomDialog"。2.在程序中增加语句setTheme(R.style.Theme_CustomDialog); PS1:如果只是将Acticity 显示为默认的 Dialog, 跳过第一步,只需要在 manifest 文中增加属性: android:theme="@android:style/Theme.Dialog"或者在程序中增加 setTheme(android.R.style.Theme_Dialog). PS2:其他创建 Dialog 的方法:创建app.Dialog类或者创建app.AlertDialog类。 Next Study:能不能在Activity已经打开以后动态修改当前Activity的风格? 在测试中发现,在onCreate()事件中增加setTheme(),必须在setContentView()之前,否则指定 Style不能生效 2.Custom Title Android 除了可以为指定的Activity 设置显示风格,此外也可以为指定的 Activity 设置一些特效,比如自定义Title,没有 Title 的 Activity 或者增加一个ICON 等。有意思的一点是,这些特效并不是你想设置的时候就行设置,你需要在 Activity 显示之前向系统申请要显示的特效,这样才能在下面的程序中为这些特效进行设置。(这样是不是多此一举有待研究) 为一个 Activity 设置自定义Title 的流程: 1)为自定义的Title 建立一个 layout(custom_title_1.xml) <RelativeLayoutxmlns:android="http://schemas.android.com /apk/res/android"android:id="@+id/screen" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> 关于为什么采用RelativeLayout,可以参见: http://code.google.com/android/devel/ui/layout.html2)为activity设定自定义Title特效并指定Title的layout: 在onCreate()事件中增加: requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); setContentView(R.layout.custom_title); getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,R.layout.custom_title_1); 这三条语句的次序不能颠倒,依次为申请特效,创建view,设置特效属性。其 中requestWindowFeature等价于getWindow().requestFeature() 3)在需要修改Title的地方,获取left_text或者right_text进行设置即可。 Next Study:Activity的其他显示特效 Window还有其他一些feature,比如FEATURE_CONTEXT_MENU,FEATURE_NO_TITLE, FEATURE_LEFT_ICON等,有待继续学习研究。 Animations(转) 文章分类:移动开发 仅用于方便查找 Animations 链接 Android支持2种类型的动画。内插动画可以应用于旋转、平移、放缩和渐变; frame-by-frame动画用来显示一系列的图片。关于创建、使用和应用动画的广泛概述可以在11章找到。 把动画定义成外部资源,有利于在多个地方使用,并且能基于设备硬件或方向选择适应的动画。 Tweened Animations 每个内插动画以独立的XML文件存储在/res/anim文件夹下。和layouts和 drawable资源一样,动画XML的文件名用作资源的标识。 每个动画可以用来定义以下的变化:alpha(渐变)、scale(放缩)、translate (平移)和rotate(旋转)。 每个类型的动画都有特性来定义内插序列如何作用: Alpha fromAlpha/toAlpha 0-1 Scale fromXScale/toXScale 0-1 fromYScale/toYScale 0-1 pivotX/pivotY 图像的宽度/高度的百分比字符串 0%-100% Translate fromX/toX 0-1 fromY/toY 0-1 Rotate fromDegrees/toDegrees 0-360 pivotX/pivotY 图像的宽度/高度的百分比字符串 0%-100% 你可以使用 接下来的列表给了一些set标签一些特性: ❑ duration 动画的持续时间(毫秒) ❑ startOffset 启动动画的延时(毫秒) ❑ fillBefore True表示在动画开始前应用动画变换 ❑ fillAfter True表示动画开始后应用动画变换 ❑ interpolator 设置整个时间范围如何影响动画的速度。在11章中会探讨这个变量。指定interpolator时需要引用系统的动画资源 (android:anim/interpolatorName)。 如果你不使用startOffset标签,动画集中的动画将同步执行。 接下来的例子显示了动画集控制目标在缩小淡出的同时旋转360度: Xml代码 Java代码 1. 1.0” encoding=”utf-8”?> 2. 3. 4. 5. android:interpolator=”@android:anim/accelerate_interpolator”> 6. 7. 9. android:fromDegrees=”0” 10. 11.android:toDegrees=”360” 12. 13.android:pivotX=”50%” 14. 15.android:pivotY=”50%” 16. 17.android:startOffset=”500” 18. 19.android:duration=”1000” /> 20. 21. 23.android:fromXScale=”1.0” 24. 25.android:toXScale=”0.0” 26. 27.android:fromYScale=”1.0” 28. 29.android:toYScale=”0.0” 30. 31.android:pivotX=”50%” 32. 33.android:pivotY=”50%” 34. 35.android:startOffset=”500” 36. 37.android:duration=”500” /> 38. 39. 41.android:fromAlpha=”1.0” 42. 43.android:toAlpha=”0.0” 44. 45.android:startOffset=”500” 46. 47.android:duration=”500” /> 48. 49. Frame-by-Frame Animations Frame-by-Frame动画用于View的背景上,显示一系列的图片,每张图片显示指定的时间。 因为Frame-by-Frame动画显示drawables,所以,它们也被放在/res/drawble 文件夹下(和Tweened动画不同),并且使用它们的文件名作为它们的资源标识。 接下来的XML片段显示了一个简单的动画,它循环显示一些位图资源,每张位图显示0.5秒。为了能使用这个XML片段,你需要创建rocket1-rocket3 三个新的图片资源。 Java代码 1. Xml代码 2. 4. xmlns:android=”http://schemas.android.com/apk/res/android” 5. 6. android:oneshot=”false”> 7. 8. 500” /> 9. 10. 500” /> 11. 12. 500” /> 13. 14. 看到了吧,在 Activity 运行的前后,无论状态怎么转移,onResume()和 onPause()一定会被执行,与其说实现的巧妙,还不如赞一下这个生命周期的设计的巧妙,这个巧妙不是说说而已,有时间的话,看看MFC 中一个 windows 或者 dialog 的生命周期,你就知道这个巧妙的含义了,我们可以省多少的事情啊!所以值得记住的是,在android 中想在运行前后必须要执行的语句,就应该放在 onResume()和 onPause()中。 4)最后说一个对android 小不爽的地方:drawable,什么鬼东西啊!在 res/drawable 放一个文件,访问的时候是 drawable/name,如果在 values 里面建立一个drawable 的变量,访问的时候也是 drawable/name,例如在 drawable 目录下放入一个 red.xml 文件,访问的时候是@drawable/red,如果建立一个 drawable 的变量 red,访问也是@drawable/red,这完全就是两个东西啊,虽然最新的编辑器会提示重名,但查找的时候真的很不方便啊,尤其是 drawable 变量,可以放在一个abc.xml 中,以后资源文件多了,管理起来 想想都头麻,就不能把其中一个改改名字吗?把 drawable 变量叫成drawable_value 不行吗? 用GridView实现Gallery的效果(转) 在实现横向的类似Gallery的效果中做了实现Gallery的尝试,但是效果不好。使用的是TableLayout,出现了横向拖动图片的时候,因为有倾斜(轻微的竖向 拖动),会整个列表竖向滚动。其实这个问题可以将TableRow中条目设置为 clickable来解决。但是效果依然不好。 • 每个可选的图,包括文字部分,是GridView中的一个条目; • 一个 GridView 条目是相对布局(RelativeLayout),里面包含一个图片(ImageView)和一个文字(TextView); • 关键点是GridView如何保持横向,默认的情况下会折行的,首先要用一个 HorizontalScrollView提供横向滚动容器,然后内部放置一个FrameLayout,如果不放置FrameLayout布局,直接放入下面的布局或者视图,GridView将会变成单列纵向 滚动,在 FrameLayout布局中加入横向的LinearLayout布局,要设置它的layout_width,要足够大,这样在其中加入GridView就能横向排列了。 首先看一下GridView中条目的布局:
xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingBottom="10.0dip" android:layout_width="90.0dip" android:layout_height="140.0dip"> android:layout_below="@+id/ItemImage" android:id="@+id/ItemText" android:ellipsize="end" android:layout_width="80.0dip" android:layout_height="26.0dip" android:layout_marginTop="5.0dip" android:singleLine="true" android:layout_centerHorizontal="true">
|
这里使用了相对布局的特性,android:layout_below,表示TextView在 ImageView下面。这里的图都是用的res/drawable目录下的静态图形文件,正式情况下,应该是从网络获取,可参见用Java concurrent编写异步加载图片功能的原型实现,二者结合可用于正式生产环境。
ListView的Header使用了自定义视图,更简单的示例可参见为ListView增加
Header。表头(ListView Header)的布局文件:
xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="200dp"> android:layout_height="wrap_content" android:text="最近访问人物" /> |
android:layout_height="match_parent" android:orientation="horizontal"> android:layout_height="fill_parent" android:horizontalSpacing="1.0dip" android:verticalSpacing="1.0dip" android:stretchMode="spacingWidthUniform" android:numColumns="auto_fit" android:columnWidth="80dip">
|
这是比较关键的布局文件,GridView能实现横向滚动主要靠它了。其中:
我是写死了1100dp,正式使用的时候,因为图片都可能是动态从服务器上获取的,可以根据数量以及图片的宽度,空白边动态计算这个长度。
GridView和ListView类似,都需要ViewAdapter来适配数据和视图。
见Activity的源代码:
package com.easymorse.grid.demo; import java.util.ArrayList; import java.util.HashMap; import android.app.ListActivity; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.widget.ArrayAdapter; import android.widget.GridView; import android.widget.ListView; import android.widget.SimpleAdapter; public class GridDemoActivity extends ListActivity { /** Called when the activity is first created. */ @Override |
public void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.main); LayoutInflater layoutInflater = (LayoutInflater) this .getSystemService("layout_inflater");
View headerView=layoutInflater.inflate(R.layout.list_header, null); setGridView(headerView); ListView listView=(ListView) this.findViewById(android.R.id.list); listView.addHeaderView(headerView); listView.setAdapter(new ArrayAdapter ","明","清"})); } private void setGridView(View view) { GridView gridView = (GridView) view.findViewById(R.id.grid); gridView.setNumColumns(10); ArrayList for (int i = 0; i < 10; i++) { HashMap map.put("ItemImage", R.drawable.k); map.put("ItemText", "清.康熙" + "(" + i + ")"); items.add(map); } SimpleAdapter adapter = new SimpleAdapter(this, items, R.layout.item, new String[] { "ItemImage", "ItemText" }, new int[] { R.id.ItemImage, R.id.ItemText }); gridView.setAdapter(adapter); } } |
Android画图之Matrix(一)
Matrix ,中文里叫矩阵,高等数学里有介绍,在图像处理方面,主要是用于平面的缩放、平移、旋转等操作。
首先介绍一下矩阵运算。加法和减法就不用说了,太简单了,
对应位相加就好。图像处理,主要用到的是乘法 。下面是一个乘法的公式:
在 Android 里面, Matrix 由 9 个 float 值构成,是一个 3*3 的矩阵。如下图。
没专业工具,画的挺难看。解释一下,上面的 sinX 和 cosX ,表示旋
转角度的 cos 值和sin 值,注意,旋转角度是按顺时针方向计算
的。 translateX 和 translateY 表示 x 和 y的平移量。 scale 是缩放的比例, 1 是不变, 2 是表示缩放 1/2 ,这样子。 下面在 Android 上试试 Matrix 的效果。
Java代码
1.publicclass MyViewextends View {
2.
3. privateBitmap mBitmap;
4.
5. privateMatrix mMatrix =new Matrix();
6.
7. publicMyView(Context context) {
8.
9. super(context);
10.
11. initialize();
12.
13. }
14.
15. privatevoid initialize() {
16.
17. mBitmap =((BitmapDrawable)getResources().getDrawable(R.drawable.sho
w)).getBitmap();
18.
19. float cosValue = (float) Math.cos(-Math.PI/6);
20.
21. float sinValue = (float) Math.sin(-Math.PI/6);
22.
23. mMatrix.setValues(
24.
25. newfloat[]{
26.
27. cosValue, -sinValue,100,
28.
29. sinValue, cosValue,100,
30.
31. 0,0,2});
32.
33. }
34.
35. @Overrideprotectedvoid onDraw(Canvas canvas) {
36.
37.// super.onDraw(canvas); //当然,如果界面上还有其他元素需要绘制,只需要将这句话写上就行了。
38.
39. canvas.drawBitmap(mBitmap, mMatrix,null);
40.
41. }
42.
43.}
运行结果如下:
以左上角为顶点,缩放一半,逆时针旋转 30 度,然后沿 x 轴和 y 轴分别平移 50 个像素,代码 里面写的是 100,为什么是平移 50 呢,因为缩放了一半。
大家可以自己设置一下 Matrix 的值,或者尝试一下两个 Matrix 相乘,得到的值设置进去,这样才能对 Matrix 更加熟练。
这里讲的直接赋值的方式也许有点不好理解,不过还好, andrid 提供了对矩阵的更方便的方法,下一篇介绍。
Android画图之Matrix(二)
文章分类:移动开发
上一篇Android画图之Matrix(一)讲了一下Matrix的原理和运算方法,涉及到高等数学,有点难以理解。还好Android里面提供了对Matrix操作的一系
列方便的接口。
Matrix的操作,总共分为translate(平移),rotate(旋转),scale
(缩放)和skew(倾斜)四种,每一种变换在
Android的API里都提供了set, post和pre三种操作方式,除了translate,其他三种操作都可以指定中心点。
set是直接设置Matrix的值,每次set一次,整个Matrix的数组都会变掉。
post是后乘,当前的矩阵乘以参数给出的矩阵。可以连续多次使用post,
来完成所需的整个变换。例如,要将一个图片旋转30度,然后平移到(100,100)的地方,那么可以这样做:
Java代码
1. Matrix m = new Matrix();
2.
3. m.postRotate(30 ); 4.
5. m.postTranslate(100 , 100 );
这样就达到了想要的效果。
pre是前乘,参数给出的矩阵乘以当前的矩阵。所以操作是在当前矩阵的最前面发生的。例如上面的例子,如果用pre的话
,就要这样:
Java代码
1. Matrix m = new Matrix();
2.
3. m.setTranslate(100 , 100 ); 4.
5. m.preRotate(30 ); 旋转、缩放和倾斜都可以围绕一个中心点来进行,如果不指定,默认情况下,是围绕(0,0)点来进行。
下面给出一个例子。
Java代码
1. package chroya.demo.graphics; 2.
3. import android.content.Context; 4. import android.graphics.Bitmap; 5. import android.graphics.Canvas;
6. import android.graphics.Matrix;
7. import android.graphics.Rect;
8. import android.graphics.drawable.BitmapDrawable;
9. import android.util.DisplayMetrics;
10.import android.view.MotionEvent;
11.import android.view.View; 12.
13.public class MyView extends View {
14.
15. private Bitmap mBitmap;
16. private Matrix mMatrix = new Matrix(); 17.
18. public MyView(Context context) {
19. super (context);
20. initialize(); 21. } 22.
23. private void initialize() {
24.
25. Bitmap bmp = ((BitmapDrawable)getResources().getDrawable(R.drawable.show)).getBitmap();
26. mBitmap = bmp;
27. /*首先,将缩放为100*100。这里scale的参数是比例。有一点要注意,如果直接用100/
28.bmp.getWidth()的话,会得到0,因为是整型相除,所以必须其中有一个是 float型的,直接用100f就好。*/
29. mMatrix.setScale(100f/bmp.getWidth(), 100f/bmp.getHeight());
30. //平移到(100,100)处
31. mMatrix.postTranslate(100 , 100 );
32. //倾斜x和y轴,以(100,100)为中心。
33. mMatrix.postSkew(0 .2f, 0 .2f, 100 , 100 ); 34. }
35.
36. @Override protected void onDraw(Canvas canvas) {
37.// super.onDraw(canvas); //如果界面上还有其他元素需要绘制,只需要将这句话写上就行了。
38.
39. canvas.drawBitmap(mBitmap, mMatrix, null );
40. }
41.}
运行效果如下:
红色的x和y表示倾斜的角度,下面是x,上面是y。看到了没,Matrix 就这么简单。
XML属性
文章分类:移动开发 一、属性分类
1. View的属性
2. TextView的属性 二、View的属性
1. 基础属性
• android:id: 设定view的id。之后在代码里面可以通过
View.findViewById()来获取相应的View
• android:tag : 设定view的tag。之后可以再代码里面通过 View.findViewByTag来获取相应的View
2. 事件相关
2.1 Click事件相关
• android:clickable:view是否能对click事件作出反应。值域【true,false】
• android:onClick: 当view被click之后,view的context的哪个方法被呼叫。通常这个context是指vieW所在的Acitvity。例如:
android:onClick = 'sayHello'.则相应的Activity里面有一个方法 public void sayHello(View view)方法。当这个view被click之后, sayHello方法就会被调用。
• android:longClickable : view是否可以对长时间的click事件作出反应。值域【true,false】
2.1 Focus事件相关
• android:focusable : view是否能响应焦点事件 android:
三、TextView的属性
其他的属性请参考:View的属性
1 文本相关的属性
1.1 文本属性
• android:text 文字
• android:typeface : 设定字体
• android:textStyle : 风格。值域【bold,italic,normal】。可以组合设定。例如:bold | italic
• android:textSize : 文字大小
• android:textColor : 文字的颜色
• android:textColorHight : 文字被选择的时候,高亮的颜色
1.2 提示文本相关的属性
• android:hint 当文本内容为空时,提示信息
• android:textColorHint 提示文本的颜色
2. 输入内容的控制
• android:number 只能输入数字。值域【integer, decimal , signed】,可以组合设定。例如:integer | signed
• 2010-10-22
Android中的长度单位详解(dp、sp、px、in、pt、mm)
• 文章分类:移动开发
• 看到有很多网友不太理解dp、sp和px的区别:现在这里介绍一下dp和 sp。dp也就是dip。这个和sp基本类似。如果设置表示长度、高度等属性时可以使用dp 或sp。但如果设置字体,需要使用sp。dp是与密度无关,sp除了与密度无关外,还与scale无关。如果屏幕密度为160,这时 dp和sp和px是一样的。1dp=1sp=1px,但如果使用px作单位,如果屏幕大小不变(假设还是3.2寸),而屏幕密度变成了320。那么原来TextView 的宽度设成160px,在密度为320的3.2寸屏幕里看要比在密度为160的 3.2寸屏幕上看短了一半。但如果设置成160dp或160sp的话。系统会自
动将width属性值设置成320px的。也就是160 * 320 / 160。其中320 /
160可称为密度比例因子。也就是说,如果使用dp和sp,系统会根据屏幕密度的变化自动进行转换。
下面看一下其他单位的含义
px:表示屏幕实际的象素。例如,320*480的屏幕在横向有320个象素,在纵向有480个象素。
in:表示英寸,是屏幕的物理尺寸。每英寸等于2.54厘米。例如,形容手机屏幕大小,经常说,3.2(英)寸、3.5(英)寸、4(英)寸就是指这个单位。这些尺寸是屏幕的对角线长度。如果手机的屏幕是3.2英寸,表示手机的屏幕(可视区域)对角线长度是3.2*2.54 = 8.128厘米。读
者可以去量一量自己的手机屏幕,看和实际的尺寸是否一致。
mm:表示毫米,是屏幕的物理尺寸。
pt:表示一个点,是屏幕的物理尺寸。大小为1英寸的1/72。
原创--解剖androidStyle原理从Button入手
文章分类:移动开发
转载 声明原处 :博客http://pk272205020.blog.163.com/
参考论坛外国android论坛http://www.androidpeople.com/ 参考资料:android Button 原理
这几日都是看android SDK原码,想封装一个HERO 效果的UI界面。刚想以为很容易,但越做越难,为有百度,Google求救,但这方面的资料还是不多,这个我也不怪了,可能android 在中国的市场还是刚刚起步。外面的一些网站 android 技术论坛打不开,闷...
但我发现http://www.android.com/ 可以打开了,以前要用XX软件先打得开,但
里面的developer标签还是俾中国网关封,这个更郁闷... 不讲了,直入正题 android Styel原理
刚刚开始得写时从最简单的Button 入手,下载SDK原码候Button 继续
TextView 原码里就三个构造方法....
Java代码
1. @RemoteView
2. public class Button extends TextView {
3. public Button(Context context) {
4. this(context, null); 5. } 6.
7. public Button(Context context, AttributeSet attrs)
{
8. this(context, attrs, com.android.internal.R.a ttr.buttonStyle);
9. } 10.
11. public Button(Context context, AttributeSetattrs, int defStyle) {
12. super(context, attrs, defStyle);
13. }
14.}[
默认样式:com.android.internal.R.attr.buttonStyle,android 的style 太强大, 网上有人说过是 GWT模式, 在校的时候我也用过GWT写过小网页,HTML 文件里标签里嵌入GWT标签,通过服务端Java代码生成页面,GWT就讲到这里,有开展过GWT的同志就知道这个也很像android的Layout布局文件,哈哈 我也是认同网上的人说。
知道android 的Style模式后,我们要进一步了解内部的实现,我们
要打开com.android.internal.R.attr.buttonStyle这个对应的XML
Xml代码
1. < stylename="Widget.Button"> 2.
3. < item name="android:background">@android:drawable/btn_default< /item>
4.
5. < item name="android:focusable" >true< /item >
6.
7. < item name="android:clickable" >true< /item > 8.
9. < item name="android:textSize" >20sp< /item > 10.
11.< item name="android:textStyle" >normal< /item > 12.
13.< item name="android:textColor" >@android:color/button_text
>
14.
15.
17.
18.< /style >
这个文件定义了好多style相关的属性,每个属性都好理解,这个 backgroud属性难道仅仅是一个drawable图片?如果仅仅是一个图片的化,怎么能够实现button各种状态下表现出不同背景的功能呢?还是来看看这个 drawable到底是什么东西。
还是埋头苦干地找出答案
在drwable目录中发现这个btn_default这个文件,还有许多这样的xml文件,
看名字可以估到是什么来的
btn_default.xml 内容
Xml代码
1. < selectorxmlns:android="http://schemas.android.com/apk/res/android">
2.
3. < itemandroid:state_window_focused="false"android:state_enabled="true"
4. android:drawable="@drawable/btn_default_normal" /> 5.
6. < itemandroid:state_window_focused="false"android:state_enabled="false"
7. android:drawable="@drawable/btn_default_normal_disable" />
8.
9. < item android:state_pressed="true"
10.android:drawable="@drawable/btn_default_pressed" /> 11.
12.< item android:state_focused="true" android:state_enabled="true"
13.android:drawable="@drawable/btn_default_selected" /> 14.
15.< item android:state_enabled="true"
16.android:drawable="@drawable/btn_default_normal" /> 17.
18.< item android:state_focused="true"
19.android:drawable="@drawable/btn_default_normal_disable_focused"
/ >
20.
21.< item android:drawable="@drawable/btn_default_normal_disable
" / >
22.
23.< /selector >
在android 中drawable文件是看图片存放的,最普通的就是一个图片。而这里用到的是StateListDrawable。当Android的解析器解析到上面的xml时,会自
动转化成一个StateListDrawable类的实例,看看SDK是这样说的
Lets you assign a number of graphicimages to a single Drawable and swap out the visible item by a string IDvalue.
It can be defined in an XML file with the
意思就是通过字符串标识符值ID 分配单个可绘制可切换 的可视图形项
看看核心代码吧:大部多代码删除了
Java代码
1. public classStateListDrawable extends DrawableContainer {
2. /**
3. * To be proper, weshould have a getter for dither (and alpha, etc.)
4. * so that proxyclasses like this can save/restore their delegates'
5. * values, but wedon't have getters. Since we do have s etters
6. * (e.g. setDither),which this proxy forwards on, we have tohave some
7. * default/initialsetting.
8. *
9. * The initialsetting for dither is now true, since it almost always seems
10.* to improve thequality at negligible cost.
11.*/
12.private static final booleanDEFAULT_DITHER = true;
13.private final StateListStatemStateListState;
14.private booleanmMutated; 15.
16.public StateListDrawable(){
17.this(null, null); 18.}
19.
20./**
21.* Add a new image/string IDto the set of images.
22.*
23.* @param stateSet- An array of resource Ids to associat e with the image.
24.* Switch to this image bycalling setState().
25.* @param drawable -The imageto show.
26.*/
27.public void addState(int[]stateSet, Drawable drawable) {
28.if (drawable != null) {
29.mStateListState.addStateSet(stateSet,drawable);
30.// in case the new statematches our current state...
31.onStateChange(getState());
32.}
33.}
34.
35.@Override
36.public boolean isStateful(){
37.return true; 38.}
39.
40.@Override
41.protected booleanonStateChange(int[] stateSet) {
42.int idx =mStateListState.indexOfStateSet(stateSet);
43.if (idx < 0) {
44.idx =mStateListState.indexOfStateSet(StateSet.WILD_CARD);
45.}
46.if (selectDrawable(idx)){
47.return true;
48.}
49.returnsuper.onStateChange(stateSet); 50.}
51.
52.
53./**
54.* Gets the state set at anindex.
55.*
56.* @param index The index ofthe state set.
57.* @return The state set atthe index.
58.* @hide pending APIcouncil
59.* @see #getStateCount()
60.* @see#getStateDrawable(int)
61.*/
62.public int[] getStateSet(intindex) {
63.returnmStateListState.mStateSets[index]; 64.}
65.
66.
67.static final classStateListState extends DrawableContainerSt ate {
68.private int[][]mStateSets; 69.
70.StateListState(StateListStateorig, StateListDrawable owner, R esources res) { 71.super(orig, owner, res); 72.
73.if (orig != null) {
74.mStateSets =orig.mStateSets;
75.} else {
76.mStateSets = newint[getChildren().length][];
77.}
78.}
79.
80.
81.
82.
83. int addStateSet(int[] stateSet, Drawable drawable){
84. final int pos = addChild(drawable);
85. mStateSets[pos] = stateSet;
86. return pos;
87. } 88.
89.
90.}
91.
92.privateStateListDrawable(StateListState state, Resources res)
{
93.StateListState as = newStateListState(state, this, res);
94.mStateListState = as;
95.setConstantState(as);
96.onStateChange(getState());
97.}
98.}
xml中每一个Item就对应一种状态,而每一个有state_的属性就是描述状态, drawable则是真正的drawable图片。当把这个实例付给View作为Background 的时候,View会根据不同的state来切换不同状态的图片,从而实现了Press 等诸多效果。简单看一下View中有关状态切换的代码吧:
Java代码
1. /**
2. * The order here isvery important to {@link #getDrawa bleState()}
3. */
4. private static finalint[][] VIEW_STATE_SETS = {
5. EMPTY_STATE_SET, //0 0 0 0 0
6. WINDOW_FOCUSED_STATE_SET,// 0 0 0 0 1
7. SELECTED_STATE_SET,// 0 0 0 1 0
8. SELECTED_WINDOW_FOCUSED_STATE_SET,// 0 0 0 1 1
9. FOCUSED_STATE_SET,// 0 0 1 0 0
10.FOCUSED_WINDOW_FOCUSED_STATE_SET,// 0 0 1 0 1
11.FOCUSED_SELECTED_STATE_SET,// 0 0 1 1 0
12.FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET,// 0 0 1 1 1
13.ENABLED_STATE_SET, // 0 1 0 00
14.ENABLED_WINDOW_FOCUSED_STATE_SET,// 0 1 0 0 1
15.ENABLED_SELECTED_STATE_SET,// 0 1 0 1 0
16.ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET,// 0 1 0 1 1
17.ENABLED_FOCUSED_STATE_SET, //0 1 1 0 0
18.ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET,// 0 1 1 0 1
19.ENABLED_FOCUSED_SELECTED_STATE_SET,// 0 1 1 1 0
20.ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET,// 0 1 1
1 1
21.PRESSED_STATE_SET,// 1 0 0 0 0
22.PRESSED_WINDOW_FOCUSED_STATE_SET,// 1 0 0 0 1
23.PRESSED_SELECTED_STATE_SET,// 1 0 0 1 0
24.PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET,// 1 0 0 1 1
25.PRESSED_FOCUSED_STATE_SET, //1 0 1 0 0
26.PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET,// 1 0 1 0 1
27.PRESSED_FOCUSED_SELECTED_STATE_SET,// 1 0 1 1 0
28.PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET,// 1 0 1
1 1
29.PRESSED_ENABLED_STATE_SET, //1 1 0 0 0
30.PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET,// 1 1 0 0 1
31.PRESSED_ENABLED_SELECTED_STATE_SET,// 1 1 0 1 0
32.PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET,// 1 1 0
1 1
33.PRESSED_ENABLED_FOCUSED_STATE_SET,// 1 1 1 0 0
34.PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET,// 1 1 1
0 1
35.PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET,// 1 1 1 1 0
36.PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET,//
1 1 1 1 1
37.};
详细打开View.java 自己看
下面是setBackground方法,红字就是是state切换 ,View 这个类太长了, android2.2版一共9321行
Java代码
1. /**
2. * Set the background to a given Drawable, or remove the background. If the
3. * background has padding, this View's padding is setto the background's
4. * padding. However, when a background is remov ed,this View's padding isn't
5. * touched. If setting the padding is desired, please use
6. * {@link #setPadding(int, int, int, int)}.
7. *
8. * @param d The Drawable to use as the backgr ound,or null to remove the
9. * background
10. */
11. public void setBackgroundDrawable(Drawable d) {
12. boolean requestLayout = false;
13.
14. mBackgroundResource = 0;
15.
16. ...............
17.
18. if (d.isStateful()) {
19. d.setState(getDrawableState());
20. }
21. d.setVisible(getVisibility() == VISIB LE,false);
22. mBGDrawable = d;
23.
24. ...............
25.
26. mBackgroundSizeChanged = true;
27. invalidate();
28.}
setBackgound方法先判断Drawable对象是否支持state切换 如果支持,设置状态就可达到图片切换的效果。
就写到这里
Android-----使用Button特效selector+shape
文章分类:移动开发
当然除了使用drawable这样的图片外今天谈下自定义图形shape的方法,对于Button控件
Android上支持以下几种属性shape、gradient、stroke、corners等。 我们就以目前系统的Button的selector为例说下:
Java代码
1.
2. 3. android:startColor="#ff8c00" 4. android:endColor="#FFFFFF" 5. android:angle="270" /> 6. 7. android:width="2dp" 8. android:color="#dcdcdc" /> 9. 10. android:radius="2dp" /> 11. 12. android:left="10dp" 13. android:top="10dp" 14. android:right="10dp" 15. android:bottom="10dp" /> 16. 对于上面,这条shape的定义,分别为渐变,在gradient中startColor属性为开始的颜色, endColor为渐变结束的颜色,下面的angle是角度。接下来是stroke可以理解为边缘,corners 为拐角这里radius属性为半径,最后是相对位置属性padding。 对于一个Button完整的定义可以为: Java代码 1. 2. 3. xmlns:android="http://www.norkoo.com"> 4. 5. 6. 7. android:startColor="#ff8c00" 8. android:endColor="#FFFFFF" 9. android:angle="270" /> 10. 11. android:width="2dp" 12. android:color="#dcdcdc" /> 13. 14. android:radius="2dp" /> 15. 16. android:left="10dp" 17. android:top="10dp" 18. android:right="10dp" 19. android:bottom="10dp" /> 20. 21. 22. 23. 24. 25. 26. android:startColor="#ffc2b7" 27. android:endColor="#ffc2b7" 28. android:angle="270" /> 29. 30. android:width="2dp" 31. android:color="#dcdcdc" /> 32. 33. android:radius="2dp" /> 34. 35. android:left="10dp" 36. android:top="10dp" 37. android:right="10dp" 38. android:bottom="10dp" /> 39. 40. 41. 42. 43. 44. 45. android:startColor="#ff9d77" 46. android:endColor="#ff9d77" 47. android:angle="270" /> 48. 49. android:width="2dp" 50. android:color="#fad3cf" /> 51. 52. android:radius="2dp" /> 53. 54. android:left="10dp" 55. android:top="10dp" 56. android:right="10dp" 57. android:bottom="10dp" /> 58. 59. 60. 注意!提示大家,以上几个item的区别主要是体现在state_pressed按下或state_focused获得焦点时,当当来判断显示什么类型,而没有state_xxx属性的item可以看作是常规状态下。 android:state_window_focused=["true" | "false"]/> Elements: 必须。必须是根元素。包含一个或多个 Attributes: xmlns:android String,必须。定义 XML的命名空间,必须是 “http://schemas.android.com/apk/res/android”. 定义特定状态的 color,通过它的特性指定。必须是 Attributes: android:color 16 进制颜色。必须。这个颜色由 RGB 值指定,可带Alpha。 这个值必须以“#”开头,后面跟随Alpha-Red-Green-Blue 信息: l #RGB l #ARGB l #RRGGBB l #AARRGGBB android:state_pressed Boolean。“true”表示按下状态使用(例如按钮按下);“false” 表示非按下状态使用。 android:state_focused Boolean。“true”表示聚焦状态使用(例如使用滚动球/D-pad 聚焦 Button);“false”表示非聚焦状态使用。 android:state_selected Boolean。“true”表示选中状态使用(例如Tab 打开);“false” 表示非选中状态使用。 android:state_checkable Boolean。“true”表示可勾选状态时使用;“false”表示非可 勾选状态使用。(只对能切换可勾选—非可勾选的构件有用。) android:state_checked Boolean。“true”表示勾选状态使用;“false”表示非勾选状态使用。 android:state_enabled Boolean。“true”表示可用状态使用(能接收触摸/点击事件); “false”表示不可用状态使用。 android:window_focused Boolean。“true”表示应用程序窗口有焦点时使用(应用程序在前台);“false”表示无焦点时使用(例如 Notification栏拉下或对话框显示)。 注意:记住一点,StateList 中第一个匹配当前状态的 item会被使用。因此,如果第一个 item 没有任何状态特性的话,那么它将每次都被使用,这也是为什么默认的值必须总是在最后(如下面的例子所示)。 Examples: XML 文件保存在res/color/button_text.xml 这个 Layout XML 会应用 ColorStateList到一个 View 上: Android——字符高亮显示(转载) 文章分类:移动开发 Java代码 1. String str="adsjoiasdjpaisdjpaidj"; 2. /** Called when the activity is first created.*/ 3. @Override 4. public void onCreate(Bundle savedInstanceState){ 5. super.onCreate(savedInstanceState); 6. setContentView(R.layout.main); 7. TextViewtextview=(TextView)findViewById(R.id.textView); 8. SpannableStringBuilder style=new SpannableStringBuilder(str); 9. style.setSpan(new ForegroundColorSpan(Color.RED),3,8,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 10. textview.setText(style); 11.} Android SDCard操作(文件读写,容量计算) 文章分类:移动开发 android.os.Environment 提供访问环境变量 java.lang.Object android.os.Environment Environment 静态方法: 方法 : getDataDirectory () 返回 : File 解释 : 返回Data的目录 方法 : getDownloadCacheDirectory () 返回 : File 解释 : 返回下载缓冲区目录 方法 : getExternalStorageDirectory () 返回 : File 解释 : 返回扩展存储区目录(SDCard) 方法 :getExternalStoragePublicDirectory (String type) 返回 : File 解释 : 返回一个高端的公用的外部存储器目录来摆放某些类型的文件(来自网 上) 方法 : getRootDirectory () 返回 : File 解释 : 返回Android的根目录 方法 : getExternalStorageState () 返回 : String 解释 : 返回外部存储设备的当前状态 getExternalStorageState () 返回的状态String 类型常量 : 常量 : MEDIA_BAD_REMOVAL 值 : "bad_removal" 解释 : 在没有正确卸载SDCard之前移除了 常量 :MEDIA_CHECKING 值 : "checking" 解释 : 正在磁盘检查 常量 : MEDIA_MOUNTED 值 : "mounted" 解释 : 已经挂载并且拥有可读可写权限 常量 : MEDIA_MOUNTED_READ_ONLY 值 : "mounted_ro" 解释 : 已经挂载,但只拥有可读权限 常量 :MEDIA_NOFS 值 : "nofs" 解释 : 对象空白,或者文件系统不支持 常量 : MEDIA_REMOVED 值 : "removed" 解释 : 已经移除扩展设备 常量 : MEDIA_SHARED 值 : "shared" 解释 : 如果SDCard未挂载,并通过USB大容量存储共享 常量 : MEDIA_UNMOUNTABLE 值 : "unmountable" 解释 : 不可以挂载任何扩展设备 常量 : MEDIA_UNMOUNTED 值 : "unmounted" 解释 : 已经卸载 使用时只需先判断SDCard当前的状态然后取得SdCard的目录即可(见源代码) Java代码 1. 2. public voidSDCardTest() { 3. // 获取扩展SD卡设备状态 4. String sDStateString =android.os.Environment.getExternalSto rageState(); 5. 6. // 拥有可读可写权限 if(sDStateString.equals(android.os.Environment.MEDIA_MOUNTED)) { try { // 获取扩展存储设备的文件目录 7. File SDFile = android.os.Environment 8. .getExternalStorageDirectory(); // 打开文件 9. File myFile = new File(SDFile.getAbsolutePath() 10. + File.separator + "MyFile.txt"); 11. // 判断是否存在,不存在则创建 12. if (!myFile.exists()) { 13. myFile.createNewFile(); 14. } 15. // 写数据 16. String szOutText = "Hello, World!"; 17. FileOutputStream outputStream = new FileOutputStream (myFile); 18. outputStream.write(szOutText.getBytes()); 19. outputStream.close(); 20. } catch (Exception e) { 21. // TODO: handle exception }// end of try 22.}// end ofif(MEDIA_MOUNTED) 23.// 拥有只读权限 24.else if (sDStateString 25. .endsWith(android.os.Environment.MEDIA_MOUNTED_READ_ONLY)) { 26. // 获取扩展存储设备的文件目录 27. File SDFile = android.os.Environment 28. .getExternalStorageDirectory(); 29.// 创建一个文件 30.File myFile = newFile(SDFile.getAbsolutePath() 31. + File.separator 32. + "MyFile.txt"); 33.// 判断文件是否存在 34.if (myFile.exists()) { 35. try { 36. // 读数据 37. FileInputStream inputStream = new FileInputStream(myFile); 38. byte[] buffer = new byte[1024]; 39. inputStream.read(buffer); 40. inputStream.close(); 41. } catch (Exception e) { 42. // TODO: handle exception 43.}// end oftry }// end of if(myFile) 44.}// end ofif(MEDIA_MOUNTED_READ_ONLY) 45.}// end offunc 计算SDCard的容量大小 android.os.StatFs 一个模拟linux的df命令的一个类,获得SD卡和手机内存的使用情况 java.lang.Object android.os.StatFs 构造方法: StatFs (String path) 公用方法: 方法 : getAvailableBlocks () 返回 : int 解释 :返回文件系统上剩下的可供程序使用的块 方法 : getBlockCount () 返回 : int 解释 : 返回文件系统上总共的块 方法 : getBlockSize () 返回 : int 解释 : 返回文件系统 一个块的大小单位byte 方法 : getFreeBlocks () 返回 : int 解释: 返回文件系统上剩余的所有块 包括预留的一般程序无法访问的 方法 : restat (String path) 返回 : void 解释 : 执行一个由该对象所引用的文件系统雷斯塔特.(Google翻译) 想计算SDCard大小和使用情况时, 只需要得到SD卡总共拥有的Block数或是剩 余没用的Block数,再乘以每个Block的大小就是相应的容量大小了单位 byte.(见代码) Java代码 1. 1 2. public void SDCardSizeTest() { 3. 2 4. 3 // 取得SDCard当前的状态 5. 4 String sDcString =android.os.Environme nt.getExternalStorageState(); 6. 5 7. 6 if(sDcString.equals(android.os.Environme nt.MEDIA_MOUNTED)) { 8. 7 9. 8 // 取得sdcard文件路径 10. 9 File pathFile = android.os.Environment 11.10 .getExternalStorage Directory(); 12.11 13.12 android.os.StatFs statfs = newandroid.os.StatFs(pathFile.getPath()); 14.13 15.14 // 获取SDCard上BLOCK总数 16.15 long nTotalBlocks = statfs.getBlockCount(); 17.16 18.17 // 获取SDCard上每个block的 SIZE 19.18 long nBlocSize = statfs.getBlockSize(); 20.19 21.20 // 获取可供程序使用的Block的数量 22.21 long nAvailaBlock = statfs.getAvailableBlocks(); 23.22 24.23 // 获取剩下的所有Block的数量(包括预留的一般程序无法使用的块) 25.24 long nFreeBlock = statfs.getFreeBlocks(); 26.25 27.26 // 计算SDCard 总容量大小MB 28.27 long nSDTotalSize = nTotalBlocks * nBlocSize / 1024 / 1024; 29.28 30.29 // 计算 SDCard 剩余大小MB 31.30 long nSDFreeSize = nAvailaBlock * nBlocSize / 1024 / 1024; 32.31 }// end of if 33.32 }// end of func Android将ButtonBar放在屏幕底部 ?转烛空间(转载) 文章分类:移动开发 接上篇《Android将TAB选项卡放在屏幕底部》写。上篇提到ButtonBar 的方式写底部button,试了试,看起来外观貌似比Tab好看,不过恐怕没有Tab管理Activity方便吧,毕竟一个Tab就是一个Activity,但是这样用Button的话,却并不如此,所以这样的涉及可能虽然好看点,但是管理起来却是相当麻烦。那么暂且把对 activity的管理放在一边,只看界面的设计吧。 要涉及这样的一个buttonbar,主要就是要用到 style="@android:style/ButtonBar"这个风格。首先还是来看xml的设计,保存layout/bottombtn.xml Java代码 1. 2. 3. android:orientation="vertical" 4. android:layout_width="fill_parent"5.android:layout_height="fill_parent"> 6. 7. 8. android:layout_width="fill_parent" 9. android:layout_height="fill_parent"> 10. 11. android:layout_width="fill_parent" 12. android:layout_height="fill_parent" 13. android:padding="5dp"> 14. 15. android:layout_width="fill_parent" 16. android:layout_height="wrap_content" 17. android:padding="5dp" 18. android:layout_weight="1" /> 19. 20. android:layout_width="fill_parent" 21. android:layout_height="wrap_content" 22. android:layout_weight="0" /> 23. 24. 25. 然后以下就是完整的代码了: Java代码 1. packagenet.wangliping.test; 2. 3. importandroid.app.ActivityGroup; 4. importandroid.content.Intent; 5. importandroid.os.Bundle; 6. importandroid.widget.TabHost; 7. importandroid.widget.TabHost.TabSpec; 8. 9. public class TestTab extends ActivityGroup { 10. public static TabHost tab_host; 11. @Override 12. protected void onCreate(Bundle savedInstanceState) { 13. super.onCreate(savedInstanceState); 14. setContentView(R.layout.bottomtab); 15. 16. tab_host = (TabHost) findViewById(R.id.edit_item_tab_host); 17. tab_host.setup(this.getLocalActivityManager()); 18. 19. TabSpec ts1 = tab_host.newTabSpec("TAB_WEATHER"); 20. ts1.setIndicator("Weather"); 21. ts1.setContent(new Intent(this, Weather.class)); 22. tab_host.addTab(ts1); 23. 24. TabSpec ts2 =tab_host.newTabSpec("TAB_MAIL" ); 25. ts2.setIndicator("Mail"); 26. ts2.setContent(new Intent(this, MailSend.clas s)); 27. tab_host.addTab(ts2); 28. 29. TabSpec ts3 =tab_host.newTabSpec("TAB_JUMP" ); 30. ts3.setIndicator("Jump"); 31. ts3.setContent(new Intent(this, TabJump.class)); 32. tab_host.addTab(ts3); 33. 34. tab_host.setCurrentTab(0); 35. } 36.} 而关于页面的跳转,就是: Java代码 1. TestTab.tabHost.setCurrentTab(0); 如此这般,就形成了下面的这个东西,其实还没有放在上面好看。。。所以也证实了上面那个应用不是简单地放置TAB在底端了。有机会还是再看看ButtonBar 了。 Android2.2 API中文文档系列(1) ——TextView 文章分类:移动开发 正文 一、TextView的API 中文文档 1.1 结构 java.lang.Object ↳ android.view.View ↳ android.widget.TextView 直接子类: Button, CheckedTextView, Chronometer, DigitalClock, EditText 间接子类: AutoCompleteTextView, CheckBox,CompoundButton, ExtractEditText,MultiAutoCompleteTextView,RadioButton, ToggleButton 1.2 API 属性名称 描述 设置是否当文本为URL链接/email/电话号码/map时,文本 android:autoL显示为可点击的链接。可选值(none/web/email/phone/map/all) ink 如果设置,将自动执行输入值的拼写纠正。此处无效果,在 android:autoT显示输入法并输入的时候起作用。 ext 指定getText()方式取得的文本类别。选项editable 类似于StringBuilder可追加字符, android:buffe 也就是说getText后可调用append方法设置文本内容。 rType spannable 则可在给定的字符区域使用样式,参见这里1、这里 2。 设置英文字母大写类型。此处无效果,需要弹出输入法才能 android:capit看得到,参见EditText此属性说明。 alize android:curso 设定光标为显示/隐藏,默认显示。 rVisible android:digit 设置允许输入哪些字符。如“1234567890.+-*/%\n()”s 在text的下方输出一个drawable,如图片。如果指定一个 android:drawa颜色的话会把text的背景设为该颜色,并且同时和background bleBottom 使用时覆盖后者。 android:drawa 在text的左边输出一个drawable,如图片。 bleLeft 设置text与drawable(图片)的间隔,与drawableLeft、 android:drawadrawableRight、drawableTop、drawableBottom一起使用,可设 blePadding 置为负数,单独使用没有效果。 android:drawa 在text的右边输出一个drawable,如图片。 bleRight 在text的正上方输出一个drawable,如图片。 android:drawa bleTop android:edita 设置是否可编辑。这里无效果,参见EditView。 ble android:edito 设置文本的额外的输入数据。在EditView再讨论。 rExtras 设置当文字过长时,该控件该如何显示。有如下值设 置:”start”—–省略号显示在开头;”end”——省略号显示 android:ellip 在结尾;”middle”—-省略号显示在中间;”marquee” —— size 以跑马灯的方式显示(动画横向移动) android:freez 设置保存文本的内容以及光标的位置。参见:这里。 esText android:gravi 设置文本位置,如设置成“center”,文本将居中显示。 ty Text为空时显示的文字提示信息,可通过textColorHint 设置提示信息的颜色。此属性在EditView中使用,但是这里也 android:hint 可以用。 附加功能,设置右下角IME动作与编辑框相关的动作,如 android:imeOpactionDone右下角将显示一个“完成”,而不设置默认是一个回 tions 车符号。这个在EditText中再详细说明,此处无用。 设置IME动作ID。在EditText再做说明,可以先看这篇帖 android:imeAc子:这里。 tionId android:imeAc 设置IME动作标签。在EditText再做说明。 tionLabel android:inclu 设置文本是否包含顶部和底部额外空白,默认为true。 deFontPadding 为文本指定输入法,需要完全限定名(完整的包名)。例如: android:inputcom.google.android.inputmethod.pinyin,但是这里报错找不 Method 到。 设置文本的类型,用于帮助输入法显示合适的键盘类型。在 android:input EditText中再详细说明,这里无效果。 Type android:links 设置链接是否点击连接,即使设置了autoLink。 Clickable 在ellipsize指定marquee的情况下,设置重复滚动的次数, android:marqu当设置为marquee_forever时表示无限次。 eeRepeatLimit 设置TextView的宽度为N个字符的宽度。这里测试为一个 android:ems 汉字字符宽度,如图: 设置TextView的宽度为最长为N个字符的宽度。与ems同 android:maxEm时使用时覆盖ems选项。 s 设置TextView的宽度为最短为N个字符的宽度。与ems同 android:minEm时使用时覆盖ems选项。 s android:maxLe 限制显示的文本长度,超出部分不显示。 ngth 设置文本的行数,设置两行就显示两行,即使第二行没有数android:lines 据。 设置文本的最大显示行数,与width或者layout_width结 android:maxLi合使用,超出部分自动换行,超出行数将不显示。 nes android:minLi 设置文本的最小行数,与lines类似。 nes android:lineS 设置行间距。 pacingExtra android:lineS 设置行间距的倍数。如”1.2” pacingMultipl ier 如果被设置,该TextView有一个数字输入法。此处无用, android:numer设置后唯一效果是TextView有点击效果,此属性在EditText将 ic 详细说明。 android:passw 以小点”.”显示文本 ord android:phone 设置为电话号码的输入方式。 Number 设置输入法选项,此处无用,在EditText将进一步讨论。 android:priva teImeOptions android:scrol 设置文本超出TextView的宽度的情况下,是否出现横拉条。 lHorizontally 如果文本是可选择的,让他获取焦点而不是将光标移动为文 android:selec本的开始位置或者末尾位置。EditText中设置后无效果。 tAllOnFocus 指定文本阴影的颜色,需要与shadowRadius一起使用。效 android:shado 果: wColor android:shado 设置阴影横向坐标开始位置。wDx android:shado 设置阴影纵向坐标开始位置。wDy 设置阴影的半径。设置为0.1就变成字体的颜色了,一般设 android:shado置为3.0的效果比较好。 wRadius 设置单行显示。如果和layout_width一起使用,当文本不 能全部显示时,后面用“„”来表示。如android:text="test_ android:singlsingleLine "android:singleLine="true" eLine android:layout_width="20dp"将只显示“t„”。如果不设置 singleLine或者设置为false,文本将自动换行 设置显示文本. android:text 设置文字外观。如 “?android:attr/textAppearanceLargeInverse ”这里引用的是系统自带的一个外观,?表示系统是否有这 种外观,否则使用默认的外观。可设置的值如下: android:textAtextAppearanceButton/textAppearanceInverse/textAppearan ppearance ceLarge /textAppearanceLargeInverse/textAppearanceMedium/textAppearanceMediumInverse/textAppearanceSmall/textAppearanc eSmallInverse android:textC 设置文本颜色 olor android:textC 被选中文字的底色,默认为蓝色 olorHighlight android:textC 设置提示信息文字的颜色,默认为灰色。与hint一起使用。 olorHint android:textC 文字链接的颜色. olorLink 设置文字之间间隔,默认为1.0f。分别设置 android:textS caleX 0.5f/1.0f/1.5f/2.0f效果如下: android:textS 设置文字大小,推荐度量单位”sp”,如”15sp” ize 设置字形[bold(粗体) 0, italic(斜体) 1, bolditalic(又 android:textS 粗又斜) 2] 可以设置一个或多个,用“|”隔开 tyle 设置文本字体,必须是以下常量值之一:normal 0, sans 1, android:typef serif 2, monospace(等宽字体) 3] ace 设置文本区域的高度,支持度量单位:px(像 android:heigh 素)/dp/sp/in/mm(毫米) t android:maxHe 设置文本区域的最大高度 ight android:minHe 设置文本区域的最小高度 ight 设置文本区域的宽度,支持度量单位:px(像 android:width 素)/dp/sp/in/mm(毫米),与layout_width的区别看这里。 android:maxWi 设置文本区域的最大宽度 dth android:minWi 设置文本区域的最小宽度 dth 1.3 补充说明 1.3.1 以下几个属性以及输入法相关的在这里都没有效果,在EditText 将补充说明。 android:numeric/android:digits/android:phoneNumber/android:inputMethod/android:capitalize/android:autoText 1.4 Word格式的API文档下载 http://download.csdn.net/source/2649980 二、例子 2.1 跑马灯的效果 http://www.cnblogs.com/over140/archive/2010/08/20/1804770.html 结束 鉴于至此仍未有完整的Android API中文文档公布出来,我会一直坚持翻译到有其他组织或官方出完整的API中文文档为止。在这里感谢女朋友的支持和帮助,为我提供日中翻译(将 Android API日文版翻译成中文)和英中翻译;感谢翻译工具和搜索引擎以及其他提供部分属性翻译参考的分享者;感谢大家的支持!Android震动示例--心跳效果 正在开发第二个游戏,计时就要结束的时候,为了营造紧张的气氛,会利用手机自身的震动模拟心跳效果,其实这个心跳效果做起来真的非常的简单。所以直接上代码了(注意模拟器是模拟不了震动的,得真机测试哦): 程序效果: Java 代码 1. packagecom.ray.test; 2. 3. import android.app.Activity; 4. import android.os.Bundle; 5. import android.os.Vibrator; 6.importandroid.view.MotionEvent; 7. 8. public class TestViberation extendsActivity { 9. Vibrator vibrator; 10. /** Called when the activity isfirst created. */ 11. @Override 12. public void onCreate(BundlesavedInstanceState) { 13. super.onCreate(savedInstanceState); 14. setContentView(R.layout.main); 15. } 16. 17. @Override 18. protected void onStop() { 19. if(null!=vibrator){ 20. vibrator.cancel(); 21. } 22. super.onStop(); 23. } 24. 25. @Override 26. public booleanonTouchEvent(MotionEvent event) { 27. 28. if(event.getAction() ==MotionEvent.ACTION_DOWN){ 29. vibrator = (Vibrator)getSystemService(VIBRATOR_SERVICE); 30. long[] pattern = {800,50,400,30};// OFF/ON/OFF/ON... 31. vibrator.vibrate(pattern,2);//-1不重复,非-1为从 pattern 的指定下标开始重复 32. } 33. returnsuper.onTouchEvent(event); 34. } 35. 36. 37. } android animation 动画效果编程基础--AnimationAndroid 在 Android中,分别可以在 xml中定义 Animation,也可以在程序代码中定义动画类型 Android 的 animation 由四种类型组成 XML 中 alpha 渐变透明度动画效果 scale 渐变尺寸伸缩动画效果 translate 画面转换位置移动动画效果 rotate 画面转移旋转动画效果 代码中 AlphaAnimation 渐变透明度动画效果 ScaleAnimation 渐变尺寸伸缩动画效果 TranslateAnimation 画面转换位置移动动画效果 RotateAnimation 画面转移旋转动画效果 Android 动画模式 Animation 主要有两种动画模式: 一种是 tweened animation(渐变动画) alpha AlphaAnimation scale ScaleAnimation 一种是 frame by frame(画面转换动画) translate TranslateAnimation rotate RotateAnimation 如何在 XML文件中定义动画 ① 打开 Eclipse,新建 Android 工程 ② 在 res 目录中新建 anim 文件夹 ③ 在 anim 目录中新建一个 myanim.xml(注意文件名小写) ④ 加入 XML 的动画代码 每个元素表示不同的动画效果 Android动画解析--XML /> "@android:anim/accelerate_decelerate_interpolator" android:fromXScale="0.0" android:toXScale="1.4" android:fromYScale="0.0" android:toYScale="1.4" android:pivotX="50%" android:pivotY="50%" android:fillAfter="false" android:startOffset=“700” android:duration="700"/> /> android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:fromDegrees="0" android:toDegrees="+350" android:pivotX="50%" android:pivotY="50%" android:duration="3000"/> 在编码中如何使用如何使用 XML 中的动画效果 在代码中使用这个方法得到 Animation 实例 //第一个参数 Context 为程序的上下文 //第二个参数 id 为动画 XML 文件的引用 //例子: myAnimation=AnimationUtils.loadAnimation(this,R.anim.my_action); //使用 AnimationUtils类的静态方法 loadAnimation()来加载XML中的动画 XML 文件 如何在 Java 代码中定义动画 //在代码中定义动画实例对象 privateAnimation myAnimation_Alpha; privateAnimation myAnimation_Scale; privateAnimation myAnimation_Translate; privateAnimation myAnimation_Rotate; //根据各自的构造方法来初始化一个实例对象 myAnimation_Alpha=newAlphaAnimation(0.1f, 1.0f); myAnimation_Scale=new ScaleAnimation(0.0f, 1.4f, 0.0f, 1.4f, Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF, 0.5f); myAnimation_Translate=newTranslateAnimation(30.0f, -80.0f, 30.0f, 300.0f); myAnimation_Rotate=newRotateAnimation(0.0f, +350.0f, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF, 0.5f); -------------------------------------------------------------------- Android 动画解析 AlphaAnimation ① AlphaAnimation类对象定义 privateAlphaAnimation myAnimation_Alpha; ② AlphaAnimation类对象构造 AlphaAnimation(floatfromAlpha, float toAlpha) //第一个参数 fromAlpha 为动画开始时候透明度 //第二个参数 toAlpha 为动画结束时候透明度 myAnimation_Alpha=newAlphaAnimation(0.1f, 1.0f); //说明: // 0.0 表示完全透明 // 1.0 表示完全不透明 ③ 设置动画持续时间 myAnimation_Alpha.setDuration(5000); //设置时间持续时间为 5000毫秒 ScaleAnimation ①ScaleAnimation 类对象定义 privateAlphaAnimation myAnimation_Scale; ② ScaleAnimation类对象构造 ScaleAnimation(floatfromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue,int pivotYType, float pivotYValue) //第一个参数 fromX 为动画起始时 X 坐标上的伸缩尺寸 //第二个参数 toX 为动画结束时 X 坐标上的伸缩尺寸 //第三个参数 fromY 为动画起始时 Y 坐标上的伸缩尺寸 //第四个参数 toY 为动画结束时 Y 坐标上的伸缩尺寸 /*说明: 以上四种属性值 0.0表示收缩到没有 1.0表示正常无伸缩 值小于1.0 表示收缩 值大于1.0 表示放大 */ //第五个参数 pivotXType 为动画在 X 轴相对于物件位置类型 //第六个参数 pivotXValue为动画相对于物件的 X坐标的开始位置 //第七个参数pivotXType为动画在 Y 轴相对于物件位置类型 //第八个参数pivotYValue 为动画相对于物件的 Y坐标的开始位置 myAnimation_Scale=new ScaleAnimation(0.0f, 1.4f, 0.0f, 1.4f, Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF, 0.5f); ③ 设置动画持续时间 myAnimation_Scale.setDuration(700); //设置时间持续时间为 700毫秒 TranslateAnimation ① TranslateAnimation类对象定义 privateAlphaAnimation myAnimation_Translate; ② TranslateAnimation类对象构造 TranslateAnimation(floatfromXDelta, float toXDelta, float fromYDelta,float toYDelta) //第一个参数 fromXDelta 为动画起始时 X 坐标上的移动位置 //第二个参数 toXDelta 为动画结束时 X 坐标上的移动位置 //第三个参数 fromYDelta 为动画起始时 Y 坐标上的移动位置 //第四个参数 toYDelta 为动画结束时 Y 坐标上的移动位置 ③ 设置动画持续时间 myAnimation_Translate.setDuration(2000); //设置时间持续时间为 2000毫秒 RotateAnimation ① RotateAnimation类对象定义 privateAlphaAnimation myAnimation_Rotate; ② RotateAnimation类对象构造 RotateAnimation(floatfromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, floatpivotYValue) //第一个参数 fromDegrees 为动画起始时的旋转角度 //第二个参数 toDegrees 为动画旋转到的角度 //第三个参数 pivotXType 为动画在 X 轴相对于物件位置类型 //第四个参数 pivotXValue 为动画相对于物件的 X坐标的开始位置 //第五个参数pivotXType为动画在 Y 轴相对于物件位置类型 //第六个参数 pivotYValue为动画相对于物件的 Y坐标的开始位置 myAnimation_Rotate=new RotateAnimation(0.0f, +350.0f, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f) ③ 设置动画持续时间 myAnimation_Rotate.setDuration(3000); //设置时间持续时间为 3000毫秒 --------------------------------------------------------------------- 下面的小例子是利用 RotateAnimation 简单展示一下两种方法的用法,对于其他动画,如 ScaleAnimation,AlphaAnimation,原理是一样的。 方法一:在 xml 中定义动画: Xml代码 1. version="1.0" encoding="utf-8"?> 2. 3. 4. 5. android:interpolator="@android:anim/accelerate_decelerate_interpolator" 6. android:fromDegrees="0" 7. android:toDegrees="+360" 8. android:duration="3000"/> 9. 10. 16. 17. android:layout_width="fill_parent"android:layout_height="wrap_content" /> 18. 19. 20. 21. 22. _TextSwitcher.java 23. 24. 代码 25. packagecom.webabcd.view; 26. 27. importjava.util.Random; 28. 29. importandroid.app.Activity; 30. importandroid.os.Bundle; 31. importandroid.view.View; 32. importandroid.view.animation.Animation; 33. importandroid.view.animation.AnimationUtils; 34. importandroid.widget.Button; 35. importandroid.widget.TextSwitcher; 36. importandroid.widget.TextView; 37. importandroid.widget.ViewSwitcher; 38. 39. publicclass _TextSwitcher extends Activity implements ViewSwitcher.ViewFactory { 40. 41. @Override 42. protected void onCreate(BundlesavedInstanceState) { 43. // TODO Auto-generated methodstub 44. super.onCreate(savedInstanceState); 45. this.setContentView(R.layout.textswithcer); 46. 47. setTitle("TextSwithcer"); 48. 49. final TextSwitcher switcher =(TextSwitcher) findViewById(R.id.textSwitcher); 50. //指定转换器的 ViewSwitcher.ViewFactory 51. switcher.setFactory(this); 52. 53. //设置淡入和淡出的动画效果 54. Animation in =AnimationUtils.loadAnimation(this, android.R.anim.fade_in); 55. Animation out =AnimationUtils.loadAnimation(this, android.R.anim.fade_out); 56. switcher.setInAnimation(in); 57. switcher.setOutAnimation(out); 58. 59. //单击一次按钮改变一次文字 60. Button btnChange = (Button)this.findViewById(R.id.btnChange); 61. btnChange.setOnClickListener(newView.OnClickListener() { 62. @Override 63. public void onClick(View v) { 64. switcher.setText(String.valueOf(newRandom().nextInt())); 65. } 66. }); 67. } 68. 69. //重写 ViewSwitcher.ViewFactory的 makeView(),返回一个 View 70. @Override 71. public View makeView() { 72. TextView textView = newTextView(this); 73. textView.setTextSize(36); 74. return textView; 75. } 76.} 77. 78. 79. 80. 2、Gallery的Demo 81.gallery.xml 82. 83. 代码 84. 85. 86. android:orientation="vertical"android:layout_width="fill_parent" 87. android:layout_height="fill_parent"> 88. 89. 93. 94. android:layout_height="wrap_content"android:spacing="20px" /> 95. 96. 97. 98. 99. _Gallery.java 100. 101. 代码 102. packagecom.webabcd.view; 103. 104. importandroid.app.Activity; 105. importandroid.content.Context; 106. importandroid.os.Bundle; 107. importandroid.view.View; 108. importandroid.view.ViewGroup; 109. importandroid.widget.AdapterView; 110. importandroid.widget.BaseAdapter; 111. importandroid.widget.Gallery; 112. importandroid.widget.ImageView; 113. importandroid.widget.Toast; 114. importandroid.widget.Gallery.LayoutParams; 115. 116.public class _Gallery extends Activity { 117. 118. @Override 119. protected void onCreate(BundlesavedInstanceState) { 120. // TODO Auto-generated methodstub 121. super.onCreate(savedInstanceState); 122. this.setContentView(R.layout.gallery); 123. 124. setTitle("Gallery"); 125. 126. Gallery gallery = (Gallery) findViewById(R.id.gallery); 127. //为缩略图浏览器指定一个适配器 128. gallery.setAdapter(newImageAdapter(this)); 129. //响应在缩略图列表上选中某个缩略图后的事件 130. gallery.setOnItemSelectedListener(newAdapterView.OnItemSelectedListener() { 131. @Override 132. public void onItemSelected(AdapterView>parent, View v, 133. int position, long id) { 134. Toast.makeText(_Gallery.this,String.valueOf(position), Toast.LENGTH_SHORT).show (); 135. } 136. 137. @Override 138. public voidonNothingSelected(AdapterView> arg0) { 139. 140. } 141. }); 142. } 143. 144. //继承 BaseAdapter用以实现自定义的图片适配器 145. public class ImageAdapter extendsBaseAdapter { 146. 147. private Context mContext; 148. 149. public ImageAdapter(Contextcontext) { 150. mContext = context; 151. } 152. 153. public int getCount() { 154. return mThumbIds.length; 155. } 156. 157. public Object getItem(int position){ 158. return position; 159. } 160. 161. public long getItemId(int position){ 162. return position; 163. } 164. 165. public View getView(int position,View convertView, ViewGroup parent) { 166. ImageView image = newImageView(mContext); 167. 168. image.setImageResource(mThumbIds[position]); 169. image.setAdjustViewBounds(true); 170. image.setLayoutParams(new Gallery.LayoutParams( 171. LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT)); 172. 173. return image; 174. } 175. } 176. 177. //需要显示的图片集合 178. private Integer[] mThumbIds = {R.drawable.icon01, R.drawable.icon02, 179. R.drawable.icon03, R.drawable.icon04,R.drawable.icon05 }; 180.} 181. 182. 183. 184. 3、ImageSwitcher的Demo 185. imageswitcher.xml 186. 187. 代码 188. 189. 190. android:orientation="vertical"android:layout_width="fill_parent" 191. android:layout_height="fill_parent"> 192. 193. 194. android:layout_height="wrap_content"android:spacing="20px" /> 195. 196. 199. 200. android:layout_width="fill_parent"android:layout_height="wrap_content" /> 201. 202. 203. 204. 205._ImageSwitcher.java 206. 207. 代码 208. packagecom.webabcd.view; 209. 210. importandroid.app.Activity; 211. importandroid.content.Context; 212. importandroid.os.Bundle; 213. importandroid.view.View; 214. importandroid.view.ViewGroup; 215. importandroid.view.animation.AnimationUtils; 216. importandroid.widget.AdapterView; 217. importandroid.widget.BaseAdapter; 218. importandroid.widget.Gallery; 219. importandroid.widget.ImageSwitcher; 220. importandroid.widget.ImageView; 221. importandroid.widget.ViewSwitcher; 222. importandroid.widget.Gallery.LayoutParams; 223. 224. //图片转换器的使用基本同文字转换器 225. //以下是一个用ImageSwitcher + Gallery 实现的经典的图片浏览器的 Demo 226. publicclass _ImageSwitcher extends Activity implements 227. ViewSwitcher.ViewFactory { 228. 229. private ImageSwitcher mSwitcher; 230. 231. @Override 232. protected void onCreate(BundlesavedInstanceState) { 233. // TODO Auto-generated methodstub 234. super.onCreate(savedInstanceState); 235. this.setContentView(R.layout.imageswithcer); 236. 237. setTitle("ImageSwithcer"); 238. 239. mSwitcher = (ImageSwitcher)findViewById(R.id.imageSwitcher); 240. mSwitcher.setFactory(this); 241. mSwitcher.setInAnimation(AnimationUtils.loadAnimation(this, 242. android.R.anim.fade_in)); 243. mSwitcher.setOutAnimation(AnimationUtils.loadAnimation(this, 244. android.R.anim.fade_out)); 245. 246. Gallery gallery = (Gallery)findViewById(R.id.gallery); 247. gallery.setAdapter(new ImageAdapter(this)); 248. gallery.setOnItemSelectedListener(newAdapterView.OnItemSelectedListener() { 249. @Override 250. public voidonItemSelected(AdapterView> parent, View v, 251. int position, long id) { 252. mSwitcher.setImageResource(mImageIds[position]); 253. } 254. 255. @Override 256. public voidonNothingSelected(AdapterView> arg0) { 257. 258. } 259. }); 260. } 261. 262. public class ImageAdapter extendsBaseAdapter { 263. 264. private Context mContext; 265. 266. public ImageAdapter(Contextcontext) { 267. mContext = context; 268. } 269. 270. public int getCount() { 271. return mThumbIds.length; 272. } 273. 274. public Object getItem(int position){ 275. return position; 276. } 277. 278. public long getItemId(int position){ 279. return position; 280. } 281. 282. public View getView(int position,View convertView, ViewGroup parent) { 283. ImageView image = newImageView(mContext); 284. 285. image.setImageResource(mThumbIds[position]); 286. image.setAdjustViewBounds(true); 287. image.setLayoutParams(newGallery.LayoutParams( 288. LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT)); 289. 290. return image; 291. } 292. } 293. 294. private Integer[] mThumbIds = {R.drawable.icon01, R.drawable.icon02, 295. R.drawable.icon03,R.drawable.icon04, R.drawable.icon05 }; 296. 297. private Integer[] mImageIds = {R.drawable.icon01, R.drawable.icon02, 298. R.drawable.icon03,R.drawable.icon04, R.drawable.icon05 }; 299. 300. @Override 301. public View makeView() { 302. ImageView image = newImageView(this); 303. image.setMinimumHeight(200); 304. image.setMinimumWidth(200); 305. image.setScaleType(ImageView.ScaleType.FIT_CENTER); 306. image.setLayoutParams(new ImageSwitcher.LayoutParams( 307. LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT)); 308. return image; 309. } 310.} 311. 312. 313. 314. 4、GridView的Demo 315. gridview.xml 316. 317. 代码 318. 319. 320. 325. 326. android:id="@+id/gridView"android:layout_width="fill_parent" 327. android:layout_height="fill_parent"android:padding="10px" 328. android:verticalSpacing="10px"android:horizontalSpacing="10px" 329. android:numColumns="auto_fit"android:columnWidth="60px" 330. android:stretchMode="columnWidth"android:gravity="center"> 331. 332. 333. 334._GridView.java 335. 336. 代码 337. packagecom.webabcd.view; 338. 339. importandroid.app.Activity; 340. importandroid.content.Context; 341. importandroid.os.Bundle; 342. importandroid.view.View; 343. importandroid.view.ViewGroup; 344. importandroid.widget.BaseAdapter; 345. importandroid.widget.GridView; 346. importandroid.widget.ImageView; 347. 348. publicclass _GridView extends Activity { 349. 350. @Override 351. protected void onCreate(Bundle savedInstanceState){ 352. // TODO Auto-generated methodstub 353. super.onCreate(savedInstanceState); 354. this.setContentView(R.layout.gridview); 355. 356. setTitle("GridView"); 357. 358. GridView gridView = (GridView) findViewById(R.id.gridView); 359. //指定网格控件的适配器为自定义的图片适配器 360. gridView.setAdapter(newImageAdapter(this)); 361. } 362. 363. //自定义的图片适配器 364. public class ImageAdapter extendsBaseAdapter { 365. 366. private Context mContext; 367. 368. public ImageAdapter(Contextcontext) { 369. mContext = context; 370. } 371. 372. public int getCount() { 373. return mThumbIds.length; 374. } 375. 376. public Object getItem(int position){ 377. return position; 378. } 379. 380. public long getItemId(int position){ 381. return position; 382. } 383. 384. public View getView(int position,View convertView, ViewGroup parent) { 385. ImageView imageView; 386. if (convertView == null) { 387. imageView = newImageView(mContext); 388. imageView.setLayoutParams(newGridView.LayoutParams(48,48)); 389. imageView.setAdjustViewBounds(false); 390. imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); 391. imageView.setPadding(5,5,5,5); 392. } else { 393. imageView = (ImageView)convertView; 394. } 395. 396. imageView.setImageResource(mThumbIds[position]); 397. 398. return imageView; 399. } 400. 401. //网格控件所需图片数据的数据源 402. private Integer[] mThumbIds = {R.drawable.icon01, R.drawable.icon02, 403. R.drawable.icon03,R.drawable.icon04, R.drawable.icon05 }; 404. } 405.} 406. 407. 408. 409. 5、ListView的Demo 410.main_list_adapter.xml 411. 412. 代码 413. 414. 417. 418. android:orientation="horizontal"android:layout_width="fill_parent" 419. android:layout_height="fill_parent"> 420. 421. 422. android:layout_height="wrap_content"android:textSize="16sp"> 423. 424. 425. 426. 427. 428.MainListAdapter.java 429. 430. 代码 431. packagecom.webabcd.view; 432. 433. importjava.util.List; 434. 435. importandroid.content.Context; 436. importandroid.view.LayoutInflater; 437. importandroid.view.View; 438. importandroid.view.ViewGroup; 439. importandroid.widget.BaseAdapter; 440. importandroid.widget.TextView; 441. 442. //继承BaseAdapter 以实现自定义的列表适配器 443. publicclass MainListAdapter extends BaseAdapter { 444. 445. private LayoutInflater mInflater; 446. private List 448. public MainListAdapter(Contextcontext, List 449. mInflater = LayoutInflater.from(context); 450. mData = data; 451. } 452. 453. @Override 454. public int getCount() { 455. return mData.size(); 456. } 457. 458. @Override 459. public Object getItem(int position){ 460. return mData.get(position); 461. } 462. 463. @Override 464. public long getItemId(int position){ 465. return position; 466. } 467. 468. @Override 469. public View getView(int position,View convertView, ViewGroup parent) { 470. 471. TextView text; 472. 473. if (convertView == null) { 474. //指定一个 layout作为自定义列表适配器的layout 475. convertView =mInflater.inflate(R.layout.main_list_adapter, null); 476. text = (TextView)convertView.findViewById(R.id.text); 477. convertView.setTag(text); 478. } else { 479. text = (TextView)convertView.getTag(); 480. } 481. 482. String mItem =mData.get(position); 483. text.setText(mItem); 484. 485. return convertView; 486. } 487.} 488. 489. Main.java 490. 491. 代码 492. packagecom.webabcd.view; 493. 494. importjava.util.ArrayList; 495. importjava.util.List; 496. 497. importandroid.app.ListActivity; 498. importandroid.content.Intent; 499. importandroid.os.Bundle; 500. importandroid.view.View; 501. importandroid.widget.ListView; 502. 503. //此处要继承ListActivity ,用以实现ListView的功能 504. publicclass Main extends ListActivity { 505. 506. private List 508. /** Called when the activity isfirst created. */ 509. @Override 510. public void onCreate(BundlesavedInstanceState) { 511. super.onCreate(savedInstanceState); 512. 513. setTheme(android.R.style.Theme_Light); 514. setContentView(R.layout.main); 515. mData = getData(); 516. 517. //使用自定义的列表适配器来展现数据 518. MainListAdapter adapter = newMainListAdapter(this, mData); 519. 520. //如需使用系统内置的列表适配器,则可以使用类似如下的方法 521. // ArrayAdapter 522. 523. this.setListAdapter(adapter); 524. } 525. 526. // ListView的数据源 527. private List 528. List 529. 530. items.add("TextView"); 531. items.add("Button"); 532. items.add("ImageButton"); 533. items.add("ImageView"); 534. items.add("CheckBox"); 535. items.add("RadioButton"); 536. items.add("AnalogClock"); 537. items.add("DigitalClock"); 538. items.add("DatePicker"); 539. items.add("TimePicker"); 540. items.add("ToggleButton"); 541. items.add("EditText"); 542. items.add("ProgressBar"); 543. items.add("SeekBar"); 544. items.add("AutoCompleteTextView"); 545. items.add("MultiAutoCompleteTextView"); 546. items.add("ZoomControls"); 547. items.add("Include"); 548. items.add("VideoView"); 549. items.add("WebView"); 550. items.add("RatingBar"); 551. items.add("Tab"); 552. items.add("Spinner"); 553. items.add("Chronometer"); 554. items.add("ScrollView"); 555. items.add("TextSwitcher"); 556. items.add("ListView"); 557. items.add("Gallery"); 558. items.add("ImageSwitcher"); 559. items.add("GridView"); 560. items.add("ExpandableList"); 561. 562. return items; 563. } 564. 565. // ListView中某项被选中后的逻辑 566. @Override 567. protected voidonListItemClick(ListView l, View v, int position, long id) { 568. Intent intent = new Intent(); 569. intent.setClassName(this,"com.webabcd.view._" + mData.get(position)); 570. 571. startActivityForResult(intent,0); 572. } 573.} 574. 575. 576. 6、ExpandableList的Demo 577. _ExpandableList.java 578. 579. 代码 580. packagecom.webabcd.view; 581. 582. importandroid.app.ExpandableListActivity; 583. importandroid.os.Bundle; 584. importandroid.view.ContextMenu; 585. importandroid.view.Gravity; 586. importandroid.view.MenuItem; 587. importandroid.view.View; 588. importandroid.view.ViewGroup; 589. importandroid.view.ContextMenu.ContextMenuInfo; 590. importandroid.widget.AbsListView; 591. importandroid.widget.BaseExpandableListAdapter; 592. importandroid.widget.ExpandableListAdapter; 593. importandroid.widget.ExpandableListView; 594. importandroid.widget.TextView; 595. importandroid.widget.Toast; 596. importandroid.widget.ExpandableListView.ExpandableListContextMenuInfo; 597. 598. //ExpandableList - 可展开/收缩列表 599. //继承ExpandableListActivity 以实现列表的可展开/收缩的功能 600. publicclass _ExpandableList extends ExpandableListActivity { 601. 602. private ExpandableListAdaptermAdapter; 603. 604. @Override 605. protected void onCreate(BundlesavedInstanceState) { 606. // TODO Auto-generated methodstub 607. super.onCreate(savedInstanceState); 608. 609. setTitle("ExpandableList"); 610. 611. mAdapter = newMyExpandableListAdapter(); 612. setListAdapter(mAdapter); 613. registerForContextMenu(this.getExpandableListView()); 614. } 615. 616. //为列表的每一项创建上下文菜单(即长按后呼出的菜单) 617. @Override 618. public voidonCreateContextMenu(ContextMenu menu, View v, 619. ContextMenuInfo menuInfo) { 620. menu.setHeaderTitle("ContextMenu"); 621. menu.add(0,0,0,"ContextMenu"); 622. } 623. 624. //单击上下文菜单后的逻辑 625. @Override 626. public booleanonContextItemSelected(MenuItem item) { 627. ExpandableListContextMenuInfo info= (ExpandableListContextMenuInfo) item.getMen uInfo(); 628. String title = ((TextView)info.targetView).getText().toString(); 629. 630. int type = ExpandableListView.getPackedPositionType(info.packedPosition); 631. if (type ==ExpandableListView.PACKED_POSITION_TYPE_CHILD) { 632. int groupPos =ExpandableListView.getPackedPositionGroup(info.packedPosition); 633. int childPos = ExpandableListView.getPackedPositionChild(info.packedPosition); 634. 635. Toast.makeText(this, title + "- Group Index: " + groupPos + " Child Index: " + childPos,Toast.LENGTH_SHORT).show(); 636. 637. return true; 638. } else if (type ==ExpandableListView.PACKED_POSITION_TYPE_GROUP) { 639. int groupPos =ExpandableListView.getPackedPositionGroup(info.packedPosition); 640. Toast.makeText(this, title + " - Group Index: " + groupPos,Toast.LENGTH_SHORT).sho w(); 641. 642. return true; 643. } 644. 645. return false; 646. } 647. 648. public class MyExpandableListAdapterextends BaseExpandableListAdapter { 649. 650. //父列表数据 651. private String[] groups = 652. { 653. "group1", 654. "group2", 655. "group3", 656. "group4" 657. }; 658. //子列表数据 659. private String[][] children = 660. { 661. { "child1" }, 662. { "child1","child2" }, 663. { "child1","child2", "child3" }, 664. { "child1","child2", "child3", "child4" } 665. }; 666. 667. @Override 668. public Object getChild(intgroupPosition, int childPosition) { 669. returnchildren[groupPosition][childPosition]; 670. } 671. 672. @Override 673. public long getChildId(intgroupPosition, int childPosition) { 674. return childPosition; 675. } 676. 677. @Override 678. public int getChildrenCount(intgroupPosition) { 679. returnchildren[groupPosition].length; 680. } 681. 682. //取子列表中的某一项的 View 683. @Override 684. public View getChildView(intgroupPosition, int childPosition, 685. boolean isLastChild, ViewconvertView, ViewGroup parent) { 686. TextView textView =getGenericView(); 687. textView.setText(getChild(groupPosition,childPosition).toString()); 688. return textView; 689. } 690. 691. @Override 692. public Object getGroup(intgroupPosition) { 693. return groups[groupPosition]; 694. } 695. 696. @Override 697. public int getGroupCount() { 698. return groups.length; 699. } 700. 701. @Override 702. public long getGroupId(intgroupPosition) { 703. return groupPosition; 704. } 705. 706. //取父列表中的某一项的 View 707. @Override 708. public View getGroupView(intgroupPosition, boolean isExpanded, 709. View convertView, ViewGroup parent){ 710. TextView textView =getGenericView(); 711. textView.setText(getGroup(groupPosition).toString()); 712. return textView; 713. } 714. 715. @Override 716. public boolean hasStableIds(){ 717. return true; 718. } 719. 720. @Override 721. public booleanisChildSelectable(int groupPosition, int childPosition) { 722. return true; 723. } 724. 725. //获取某一项的 View的逻辑 726. private TextView getGenericView(){ 727. AbsListView.LayoutParams lp = newAbsListView.LayoutParams( 728. ViewGroup.LayoutParams.FILL_PARENT,48); 729. TextView textView = newTextView(_ExpandableList.this); 730. textView.setLayoutParams(lp); 731. textView.setGravity(Gravity.CENTER_VERTICAL| Gravity.LEFT); 732. textView.setPadding(32,0,0,0); 733. return textView; 734. } 735. } 736. } Android SurfaceView小解 文章分类:移动开发 注:来自东方尚智沈大海博客 在 android 中开发游戏,一般来说,或想写一个复杂一点的游戏,是必须用到SurfaceView来开发的。经过这一阵子对android的学习,我找到了自已在 android中游戏开发的误区,不要老想着用Layout和 view 去实现,不要将某个游戏中的对象做成一个组件来处理。应该尽量想着在Canvas(画布)中画出游戏戏中的背景、人物、动画等...SurfaceView提供直接访问一个可画图的界面,可以控制在界面顶部的子视图层。SurfaceView是提供给需要直接画像素而不是使用窗体部件的应用使用的。Android图形系统中一个重要的概念和线索是surface。 View 及其子类(如 TextView, Button)要画在 surface 上。每个surface创建一个 Canvas 对象(但属性时常改变),用来管理 view在 surface上的绘图操作,如画点画线。还要注意的是,使用它的时候,一般都是出现在最顶层的:Theview hierarchy will take care of correctly compositing with the Surface anysiblings of the SurfaceView that would normally appear on top of it. 使用的 SurfaceView 的时候,一般情况下还要对其进行创建,销毁,改变时的情况进行监视,这就要用到SurfaceHolder.Callback. 在用 SurfaceView 进行游戏开发过程中,用到 SurfaceHolder来处理它的 Canvas上画的效果和动画是必不可少的。用于控制表面,大小,像素等。 Abstractinterface to someone holding a display surface. Allows you to control thesurface size and format, edit the pixels in the surface, andmonitor changes to the surface. This interface is typically available through the SurfaceView class. 其中特别要注意以下的几个函数: abstractvoid addCallback(SurfaceHolder.Callback callback); // 给 SurfaceView当前的持有者一个回调对象。 abstractCanvas lockCanvas(); // 锁定画布,一般在锁定后就可以通过其返回的画布对象 Canvas,在其上面画图等操作了。 abstract Canvas lockCanvas(Rect dirty); // 锁定画布的某个区域进行画图等..因为画完图后,会调用下面的unlockCanvasAndPost来改变显示内容。 // 相对部分内存要求比较高的游戏来说,可以不用重画 dirty 外的其它区域的像素,可以提高速度。 abstractvoid unlockCanvasAndPost(Canvas canvas); // 结束锁定画图,并提交改变。 实例:用线程画一个蓝色的长方形。 Java代码 1. import android.app.Activity; 2. importandroid.content.Context; 3. importandroid.graphics.Canvas; 4. import android.graphics.Color; 5. import android.graphics.Paint; 6. import android.graphics.RectF; 7. import android.os.Bundle; 8. importandroid.view.SurfaceHolder; 9. importandroid.view.SurfaceView; 10. 11. publicclass Test extends Activity { 12. 13. publicvoid onCreate(Bundle savedInstanceState) { 14. super.onCreate(savedInstanceState); 15. setContentView(newMyView(this)); 16. } 17. 18. //内部类 19. classMyView extends SurfaceView implements SurfaceHolder.Callback{ 20. 21. SurfaceHolderholder; 22. publicMyView(Context context) { 23. super(context); 24. holder= this.getHolder();//获取 holder 25. holder.addCallback(this); 26. //setFocusable(true); 27. } 28. 29. @Override 30. publicvoid surfaceChanged(SurfaceHolder holder, int format, int width, 31.int height){ 32. 33. } 34. 35. @Override 36. publicvoid surfaceCreated(SurfaceHolder holder) { 37. newThread(new MyThread()).start(); 38. } 39. 40. @Override 41. publicvoid surfaceDestroyed(SurfaceHolder holder) {} 42. 43. //内部类的内部类 44. classMyThread implements Runnable{ 45. 46. @Override 47. publicvoid run() { 48. Canvascanvas = holder.lockCanvas(null);//获取画布 49. PaintmPaint = new Paint(); 50. mPaint.setColor(Color.BLUE); 51. 52. canvas.drawRect(newRectF(40,60,80,80),mPaint); 53. holder.unlockCanvasAndPost(canvas);//解锁画布,提交画好的图像 54. } 55. 56. } 57. 58. } 59. } 访问 SurfaceView 的底层图形是通过 SurfaceHolder 接口来实现的,通过 getHolder()方法可以得 到 这 个SurfaceHolder对 象 。 你 应 该 实 现surfaceCreated(SurfaceHolder)和surfaceDestroyed(SurfaceHolder)方法来知道在这个Surface在窗口的显示和隐藏过程中是什么时候创建和销毁的。SurfaceView可以在多线程中被访问。注意:一个SurfaceView只在 SurfaceHolder.Callback.surfaceCreated()和SurfaceHolder.Callback.surfaceDestroyed()调用之间是可用的,其他时间是得不到它的Canvas对象的(null)。 我的访问过程: 创建一个 SurfaceView 的子类,实现 SurfaceHolder.Callback接口。 得到这个 SurfaceView 的 SurfaceHolder对象 holder。 holder.addCallback(callback),也就是实现 SurfaceHolder.Callback接口的类对象。 在 SurfaceHolder.Callback.surfaceCreated() 调用过后 holder.lockCanvas()对象就可以得到 SurfaceView对象对应的 Canvas对象 canvas了。 用 canvas 对象画图。 画图结束后调用 holder.unlockCanvasAndPost()就把图画在窗口中了。 SurfaceView 可以多线程访问,在多线程中画图。 Java代码 1. importandroid.content.Context; 2. import android.graphics.Canvas; 3. import android.graphics.Color; 4. import android.graphics.Paint; 5. import android.util.Log; 6. importandroid.view.SurfaceHolder; 7.importandroid.view.SurfaceView; 8. 9. publicclass MySurfaceView extends SurfaceView implements 10. SurfaceHolder.Callback { 11. 12. 13. privateContext mContext; 14. privateSurfaceHolder mHolder; 15. 16. publicTouchScreenAdjusterSurfaceView(Context context,) { 17. super(context); 18. 19. mContext= context; 20. 21. mHolder= TouchScreenAdjusterSurfaceView.this.getHolder(); 22. mHolder.addCallback(TouchScreenAdjusterSurfaceView.this); 23. 24. this.setFocusableInTouchMode(true);// to make sure that we can get 25. //touch events and key events,and 26. //"setFocusable()" to make sure we 27. //can get key events 28. } 29. 30. @Override 31. publicvoid surfaceChanged(SurfaceHolder holder, int format, int width, 32. intheight) { 33. //TODO Auto-generated method stub 34. 35. } 36. 37. @Override 38. publicvoid surfaceCreated(SurfaceHolder holder) { 39. //nowyou can get the Canvas and draw something here 40. } 41. 42. @Override 43. publicvoid surfaceDestroyed(SurfaceHolder holder) { 44. //TODO Auto-generated method stub 45. 46. } 47. 48. 49. publicvoid drawMyShape(PointPostion ps) { 50. 51. mCanvas= mHolder.lockCanvas(); 52. 53. //draw anything you like 54. 55. mHolder.unlockCanvasAndPost(mCanvas); 56. } 57. 58. } android琐碎笔记六 文章分类:移动开发 1.得到屏幕的 screendimensions Displaydisplay = getWindowManager().getDefaultDisplay(); int width = display.getWidth();int height =display.getHeight(); 2. 播放 gif图片在android @Overrideprotected void onDraw(Canvas canvas) { canvas.drawColor(0xFFCCCCCC); Paint p = newPaint(); p.setAntiAlias(true); canvas.drawBitmap(mBitmap4, 210, 170,null); mDrawable.draw(canvas); long now = android.os.SystemClock.uptimeMillis(); if (mMovieStart == 0) { // first time mMovieStart = now; } if (mMovie != null) { int dur =mMovie.duration(); if (dur == 0) { dur = 1000; } int relTime =(int)((now - mMovieStart) % dur); mMovie.setTime(relTime); mMovie.draw(canvas, getWidth()- mMovie.width(), getHeight() - mMovie.height()); invalidate(); } } @Override protected voidonDraw(Canvas canvas) { if(movie != null) { long now =android.os.SystemClock.uptimeMillis(); int dur =Math.max(movie.duration(), 1); // isit really animated? int pos = (int)(now % dur); movie.setTime(pos); movie.draw(canvas, x, y); invalidate(); }} 4. 打开 sd 卡中的 sqllite File dbfile= new File("/sdcard/mydb.sqlite" ); SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbfile,null); 5.得到手机的 IMEI ((TelephonyManager)getSystemService=(Context.TELEPHONY_SERVICE)).getDeviceId(); 6. 不让程序生成一个 appliation 去掉 当然你的让你的程序被引导启动 7.使用 appliation 的 id 可以获得不同 appliation 的数据: android:sharedUserId="string"在主xml 中添加上面一句话,然后签名也要一样两个 app 的 id 也要设置成一样如都是 string 那么这两个程序就可以相互访问彼此的数据,也可以在同一个 process中了 8.判断相机设备存在不 privateandroid.hardware.Camera mCameraDevice; try { mCameraDevice =android.hardware.Camera.open();} catch(RuntimeException e) { Log.e(TAG,"fail to connect Camera", e); 9 使 listView 透明 android:background="#00000000" android:cacheColorHint="#00000000" 或者 android:background="@android:color/transparent" •The backgroundandroid screen image should be visible. 屏幕的背景图像可以看见 manifest file 添加 attribute 到activity. android:theme="@android:style/Theme.Dialog" Android通过selector改变界面状态 文章分类:移动开发 先上图,看看效果: 初始效果 按下后效果 在res/drawable文件夹新增一个文件,此文件设置了图片的触发状态,你可以 设置state_pressed,state_checked,state_pressed,state_selected, state_focused,state_enabled等几个状态: Java 代码 1. 2. 3. > 4. 5. > 6. 实现如下,注意其中的android:src="@drawable/imageselector" Xml 代码 1. 2. android:layout_height="@android:dimen/app_icon_size" 3. android:layout_alignParentRight="true"android:scaleType="fitCenter" 4. android:layout_gravity="center"android:src="@drawable/imageselector" 5. android:clickable="true"android:focusable="true"android:id="@+id/blacklistImageVi ew" 6. android:layout_marginRight="10dip"/> 如果当触发的控件不是ImageView,而是别的控件,可在代码中用 Java 代码 1. blacklistImageView.setPressed(true); Java 代码 1. blacklistImageView.setChecked(true); Android经典小技巧总结 一、这是一篇关于如何将自定义的 homescreen 设定为Android的默认主页,而不需要用户选择的讨论贴,原文如下: Anotheradditional info: If you want that your homescreen is always the default andthat the system doesn't ask to choose between different home screens simply putit that way: XML: The difference to the XML above is android:priority="1".It seems that the default home screen has priority 0 and therefore setting thepriority of your home screen to 1 is sufficient to force the usage of your homescreen android shape渐近线效果 文章分类:综合技术 http://wang-peng1.javaeye.com/blog/523869 android 画图-----shape的使用 在 GradientDrawable1 试图中终于把 shape 学会了,以前总是似懂非懂, 现在终于把里面的东西搞清楚了,同时也挺佩服谷歌的用心,故意设置一些陷阱吧,不认真对待还真以为没有啥效果呢。 setContentView(R.layout.shape_drawable_1) shape_drawable_1代码如下: android:src="@drawable/shape_5"/> shape_5 的代码: gradient 产生颜色渐变 android:angle从哪个角度开始变貌似只有90 的整数倍可以 android:shape="rectangle"默认的也是长方形 #ff4100ff 蓝色#ff4100ff绿色 android:dashWidth="3dp"android:dashGap="2dp"默认值为0 android:width="2dp"android:color="#FF00ff00"笔的粗细, android:dashWidth="5dp"android:dashGap="5dp"实现- - -这样的效果,dashWidth指的 是一条小横线的宽度 dashGap 指的是小横线与小横线的间距。 width="2dp"不能太宽 分析android动画模块 关键字: android 动画 主要思路 Tween 动画通过对 View 的内容完成一系列的图形变换 (包括平移、缩放、旋转、改变透明度)来实现动画效果。 具体来讲,预先定义一组指令,这些指令指定了图形变换的类型、触发时间、持续时间。这些指令可以是以 XML 文件方式定义,也可以是以源代码方式定义。程序沿着时间线执行这些指令就可以实现动画效果。 动画的进度使用Interpolator 控制,android 提供了几个Interpolator 子类,实现了不同的速度曲线,如LinearInterpolator 实现了匀速效果、 Accelerateinterpolator 实现了加速效果、DecelerateInterpolator实现了减速效果等。还可以定义自己的 Interpolator 子类,实现抛物线、自由落体等物理效果。动画的运行模式有两种: • 独占模式,即程序主线程进入一个循环,根据动画指令不断刷新屏幕,直到动画结束; • 中断模式,即有单独一个线程对时间计数,每隔一定的时间向主线程发通知,主线程接到通知后更新屏幕; 图形变换通过仿射矩阵实现。图形变换是图形学中的基本知识。简单来说就是,每种变换都 是一次矩阵运算。在 Android中,Canvas 类中包含当前矩阵,当调用 Canvas.drawBitmap (bmp, x, y, Paint) 绘制时,android会先把 bmp 做一次矩阵运算,然后将运算的结果显示在Canvas 上。这样,编程人员只需不断修改 Canvas 的矩阵并刷新屏幕,View 里的对象就会不停的做图形变换,动画就形成了。 在 android 中提供了 Animation 、 Interpolator、Transformation 等类具体实现 Tween 动画,下面逐一分析。 Animation 类及其子类 Animation 类及其子类是动画的核心模块,它实现了各种动画效果,如平移、缩 放、旋转、改变透明度等。 Tween 动画的每一桢都根据Interpolator 对 view 的内容做一次图形变换,因此 Animation 的核心工作是做变换(transformation)。 Aniamtion 是基类,他记录了动画的通用属性和方法。主要的属性包括动画持续时间、重复 次数、interpolator等。动画里最重要的方法是 getTransformation (currentTime,outTransformation),该方法根据当前间 (currentTime) 和 interpolator,计算当前的变换,在 outTransformation 中返回。 TranslateAnimation、RotateAnimation、AlphaAnimation 等是 Animation 的 子类,分别实现了平移、旋转、改变 Alpha 值等动画。 每个动画都重载了父类的applyTransformation 方法,这个方法会被父类的 getTransformation 方法调用。另外每个动画还有个 initialize 方法,完成初始化工作。 不同的动画具有不同的属性,如RotateAnimation 的属性是起始角度、终止角度和旋转点坐标, TranslateAnimation的属性是起始位置和终止位置。AlphaAnimation 的属性是起始 alpha 值和终止 alpha 值。 Animation 类及其子类的类图如下所示: Interpolator 类及其子类 Interpolator 定义了动画的变化速度,可以实现匀速、正加速、负加速、无规则变加速等; Interpolator 是基类,封装了所有 Interpolator 的共同方法,它只有一个方法,即 getInterpolation(float input),该方法maps a point on the timeline to a multiplier to be applied tothe transformations of an animation. LinearInerpolator、AccelerateInterpolator,DecelerateInterpolator, AccelerateDecelerateInterpolator,CycleInterpolator是 Interpolator 的子类,分别实现了匀速、加速、减速、变速、循环等效果。 对于 LinearInterpolator ,变化率是个常数,即 f (x) = x. Java 代码 1. public float getInterpolation(floatinput) { 2. return input; 3. } 对于 AccelerateInterpolator,开始变化很慢,然后逐渐变快,即 f(x) = x*x 或者 f(x) = pow(x, 2*mFactor). Java 代码 1. public float getInterpolation(floatinput) { 2. if (mFactor ==1.0f) { 3. return (float)(input * input); 4. } else { 5. return (float)Math.pow(input,2 * mFactor); 6. } 7. } 对于 AccelerateDecelerateInterpolator,变化率开始和结束都很慢,但中间很快,即 f(x) = (cos ((x+1)*PI) / 2.0f) + 0.5f. Java 代码 1. public float getInterpolation(floatinput) { 2. return (float)(Math.cos((input +1) * Math.PI) /2.0f)+0.5f; 3. } Interpolator 类及其子类的类图如下所示: Transformation 类 Transformation 记录了仿射矩阵 Matrix,动画每触发一次,会对原来的矩阵做一次运算, View 的 Bitmap 与这个矩阵相乘就可实现相应的操作(旋转、平移、缩放等)。 Transformation 类封装了矩阵和 alpha 值,它有两个重要的成员,一是 mMatrix,二是 mAlpha。 Transformation 类图如下所示: 如何在 View 中实现动画 从逻辑上讲,实现动画需要如下几步: 1. view创建动画对象,设置动画属性,调用 invalidate刷新屏幕,启动动画; 2. invalidate方法触发了 onDraw函数; 3. 在 onDraw函数中: o 调用动画的getTransformation方法,得到当前时间点的矩阵 o 将该矩阵设置成 Canvas的当前矩阵 o 调用 canvas的 drawBitmap方法,绘制屏幕。 o 判断getTransformation 的返回值,若为真,调用invalidate方法,刷新屏幕进入下一桢;若为假,说明动画完成。 整个流程可用一个序列图表示: 使用样例 下面的代码是一个 view,系统创建 view 时会调用 onCreate 方法,该方法定义了一个 TranslateAniamtion,指定了移动起点和终点,动画持续时间为 1s,最后调用startAnimation 将该动画保存在 View 的成员 mCurrentAnianmtion 中并启动动画。 注意,在 View 中需要定义成员变量 mCurrentAnimation 和 mTransformation ,分别记录当前的动画和变换。另外需要定义成员函数 startAnimation 启动动画。 Java 代码 1. classMyView extends View { 2. 3. Animation mCurrentAnimation = null; 4. 5. Transformation mTransformation = newTransformation; 6. 7. 8. 9. private void setAnimation(Animationanimation) { 10. mCurrentAnimation = animation; 11. if (animation != null) { 12. animation.reset(); 13. } 14. } 15. 16. 17. 18. public voidstartAnimation(Animation animation) { 19. animation.setStartTime(animation.START_ON_FIRST_FRAME); 20. setAnimation(animation); 21. invalidate(); 22. } 23. 24. 25. onDraw (Canvas canvas) { 26. 27. long curTime = SystemClock.uptimeMillis(); 28. 29. if (mCurrentAniamtion == null){ 30. 31. canvas.drawBitmap (b, x, y,mPaint); 32. 33. } 34. 35. else { 36. 37. if(!mCurrentAnimation.isInitialized()) //initialize animation 38. 39. mCurrentAnimation.initialize(w, h, pw, ph); 40. 41. boolean more =mCurrentAnimation.getTransformation (curTime, mTransformatio n); 42. 43. if(more) { 44. 45. Matrix m =canvas.getMatrix(); 46. 47. canvas.setMatrix(mTransformation.getMatrix()); 48. 49. canvas.drawBitmap (b, x, y,mPaint); 50. 51. canvas.setMatrix (m); 52. 53. this.invalidate (); 54. 55. } 56. 57. else { 58. 59. mCurrentAnimation = null; 60. 61. this.invalidate (); 62. 63. } 64. 65. } 66. 67. 68. 69. } 70. 71. 72. void onCreate (){ 73. 74. Animation anim = new TranslateAnimation (10,20,0,0); 75. 76. anim.setDuration (1000); // 1s 77. 78. anim.setInterpolator (newAcceleratInterpolator(3.0f)); 79. 80. startAniamtion (anim); 81. 82. } 83. } Android AnimationFrame动画 文章分类:Java编程 1.java 代码实现: Java 代码 1. packagecom.Aina.Android; 2. 3. importandroid.content.Context; 4. importandroid.graphics.Canvas; 5. importandroid.graphics.drawable.AnimationDrawable; 6. import android.graphics.drawable.Drawable; 7. import android.view.KeyEvent; 8. import android.view.View; 9.importandroid.widget.ImageView; 10. 11. /** 12. *com.Aina.Android Pro_AnimationFrame 13. * 14. *@author Aina.huang E-mail: [email protected] 15. *@version 创建时间:2010Jun 18, 2010 1:56:18 PM类说明 16. */ 17. publicclass GameView extends View { 18. 19. private AnimationDrawablemAnimationDrawable = null; 20. private Context mContext =null; 21. private Drawable mDrawable = null; 22. 23. public GameView(Context context){ 24. super(context); 25. this.mContext = context; 26. 27. mAnimationDrawable = newAnimationDrawable(); 28. for (int i =1; i <=15;i++) { 29. int id =this.getResources().getIdentifier("a" + i, "drawable", 30. mContext.getPackageName()); 31. mDrawable =this.getResources().getDrawable(id); 32. mAnimationDrawable.addFrame(mDrawable,100);//为动画添加一帧.时间为毫秒 33. } 34. mAnimationDrawable.setOneShot(false);//设置播放模式是否循环,false循环,true不循环. 35. 36. // ImageView iv = newImageView(mContext); 37. // iv.setBackgroundResource(R.anim.frame); 38. // mAnimationDrawable = (AnimationDrawable)iv.getBackground(); 39. this.setBackgroundDrawable(mAnimationDrawable);//显示动画. 40. 41. } 42. 43. @Override 44. protected void onDraw(Canvascanvas) { 45. super.onDraw(canvas); 46. } 47. public boolean onKeyDown(intkeyCode, KeyEvent event) { 48. if(keyCode==KeyEvent.KEYCODE_1){ 49. mAnimationDrawable.start();//启动动画. 50. } 51. return super.onKeyDown(keyCode,event); 52. } 53. } Java 代码 1. packagecom.Aina.Android; 2. 3. import android.app.Activity; 4. import android.os.Bundle; 5.import android.view.KeyEvent; 6. 7. public class Test_Frame extendsActivity { 8. /** Called when the activity isfirst created. */ 9. private GameView gv = null; 10. @Override 11. public void onCreate(BundlesavedInstanceState) { 12. super.onCreate(savedInstanceState); 13. gv = new GameView(this); 14. setContentView(gv); 15. } 16. @Override 17. public boolean onKeyDown(intkeyCode, KeyEvent event) { 18. return gv.onKeyDown(keyCode,event); 19. } 20. 21. } 2.xml 布局文件实现: Java 代码 1. 2. 3. xmlns:android="http://schemas.android.com/apk/res/android" 4. android:oneshot="false"> 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. Java 代码 1. packagecom.Aina.Android; 2. 3. importandroid.content.Context; 4. importandroid.graphics.Canvas; 5. importandroid.graphics.drawable.AnimationDrawable; 6. import android.graphics.drawable.Drawable; 7. import android.view.KeyEvent; 8. import android.view.View; 9.importandroid.widget.ImageView; 10. 11. /** 12. *com.Aina.Android Pro_AnimationFrame 13. * 14. *@author Aina.huang E-mail: [email protected] 15. *@version 创建时间:2010Jun 18, 2010 1:56:18 PM类说明 16. */ 17. publicclass GameView extends View { 18. 19. private AnimationDrawablemAnimationDrawable = null; 20. private Context mContext =null; 21. private Drawable mDrawable = null; 22. 23. public GameView(Context context){ 24. super(context); 25. this.mContext = context; 26. /* 27. mAnimationDrawable = newAnimationDrawable(); 28. for (int i = 1; i <= 15; i++){ 29. int id =this.getResources().getIdentifier("a" + i, "drawable", 30. mContext.getPackageName()); 31. mDrawable =this.getResources().getDrawable(id); 32. mAnimationDrawable.addFrame(mDrawable,100);//为动画添加一帧.时间为毫秒 33. } 34. mAnimationDrawable.setOneShot(false);//设置播放模式是否循环,false循环,true不循环. 35. */ 36. ImageView iv = newImageView(mContext); 37. iv.setBackgroundResource(R.anim.frame); 38. mAnimationDrawable =(AnimationDrawable) iv.getBackground(); 39. this.setBackgroundDrawable(mAnimationDrawable);//显示动画. 40. 41. } 42. 43. @Override 44. protected void onDraw(Canvascanvas) { 45. super.onDraw(canvas); 46. } 47. public boolean onKeyDown(intkeyCode, KeyEvent event) { 48. if(keyCode==KeyEvent.KEYCODE_1){ 49. mAnimationDrawable.start();//启动动画. 50. } 51. return super.onKeyDown(keyCode,event); 52. } 53. } AndroidImageSwithcher的使用 文章分类:Java编程 图片切换ImageSwitcher的使用: Java 代码 1. package com.Aina.Android; 2. import android.app.Activity; 3. import android.os.Bundle; 4. import android.util.Log; 5. import android.view.View; 6. importandroid.view.View.OnClickListener; 7. import android.widget.Button; 8. import android.widget.ImageSwitcher; 9. importandroid.widget.ImageView; 10. importandroid.widget.LinearLayout; 11. importandroid.widget.ViewSwitcher.ViewFactory; 12. 13. public class Test_ImageSwitcherextends Activity implements OnClickListener,ViewFactor y{ 14. /** Called when the activity isfirst created. */ 15. //所有要显示的图片资源索引 16. private static final Integer[]imagelist = { 17. R.drawable.img1, 18. R.drawable.img2, 19. R.drawable.img3, 20. R.drawable.img4, 21. R.drawable.img5, 22. R.drawable.img6, 23. R.drawable.img7, 24. R.drawable.img8 25. }; 26. private ImageSwitcherimageswitcher; 27. private static int index =0; 28. //设置各组件ID 29. private static final intButton_NEXT =0x123456; 30. private static final intButton_BACK =0x123457; 31. private static final intImageSwitcher =0x123458; 32. @Override 33. public void onCreate(BundlesavedInstanceState) { 34. super.onCreate(savedInstanceState); 35. //创建一个线性布局 36. LinearLayout layout = newLinearLayout(this); 37. layout.setOrientation(LinearLayout.HORIZONTAL);//水平布局 38. imageswitcher = newImageSwitcher(this); 39. LinearLayout.LayoutParams p2 = newLinearLayout.LayoutParams(120,120); 40. layout.addView(imageswitcher,p2); 41. imageswitcher.setId(ImageSwitcher);//设置ID 42. imageswitcher.setFactory(this);//设置此对象的数据源 43. imageswitcher.setImageResource(imagelist[index]); 44. setContentView(layout); 45. 46. //创建下一张按钮 47. Button next = newButton(this); 48. next.setId(Button_NEXT); 49. next.setText("下一张"); 50. next.setOnClickListener(this); 51. LinearLayout.LayoutParams p = newLinearLayout.LayoutParams(100,100); 52. layout.addView(next, p); 53. //创建上一张按钮 54. Button back = newButton(this); 55. back.setId(Button_BACK); 56. back.setText("上一张"); 57. back.setOnClickListener(this); 58. layout.addView(back, p); 59. } 60. @Override 61. public void onClick(View v) { 62. if(v.getId()==Button_BACK){ 63. index--; 64. if(index<0){ 65. index = imagelist.length-1; 66. } 67. imageswitcher.setImageResource(imagelist[index]); 68. }elseif(v.getId()==Button_NEXT){ 69. index++; 70. if(index>=imagelist.length){ 71. index =0; 72. } 73. imageswitcher.setImageResource(imagelist[index]); 74. } 75. } 76. &nbpublic static Animation loadAnimation (Context context,int id)