Android开发_android界面效果全汇总

(一)Activity页面切换的效果

 

先介绍下左右滑动切换Activity,对于复杂的手势原理一样,具体后述。

主要原理为监控触屏事件和手势事件,在触屏事件处理函数中调用手势事件处理函数,表示用户触屏后是否有手势操作,有则进行手势事件处理,大致分为四步

 

1、需要继承OnGestureListener和OnDoubleTapListener,如下:

Java代码 复制代码  收藏代码
  1. public class ViewSnsActivity extends Activity implements OnTouchListener, OnGestureListener  
public class ViewSnsActivity extends Activity implements OnTouchListener, OnGestureListener

 

这两个类分别是触屏监听器和手势监控器,具体可查看OnTouchListenerOnGestureListener

 

2、在添加mGestureDetector的定义,并在ViewSnsActivity的onCreate函数中加入其页面布局的setOnTouchListener事件

Java代码 复制代码  收藏代码
  1. GestureDetector mGestureDetector;  
GestureDetector mGestureDetector;

  

Java代码 复制代码  收藏代码
  1. public void onCreate(Bundle savedInstanceState) {  
  2.         super.onCreate(savedInstanceState);  
  3.         setContentView(R.layout.view_sns_activity);  
  4.           
  5.         mGestureDetector = new GestureDetector((OnGestureListener) this);    
  6.         LinearLayout viewSnsLayout = (LinearLayout)findViewById(R.id.viewSnsLayout);    
  7.         viewSnsLayout.setOnTouchListener(this);    
  8.         viewSnsLayout.setLongClickable(true);    
  9.     }  
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函数

Java代码 复制代码  收藏代码
  1. private int verticalMinDistance = 20;  
  2. private int minVelocity         = 0;  
  3.   
  4. public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {  
  5.   
  6.     if (e1.getX() - e2.getX() > verticalMinDistance && Math.abs(velocityX) > minVelocity) {  
  7.   
  8.         // 切换Activity  
  9.         // Intent intent = new Intent(ViewSnsActivity.this, UpdateStatusActivity.class);  
  10.         // startActivity(intent);  
  11.         Toast.makeText(this"向左手势", Toast.LENGTH_SHORT).show();  
  12.     } else if (e2.getX() - e1.getX() > verticalMinDistance && Math.abs(velocityX) > minVelocity) {  
  13.   
  14.         // 切换Activity  
  15.         // Intent intent = new Intent(ViewSnsActivity.this, UpdateStatusActivity.class);  
  16.         // startActivity(intent);  
  17.         Toast.makeText(this"向右手势", Toast.LENGTH_SHORT).show();  
  18.     }  
  19.   
  20.     return false;  
  21. }  
    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的四个参数意思分别为

Xml代码 复制代码  收藏代码
  1. e1  The first down motion event that started the fling.手势起点的移动事件  
  2. e2  The move motion event that triggered the current onFling.当前手势点的移动事件  
  3. velocityX   The velocity of this fling measured in pixels per second along the x axis.每秒x轴方向移动的像素  
  4. velocityY   The velocity of this fling measured in pixels per second along the y axis.每秒y轴方向移动的像素  

 

说的更简单点就是,鼠标手势相当于一个向量(当然有可能手势是曲线),e1为向量的起点,e2为向量的终点,velocityX为向量水平方向的速度,velocityY为向量垂直方向的速度

Java代码 复制代码  收藏代码
  1. if (e1.getX() - e2.getX() > verticalMinDistance && Math.abs(velocityX) > minVelocity)  
if (e1.getX() - e2.getX() > verticalMinDistance && Math.abs(velocityX) > minVelocity)

 

 则上面的语句能知道啥意思了吧,就是说向量的水平长度必须大于verticalMinDistance,并且水平方向速度大于minVelocity

 

从而我们可以如此判断手势是否满足一定的条件从而进行相应响应,也可以根据这个写出更复杂的手势判断。

 

4、重载onTouch函数

在2中我们定义了viewSnsLayout的touch事件处理,下面我们来实现,直接调用手势的处理函数

Java代码 复制代码  收藏代码
  1. public boolean onTouch(View v, MotionEvent event) {  
  2.     return mGestureDetector.onTouchEvent(event);  
  3. }  
	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.       <?xml version="1.0"encoding="utf-8"?>  

2.       <set 

3.       xmlns:Android="http://schemas.android.com/apk/res/android"  

4.       Android:interpolator="@android:anim/decelerate_interpolator">

<scale Android:fromXScale="2.0"android:toXScale="1.0"  

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"/></set>     新建zoomout.xml文件 

Xml代码  

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

2.        <set 

3.        xmlns:Android="http://schemas.android.com/apk/res/android"  

4.        Android:interpolator="@android:anim/decelerate_interpolator"

5.        Android:zAdjustment="top">  

6.        <scale Android:fromXScale="1.0"android:toXScale=".5"  

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.<alpha Android:fromAlpha="1.0"android:toAlpha="0"  

11.Android:duration="@android:integer/config_mediumAnimTime"/>  

12.</set>   

(二)android 菜单动画

先请注意,这里的菜单并不是按机器上的MENU出现在那种菜单,而是基于

Android SDK 提供的android.view.animation.TranslateAnimationextends

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

<?xmlversion="1.0" encoding="utf-8"?>

<RelativeLayout

xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"> <TextViewandroid:layout_width="fill_parent"   android:layout_height="wrap_content" android:text="@string/hello"/> <LinearLayout android:id="@+id/menu"

   android:layout_height="100px"android:layout_width="fill_parent"   android:layout_alignParentTop="true"android:background="#ffffff">

   <TextViewandroid:layout_width="fill_parent"

    android:layout_height="fill_parent"android:text="I am a menu"    android:gravity="center" />

</LinearLayout>

<Buttonandroid:id="@+id/button"android:layout_width="fill_parent"   android:layout_height="wrap_content"android:layout_alignParentBottom="true"    android:text="Click to show/hidemenu" />

</RelativeLayout>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.<com.me.page.PageView   

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>< !--亮金黄色 --> 

 

 < 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>< !--中紫罗兰色 --> 

 

 < 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>< !--暗灰色 --> 

< 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>< !--中绿色

--> 

 

 < color name="cornflowerblue">#6495ED< /color><!--菊兰色 -->  

 < color name="cadetblue">#5F9EA0< /color>< !--军兰色 -->  

 < color name="darkolivegreen">#556B2F< /color><!--暗橄榄绿 

 

 < color name="indigo">#4B0082< /color>< !--靛青色 -->  

 < color name="mediumturquoise">#48D1CC</color>< !--中绿宝石

--> 

 

 < 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>< !--中春绿色 --> 

 

 < 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<String> data = newArrayList<String>();

09                     @Override

10                     public void onCreate(Bundle savedInstanceState){

11                     super.onCreate(savedInstanceState);

12          

13                     listView = new ListView(this);  

14                     listView.setAdapter(new    ArrayAdapter<String>(this,android.R.layout.simple_expandable_list_item_1,getData())); 

15                     setContentView(listView);

16                     }  

17        

18        

19

 

20   private List<String> getData(){

21            

22               List<String> data = new ArrayList<String>();

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<T>  objects)来装配数据,要装配这些数据就需要一个连接 ListView 视图对象和数组数据的适配器来两者的适配工作,ArrayAdapter的构造需要三个参数,依次为this,布局文件(注意这里的布局文件描述的是列表的每一行的布局,android.R.layout.simple_list_item_ 1 是系统定义好的布局文件只显示一行文字,数据源(一个 List集合)。同时用setAdapter

()完成适配的最后工作。运行后的现实结构如下图:

 

 

 

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<String> data = newArrayList<String>();

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 中如权限:<uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission>

运行后效果如下图:

 

 

 

SimpleAdapter

 simpleAdapter 的扩展性最好,可以定义各种各样的布局出来,可以放上 ImageView(图片),还可以放上Button(按钮),CheckBox(复选框)等等。下面的代码都直接继承了

ListActivity,ListActivity 和普通的Activity没有太大的差别,不同就是对显示ListView 做了许多优化,方面显示而已。下面的程序是实现一个带有图片的类表。首先需要定义好一个用来显示每一个列内容的xml

vlist.xml

 

view source 

 print?

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

<LinearLayout

02xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="horizontal" 

03android:layout_width="fill_parent"

04android:layout_height="fill_parent">

07          <ImageView android:id="@+id/img" 

08          android:layout_width="wrap_content"

09          android:layout_height="wrap_content" 

10          android:layout_margin="5px"/>  

11    

12               <LinearLayout android:orientation="vertical"

13               android:layout_width="wrap_content" 

14               android:layout_height="wrap_content">

15    

16                     <TextView android:id="@+id/title" 

17                     android:layout_width="wrap_content"

18                     android:layout_height="wrap_content" 

19                     android:textColor="#FFFFFFFF"

20                     android:textSize="22px" />  

21                     <TextView android:id="@+id/info" 

22                     android:layout_width="wrap_content"

23                     android:layout_height="wrap_content" 

24                     android:textColor="#FFFFFFFF"

25                     android:textSize="13px" />

26    

27 </LinearLayout>

30 </LinearLayout>

下面是实现代码:

view source 

 print?

01      /**  

02      * @author allin

03      * 

04      */

05      public class MyListView3 extends ListActivity { 

08      // privateList<String> data = new ArrayList<String>();

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<Map<String, Object>> getData() { List<Map<String,Object>> list = 

20      new ArrayList<Map<String, Object>>();

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

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<String, Object>();

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<String, Object>();

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   <?xml version="1.0" encoding="utf-8"?> 

<LinearLayout

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               <ImageView android:id="@+id/img" 

09               android:layout_width="wrap_content"

10               android:layout_height="wrap_content" 

11               android:layout_margin="5px"/>

12    

13 <LinearLayout android:orientation="vertical" 14    android:layout_width="wrap_content" 

15    android:layout_height="wrap_content">

16    

17               <TextView android:id="@+id/title" 

18               android:layout_width="wrap_content"

19               android:layout_height="wrap_content" 

20               android:textColor="#FFFFFFFF"

21               android:textSize="22px" /> 22 <TextViewandroid:id="@+id/info" 

23               android:layout_width="wrap_content"

24               android:layout_height="wrap_content" 

25               android:textColor="#FFFFFFFF"

26               android:textSize="13px" />  

27    

28 </LinearLayout>

29    

30    

31               <Button android:id="@+id/view_btn"

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               </LinearLayout>

程序代码:

 

view source 

 print?

001 /**  

002  * @author allin

003  * 

004  */

005 public class MyListView4 extends ListActivity {

008   private List<Map<String, Object>> mData;  

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<Map<String, Object>> getData() {

019    List<Map<String,Object>> list = new ArrayList<Map<String,bject>>(); 

020    

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

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<String, Object>();

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<String, Object>();

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:

<stylename="Theme.CustomDialog"parent="android:style/Theme.Dialog">

<itemname="android:windowBackground">@drawable/filled_box

</item> 

</style>

drawable/filled_box.xml

<shapexmlns:android="http://schemas.android.com/apk/res/android"

    <solidandroid:color="#f0600000"/> 

    <stroke android:width="3dp"color="#ffff8080"/>     <corners android:radius="3dp" /> 

    <padding android:left="10dp"android:top="10dp"         android:right="10dp" android:bottom="10dp"/>  </shape>

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">      <TextView android:id="@+id/left_text"         android:layout_width="wrap_content"         android:layout_height="wrap_content"          android:layout_alignParentLeft="true"          android:text="Left"/> 

    <TextViewandroid:id="@+id/right_text"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_alignParentRight="true"          android:text="Right"/> 

</RelativeLayout>

关于为什么采用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/>标签来创建多个动画。一个动画集包含一个到多个动画变化,并且支持一些额外的标签和特性来定制动画集中的动画何时以及怎样运行。 

 

接下来的列表给了一些set标签一些特性: 

 

❑ duration 动画的持续时间(毫秒) 

 

❑ startOffset 启动动画的延时(毫秒) 

 

❑ fillBefore  True表示在动画开始前应用动画变换 

 

❑ fillAfter   True表示动画开始后应用动画变换 

 

❑ interpolator  设置整个时间范围如何影响动画的速度。在11章中会探讨这个变量。指定interpolator时需要引用系统的动画资源

(android:anim/interpolatorName)。 

 

如果你不使用startOffset标签,动画集中的动画将同步执行。 

 

接下来的例子显示了动画集控制目标在缩小淡出的同时旋转360度: 

 

Xml代码 

Java代码  

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

3. <set xmlns:android=”http://schemas.android.com/apk/res/android”      

4.        

5. android:interpolator=”@android:anim/accelerate_interpolator”>

      

6.        

7. <rotate       8.        

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.<scale       22.      

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.<alpha       40.      

41.android:fromAlpha=”1.0”       42.      

43.android:toAlpha=”0.0”       44.      

45.android:startOffset=”500”       46.      

47.android:duration=”500” />       48.      

49.</set>   

 

 

 

 

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. <animation-list       3.        

4. xmlns:android=”http://schemas.android.com/apk/res/android”  

    5.        

6. android:oneshot=”false”>       7.        

8. <item android:drawable=”@drawable/rocket1”android:duration=”

500” />      

9.        

10.<item android:drawable=”@drawable/rocket2”android:duration=”

500” />      

11.      

12.<item android:drawable=”@drawable/rocket3”android:duration=”

500” />      

13.      

14.</animation-list>     

 

 

看到了吧,在 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中条目的布局:

<?xmlversion="1.0" encoding="utf-8"?> 

<RelativeLayout


xmlns:android="http://schemas.android.com/apk/res/android" 

android:paddingBottom="10.0dip"       android:layout_width="90.0dip"  android:layout_height="140.0dip"> 

<ImageView  android:id="@+id/ItemImage"  android:layout_width="80.0dip"  android:layout_height="108.0dip"  android:layout_marginLeft="10.0dip"   android:layout_centerHorizontal="true"> 

</ImageView>  <TextView 

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"> 

</TextView> 

</RelativeLayout>

这里使用了相对布局的特性,android:layout_below,表示TextView在 ImageView下面。这里的图都是用的res/drawable目录下的静态图形文件,正式情况下,应该是从网络获取,可参见用Java concurrent编写异步加载图片功原型实现,二者结合可用于正式生产环境。

ListView的Header使用了自定义视图,更简单的示例可参见为ListView增加

Header表头(ListView Header)的布局文件:

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

<LinearLayout 

xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical"   android:layout_width="fill_parent"  android:layout_height="200dp">  

<TextView android:layout_width="fill_parent" 

android:layout_height="wrap_content"  android:text="最近访问人物" />

<HorizontalScrollView  android:layout_width="fill_parent"  android:layout_height="160dp"> 

<FrameLayout  android:layout_width="fill_parent"  android:layout_height="match_parent"> 

<LinearLayoutandroid:layout_width="1100dp" 

android:layout_height="match_parent"  android:orientation="horizontal"> <GridView  android:id="@+id/grid"   android:layout_width="fill_parent"  android:gravity="center" 

android:layout_height="fill_parent"   android:horizontalSpacing="1.0dip"   android:verticalSpacing="1.0dip"  android:stretchMode="spacingWidthUniform"  android:numColumns="auto_fit"   android:columnWidth="80dip">  </GridView>

</LinearLayout> 

</FrameLayout>   

</HorizontalScrollView>  </LinearLayout>

 

这是比较关键的布局文件,GridView能实现横向滚动主要靠它了。其中:

<LinearLayoutandroid:layout_width="1100dp"

我是写死了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<String>(this, android.R.layout.simple_list_item_1,new  String[]{"隋","唐","宋","元

","明","清"})); 

    }

     private void setGridView(View view) {          GridView gridView = (GridView)

view.findViewById(R.id.grid);          gridView.setNumColumns(10);

        ArrayList<HashMap<String,  Object>> items = new ArrayList<HashMap<String, Object>>();

        for (int i = 0; i < 10; i++)  { 

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

            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(100100 );   

32.                                                                                     //倾斜x和y轴,以(100,100)为中心。    

33.                                                                                     mMatrix.postSkew(0 .2f, 0 .2f, 100100 );     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中的长度单位详解(dpsppxinptmm

•       文章分类:移动开发 

•       看到有很多网友不太理解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

 </item >    

14.  

15.<item name="android:gravity">center_vertical|center_horizontal>16.< /item>  

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 <selector> element. Eachstate Drawable is defined in a nested <item> element. For moreinformation, see the guide to Drawable Resources. 

 

意思就是通过字符串标识符值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.              <shape>   

2.              <gradient   

3.              android:startColor="#ff8c00"  

4.              android:endColor="#FFFFFF"  

5.              android:angle="270" />   

6.              <stroke   

7.              android:width="2dp"  

8.              android:color="#dcdcdc" />   

9.              <corners   

10.           android:radius="2dp" />   

11.<padding   

12.           android:left="10dp"  

13.           android:top="10dp"  

14.           android:right="10dp"  

15.           android:bottom="10dp" />   

16.</shape>    

对于上面,这条shape的定义,分别为渐变,在gradient中startColor属性为开始的颜色, endColor为渐变结束的颜色,下面的angle是角度。接下来是stroke可以理解为边缘,corners 为拐角这里radius属性为半径,最后是相对位置属性padding。

 对于一个Button完整的定义可以为:

Java代码  

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

2.                                                                                        <selector   

3.                                                                                        xmlns:android="http://www.norkoo.com">   

4.                                                                                        <item android:state_pressed="true">   

5.                                                                                        <shape>   

6.                                                                                        <gradient   

7.                                                                                        android:startColor="#ff8c00"  

8.                                                                                        android:endColor="#FFFFFF"  

9.                                                                                        android:angle="270" />   

10.                                                                                     <stroke   

11.                                                                                     android:width="2dp"  

12.                                                                                     android:color="#dcdcdc" />   

13.                                                                                     <corners   

14.                                                                                     android:radius="2dp" />   

15.                                                                                     <padding   

16.                                                                                     android:left="10dp"  

17.                                                                                     android:top="10dp"  

18.                                                                                     android:right="10dp"  

19.                                                                                     android:bottom="10dp" />   

20.                                                                                     </shape>   21.    </item>    22.  

23.                                                                                     <item android:state_focused="true">   

24.                                                                                     <shape>   

25.                                                                                     <gradient   

26.                                                                                     android:startColor="#ffc2b7"  

27.                                                                                     android:endColor="#ffc2b7"  

28.                                                                                     android:angle="270" />   

29.                                                                                     <stroke   

30.                                                                                     android:width="2dp"  

31.                                                                                     android:color="#dcdcdc" />   

32.                                                                                     <corners   

33.                                                                                     android:radius="2dp" />   

34.                                                                                     <padding   

35.                                                                                     android:left="10dp"  

36.                                                                                     android:top="10dp"  

37.                                                                                     android:right="10dp"  

38.                                                                                     android:bottom="10dp" />   

39.                                                                                     </shape>   40.    </item>    41.  

42.                                                                                     <item>           

43.                                                                                     <shape>   

44.                                                                                     <gradient   

45.                                                                                     android:startColor="#ff9d77"  

46.                                                                                     android:endColor="#ff9d77"  

47.                                                                                     android:angle="270" />   

48.                                                                                     <stroke   

49.                                                                                     android:width="2dp"  

50.                                                                                     android:color="#fad3cf" />   

51.                                                                                     <corners   

52.                                                                                     android:radius="2dp" />   

53.                                                                                     <padding   

54.                                                                                     android:left="10dp"  

55.                                                                                     android:top="10dp"  

56.                                                                                     android:right="10dp"  

57.                                                                                     android:bottom="10dp" />   

58.                                                                                     </shape>   

59.                                                                                     </item>   

60.</selector>  

 

注意!提示大家,以上几个item的区别主要是体现在state_pressed按下或state_focused获得焦点时,当当来判断显示什么类型,而没有state_xxx属性的item可以看作是常规状态下。

 

<?xmlversion="1.0" encoding="utf-8"?>

    <selectorxmlns:android="http://schemas.android.com/apk/res/android" >

        <item             android:color="hex_color"             android:state_pressed=["true"| "false"]             android:state_focused=["true"| "false"]             android:state_selected=["true"| "false"]             android:state_active=["true"| "false"]             android:state_checkable=["true"| "false"]             android:state_checked=["true"| "false"]             android:state_enabled=["true"| "false"]

           android:state_window_focused=["true" | "false"]/>

    </selector>

  

Elements:

<selector>

必须。必须是根元素。包含一个或多个<item>元素。

              Attributes:

                  xmlns:android

                            String,必须。定义 XML的命名空间,必须是

                            “http://schemas.android.com/apk/res/android”.

    <item>

              定义特定状态的 color,通过它的特性指定。必须是<selector>的子元素。

              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

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

<selectorxmlns:android="http://schemas.android.com/apk/res/android">

    <itemandroid:state_pressed="true"           android:color="#ffff0000"/><!-- pressed -->     <itemandroid:state_focused="true"           android:color="#ff0000ff"/><!-- focused -->

    <itemandroid:color="#ff000000"/> <!-- default -->

</selector>

  

    这个 Layout XML 会应用 ColorStateList到一个 View 上:

<Button     android:layout_width="fill_parent"     android:layout_height="wrap_content"     android:text="@string/button_text"     android:textColor="@color/button_text"/>

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.    <SPANstyle="FONT-SIZE: small"> 1    //SDcard 操作   

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</SPAN>  

 计算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.        <SPAN style="FONT-SIZE: small"> 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</SPAN>  

Android将ButtonBar放在屏幕底部 ?转烛空间(转载)

文章分类:移动开发 接上篇《Android将TAB选项卡放在屏幕底部》写。上篇提到ButtonBar 的方式写底部button,试了试,看起来外观貌似比Tab好看,不过恐怕没有Tab管理Activity方便吧,毕竟一个Tab就是一个Activity,但是这样用Button的话,却并不如此,所以这样的涉及可能虽然好看点,但是管理起来却是相当麻烦。那么暂且把对 activity的管理放在一边,只看界面的设计吧。

 

  要涉及这样的一个buttonbar,主要就是要用到

style="@android:style/ButtonBar"这个风格。首先还是来看xml的设计,保存layout/bottombtn.xml 

 

 

Java代码  

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

2.    <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/a ndroid"  

3.    android:orientation="vertical"

4.    android:layout_width="fill_parent"5.android:layout_height="fill_parent">   

6.      

7.        <TabHostandroid:id="@+id/edit_item_tab_host"  

8.        android:layout_width="fill_parent"

9.        android:layout_height="fill_parent">   

10.<LinearLayoutandroid:orientation="vertical"  

11.      android:layout_width="fill_parent" 

12.      android:layout_height="fill_parent"  

13.      android:padding="5dp">   

14.<FrameLayoutandroid:id="@android:id/tabcontent"  

15.           android:layout_width="fill_parent" 

16.           android:layout_height="wrap_content"  

17.           android:padding="5dp" 

18.           android:layout_weight="1" />   

19.<TabWidgetandroid:id="@android:id/tabs"  

20.           android:layout_width="fill_parent" 

21.           android:layout_height="wrap_content"  

22.           android:layout_weight="0" />   

23.</LinearLayout>   

24.</TabHost>   

25.</LinearLayout>     

然后以下就是完整的代码了:

 

 

 

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 的动画代码 

<?xmlversion="1.0" encoding="utf-8"?> 

<setxmlns:android="http://schemas.android.com/apk/res/android"> 

  <alpha/> 

  <scale/> 

  <translate/> 

  <rotate/> 

</set> 

每个元素表示不同的动画效果 

 

 

Android动画解析--XML

<alpha> 

<?xmlversion="1.0" encoding="utf-8"?> 

<setxmlns:android="http://schemas.android.com/apk/res/android" > 

<alpha  android:fromAlpha="0.1"  android:toAlpha="1.0"  android:duration="3000" 

/> 

<!-- 透明度控制动画效果alpha         浮点型值:              fromAlpha属性为动画起始时透明度              toAlpha  属性为动画结束时透明度             说明

                0.0 表示完全透明                  1.0表示完全不透明             以上值取 0.0-1.0 之间的 float 数据类型的数字 

       

        长整型值:              duration 属性为动画持续时间             说明:    

                时间以毫秒为单位 

--> 

</set> 

 

 

<scale> 

<?xmlversion="1.0" encoding="utf-8"?> 

<setxmlns:android="http://schemas.android.com/apk/res/android"> 

   <scale            android:interpolator= 

                    "@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"/> 

</set> 

<!--尺寸伸缩动画效果 scale 

       属性:interpolator指定一个动画的插入器         在我试验过程中,使用 android.res.anim 中的资源时候发现         有三种动画插入器

           accelerate_decelerate_interpolator 加速-减速动画插入器              accelerate_interpolator       加速-动画插入器              decelerate_interpolator       减速- 动画插入器 

        其他的属于特定的动画效果       浮点型值: 

        

            fromXScale 属性为动画起始时 X坐标上的伸缩尺寸                toXScale  属性为动画结束时 X 坐标上的伸缩尺寸    

       

            fromYScale 属性为动画起始时 Y坐标上的伸缩尺寸                toYScale   属性为动画结束时 Y 坐标上的伸缩尺寸               startOffset 属性为从上次动画停多少时间开始执行下个动画 

       

            说明

                 以上四种属性值    

   

                    0.0 表示收缩到没有                      1.0表示正常无伸缩                        值小于1.0 表示收缩                     值大于1.0 表示放大 

       

            pivotX     属性为动画相对于物件的 X 坐标的开始位置              pivotY     属性为动画相对于物件的 Y 坐标的开始位置 

       

            说明

                    以上两个属性值从 0%-100%中取值 

                    50%为物件的 X Y 方向坐标上的中点位置 

       

        长整型值:              duration 属性为动画持续时间             说明:  时间以毫秒为单位 

 

        布尔型值

            fillAfter 属性当设置为 true ,该动画转化在动画结束后被应用 

--> 

 

 

<translate>  

<?xmlversion="1.0" encoding="utf-8"?> 

<setxmlns:android="http://schemas.android.com/apk/res/android">  <translate android:fromXDelta="30" android:toXDelta="-80" android:fromYDelta="30" android:toYDelta="300" android:duration="2000" 

/> 

<!--translate 位置转移动画效果         整型值

            fromXDelta 属性为动画起始时 X坐标上的位置                toXDelta  属性为动画结束时 X 坐标上的位置              fromYDelta属性为动画起始时 Y坐标上的位置              toYDelta  属性为动画结束时 Y坐标上的位置             注意

                     没有指定 fromXTypetoXType fromYType toYType 时候,                      默认是以自己为相对参照物                    长整型值:              duration 属性为动画持续时间             说明:  时间以毫秒为单位 

--> 

</set> 

 

 

 

<rotate>  

 

<?xmlversion="1.0" encoding="utf-8"?> 

<setxmlns:android="http://schemas.android.com/apk/res/android"> 

<rotate 

       android:interpolator="@android:anim/accelerate_decelerate_interpolator"         android:fromDegrees="0"          android:toDegrees="+350"                android:pivotX="50%"         android:pivotY="50%"             android:duration="3000"/> 

<!-- rotate 旋转动画效果        属性:interpolator指定一个动画的插入器              在我试验过程中,使用android.res.anim 中的资源时候发现              有三种动画插入器

               accelerate_decelerate_interpolator  加速-减速动画插入器                 accelerate_interpolator              加速-动画插入器                 decelerate_interpolator              减速-动画插入器 

             其他的属于特定的动画效果 

                          

       浮点数型值

           fromDegrees 属性为动画起始时物件的角度               toDegrees  属性为动画结束时物件旋转的角度可以大于360   

       

            说明

                     当角度为负数——表示逆时针旋转                      当角度为正数——表示顺时针旋转                                   (负数from——to 正数:顺时针旋转)  

                     (负数 from——to 负数:逆时针旋转

                     (正数 from——to 正数:顺时针旋转

                     (正数 from——to 负数:逆时针旋转)      

 

            pivotX     属性为动画相对于物件的 X 坐标的开始位置              pivotY     属性为动画相对于物件的 Y 坐标的开始位置 

               

           说明:       以上两个属性值从0%-100%中取值 

                         50%为物件的 X Y 方向坐标上的中点位置 

 

        长整型值:              duration 属性为动画持续时间             说明:      时间以毫秒为单位 

--> 

</set> 

 

 

在编码中如何使用如何使用 XML 中的动画效果 

 

在代码中使用这个方法得到 Animation 实例 

public static Animation loadAnimation (Context context,int id) 

//第一个参数 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 简单展示一下两种方法的用法,对于其他动画,如

ScaleAnimationAlphaAnimation,原理是一样的。 

方法一:在 xml 中定义动画:  Xml代码 

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

2.      <setxmlns:android="http://schemas.android.com/apk/res/android">    

3.    

4.                  <rotate             

5.                  android:interpolator="@android:anim/accelerate_decelerate_interpolator"     

6.                  android:fromDegrees="0"      

7.                  android:toDegrees="+360"      8.        android:duration="3000"/>     

9.               

10.               <!-- rotate旋转动画效果     

11.               属性:interpolator指定一个动画的插入器,用来控制动画的速度变化     

12.               fromDegrees属性为动画起始时物件的角度         

13.               toDegrees  属性为动画结束时物件旋转的角度,正代表顺时针     

14.               duration 属性为动画持续时间,以毫秒为单位     

15.               -->  

16.               lt;/set>     

 

 

使用动画的 Java 代码,程序的效果是点击按钮,TextView旋转一周: 

Java 代码 

1. packagecom.ray.animation;     

2.       

3.      import android.app.Activity;     

4.      import android.os.Bundle;     

5.      import android.view.View;     

6.      importandroid.view.View.OnClickListener;     

7.      importandroid.view.animation.Animation;     

8.      importandroid.view.animation.AnimationUtils;     

9.       importandroid.widget.Button;     

10.   importandroid.widget.TextView;     

11.       

12.               public class TestAnimation extendsActivity implements OnClickListener{     

13.               public void onCreate(BundlesavedInstanceState) {     

14.               super.onCreate(savedInstanceState);     

15.               setContentView(R.layout.main);     

16.               Button btn =(Button)findViewById(R.id.Button01);     

17.               btn.setOnClickListener(this);           18.    }     

19.       

20.               @Override     

21.               public void onClick(View v) {     

22.               Animation anim =AnimationUtils.loadAnimation(this, R.anim.my_rotate_action);     

23.               findViewById(R.id.TextView01).startAnimation(anim);     

24.               }     

25.               }  

 

 

方法二:直接在代码中定义动画(效果跟方法一类似): 

Java 代码 

1. packagecom.ray.animation;     

2.       

3.      import android.app.Activity;     

4.      import android.os.Bundle;     

5.      import android.view.View;     

6.      importandroid.view.View.OnClickListener;      

7.      importandroid.view.animation.AccelerateDecelerateInterpolator;     

8.      importandroid.view.animation.Animation;     

9.      importandroid.view.animation.RotateAnimation;     

10.   importandroid.widget.Button;     

11.       

12. publicclass TestAnimation extends Activity implements OnClickListener{     

13.       

14.               public void onCreate(BundlesavedInstanceState) {     

15.               super.onCreate(savedInstanceState);     

16.               setContentView(R.layout.main);     

17.               Button btn =(Button)findViewById(R.id.Button);     

18.               btn.setOnClickListener(this);           19.    }     

20.       

21.               public void onClick(View v) {     

22.               Animation anim = null;     

23.               anim = new RotateAnimation(0.0f,+360.0f);     

24.               anim.setInterpolator(newAccelerateDecelerateInterpolator());     

25.               anim.setDuration(3000);     

26.               findViewById(R.id.TextView01).startAnimation(anim);      

27.               }     

28.               }   

29.一、Android 中的通知  

30. 一般手机上边都有一个状态条,显示电池电量、信号强度、未接来电、短信...。Android 的屏幕上方也具有状态条。这里所说的通知,就是在这个状态条上显示通知。

31. 

32.      发送通知的步骤如下:

33.      1).获取通知管理器

34.      NotificationManagermNotificationManager = (NotificationManager)  getSystemService(Context.NOTIFICATION_SERVICE);

35.      2).新建一个通知,指定其图标和标题

36.      inticon = android.R.drawable.stat_notify_chat;

37.      longwhen = System.currentTimeMillis();

38.      //第一个参数为图标,第二个参数为标题,第三个为通知时间

39.     Notification notification = new Notification(icon,null, when);

40.      Intentopenintent = new Intent(this, OtherActivity.class);

41.      //当点击消息时就会向系统发送 openintent 意图

42.      PendingIntentcontentIntent = PendingIntent.getActivity(this, 0, openintent, 0);

43.      notification.setLatestEventInfo(this,“标题”, “内容", contentIntent);

44.      mNotificationManager.notify(0,notification);

45. 

Android中的样式和主题

46.  android 中的样式和 CSS 样式作用相似,都是用于为界面元素定义显示风格,它是一个包含一个戒者多个 view 控件属性的集合。如:需要定义字体的颜色和大小。

47. 

48.  1).在 values 目录下添加 styles.xml:

<?xmlversion="1.0"encoding="utf-8"?>

<resources>

             <stylename="changcheng">

                          <itemname="android:textSize">18px</item>

        <itemname="android:textColor">#0000CC</item>

             </style>

</resources>

49. 

50. 2).在 layout 文件中可以通过 style 戒 theme 属性设置样式戒主题。三、使用 HTML 做为 UI

51. 使用 LayoutUI 比较麻烦,丌能让美工参不进来,这样就为开发人员带来了麻烦。但我们可以通过 HTML+JS 来进行 UI 的设计不操作。

52. 

53.  1).在 assets 添加 Html 页面

<!DOCTYPE  html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"  "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta  http-equiv="Content-Type" content="text/html;  charset=UTF-8">

<title>联系人列表</title>

<script  type="text/javascript">       function show(jsondata){                      var jsonobjs = eval(jsondata);

   var table =  document.getElementById("personTable");   for(var  y=0; y<jsonobjs.length; y++){

                      var tr =  table.insertRow(table.rows.length); //添加一行

                      //添加三列

                      var td1 = tr.insertCell(0);                        var td2 = tr.insertCell(1);                        td2.align = "center";                 var td3 = tr.insertCell(2);

                      //设置列内容和属性

                      td1.innerHTML = jsonobjs[y].id;                       td2.innerHTML = jsonobjs[y].name;

                      td3.innerHTML = "<a  href='javascript:itcast.call(\""+ jsonobjs[y].phone  +"\")'>"+ jsonobjs[y].phone+ "</a>";

                           }

              }

</script>

</head>

<body>


               <body bgcolor="#000000"text="#FFFFFF" style="margin:0 0 0 0"οnlοad="javascript:itcast.getContacts()">      <table border="0"width="100%" id="personTable" cellspacing="0">

                            <tr>

                                         <td width="15%">编号</td><td align="center">姓名</td><td width="15%">电话</td>

                            </tr>

               </table>

               

</body>

</html>

54. 

55. 2).在 main.xlm 中添加一个WebView 控件

<?xmlversion="1.0"encoding="utf-8"?>

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="fill_parent"    android:layout_height="fill_parent"

    >

              <WebView

                  android:layout_width="fill_parent"                  android:layout_height="fill_parent"             android:id="@+id/webView"

                 />

</LinearLayout>

56. 

57. 3).Activity 类

packagecn.itcast.html;

  importjava.util.ArrayList;importjava.util.List;importorg.json.JSONArray;importorg.json.JSONObject;importcn.itcast.domain.Contact;importandroid.app.Activity;importandroid.content.Intent;

importandroid.net.Uri;importandroid.os.Bundle;importandroid.os.Handler;importandroid.util.Log;

importandroid.webkit.WebView;

  

publicclassContactActivityextendsActivity {

              privatestaticfinalStringTAG="ContactActivity";         privateWebViewwebView;

              privateHandlerhandler=newHandler();

              

    @Override

    publicvoidonCreate(Bundle  savedInstanceState) {         super.onCreate(savedInstanceState);        setContentView(R.layout.main);

        webView= (WebView)this.findViewById(R.id.webView);

        webView.getSettings().setJavaScriptEnabled(true);//设置支持javaScript        webView.getSettings().setSaveFormData(false);//丌保存表单数据        webView.getSettings().setSavePassword(false);//丌保存密码        webView.getSettings().setSupportZoom(false);//丌支持页面放大功能

        //addJavascriptInterface方法中要绑定的Java对象及方法要运行在另外的线程中,丌能运行在构造他的线程中        webView.addJavascriptInterface(newMyJavaScript(),"itcast");        webView.loadUrl("file:///android_asset/index.html");

    }

    privatefinalclassMyJavaScript{       publicvoidcall(finalString  phone){

         handler.post(newRunnable() {                               

                                                    @Override

                                                    publicvoidrun() {

                                                                  Intent intent =newIntent(Intent.ACTION_CALL, Uri.parse("tel:"+ phone));                                                                  startActivity(intent);

                                                     }

                                        });                               

      }

      /**

       *获取所有联系人

       */

      publicvoidgetContacts(){

         handler.post(newRunnable() {                               

                                                    @Override

                                                    publicvoidrun() {

                                                                 //可以通过访问SQLLite数据库得到联系人

                                                List<Contact> contacts =newArrayList<Contact>();                                                  contacts.add(newContact(27,"路飞","12345"));

          contacts.add(newContact(28,"索隆","67890"));          String json = buildJson(contacts);

                                               webView.loadUrl("javascript:show('"+ json +"')");

                                                     }

                                        });                               

      }

      //生成Json格式的数据

      privateString buildJson(List<Contact> contacts){

         try{

         JSONArray array = newJSONArray();     for(Contact  contact : contacts){

       JSONObject item = newJSONObject();      item.put("id",  contact.getId());      item.put("name",  contact.getName());      item.put("phone",  contact.getPhone());      array.put(item);

                                                     }

     returnarray.toString();    } catch(Exception  e) {

                                                     Log.e(TAG, e.toString());

                                        }

                                        return"";

      }

    }

}

58. 

59.     MyJavaScript 接口实现的方法正是提供给页面中的 JS 代码调用的!

60.     2.将 APK 包放入到SDCard 目录中

61.     在 FileExplorer 面板的右上角有一个导入手机图标,将上面生成的 APK 包导入到 SDCard 目录中。

 

 


Android选项卡效果

首先创建Android工程命名自己的Activity为HelloTabWidget

在main.xml或者自己定义的*.xml文件中创建一个TabHost,需要两个元素 TabWidget和FrameLayout 通常会把这两个元素放到LinearLayout中。

FrameLayout作为改变内容content用的。

注意:TabWidget和FrameLayout 有不同的ID命名空间

android:id="@android:id/idnames",这个是必须的因此TabHost才能自动找到它,Activity需要继承TabActivity。

 

Xml 代码 

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

2.                               <TabHostxmlns:android="http://schemas.android.com/apk/res/android"  

3.                               android:id="@android:id/tabhost"  

4.                               android:layout_width="fill_parent"  

5.                               android:layout_height="fill_parent">  

6.                               <LinearLayout  

7.                               android:orientation="vertical"  

8.                               android:layout_width="fill_parent"  

9.                               android:layout_height="fill_parent">  

10.                            <TabWidget  

11.                            android:id="@android:id/tabs"  

12.                            android:layout_width="fill_parent"  

13.                            android:layout_height="wrap_content"/>  

14.                            <FrameLayout  

15.                            android:id="@android:id/tabcontent"  

16.                            android:layout_width="fill_parent"  

17.                            android:layout_height="fill_parent">  

18.                            <TextView    

19.                            android:id="@+id/textview1"  

20.                            android:layout_width="fill_parent"   

21.                            android:layout_height="fill_parent"    

22.                            android:text="this is atab"/>  

23.                            <TextView    

24.                            android:id="@+id/textview2"  

25.                            android:layout_width="fill_parent"  

26.                            android:layout_height="fill_parent"    

27.                            android:text="this isanother tab"/>  

28.                            <TextView    

29.                            android:id="@+id/textview3"  

30.                            android:layout_width="fill_parent"  

31.                            android:layout_height="fill_parent"    

32.                            android:text="this is athird tab"/>  

33.                            </FrameLayout>  

34.                            </LinearLayout>  

35.                            </TabHost>  

 Activity需要继承TabActivity

Java 代码 

1. publicclass HelloTabWidget extends TabActivity  

 

Java 代码 

1.                       public void onCreate(BundlesavedInstanceState) {   

2.                       super.onCreate(savedInstanceState);   

3.                       setContentView(R.layout.main);   

4.                       mTabHost = getTabHost();   

5.                       mTabHost.addTab(mTabHost.newTabSpec("tab_test1").setIndicator("TAB1")

6.                       . setContent(R.id.textview1));   

7.                       mTabHost.addTab(mTabHost.newTabSpec("tab_test2").setIndicator("TAB2").setConte nt(R.id.textview2));   

8.                       mTabHost.addTab(mTabHost.newTabSpec("tab_test3").setIndicator("TAB3").setConte nt(R.id.textview3));   

9.         

10.         mTabHost.setCurrentTab(0);   

11.         }  

AndroidBaseExpandableListAdapter教程

文章分类:移动开发 

先上图再说,实现效果如下图,选项可多少可变化。

 

 

 

 

BaseExpandableListAdapter实现

 

Java 代码 

1. importjava.util.List;   

2.    

3.      importandroid.content.Context;   

4.      importandroid.graphics.drawable.Drawable;   

5.      importandroid.view.LayoutInflater;   

6.      import android.view.View;   

7.      import android.view.ViewGroup;   

8.      importandroid.widget.BaseExpandableListAdapter;   

9.      importandroid.widget.CheckBox;   

10.   importandroid.widget.ImageView;   

11.   importandroid.widget.TextView;   

12.   importcom.iwidsets.clear.manager.R;   

13.   importcom.iwidsets.clear.manager.adapter.BrowserInfo;   

14.    

15. publicclass ClearExpandableListAdapter extends BaseExpandableListAdapter {   

16.    

17.               class ExpandableListHolder {   

18.               ImageView appIcon;   

19.               TextView appInfo;   

20.               CheckBox appCheckBox;   

21.               }   

22.    

23.         private Context context;   

24.         private LayoutInflatermChildInflater;   

25.         private LayoutInflatermGroupInflater;    26.    private List<GroupInfo> group;   

27.    

28.               publicClearExpandableListAdapter(Context c, List<GroupInfo> group) {   

29.               this.context = c;   

30.               mChildInflater = (LayoutInflater)context   

31.               .getSystemService(Context.LAYOUT_INFLATER_SERVICE);    32.        mGroupInflater = (LayoutInflater)context   

33.                            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);   

34.                            this.group = group;    35.    }   

36.    

37.         public Object getChild(intchildPosition, int itemPosition) {   

38.         returngroup.get(childPosition).getChild(itemPosition);    39.    }   

40.    

41.     public long getChildId(int childPosition,int itemPosition) {   

42.    

43.         return itemPosition;    44.     }   

45.    

46.         @Override  

47.         public int getChildrenCount(intindex) {   

48.         returngroup.get(index).getChildSize();    49.    }   

50.    

51.         public Object getGroup(int index){   

52.         return group.get(index);    53.    }   

54.    

55.         public int getGroupCount() {   

56.         return group.size();    57.    }   

58.    

59.         public long getGroupId(int index){   

60.         return index;    61.    }   

62.    

63.                                  public View getGroupView(intposition, boolean flag, View view,   

64.                                  ViewGroup parent) {   

65.                                  ExpandableListHolder holder =null;   

66.                                  if (view == null) {   

67.                                  view = mGroupInflater.inflate(   

68.                                  R.layout.browser_expandable_list_item,null);   

69.                                  holder = newExpandableListHolder();   

70.                                  holder.appIcon = (ImageView)view.findViewById(R.id.app_icon);   

71.                                  view.setTag(holder);   

72.                                  holder.appInfo = (TextView)view.findViewById(R.id.app_info);   

73.                                  holder.appCheckBox = (CheckBox)view   

74.                                  .findViewById(R.id.app_checkbox);   

75.                                  } else {   

76.                                  holder = (ExpandableListHolder)view.getTag();    

77.                                  }   

78.                                  GroupInfo info =this.group.get(position);   

79.                                  if (info != null) {   

80.                                  holder.appInfo.setText(info.getBrowserInfo().getAppInfoId());   

81.                                  Drawable draw =this.context.getResources().getDrawable(   

82.                                  info.getBrowserInfo().getImageId());   

83.                                  holder.appIcon.setImageDrawable(draw);   

84.                                  holder.appCheckBox.setChecked(info.getBrowserInfo().isChecked());   

85.                                  }   

86.                                  return view;    87.    }   

88.    

89.         public boolean hasStableIds(){   

90.         return false;    91.    }   

92.    

93.         public boolean isChildSelectable(intarg0, int arg1) {   

94.         return false;    95.    }   

96.    

97.                                      @Override  

98.                                      public View getChildView(intgroupPosition, int childPosition,   

99.                                      boolean isLastChild, ViewconvertView, ViewGroup parent) {   

100.                                   ExpandableListHolder holder = null;   

101.                                   if (convertView == null) {   

102.                                   convertView =mChildInflater.inflate(   

103.                                   R.layout.browser_expandable_list_item,null);   

104.                                   holder = newExpandableListHolder();   

105.                                   holder.appIcon = (ImageView)convertView   

106.                                   .findViewById(R.id.app_icon);   

107.                                   convertView.setTag(holder);   

108.                                   holder.appInfo = (TextView)convertView.findViewById(R.id.app_info);   

109.                                   holder.appCheckBox = (CheckBox)convertView   

110.                                   .findViewById(R.id.app_checkbox);   

111.                                   } else {   

112.                                   holder = (ExpandableListHolder)convertView.getTag();   

113.                                   }   

114.                                   BrowserInfo info =this.group.get(groupPosition)   

115.                                   .getChild(childPosition);   

116.                                   if (info != null) {   

117.                                   holder.appInfo.setText(info.getAppInfoId());   

118.                                   Drawable draw =this.context.getResources().getDrawable(   

119.                                   info.getImageId());   

120.                                   holder.appIcon.setImageDrawable(draw);   

121.                                   holder.appCheckBox.setChecked(info.isChecked());   

122.                                   }   

123.                                   return convertView;    124.    }   125.   

126. }  

 要想让child获得焦点,只在改

 

Java 代码 

1.            public booleanisChildSelectable(int arg0, int arg1) {   

2.            return true;   

3.            }  

  

 

browser_expandable_list_item.xml用于显示每一个ITEM的XML

 

 

Xml 代码 

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

2.                  <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"  

3.                  android:layout_width="fill_parent"android:layout_height="wrap_content"  

4.                  android:orientation="horizontal"android:minHeight="40px"  

5.                  android:layout_gravity="center_vertical">  

6.                  <CheckBoxandroid:id="@+id/app_checkbox"android:focusable="false"  

7.                  android:layout_width="wrap_content"android:layout_height="wrap_content"  

8.                  android:layout_marginLeft="35px"android:checked="true"/>  

9.                  <ImageViewandroid:id="@+id/app_icon"android:layout_width="wrap_content"   10.        android:layout_height="wrap_content"android:layout_gravity="center_vertical"/>  

11.    

12.               <TextViewandroid:id="@+id/app_info"android:layout_width="wrap_content"  

13.               android:layout_height="wrap_content"android:textColor="?android:attr/textColorPrim ary"  

14.               android:paddingLeft="3px"android:layout_gravity="center_vertical"/>  

15.               </LinearLayout>  

    browserlayout.xml 用于显示整个界面

 

Xml 代码 

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

2.                         <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"  

3.                         android:layout_width="fill_parent"android:layout_height="fill_parent"  

4.                         android:orientation="vertical">  

5.                         <ExpandableListViewandroid:id="@+id/appList"  

6.                         android:layout_width="fill_parent"android:layout_height="0dip"  

7.                         android:layout_weight="1"/>  

8.                         <LinearLayoutandroid:layout_height="wrap_content"  

9.                         android:layout_width="fill_parent"android:paddingLeft="4dip"  

10.                     android:paddingRight="4dip"android:paddingBottom="1dip"  

11.                     android:paddingTop="5dip"android:background="@android:drawable/bottom_bar"

 

12.                     android:id="@+id/app_footer">  

13.                     <Buttonandroid:layout_weight="1"android:id="@+id/btn_export"  

14.                     android:layout_width="0dip"android:layout_height="fill_parent"  

15.                     android:text="@string/clear"></Button>  

16.                     <Buttonandroid:layout_weight="1"android:id="@+id/btn_sel_all"  

17.                     android:layout_width="0dip"android:layout_height="fill_parent"  

18.                     android:text="select_all"></Button>  

19.                     <Buttonandroid:layout_weight="1"android:id="@+id/btn_desel_all"  

20.                     android:layout_width="0dip"android:layout_height="fill_parent"  

21.                     android:text="deselect_all"></Button>   22.    </LinearLayout>  

23.    

24. </LinearLayout>  

 

BrowserInfo用于提供一个项的信息

 

Java 代码 

1. publicclass BrowserInfo {   

2.    

3.            private int appInfoId;   

4.            private int imageId;   

5.            private boolean checked;   

6.    

7.                  public BrowserInfo(int appInfoId,int imageId, boolean checked) {   

8.                  this.appInfoId = appInfoId;   

9.                  this.imageId = imageId;   

10.               this.checked = checked;    11.    }   

12.    

13.         public boolean isChecked() {   

14.         return checked;    15.    }   

16.    

17.         public void setChecked(booleanchecked) {   

18.         this.checked = checked;    19.    }   

20.    

21.         public int getAppInfoId() {   

22.         return appInfoId;    23.   }   

24.    

25.         public void setAppInfoId(intappInfoId) {   

26.         this.appInfoId = appInfoId;    27.    }   

28.    

29.         public int getImageId() {   

30.         return imageId;    31.    }   

32.    

33.         public void setImageId(int imageId){   

34.         this.imageId = imageId;    35.    }   

36.    

37. }  

 

GroupInfo 用于显示一个组的信息

 

Java 代码 

1. importjava.util.List;   

2.    

3. publicclass GroupInfo {   

4.    

5.     private BrowserInfo group;    6.     private List<BrowserInfo> child;   

7.    

8.     public GroupInfo(BrowserInfo group,List<BrowserInfo> child) {   

9.    

10.               this.group = group;    

11.               this.child = child;    12.    }   

13.         

14.         public void add(BrowserInfoinfo){   

15.         child.add(info);    16.    }   

17.         

18.               public void remove(BrowserInfoinfo){   

19.               child.remove(info);   

20.               }   

21.   

22.                     public void remove(int index){   

23.                     child.remove(index);    24.   }   

25.       

26.         public int getChildSize(){   

27.         return child.size();    28.    }   

29.         

30.         public BrowserInfo getChild(intindex){   

31.         return child.get(index);    32.    }   

33.    

34.         public BrowserInfo getBrowserInfo(){   

35.         return group;    36.    }   

37.    

38.         public voidsetBrowserInfo(BrowserInfo group) {   

39.         this.group = group;    40.    }   

41.    

42.         public List<BrowserInfo>getChild() {   

43.         return child;    44.    }   

45.    

46.         public void setChild(List<BrowserInfo>child) {   

47.         this.child = child;    48.    }   

49.    

50. }  

 

 

ClearBrowserActivity 最后就是把要显示的内容显示出来的。

 

 

Java 代码 

1. publicclass ClearBrowserActivity extends Activity implements ExpandableListView.OnGroupClickListener,ExpandableListView.OnChildClickListener{   

2.   

3.    private List<GroupInfo> group;   

4.    

5.     private ClearExpandableListAdapterlistAdapter = null;    6.     private ExpandableListView appList;   

7.    

8.                               public void onCreate(BundlesavedInstanceState) {   

9.                               super.onCreate(savedInstanceState);   

10.                            setContentView(R.layout.browserlayout);   

11.                            appList = (ExpandableListView)findViewById(R.id.appList);   

12.                            init();   

13.                            BrowserInfo browsingHistoryParents= newBrowserInfo(   

14.                            R.string.browsinghistory,R.drawable.browser_image,true);   

15.                            List<BrowserInfo>browsingHistoryChild = new ArrayList<BrowserInfo>();   

16.                            BrowserInfo browser =newBrowserInfo(R.string.browser,   

17.                            R.drawable.browser_image,true);    18.        browsingHistoryChild.add(browser);   

19.    

20.               BrowserInfo operaClear =newBrowserInfo(R.string.opera_clear,   

21.               R.drawable.browser_image,true);    22.        browsingHistoryChild.add(operaClear);   

23.             

24.               BrowserInfo firefoxClear =newBrowserInfo(R.string.firefox_clear,   

25.               R.drawable.browser_image,true);    26.        browsingHistoryChild.add(firefoxClear);   

27.             

28.               BrowserInfo ucwebClear =newBrowserInfo(R.string.ucweb_clear,   

29.               R.drawable.browser_image,false);    30.        browsingHistoryChild.add(ucwebClear);   

31.             

32.               GroupInfo browserGroup = newGroupInfo(browsingHistoryParents,   

33.               browsingHistoryChild);    34.        addGroup(browserGroup);   

35.    

36.               listAdapter = newClearExpandableListAdapter(this, group);   

37.               appList.setOnChildClickListener(this);   

38.               appList.setOnGroupClickListener(this);   

39.               appList.setAdapter(listAdapter);    40.    }   

41.    

42.         private void init() {   

43.         group = new ArrayList<GroupInfo>();    44.    }   

45.    

46.               private void addGroup(GroupInfoinfo) {   

47.               group.add(info);   

48.               }   

49.  

50.         private static BrowserInfonewBrowserInfo(int infoId, int imageId,boolean checked) {   

51.         return new BrowserInfo(infoId,imageId,checked);    52.    }   

53.    

54.                     @Override  

55.                     public booleanonGroupClick(ExpandableListView parent, View v,   

56.                     int groupPosition, long id) {   

57.                     return false;    58.    }   

59.    

60.                     @Override  

61.                     public booleanonChildClick(ExpandableListView parent, View v,    

62.                     int groupPosition, intchildPosition, long id) {   

63.                     return false;   

64.                     }   

65.                     }  

android 3d旋转

文章分类:Java编程 

 在javaeye里看到了关于3d旋转的文章,可是博主没有透入什么技术细节。由于一直想做出那种旋转效果,所以就想啊想,终于想出来了(我是个小菜鸟)。呵呵,不管怎样,希望对想做还没做出来的朋友一些帮助。

 先上一个效果图:

 

 

 

 这是你想要的吗?如果是就继续往下看吧。

 其实,这个效果是用animation配合camera做出来的,相信大家在apidemo 里面看过类似的。

 那么先写一个继承animation的类:Rotate3d

 

Rotate3d 代码 

1.            public class Rotate3d extendsAnimation {   

2.            private float mFromDegree;   

3.            private float mToDegree;   

4.            private float mCenterX;   

5.            private float mCenterY;   

6.            private float mLeft;   

7.            private float mTop;   

8.            private Camera mCamera;   

9.            private static final String TAG ="Rotate3d";   

10.    

11.                     public Rotate3d(float fromDegree,float toDegree, float left, float top,   

12.                     float centerX, float centerY){   

13.                     this.mFromDegree = fromDegree;   

14.                     this.mToDegree = toDegree;   

15.                     this.mLeft = left;   

16.                     this.mTop = top;   

17.                     this.mCenterX = centerX;    18.       this.mCenterY = centerY;   

19.    

20.     }   

21.    

22.                     @Override   

23.                     public void initialize(int width,int height, int parentWidth,   

24.                     int parentHeight) {   

25.                     super.initialize(width, height,parentWidth, parentHeight);   

26.                     mCamera = new Camera();   

27.                     }   

28.    

29.                            @Override   

30.                            protected voidapplyTransformation(float interpolatedTime, Transformation t) {   

31.                            final float FromDegree = mFromDegree;   

32.                            float degrees = FromDegree +(mToDegree - mFromDegree)   

33.                            * interpolatedTime;   

34.                            final float centerX =mCenterX;   

35.                            final float centerY =mCenterY;    36.        final Matrix matrix =t.getMatrix();   

37.    

38.                                       if (degrees <= -76.0f) {   

39.                                       degrees = -90.0f;   

40.                                       mCamera.save();   

41.                                       mCamera.rotateY(degrees);   

42.                                       mCamera.getMatrix(matrix);   

43.                                       mCamera.restore();   

44.                                       } else if(degrees >=76.0f){   

45.                                       degrees =90.0f;   

46.                                       mCamera.save();   

47.                                       mCamera.rotateY(degrees);   

48.                                       mCamera.getMatrix(matrix);   

49.                                       mCamera.restore();   

50.                                       }else{   

51.                                       mCamera.save();   

52.                                       //这里很重要哦。   

53.                                       mCamera.translate(0,0,centerX);   

54.                                       mCamera.rotateY(degrees);   

55.                                       mCamera.translate(0,0,-centerX);   

56.                                       mCamera.getMatrix(matrix);   

57.                                       mCamera.restore();   

58.                                       }   

59.    

60.               matrix.preTranslate(-centerX,-centerY);   

61.               matrix.postTranslate(centerX,centerY);   

62.               }   

63.               }  

   有了这个类一切都会变得简单的,接着只要在activity中写两个Rotate3d 的对象,让两个view,分别做这两个对象的animation就好了。(原来就这么简单啊!无语)

 

Activity 代码 

1.                  //下面两句很关键哦,呵呵,心照不宣。   

2.                  Rotate3d leftAnimation = newRotate3d(-0, -90,0,0, mCenterX, mCenterY);   

3.                  Rotate3d rightAnimation = newRotate3d(-0+90, -90+90,0.0f,0.0f, mCenterX, mCent erY);   

4.    

5.                  leftAnimation.setFillAfter(true);   

6.                  leftAnimation.setDuration(1000);   

7.                  rightAnimation.setFillAfter(true);    8.        rightAnimation.setDuration(1000);   

9.    

10.               mImageView1.startAnimation(leftAnimation);   

11.               mImageView2.startAnimation(rightAnimation);  

  

 

  

 

还要写一下mImageView1,mImageView2的xml,

 

Xml 代码 

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

2.            <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"  

3.            android:orientation="vertical"  

4.            android:layout_width="fill_parent"  

5.            android:layout_height="wrap_content"  

6.            >  

7.    

8.                  <FrameLayout  

9.                  android:layout_width="fill_parent"   10.        android:layout_height="fill_parent">  

11.    

12.                                  <ImageView  

13.                                  android:id="@+id/image1"  

14.                                  android:layout_gravity="center_horizontal"  

15.                                  android:layout_width="fill_parent"  

16.                                  android:layout_height="wrap_content"  

17.                                  android:src="@drawable/image1"  

18.                                  />  

19.                                  <ImageView  

20.                                  android:id="@+id/image2"  

21.                                  android:background="#ffff0000"  

22.                                  android:layout_gravity="center_horizontal"  

23.                                  android:layout_width="fill_parent"  

24.                                  android:layout_height="wrap_content"  

25.                                  android:src="@drawable/image2"  

26.                                  />  

27.    

28.         </FrameLayout>  

29.         </LinearLayout>  

 写完收工。如果有不足之处,还请朋友们不吝指教。

 

 

Android File Explorer展示图片

文章分类:移动开发 

 

res/layout/row.xml

 

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

<TextView 

 xmlns:android="http://schemas.android.com/apk/res/android"   android:id="@+id/rowtext"   android:layout_width="fill_parent"     android:layout_height="25px"      android:textSize="23sp" />

 

/res/layout/main.xml 

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

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="fill_parent"    android:layout_height="fill_parent"

    > <TextView  android:id="@+id/path"     android:layout_width="fill_parent"     android:layout_height="wrap_content" 

    />

<ListView

android:id="@android:id/list"

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

 /> <TextView

 android:id="@android:id/empty"  android:layout_width="fill_parent"     android:layout_height="wrap_content"      android:text="No Data"

 />

</LinearLayout>

/res/layout/jpgdialog.xml

 

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

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"              android:id="@+id/layout_root"              android:orientation="vertical"              android:layout_width="fill_parent"              android:layout_height="fill_parent"              android:paddingLeft="10dip"               android:paddingRight="10dip"

              >

    <TextViewandroid:id="@+id/text"              android:layout_width="wrap_content"               android:layout_height="wrap_content"              android:textSize="11sp" />

              />

    <ImageViewandroid:id="@+id/image"               android:layout_width="150px"               android:layout_height="150px"                />

    <Buttonandroid:id="@+id/okdialogbutton"        android:layout_width="fill_parent"               android:layout_height="wrap_content"               android:text="OK"

        /> </LinearLayout>

import java.io.File; importjava.io.IOException; import java.util.ArrayList; import java.util.List; importandroid.app.AlertDialog; import android.app.Dialog; import android.app.ListActivity;import android.content.Context; import android.content.DialogInterface; importandroid.graphics.Bitmap; import android.graphics.BitmapFactory; importandroid.media.ExifInterface; import android.os.Bundle; importandroid.view.View; import android.widget.ArrayAdapter; importandroid.widget.Button; import android.widget.ImageView; importandroid.widget.ListView; import android.widget.TextView;

 

public class AndroidExplorerextends ListActivity {

 

static final int ID_JPGDIALOG =0;

 

String filename;

String exifAttribute;

TextView exifText;

ImageView bmImage;

BitmapFactory.OptionsbmOptions; 

File jpgFile;

Dialog jpgDialog;

 

private List<String> item= null; private List<String> path = null; private Stringroot="/"; private TextView myPath;

 

    /** Called when the activity is firstcreated. */

    @Override

    public void onCreate(BundlesavedInstanceState) {        super.onCreate(savedInstanceState);      setContentView(R.layout.main);      myPath = (TextView)findViewById(R.id.path);

      getDir(root);

 }

 

 private void getDir(String dirPath)

{      myPath.setText("Location: " +dirPath);

     

     item = new ArrayList<String>();      path = new ArrayList<String>();

     

     File f = new File(dirPath);

     File[] files = f.listFiles();

     

     if(!dirPath.equals(root))

     {

 

      item.add(root);       path.add(root);

      

      item.add("../");

      path.add(f.getParent());

            

     }

     

     for(int i=0; i < files.length; i++)

     {

       File file = files[i];        path.add(file.getPath());        if(file.isDirectory())         item.add(file.getName() +"/");        else

        item.add(file.getName());

     }

 

     ArrayAdapter<String> fileList =

      new ArrayAdapter<String>(this,R.layout.row, item);     setListAdapter(fileList);

    }

 @Override

protected voidonListItemClick(ListView l, View v, int position, long id) {

 

File file = newFile(path.get(position));

 

if (file.isDirectory())

{ if(file.canRead())getDir(path.get(position));

   else

   {

    new AlertDialog.Builder(this)

    .setIcon(R.drawable.icon)

    .setTitle("[" + file.getName() +"] folder can't be read!")

    .setPositiveButton("OK", 

      new DialogInterface.OnClickListener() {

       

       @Override

       public void onClick(DialogInterfacedialog, int which) {

        // TODO Auto-generated method stub

       }

      }).show();

   }  }   else   {

   exifAttribute = null;    filename = file.getName();

   String ext =filename.substring(filename.lastIndexOf('.')+1, filename.length());

 

   if(ext.equals("JPG")||ext.equals("jpg"))

   {

    try {

     ExifInterface exif = newExifInterface(file.toString());     exifAttribute = getExif(exif);    } catch (IOException e) {

     // TODO Auto-generated catch block

     ;

    }

    jpgFile = file;

    showDialog(ID_JPGDIALOG);

   }   else{

    new AlertDialog.Builder(this)        .setIcon(R.drawable.icon)

     .setTitle("[" + filename +"]")

     .setMessage(exifAttribute)      .setPositiveButton("OK", 

       new DialogInterface.OnClickListener() {

       

       @Override

      public void onClick(DialogInterfacedialog, int

which) {

           // TODO Auto-generated method stub

          }

         }).show();

   }

 }

}

 

    private String getExif(ExifInterface exif)

    {

     String myAttribute=null;

    myAttribute += getTagString(ExifInterface.TAG_DATETIME, exif);      myAttribute +=getTagString(ExifInterface.TAG_FLASH, exif);      myAttribute +=getTagString(ExifInterface.TAG_GPS_LATITUDE, exif);      myAttribute +=

getTagString(ExifInterface.TAG_GPS_LATITUDE_REF,exif);      myAttribute +=getTagString(ExifInterface.TAG_GPS_LONGITUDE, exif);      myAttribute +=

getTagString(ExifInterface.TAG_GPS_LONGITUDE_REF,exif);      myAttribute +=getTagString(ExifInterface.TAG_IMAGE_LENGTH, exif);

     myAttribute +=getTagString(ExifInterface.TAG_IMAGE_WIDTH, exif);

     myAttribute +=getTagString(ExifInterface.TAG_MAKE, exif);     myAttribute += getTagString(ExifInterface.TAG_MODEL, exif);      myAttribute += getTagString(ExifInterface.TAG_ORIENTATION,exif);

     myAttribute +=getTagString(ExifInterface.TAG_WHITE_BALANCE, exif);

     return myAttribute;

    }

    

    private String getTagString(String tag,ExifInterface exif)

    {

     return(tag + " : " +exif.getAttribute(tag) + "\n");

    }

 @Override

protectedDialog onCreateDialog(int id) { jpgDialog = null;; switch(id){

case ID_JPGDIALOG:

 

   Context mContext = this;    jpgDialog = new Dialog(mContext);

 

   jpgDialog.setContentView(R.layout.jpgdialog);    exifText = (TextView)jpgDialog.findViewById(R.id.text);   bmImage = (ImageView)jpgDialog.findViewById(R.id.image);    bmOptions = newBitmapFactory.Options();   bmOptions.inSampleSize = 2;

   

   Button okDialogButton =

(Button)jpgDialog.findViewById(R.id.okdialogbutton);

  okDialogButton.setOnClickListener(okDialogButtonOnClickListener);

   

   break;  default:    break;   }

 return jpgDialog;

}

 @Override

protected voidonPrepareDialog(int id, Dialog dialog) {

 // TODO Auto-generated method stub

   switch(id){  case ID_JPGDIALOG:

   dialog.setTitle("[" + filename +"]");   exifText.setText(exifAttribute);

   Bitmap bm = BitmapFactory.decodeFile(jpgFile.getPath(),bmOptions);   bmImage.setImageBitmap(bm); 

   

   break;  default:    break;

 }

}

    

private Button.OnClickListenerokDialogButtonOnClickListener

 = new Button.OnClickListener(){

 

 @Override

 public void onClick(View v) {

  // TODO Auto-generated method stub     jpgDialog.dismiss();

   }

};

} android ShapeDrawable实例

文章分类:移动开发 

 今天看了一下api中的画图,遇到了一个新的类,Shader类介绍,android

中提供了Shader类专门来渲染图像已经一些几何图形,shader 下面包括几个直

接子类,分别是BitmapShaper,ComposeShader,

LinerGradient,RadialGradient,SweepGradient.BitmapShader主要用来渲染

图像,Shader类的使用,先构造Shdaer对象,然后通过Paint的setShader方法来设置渲染对象,然后再绘制使用这个Paint对象既可。

Java 代码 

1.      import android.app.Activity;   

2.      importandroid.content.Context;   

3.      importandroid.graphics.Bitmap;   

4.      importandroid.graphics.BitmapShader;   

5.      importandroid.graphics.Canvas;   

6.      import android.graphics.ComposePathEffect;   

7.      importandroid.graphics.CornerPathEffect;   

8.      importandroid.graphics.DiscretePathEffect;   

9.      importandroid.graphics.LinearGradient;   

10.   importandroid.graphics.Paint;   

11.   importandroid.graphics.Path;   

12.   importandroid.graphics.PathEffect;   

13.   importandroid.graphics.RectF;   

14.   importandroid.graphics.Shader;   

15.   importandroid.graphics.SweepGradient;   

16.   importandroid.graphics.drawable.Drawable;   

17.   importandroid.graphics.drawable.ShapeDrawable;   

18.   importandroid.graphics.drawable.shapes.ArcShape;   

19.   importandroid.graphics.drawable.shapes.OvalShape;   

20.   importandroid.graphics.drawable.shapes.PathShape;   

21.   importandroid.graphics.drawable.shapes.RectShape;   

22.   importandroid.graphics.drawable.shapes.RoundRectShape;   

23.   importandroid.graphics.drawable.shapes.Shape;   

24.   importandroid.os.Bundle;   

25.   importandroid.view.View;   

26.  

27. publicclass ShapeDrawble1 extends Activity {   28.     /** Calledwhen the activity is first created. */  

29.         

30.    

31.                     @Override  

32.                     protected void onCreate(BundlesavedInstanceState) {   

33.                     super.onCreate(savedInstanceState);   

34.                     setContentView(newSampleView(this));   

35.                     }   

36.             

37.                     private static class SampleViewextends View {   

38.                     private ShapeDrawable[]mDrawables;   

39.                 

40.                                  private static Shader makeSweep(){   

41.                                  /* SweepGradient是继承于Shader 的,它是以中心点(15025  

42.                                  *按照下列四种颜色进行变化的*/  

43.                                  return new SweepGradient(0,0,   

44.                                  new int[] {0xFFFF0000,0xFF00FF00,0xFF0000FF,0xFFFF0000 },   

45.                                  null);// null表示均衡变化   

46.                                  }   

47.                 

48.                                                        private static Shader makeLinear(){   

49.                                                        //颜色按照直线线性变化的着色器   

50.                                                        return new LinearGradient(100,100,0,0,   

51.                                                        new int[] {0xFFFF0000,0xFF00FF00,0xFF0000FF },   

52.                                                        null, Shader.TileMode.MIRROR);    53.            }   

54.                 

55.                                                                              private static Shader makeTiling(){   

56.                                                                              int[] pixels = new int[] {0xFFFF0000,0xFF00FF00,0xFF0000FF,0};   

57.                                                                              Bitmap bm =Bitmap.createBitmap(pixels,1,1,   

58.                                                                              Bitmap.Config.ARGB_8888);   

59.                                                                              /**  

60.                                                                              * BitmapShader是一个位图着色器,这个着色器是通过  

61.                                                                              *xy方向重复位图bm 的像素来着色的  

62.                                                                              *  

63.                                                                              */  

64.                                                                              return new BitmapShader(bm,Shader.TileMode.REPEAT,   

65.                                                                              Shader.TileMode.REPEAT);   

66.                                                                              }   

67.                                                                              /**  

68.                                                                              * ShapeDrawable是绘制各种几何体的类。它注入想要绘制的形状shap  

69.                                                                              *类,就可以绘制出我们想要的集合体,这个类最寒心的就是drawcanvas  

70.                                                                              *onDrawShapeCanvasPaint)这个方法调用  

71.                                                                              *  

72.                                                                              */  

73.                                                                              private static classMyShapeDrawable extends ShapeDrawable {   

74.                                                                              //Paint.ANTI_ALIAS_FLAG代表这个画笔的图形是光滑的   

75.                                                                              private Paint mStrokePaint = newPaint(Paint.ANTI_ALIAS_FLAG);   

76.                     

77.                                  public MyShapeDrawable(Shape s){   

78.                                  super(s);   

79.                                  mStrokePaint.setStyle(Paint.Style.STROKE);   

80.                                  }   

81.                     

82.                            public Paint getStrokePaint(){   

83.                            return mStrokePaint;    84.                }   

85.                     

86.                                  @Overrideprotected void onDraw(Shape s, Canvas c, Paint p) {   

87.                                  //绘制填充效果的图形   

88.                                  s.draw(c, p);   

89.                                  //绘制黑边   

90.                                  s.draw(c, mStrokePaint);   

91.                                  }   92.            }   

93.                 

94.                                public SampleView(Context context){   

95.                                super(context);   

96.                                setFocusable(true);   

97.                                //外部圆角矩形的圆角圆半径,上面俩个角是圆   

98.                                float[] outerR = new float[] {12,12,12,12,0,0,0, 0};   

99.                                //内部矩形   

100.                            RectF   inset = new RectF(6,6,6,6);   

101.                            //内部圆角矩形的圆角是圆半径,左上角和右下角是圆角矩形   

102.                            float[] innerR = new float[] {12,12,0,0,12,12,0, 0};   

103.                            //绘制一个顶点为下列四个点的棱形   

104.                            Path path = new Path();   

105.                            path.moveTo(50,0);   

106.                            path.lineTo(0,50);   

107.                            path.lineTo(50,100);   

108.                            path.lineTo(100,50);   

109.                            //封闭前面点所绘制的路径   

110.                            path.close();    111.              

112.                                                                                                                mDrawables = new ShapeDrawable[7];   

113.                                                                                                                //绘制矩形   

114.                                                                                                                mDrawables[0]= new ShapeDrawable(new RectShape());   

115.                                                                                                                //绘制椭圆   

116.                                                                                                                mDrawables[1]= new ShapeDrawable(new OvalShape());   

117.                                                                                                                //绘制上面俩个角是圆角的矩形   

118.                                                                                                                mDrawables[2]= new ShapeDrawable(new RoundRectShape(outerR, null,   

119.                                                                                                                null));    

120.                                                                                                                //绘制上面俩角是圆角,并且有一个内嵌的矩形   

121.                                                                                                                mDrawables[3]= new ShapeDrawable(new RoundRectShape(outerR, inset,   

122.                                                                                                                null));   

123.                                                                                                                绘制上面俩角是圆角,并且有一个内嵌的矩形且左上角和右下角是圆形矩形环   

124.                                                                                                                mDrawables[4]= new ShapeDrawable(new RoundRectShape(outerR, inset,   

125.                                                                                                                innerR));   

126.                                                                                                                //绘制指定路径的集合体   

127.                                                                                                                mDrawables[5]= new ShapeDrawable(new PathShape(path, 100,100));   

128.                                                                                                                //用自定的ShapDrawble 绘制开始弧度 45 扫过弧度-270 的椭圆   

129.                                                                                                                mDrawables[6]= new MyShapeDrawable(new ArcShape(45,-270));   

130.                     

131.                            mDrawables[0].getPaint().setColor(0xFFFF0000);   

132.                            mDrawables[1].getPaint().setColor(0xFF00FF00);   

133.                            mDrawables[2].getPaint().setColor(0xFF0000FF);   

134.                            mDrawables[3].getPaint().setShader(makeSweep());   

135.                            mDrawables[4].getPaint().setShader(makeLinear());   

136.                            mDrawables[5].getPaint().setShader(makeTiling());   

137.                            mDrawables[6].getPaint().setColor(0x88FF8844);   

138.                            //DiscretePathEffect是一个折线路径效果,分割长度是10,偏差时 4   

139.                            PathEffect pe = newDiscretePathEffect(10,4);   

140.                            //CornerPathEffect是将2 个路径效果合并后的路径效果   

141.                            PathEffect pe2 = newCornerPathEffect(4);   

142.                            mDrawables[3].getPaint().setPathEffect(   

143.                            new ComposePathEffect(pe2,pe));    144.                

145.                            MyShapeDrawable msd =(MyShapeDrawable)mDrawables[6];   

146.                            //设置笔画宽度等于4   

147.                            msd.getStrokePaint().setStrokeWidth(4);   

148.                            }   149.                

150.   @Overrideprotected void onDraw(Canvas canvas) {   151.           

152.      int x = 10;    153.      int y = 10;   

154.                                   int width =300;   

155.                                   int height =50;   

156.                                   //循环绘制   

157.                                   for (Drawable dr : mDrawables){   

158.                                   dr.setBounds(x, y, x + width, y +height);   

159.                                   dr.draw(canvas);                   

160.                                   y += height +5;   

161.                                   }   

162.                                   }   

163.                                   }   

164.                                   

 

Eclipse开发Android, TableLayout(学习4

Hello, TableLayout

A TableLayoutis a ViewGroup that will lay child View elementsinto rows and columns.

1.                      Start a new project/Activity calledHelloTableLayout. 

2.                      Open the layout file. Make it likeso: 

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

4.                      <TableLayoutxmlns:android="http://schemas.android.com/apk/res/android"

5.                      android:layout_width="fill_parent"

6.                      android:layout_height="fill_parent" 7.     android:stretchColumns="1"> 8.  

9.                        <TableRow>

10.                     <TextView

11.                     android:layout_column="1" 12.            android:text="Open..."

13.                                android:padding="3dip" />

14.                                <TextView

15.                                android:text="Ctrl-O"

16.                                android:gravity="right"

17.                                android:padding="3dip" /> 18.    </TableRow> 19.

20.                                <TableRow>

21.                                <TextView

22.                                android:layout_column="1"

23.                                android:text="Save..."

24.                                android:padding="3dip" />

25.                                <TextView

26.                                android:text="Ctrl-S"

27.                                android:gravity="right"

28.                                android:padding="3dip" /> 29.    </TableRow> 30.

31.                     <TableRow>

32.                     <TextView

33.                     android:layout_column="1" 34.            android:text="Save As..."

35.                                android:padding="3dip" />

36.                                <TextView

37.                                android:text="Ctrl-Shift-S"

38.                                android:gravity="right"

39.                                android:padding="3dip" /> 40.    </TableRow> 41.

42.                     <View

43.                     android:layout_height="2dip"

44.                     android:background="#FF909090" /> 45.

46.                                <TableRow>

47.                                <TextView

48.                                android:text="X"

49.                                android:padding="3dip" />

50.                                <TextView

51.                                android:text="Import..."

52.                                android:padding="3dip" /> 53.    </TableRow> 54.

55.                                <TableRow>

56.                                <TextView

57.                                android:text="X"

58.                                android:padding="3dip" />

59.                                <TextView

60.                                android:text="Export..."

61.                                android:padding="3dip" />

62.                                <TextView

63.                                android:text="Ctrl-E"

64.                                android:gravity="right"

65.                                android:padding="3dip" />

66.                                </TableRow>

67.

68.                     <View

69.                     android:layout_height="2dip"

70.                     android:background="#FF909090" /> 71.

72.                     <TableRow>

73.                     <TextView

74.                     android:layout_column="1" 75.            android:text="Quit"

76.                                android:padding="3dip" />

77.                                </TableRow>

78.</TableLayout>

Notice how this resembles the structure of an HTMLtable. TableLayout is like the table element; TableRow is like a tr element;but for our cells like the html td element, we can use any kind of View. Here,we use TextView for the cells.

79. Makesure your Activity loads this layout in the onCreate()method: 

80.public void onCreate(BundlesavedInstanceState) {

81.           super.onCreate(savedInstanceState);

82.           setContentView(R.layout.main);

83.}

R.layout.main refers to themain.xml layout file.

84. Runit. 

You should see the following:

 

备注:TableLayout html 中表格类似。

 

 

系出名门Android(8)

文章分类:移动开发 

系出名门Android(8) - 控件(View)之TextSwitcher, Gallery, ImageSwitcher,GridView, ListView, ExpandableList 

 

介绍 

在 Android 中使用各种控件(View) 

TextSwitcher - 文字转换器控件(改变文字时增加一些动画效果) 

Gallery - 缩略图浏览器控件 

ImageSwitcher - 图片转换器控件(改变图片时增加一些动画效果) 

GridView - 网格控件 

ListView - 列表控件 

ExpandableList - 支持展开/收缩功能的列表控件

Java 代码 

1. 1TextSwitcherDemo    2.textswitcher.xml    

3.    

4.      代码    

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

6.      <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"  

7.      android:orientation="vertical"android:layout_width="fill_parent"  8.    android:layout_height="fill_parent">   

9.    

10.     <Buttonandroid:id="@+id/btnChange"android:layout_width="wrap_content"  11.        android:layout_height="wrap_content"android:text="改变文字" />   

12.    

13.               <!--   

14.               TextSwitcher -文字转换器控件(改变文字时增加一些动画效果)   

15.               -->   

16.               <TextSwitcherandroid:id="@+id/textSwitcher"  

17.               android:layout_width="fill_parent"android:layout_height="wrap_content" />   

18.    

19. </LinearLayout>   

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. 2GalleryDemo    81.gallery.xml   

82.    

83.   代码    

84.   <?xmlversion="1.0" encoding="utf-8"?>   

85.   <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"  

86.   android:orientation="vertical"android:layout_width="fill_parent"  87.     android:layout_height="fill_parent">   

88.    

89.                     <!--   

90.                     Gallery -缩略图浏览器控件   

91.                     spacing -缩略图列表中各个缩略图之间的间距   

92.                     -->   

93.                     <Galleryandroid:id="@+id/gallery"android:layout_width="fill_parent"  

94.                     android:layout_height="wrap_content"android:spacing="20px" />   

95.    

96. </LinearLayout>   

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.  3ImageSwitcherDemo   

185.  imageswitcher.xml    186.    

187.  代码    

188.  <?xmlversion="1.0" encoding="utf-8"?>   

189.  <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"  

190.  android:orientation="vertical"android:layout_width="fill_parent"  191.     android:layout_height="fill_parent">    192.    

193.       <Galleryandroid:id="@+id/gallery"android:layout_width="fill_parent"  

194.       android:layout_height="wrap_content"android:spacing="20px" />   195.   

196.             <!--   

197.             ImageSwitcher -图片转换器控件(改变图片时增加一些动画效果)   

198.             -->   

199.             <ImageSwitcherandroid:id="@+id/imageSwitcher"  

200.             android:layout_width="fill_parent"android:layout_height="wrap_content" />    201.  

202.</LinearLayout>    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.  4GridViewDemo   

315.  gridview.xml    316.    

317.  代码    

318.  <?xmlversion="1.0" encoding="utf-8"?>    319.    

320.             <!--   

321.             GridView -网格控件   

322.             numColumns="auto_fit" -列数自适应   

323.             stretchMode -缩放模式(stretchMode="columnWidth"-缩放与列宽大小同步)   

324.             -->   

325.             <GridViewxmlns:android="http://schemas.android.com/apk/res/android"  

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. </GridView>   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. 5ListViewDemo    410.main_list_adapter.xml    411.    

412.       代码    

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

414.       <!--   

415.       自定义列表适配器的 layout   

416.       -->   

417.       <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"  

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

419.       android:layout_height="fill_parent">    420.      

421.             <TextViewandroid:id="@+id/text" android:layout_width="wrap_content"  

422.             android:layout_height="wrap_content"android:textSize="16sp">   

423.             </TextView>   

424.             425. </LinearLayout>    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<String> mData;    447.    

448.             public MainListAdapter(Contextcontext, List<String> data) {   

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<String> mData;    507.       

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<String>adapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, mData);   

522.             

523.         this.setListAdapter(adapter);    524.     }   525.    

526.             // ListView的数据源   

527.             private List<String>getData()    {   

528.             List<String> items = newArrayList<String>();   

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.  6ExpandableListDemo   

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中游戏开发的误区,不要老想着用Layoutview 去实现,不要将某个游戏中的对象做成一个组件来处理。应该尽量想着在Canvas(画布)中画出游戏戏中的背景、人物、动画等...SurfaceView提供直接访问一个可画图的界面,可以控制在界面顶部的子视图层。SurfaceView是提供给需要直接画像素而不是使用窗体部件的应用使用的。Android图形系统中一个重要的概念和线索是surface

View 及其子类(如 TextView, Button)要画在 surface 上。每个surface创建一个 Canvas 对象(但属性时常改变),用来管理 viewsurface上的绘图操作,如画点画线。还要注意的是,使用它的时候,一般都是出现在最顶层的: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 去掉 

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

当然你的让你的程序被引导启动 

 

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. <selectorxmlns:android="http://schemas.android.com/apk/res/android">   

2.    

3.            <itemandroid:state_pressed="true"android:drawable="@drawable/arrow_pressed" /

>   

4.            <itemandroid:drawable="@drawable/arrow_normal" />   

5.            <itemandroid:state_checked="true"android:drawable="@drawable/arrow_pressed" /

>   

6.            </selector>   

 

 实现如下,注意其中的android:src="@drawable/imageselector"

 

Xml 代码 

1.            <ImageViewandroid:layout_width="wrap_content"  

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: 

 

<intent-filterpriority="1">

<actionname="android.intent.action.MAIN"></action>

<categoryname="android.intent.category.HOME"></category>

<categoryname="android.intent.category.DEFAULT"></category><categoryname="android.intent.category.MONKEY"></category>

</intent-filter> 

 

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代码如下: 

<ScrollViewxmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content"> 

 

    <LinearLayout      android:orientation="vertical"         android:layout_width="fill_parent"         android:layout_height="wrap_content"> 

    

<ImageView android:layout_width="fill_parent"  android:layout_height="50dip"  android:src="@drawable/shape_1"/> 

 

<ImageView  android:layout_width="fill_parent"  android:layout_height="50dip"  android:src="@drawable/line"/> 

 

<ImageView android:layout_width="fill_parent"  android:layout_height="50dip"  android:src="@drawable/shape_2"/> 

 

<ImageView  android:layout_width="fill_parent" android:layout_height="wrap_content"  android:src="@drawable/line"/>  <ImageView android:layout_width="fill_parent"  android:layout_height="50dip"  android:src="@drawable/shape_3"/> 

 

<ImageView android:layout_width="fill_parent"  android:layout_height="20dip"  android:src="@drawable/line"/> 

 

<ImageView android:layout_width="fill_parent"  android:layout_height="50dip"  android:src="@drawable/shape_4"/> 

 

<ImageView android:layout_width="fill_parent"  android:layout_height="wrap_content"  android:src="@drawable/line"/> 

 

<ImageView android:layout_width="fill_parent"  android:layout_height="50dip" 

 

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

 

</LinearLayout> 

</ScrollView> 

shape_5 的代码: 

<shape    xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle"> 

    <gradientandroid:startColor="#FFFF0000"android:endColor="#80FF00FF"             android:angle="270"/> 

    <padding android:left="50dp"android:top="20dp"              android:right="7dp"android:bottom="7dp" /> 

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

    

</shape> 

gradient  产生颜色渐变 android:angle从哪个角度开始变貌似只有90 的整数倍可以 android:shape="rectangle"默认的也是长方形 

 

<shapexmlns:android="http://schemas.android.com/apk/res/android"android:shape="oval"> 

    <solidandroid:color="#ff4100ff"/> 

    <stroke android:width="2dp"android:color="#ee31ff5e"             android:dashWidth="3dp" android:dashGap="2dp" />      <padding android:left="7dp"android:top="7dp"              android:right="7dp"android:bottom="7dp" /> 

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

</shape> 

 

#ff4100ff 蓝色#ff4100ff绿色 

     <solidandroid:color="#ff4100ff"/>实心的填充里面 

    <stroke 描边采用那样的方式将外形轮廓线画出来 

 

android:dashWidth="3dp"android:dashGap="2dp"默认值为

 

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: 674023920@qq.com  

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.            <?xml version="1.0"encoding="utf-8"?>   

2.            <animation-list   

3.            xmlns:android="http://schemas.android.com/apk/res/android"  

4.            android:oneshot="false">   

5.            <itemandroid:drawable="@drawable/a1" android:duration="100"/>   

6.            <itemandroid:drawable="@drawable/a2" android:duration="100"/>   

7.            <itemandroid:drawable="@drawable/a3" android:duration="100"/>   

8.            <itemandroid:drawable="@drawable/a4" android:duration="100"/>   

9.            <item android:drawable="@drawable/a5"android:duration="100" />   

10.         <itemandroid:drawable="@drawable/a6" android:duration="100"/>   

11.         <itemandroid:drawable="@drawable/a7" android:duration="100"/>   

12.         <itemandroid:drawable="@drawable/a8" android:duration="100"/>   

13.         <item android:drawable="@drawable/a9"android:duration="100" />   

14.         <itemandroid:drawable="@drawable/a10" android:duration="100"/>   

15.         <itemandroid:drawable="@drawable/a11" android:duration="100"/>   

16.         <itemandroid:drawable="@drawable/a12" android:duration="100"/>   

17.         <itemandroid:drawable="@drawable/a13" android:duration="100"/>   

18.         <itemandroid:drawable="@drawable/a14" android:duration="100"/>   

19.         <itemandroid:drawable="@drawable/a15" android:duration="100"/>   

20.         </animation-list>  

 

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: 674023920@qq.com  

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.                            @Override  

77.                            public View makeView() {   

78.                            Log.i("TAG","makeView()");   

79.                            return new ImageView(this);   

80.                            }   

81.                            }  

android图形图像

文章分类:移动开发 

 一、 android.graphics.Matrix   有关图形的变换、缩放等相关操作常用的方法有:    void reset() //重置一个matrix对象。 

 void  set(Matrix src) //复制一个源矩阵,和本类的构造方法Matrix(Matrix src) 一样    boolean isIdentity() //返回这个矩阵是否定义(已经有意义)    voidsetRotate(float degrees) //指定一个角度以0,0为坐标进行旋转 

 

  void setRotate(float degrees, float px, float py)  //指定一个角度以px,py为坐标进行旋转 

 

  void setScale(float sx, float sy)  // 缩放 

 

  void setScale(float sx, float sy, float px, float py)  //以坐标px,py进行缩放 

 

  void setTranslate(float dx, float dy) //平移 void setSkew(float kx, float ky, float px, float py) //以坐标px,py进行倾斜 void setSkew (float kx,float ky) //倾斜   二、android.graphics.NinePatch 

 NinePatch Android平台特有的一种非矢量图形自然拉伸处理方法,可以帮助常规的图形在拉伸时不会缩放,实例中Android开发网提示大家对于Toast 的显示就是该原理,同时 SDK 中提供了一个工具名为 Draw 9-Patch,有关该工具的使用方法可以参考我们经发布的 Draw

9-Patch 使用方法介绍一文。由于该类提供了高质量支持透明的缩放方式,所以图形格式为

PNG,文件命名方式为.9.png的后缀比如android123.9.png 

  三、android.graphics.Paint 

 Paint 类我们可以理解为画笔、画刷的属性定义,本类常用的方法如下:    void reset()  //重置 

 void  setARGB(int a, int r, int g,int b) void  setColor(int color) 均为设置 Paint 对象的颜色  void  setAntiAlias(booleanaa)  //是否抗锯齿,需要配合void setFlags(Paint.ANTI_ALIAS_FLAG)来帮助消除锯齿使其边缘更平滑。 

 

Shader  setShader(Shader shader) //设置阴影,Shader类是一个矩阵对象,如果为NULL将清除阴影。 

void  setStyle(Paint.Style style)  //设置样式,一般为 FILL填充,或者STROKE 凹陷效果。  void setTextSize(float textSize)  //设置字体大小  void setTextAlign(Paint.Align align) //文本对齐方式 

Typeface  setTypeface(Typeface typeface)  //设置字体,通过Typeface可以加载 Android 内部

的字体,一般为宋体对于中文,部分 ROM 可以自己添加比如雅黑等等 

void  setUnderlineText(boolean underlineText) //是否设置下划线,需要撇和voidsetFlags (Paint.UNDERLINE_TEXT_FLAG)方法。 

四、android.graphics.Rect 

  Rect 我们可以理解为矩形区域,类似的还有 Point一个点,Rect类除了表示一个矩形区域位置描述外,android123提示主要可以帮助我们计算图形之间是否碰撞(包含)关系,对于Android游戏开发比较有用,其主要的成员 contains包含了三种重载方法,来判断包含关系 boolean contains(intleft, int top, int right, int bottom) boolean  contains(int x, inty)  boolean  contains(Rect r)  五、android.graphics.Region 

Region Android 平台中表示一个区域和 Rect不同的是,它表示的是一个不规则的样子,可以是椭圆、多边形等等,而Rect仅仅是矩形。同样Region boolean  contains(int x, int y) 

员可以判断一个点是否在该区域内 

六、android.graphics.Typeface 

 Typeface 类是帮助描述一个字体对象,在TextView中通过使用setTypeface 方法来制定一个输出文本的字体,其直接构造调用成员create方法可以直接指定一个字体名称和样式,比如    static Typeface  create(Typeface family, int style)    static Typeface  create(String familyName, int style)   同时使用isBold isItalic 方法可以判断出是否包含粗体或斜体的字型。    final boolean  isBold()   final boolean  isItalic() 

 该类的创建方法还有从apk的资源或从一个具体的文件路径,其具体方法为 

  static Typeface  createFromAsset(AssetManager mgr, Stringpath)    static Typeface  createFromFile(File path)    static Typeface  createFromFile(String path) 

Android ImageSwitcher和Gallery综合使用

文章分类:移动开发 

一个简易的相册

功能描述: 点击按钮进入下一屏,在屏幕上面展示一个大图,在屏幕的下面是一组可以滚动的图片,点击滚动的图片可以显示在上面的控件中。

效果图如下:

 

 

 

  

 

开发环境:eclipse3.4.2  AndroidSDK2.0 ADT0.9.7

代码:

1.MainActivity 单击按钮时,跳转到ImageShowActivity 

Java代码 

1. packagecom.small.photos;   

2.    

3.      import com.small.photos.R;   

4.      import android.widget.*;   

5.      import android.app.Activity;   

6.      import android.content.Intent;   

7.      import android.os.Bundle;   

8.      import android.view.View;   

9.      import android.view.View.OnClickListener;   

10.    

11. publicclass MainActivity extends Activity {   

12.    

13.     OnClickListener listener0 = null;    14.     Button button0;   

15.    

16.         @Override  

17.         public void onCreate(BundlesavedInstanceState) {   

18.         super.onCreate(savedInstanceState);    19.        setContentView(R.layout.main);   

20.    

21.                                        //单击按钮跳转到ImageShowActivity   

22.                                        listener0 = new OnClickListener(){   

23.                                        public void onClick(View v) {   

24.                                        Intent intent = newIntent(MainActivity.this,   

25.                                        ImageShowActivity.class);   

26.                                        startActivity(intent);   

27.                                        }   

28.                                        };   

29.    

30.               button0 = (Button)findViewById(R.id.image_show_button);   

31.               button0.setOnClickListener(listener0);    32.    }   

33.    

34. }  

 2. main.xml 定义入口按钮

Java 代码 

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

2.                         <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"  

3.                         android:orientation="vertical"  

4.                         android:layout_width="fill_parent"  

5.                         android:layout_height="fill_parent"  

6.                         >   

7.                         <Buttonandroid:id="@+id/image_show_button"     

8.                         android:text="ImageSwitcherGallery"     

9.                         android:layout_width="wrap_content"     

10.                     android:layout_height="wrap_content">     

11.                     </Button>     

12.                     </LinearLayout>  

 3.image_show.xml  

    ImageSwitcher是用来图片显示那块区域的控件  Gallery 是来控制底下那个图标列表索引用的

Java 代码 

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

2.           <RelativeLayout   

3.           xmlns:android="http://schemas.android.com/apk/res/android"  

4.           android:layout_width="fill_parent"   5.   android:layout_height="fill_parent">   

6.       

7.              <ImageSwitcherandroid:id="@+id/ImageSwitcher01"  

8.              android:layout_height="fill_parent"  

9.              android:layout_width="fill_parent"  

10.          android:layout_alignParentTop="true"  

11.          android:layout_alignParentLeft="true">   

12.          </ImageSwitcher>   

13.         

14.         

15.          <Gallery    

16.          android:id="@+id/gallery"  

17.          android:background="#55000000"  

18.          android:layout_width="fill_parent"  

19.          android:layout_height="60dp"  

20.          android:layout_alignParentBottom="true"  

21.          android:layout_alignParentLeft="true"     

22.          android:gravity="center_vertical"   23.     android:spacing="16dp"/>   

24.    

25. </RelativeLayout>  

 4.ImageShowActivity 

 R.drawable.sample_thumb_0 为图片的标识图片放在res/drawable/目录下  图片名称为sample_thumb_0.gif

Java 代码  

1. packagecom.small.photos;   

2.    

3.      import android.app.Activity;    

4.      importandroid.content.Context;   

5.      import android.os.Bundle;   

6.      import android.view.View;   

7.      import android.view.ViewGroup;   

8.      import android.view.Window;   

9.      importandroid.view.animation.AnimationUtils;   

10.   importandroid.widget.AdapterView;   

11.   importandroid.widget.BaseAdapter;   

12.   importandroid.widget.Gallery;   

13.   importandroid.widget.ImageSwitcher;   

14.   importandroid.widget.ImageView;   

15.   importandroid.widget.AdapterView.OnItemSelectedListener;   

16.   importandroid.widget.RelativeLayout.LayoutParams;   

17.   importandroid.widget.ViewSwitcher.ViewFactory;   

18.    

19.                     public class ImageShowActivityextends Activity implements ViewFactory,   

20.                     OnItemSelectedListener {   

21.                     /** Called when the activity isfirst created. */  

22.                     ImageSwitcher mSwitcher;    

23.                     private Integer[] mThumbIds = {R.drawable.sample_thumb_0,   

24.                     R.drawable.sample_thumb_1,R.drawable.sample_0, R.drawable.sample_1 };   

25.    

26.                     private Integer[] mImageIds = {R.drawable.sample_thumb_0,   

27.                     R.drawable.sample_thumb_1, R.drawable.sample_0,R.drawable.sample_1 };   

28.    

29.               @Override  

30.               public void onCreate(BundlesavedInstanceState) {   

31.               super.onCreate(savedInstanceState);   

32.               requestWindowFeature(Window.FEATURE_NO_TITLE);   

33.    

34.         setContentView(R.layout.image_show);    35.         setTitle("ImageShowActivity");   

36.    

37.                            mSwitcher = (ImageSwitcher)findViewById(R.id.ImageSwitcher01);   

38.                            //系统的anim 中的 fade_in.xml   

39.                            mSwitcher.setFactory(this);   

40.                            mSwitcher.setInAnimation(AnimationUtils.loadAnimation(this,   

41.                            android.R.anim.fade_in));   

42.                            mSwitcher.setOutAnimation(AnimationUtils.loadAnimation(this,   

43.                            android.R.anim.fade_out));   

44. 

45.               Gallery g = (Gallery)findViewById(R.id.gallery);   

46.               //为缩略图浏览器指定一个适配器   

47.               g.setAdapter(newImageAdapter(this));   

48.               //响应在缩略图列表上选中某个缩略图后的事件   

49.               g.setOnItemSelectedListener(this);   

50.    

51.     }   

52.    

53.               @SuppressWarnings("unchecked")   

54.               public voidonItemSelected(AdapterView parent, View v, int position, long id) {    

55.               mSwitcher.setImageResource(mImageIds[position]);   

56.               }   

57.    

58.         @SuppressWarnings("unchecked")   

59.         public voidonNothingSelected(AdapterView parent) {   

60.         }   

61.    

62.                            @Override  

63.                            public View makeView() {   

64.                            ImageView i = newImageView(this);   

65.                            i.setBackgroundColor(0xFF000000);   

66.                            i.setScaleType(ImageView.ScaleType.FIT_CENTER);   

67.                            i.setLayoutParams(newImageSwitcher.LayoutParams(   

68.                            LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));   

69.                            return i;    70.    }   

71.    

72.     public class ImageAdapter extendsBaseAdapter {    73.         private Context mContext;   

74.    

75.                     public ImageAdapter(Context c){   

76.                     mContext = c;   

77.                     }   

78.    

79.                     public int getCount() {   

80.                     return mThumbIds.length;   

81.                     }   

82.    

83.                     public Object getItem(int position){   

84.                     return position;   

85.                     }   

86.    

87.               public long getItemId(int position){   

88.               return position;    89.       }   

90.             

91.               //getView方法动态生成一个ImageView,然后利用setLayoutParamssetImageResource   

92.               //setBackgroundResource分别设定图片大小、图片源文件和图片背景。当图片被显示到当前   

93.               //屏幕的时候,这个函数就会被自动回调来提供要显示的ImageView   

94.               public View getView(int position,View convertView, ViewGroup parent) {   95.            ImageView i = newImageView(mContext);   

96.    

97.                                      i.setImageResource(mThumbIds[position]);   

98.                                      i.setAdjustViewBounds(true);   

99.                                      i.setLayoutParams(newGallery.LayoutParams(   

100.                                  LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));   

101.                                  i.setBackgroundResource(R.drawable.picture_frame);   

102.                                  return i;   

103.                                  }   104.   105.    }   106.    

107. }  

 5.AndroidManifest.xml  标识MainActivity为一个程序的开始

Java 代码 

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

2.                                  <manifestxmlns:android="http://schemas.android.com/apk/res/android"  

3.                                  package="com.small.photos"  

4.                                  android:versionCode="1"  

5.                                  android:versionName="1.0">   

6.                                  <applicationandroid:label="@string/app_name">   

7.                                  <activityandroid:name=".ImageShowActivity"  

8.                                  android:label="@string/app_name">   

9.                 

10.         </activity>   

11.    

12.         <activityandroid:name="MainActivity"><intent-filter><actionandroid:name="android.

intent.action.MAIN"></action>   

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

14.         </intent-filter>   

15.         </activity>   

16.         </application>   

17. 

18. 

19.</manifest>   

 

 基本上就是这些了,然后启动吧!

opengl es

文章分类:移动开发 

雾效果在某种场合很重要,想象你正在游戏中穿过城市的边缘,显然你并没有渲染场景中很远距的物体,因为代价很大。当然你不愿意突然出现的场景或物体。

雾可以解决这个问题。

 

雾同样可以使场景更加逼真,例如一个山谷中的场景,往往会云气缭绕。

 

这一章依据第17章的代码。

 

程序代码:

 

雾可以指定一个颜色,我们创建一个灰色的颜色。

 float fogColor[] = { 0.5f, 0.5f, 0.5f, 1.0f };

 

雾又三种模式,下面列表给出:

 

模式       描述

GL_EXP     雾的最简单的一种模式. 物体并没有真正的存在雾中,仅仅是一种阴霾的效果。

GL_EXP2     比第一种模式高级. 比第一种逼真些,但远近距离效果不够真实。

GL_LINEAR     最逼真的一种模式. 模拟现实中的场景。

 

由上可以看出,GL_LINEAR是最好的一种效果,但并不意味着你要使用它。显然

越好的效果,性能的损失就越大,根据你的需要选择哪种模式。

 

创建一个数组,保存雾的所有模式,用于即使切换。fogType指明当前使用的哪种模式。

 float fogTypes[] = { GL_EXP, GL_EXP2,GL_LINEAR }; int fogType = 0; 设置雾的效果,需要使用glFogf或glFogfv函数。glFogf函数有两个参数,第一个是指定要修改的雾的属性标志,第二个是修改的值。

 

下表描述了雾的各种属性。

标记                    浮点值                     描述

GL_FOG_MODE     GL_EXP, GL_EXP2 or GL_LINEAR     雾的效果模式. GL_FOG_DENSITY     > 0.0f (default 1.0f)         雾的密度,值越大密度越高。

GL_FOG_START     Any float (default 0.0f)         指定雾的近面距离,在此距离内不渲染.

GL_FOG_END     Any float (default 1.0f)           指定雾的远面距离,超过此距离不渲染.

 

了解了属性参数,下面设置雾的属性,初始化雾的模式为GL_EXP.

 

bool init() {

    .

    .

    glFogf(GL_FOG_MODE, GL_EXP);

 

    //指定雾的颜色,灰色

    glFogfv(GL_FOG_COLOR, fogColor);

 

    //雾的密度

    glFogf(GL_FOG_DENSITY, 0.35f);

    

    //系统如何计算雾气,这里设置不关心     glHint(GL_FOG_HINT, GL_DONT_CARE);

 

    glFogf(GL_FOG_START, 1.0f);     glFogf(GL_FOG_END, 5.0f);

 

    glEnable(GL_FOG);     .

    .

}

 

void display() {

    .

    .

    glTranslatef(0.0f, 0.0f, -5.0f);

    .

    .

}

 

menu函数中动态改变雾的模式。

     case 3 :         ++fogType %= 3;

        glFogf(GL_FOG_MODE, fogTypes[fogType]);

        break;

 

至此,雾已经加入到你的场景了,观察效果吧。

 

 

  Opengl归纳

文章分类:移动开发 

1. 

Java 代码 

1. //fog  opengles   

2.                    

3.                               gl.glFogfv(GL10.GL_FOG_COLOR,fogColorBfr);   

4.                               gl.glFogf(GL10.GL_FOG_DENSITY,0.35f);   

5.                               gl.glHint(GL10.GL_FOG_HINT,GL10.GL_DONT_CARE);   

6.                               gl.glFogf(GL10.GL_FOG_START,2.0f);   

7.                               gl.glFogf(GL10.GL_FOG_END,6.0f);   

8.                               gl.glEnable(GL10.GL_FOG);  

 

Java 代码 

1.      glClearColor(0.5f,0.5f,0.5f,1.0f);   //设置背景的颜色为雾气的颜色   

2.      glFogi(GL_FOG_MODE,fogMode[fogfilter]);  //设置雾气的模式   

3.      glFogfv(GL_FOG_COLOR,fogColor);   //设置雾的颜色   

4.      glFogf(GL_FOG_DENSITY,0.35f);   //设置雾的密度   

5.      glHint(GL_FOG_HINT,GL_DONT_CARE);   //设置系统如何计算雾气   

6.      glFogf(GL_FOG_START,1.0f);    //雾气的开始位置   

7.      glFogf(GL_FOG_END,5.0f);    //雾气的结束位置   

8.      glEnable(GL_FOG);     //使用雾气  

 

 

 

2.混合 Blend 

Java 代码 

1.      gl.glBlendFunc(GL10.GL_SRC_ALPHA,GL10.GL_ONE);   

2.      gl.glEnable(GL10.GL_BLEND);  

 

 

3.纹理 

Java 代码 

1.                              // create textures   

2.                              gl.glEnable(GL10.GL_TEXTURE_2D);   

3.                              texturesBuffer =IntBuffer.allocate(3);   

4.                              gl.glGenTextures(3, texturesBuffer);   

5.                    

6.                              // load bitmap   

7.                              Bitmap texture =Utils.getTextureFromBitmapResource(context, R.drawable.glas s);   

8.                    

9.                              // setup texture 0   

10.                          gl.glBindTexture(GL10.GL_TEXTURE_2D,texturesBuffer.get(0));   

11.                          gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER, GL1

0.GL_NEAREST);   

12.                          gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER, GL1 0.GL_NEAREST);   

13.                          gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_S, GL10.G L_CLAMP_TO_EDGE);   

14.                          gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_T, GL10.G

L_CLAMP_TO_EDGE);   

15.                          GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0, texture,0);   

16.                    

17.                          // setup texture 1   

18.                          gl.glBindTexture(GL10.GL_TEXTURE_2D,texturesBuffer.get(1));   

19.                          gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER, GL1

0.GL_LINEAR);   

20.                          gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER, GL1 0.GL_LINEAR);   

21.                          gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_S, GL10.G L_CLAMP_TO_EDGE);   

22.                          gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_T, GL10.G L_CLAMP_TO_EDGE);   

23.                          GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0, texture,0);   

24.                    

25.                          // setup texture 2   

26.                          gl.glBindTexture(GL10.GL_TEXTURE_2D,texturesBuffer.get(2));   

27.                          gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER, GL1

0.GL_LINEAR);   

28.                          gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER, GL1 0.GL_LINEAR_MIPMAP_NEAREST);   

29.                          gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_S, GL10.G L_CLAMP_TO_EDGE);   

30.                          gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_T, GL10.G L_CLAMP_TO_EDGE);   

31.                          Utils.generateMipmapsForBoundTexture(texture);   

32.    

33.                          // free bitmap   

34.                          texture.recycle();  

定向光

文章分类:移动开发 

这一节我们使用定向光,涉及漫射光的高级应用和镜面光源。我们将展示镜面光的显示效果,使用红色的小球和照在小球上的光源。

 

程序代码:

 

第一步依然是定义属性值,这里我们要加上镜面光的属性值定义。 float lightAmbient[] = { 0.2f, 0.0f, 0.0f, 1.0f }; floatlightDiffuse[] = { 0.5f, 0.0f, 0.0f, 1.0f }; float lightSpecular[] = { 1.0f,1.0f, 1.0f, 1.0f };

 

同样,定义材质对镜面光的反射值

float matAmbient[] = { 1.0f,1.0f, 1.0f, 1.0f }; float matDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f }; floatmatSpecular[] = { 1.0f, 1.0f, 1.0f, 1.0f };

 

因为是定向光,所以我们需要知道光的位置和方向,下面代码就是定义位置和方向,

 

float lightPosition[] = { 2.0f,2.0f, 3.0f, 0.0f }; float lightDirection[] = { -2.0f, -2.0f, -3.0f };

 

下面启用第一个光源

void init() {

    glEnable(GL_LIGHTING);     glEnable(GL_LIGHT0);

 

设置材质属性

    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT,matAmbient);     glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,matDiffuse);    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matSpecular);

 

另一个可以用glMaterialf 设置的属性是GL_SHININESS,它的值在0到128之间,它表明镜面光的焦距度,值越大镜面光焦距越多。

 

glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS, 20.0f);

 

下一步设置光属性

    glLightfv(GL_LIGHT0, GL_AMBIENT,lightAmbient);     glLightfv(GL_LIGHT0,GL_DIFFUSE, lightDiffuse);    glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpecular);

 

设置光源的位置和方向,使用glLightfv 函数,它的第二个参数可以指明设置的是位置还是方向。

 

    glLightfv(GL_LIGHT0, GL_POSITION,lightPosition);     glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION, lightDirection);

 

另一个有用的标记是GL_SPOT_CUTOFF,它指定光锥体的大小,想象一个火把远离你时所产生的火光锥体,1.2将产生2.4度大的光锥体,如果设置为180度,则发射的光会照到各个角落。

 

glLightf(GL_LIGHT0,GL_SPOT_CUTOFF, 1.2f);

 

我们要讨论的下一个标记是GL_SPOT_EXPONENT,它控制圆锥体内光强分布的指数因子,值在0到128之间,值越大,锥体轴线部分的光越强。

 

glLightf(GL_LIGHT0,GL_SPOT_EXPONENT, 20.0f);

 

glLightf 函数还有三个标记可以设置,是用来控制衰减方式的,分别是:

GL_CONSTANT_ATTENUATION(1),GL_LINEAR_ATTENUATION(0),

GL_QUADRATIC_ATTENUATION。即常数衰减,线性衰减和二次衰减。括号中的值是它的默认值。

衰减指的是光的强度逐渐减弱,就像你离火光越来越远一样。设置这些属性会导致程序大幅减慢。

 

display 函数余下部分不变。

 

    glEnable(GL_DEPTH_TEST);     glDepthFunc(GL_LEQUAL);

 

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);     glClearDepthf(1.0f);

 

    glEnable(GL_CULL_FACE);     glShadeModel(GL_SMOOTH);

}

 

我们简单的使用glutSolidSphere /ugSolidSpheref 来创建求面体,这个球面体由水平24栈和垂直24片组成,这样可以更多的体现光照细节。

 

也许你奇怪我们为什么没有指定球面的法线,令人高兴的是UG / GLUT|ES库中创建的形状物体,法线是自动生成的,均由库自动计算,这大大简化了我们的任务。

void display()

{

   glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);   glLoadIdentity();

 

   gluLookAtf(

        0.0f, 0.0f, 4.0f,

        0.0f, 0.0f, 0.0f,

        0.0f, 1.0f, 0.0f); 

   glRotatef(xrot, 1.0f, 0.0f, 0.0f);    glRotatef(yrot, 0.0f, 1.0f, 0.0f);

 

   ugSolidSpheref(1.0f, 24, 24);

 

  glFlush();   glutSwapBuffers();

}

 

运行程序,会呈现一个红色的球,注意镜面光源在球的右上方,那么现在你可以把定向光加入自己的程序了。

 

opengl es灯光

文章分类:移动开发 

这一章将在你的程序中加入灯光,使场景看起来和真实场景一样。

 

灯光

 

opengl中灯光分为好几种,都可以加入到你的场景中。

 

Ambiend Light 环境光

环境光没有确切的来源方向,当环境光照射到物体时,光被反射到各个方向。

 

Diffuse Light 漫射光

漫射光不同于环境光,它来自某个方向,但和环境光一样,照射到物体时,会被反射到各个方向。

 

Specular Light 镜面光

镜面光和漫射光一样是有方向的,但它反射方向是一定的,而不像漫射光一样反射到各个方向。所以当镜面光照射到物体时,你会看到物体表面被照射的亮点。

 

Emissive Light 发射光

它来自于某一物体,该物体散发出大量的光,但不会被任何物体面反射。

 

为了更好的理解这几种光,我从网络上摘抄了一段定义:

*       环境光——经过多次反射而来的光称为环境光,无法确定其最初的方向,但当特定的光源关闭后,它们将消失.

*       全局环境光——它们并非来自特定的光源,这些光经过了多次散射,已经无法确定其光源位于何处.

*       散射光——来自同一方向,照射到物体表面后,将沿各个方向均匀反射,因此,无论从哪个方向观察,表面的亮度都相同.

*       镜面反射光——来自特定方向,也被反射到特定方向.镜面反射度与之相关.

*       材质发射光——用于模拟发光物体.在OpenGL光照模型中,表面的发射光增加了物体的亮度,它不受光源的影响,另外,发射光不会给整个场景中增加光线.

 

材质

 

你不光可以设置光的属性,而且还可以指定不同的面对光照作出的反应,这就要指定材质属性。

这就指定了一个面对光源反射多少。

 

法线

 

法线是一个向量垂直于(90度)某一特定面,就称这个向量是某个面的法线。法线可以用于光的计算。如果你想让画出的物体对光源产生影响,那么必须指定物体每个面的法线。下面将会说明。

 

另一个需要注意的一点是,法线要单位化,我们不会深入数学计算,这不是我们这章的目的。如果需要会在将来某章中讲解。简明的说,一个向量的长度等于各个向量分量的平方和的平方根,再把每个向量的分量除以这个值。现在不需要过多担心这个。

 

程序代码:

 

下面定义两个颜色数组,一个用于环境光,一个用于漫射光,它们是光源的颜色值。

float lightAmbient[] = { 0.2f,0.3f, 0.6f, 1.0f }; float lightDiffuse[] = { 0.2f, 0.3f, 0.6f, 1.0f };

 

下面创建一个材质属性数组,分别用于环境光和漫射光。

用材质属性值乘以光源值得出面的反射颜色值,下面的值将会导致面反射的光失

去接收光的百分之四十。每个值表示特定颜色被反射的数量。

float matAmbient[] = { 0.6f,0.6f, 0.6f, 1.0f }; float matDiffuse[] = { 0.6f, 0.6f, 0.6f, 1.0f };

 void init()

{

首先先启用光源,这样光才会在场景中起作用。

glEnable(GL_LIGHTING); opengl最多允许8个光源,要使用某个光源,需要使用glEnable打开它,光源的编号是GL_LIGHTX,X的值是0---7。

指定材质属性,可以使用glMaterialfv和glMaterialf ,glMaterialfv接受向量数组,而glMaterialf只接受一个向量。第一个参数指定那个面被更新,在 opengl es中只可以使用GL_FRONT_AND_BACK,其他参数不起作用。之所以存在这个参数,是因为opengl可以设置多个参数。

第二个参数指定光源的类型,GL_AMBIENT,GL_DIFFUSE, GL_SPECULAR, GL_EMISSION 和GL_AMBIENT_AND_DIFFUSE.  最后一个参数指定一个数组或单个值,取决于你使用的哪个函数。

 

下一行设置面的材质属性:

    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT,matAmbient);    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiffuse);

 

灯光的设置和材质的设置相同,使用glLightfv或glLightf函数:

    glLightfv(GL_LIGHT0, GL_AMBIENT,lightAmbient);     glLightfv(GL_LIGHT0,GL_DIFFUSE, lightDiffuse);

 

init函数没有发生改变:    

    glEnable(GL_DEPTH_TEST);     glDepthFunc(GL_LEQUAL);

 

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);     glClearDepthf(1.0f);

 

    glVertexPointer(3, GL_FLOAT, 0, box);     glEnableClientState(GL_VERTEX_ARRAY);

 

    glEnable(GL_CULL_FACE);     glShadeModel(GL_SMOOTH);

}

 

display函数的开头部分没有发生改变:

void display()

{

   glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);    glLoadIdentity();

 

   gluLookAtf(

        0.0f, 0.0f, 3.0f,

        0.0f, 0.0f, 0.0f,

        0.0f, 1.0f, 0.0f);

 

  glRotatef(xrot, 1.0f, 0.0f, 0.0f);    glRotatef(yrot, 0.0f, 1.0f, 0.0f);

 

前面我们讨论了法线,法线是垂直于面的,所以前平面的法线是(0, 0,1),后平面的法线是(0, 0, -1),两个法线的长度为1,所以不用再单位化。法线由glNormal3f 函数指定,并在渲染时调用。这个函数由3个float类型的数据组成单位化的向量。

   // FRONT AND BACK

   glColor4f(1.0f, 0.0f, 0.0f, 1.0f);    glNormal3f(0.0f, 0.0f, 1.0f);    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);    glNormal3f(0.0f, 0.0f, -1.0f);

   glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);

       其他页面设置也同上,

 

   // LEFT AND RIGHT

   glColor4f(0.0f, 1.0f, 0.0f, 1.0f);    glNormal3f(-1.0f, 0.0f, 0.0f);    glDrawArrays(GL_TRIANGLE_STRIP, 8, 4);    glNormal3f(1.0f, 0.0f, 0.0f);    glDrawArrays(GL_TRIANGLE_STRIP, 12, 4);

 

   // TOP AND BOTTOM

   glColor4f(0.0f, 0.0f, 1.0f, 1.0f);    glNormal3f(0.0f, 1.0f, 0.0f);    glDrawArrays(GL_TRIANGLE_STRIP, 16, 4);    glNormal3f(0.0f, -1.0f, 0.0f);    glDrawArrays(GL_TRIANGLE_STRIP, 20, 4);

    glFlush();    glutSwapBuffers();

}

 

最后菜单增加一项彩色材质,这项选择打开或关闭色彩跟踪。色彩跟踪根据当前面的色彩反色不同色的光。

     case 2 : 

        if(glIsEnabled(GL_COLOR_MATERIAL))            glDisable(GL_COLOR_MATERIAL);

        else

            glEnable(GL_COLOR_MATERIAL);

        break; 下面两张图是程序的运行结果,分别是普通灯光和色彩追踪的效果。

   普通灯光         色彩跟踪

opengl es色彩混合

文章分类:移动开发 

色彩混合对于效果有很大作用,通过它,可以实现物体透明,例如玻璃、水、窗户等等。

 

alpha是混合的基础,前面说过,色彩是由RGBA表示的,A就代表alpha,我们可以简单理解为透明度。A值为0代表完全透明,1代表不透明,指定A的值0 到1之间可以调整色彩的透明度。

 

当使用混合时,始终要记住两个不同的颜色,一个是源色彩(用来参加运算),一

个是目标色彩(已经存在于缓冲区)。混合就是进行两个色彩的运算。

 

程序代码:

 

这章使用正交视图

 glOrthof(0.0f, 3.0f, 0.0f, 3.0f, -1.0f, 1.0f);然后重叠几个矩形放在屏幕上,顶点数组下面给出:

 

GLfloat rectangle[] = {

    -1.0f, -0.25f,

     1.0f, -0.25f,     -1.0f, 0.25f,

     1.0f, 0.25f

};

 

下面将显示色彩的不同混合方式,下面的变量用来控制混合方式。

 

int currBlend = 4;

 

init函数首先选择清除缓冲区的颜色,并且不使用深度值。

 

void init() {

    glClearColor(0.25f, 0.25f, 0.25f, 1.0f);

 

然后启用混合功能,传递GL_BLEND参数给glEnable函数。

 

glEnable(GL_BLEND);

 

glBlendFunc函数用于指定颜色如何混合,有两个参数,它们指定颜色运算方式,有下面几种方式:

 

GL_ZERO

GL_ONE

GL_SRC_COLOR

GL_ONE_MINUS_SRC_COLORGL_DST_COLOR

GL_ONE_MINUS_DST_COLORGL_SRC_ALPHA

GL_ONE_MINUS_SRC_ALPHAGL_DST_ALPHA

GL_ONE_MINUS_DST_ALPHA

 

第一个参数也可以指定为GL_SRC_ALPHA_SATURATE。

 

glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

 

下面的数组用于切换不同的混合操作。

 

GLenum blendSrc[] ={

    GL_ONE,

    GL_ONE,

    GL_ONE,

    GL_SRC_ALPHA,

    GL_SRC_ALPHA

};

 

GLenum blendDst[] = {

    GL_ZERO,

    GL_ONE,

    GL_ONE_MINUS_DST_ALPHA,

    GL_ONE,

    GL_ONE_MINUS_SRC_ALPHA

};

 

display函数放置4个矩形在屏幕上

 void display() {

    glClear(GL_COLOR_BUFFER_BIT);     glLoadIdentity();

 

    glVertexPointer(2, GL_FLOAT, 0, rectangle);

 

    glEnableClientState(GL_VERTEX_ARRAY);

     glPushMatrix();

        glTranslatef(1.5f, 2.0f, 0.0f);         glColor4f(1.0f, 0.0f, 0.0f,0.5f);        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);     glPopMatrix();

     glPushMatrix();

        glTranslatef(0.7f, 1.5f, 0.0f);         glRotatef(90.0f, 0.0f ,0.0f,1.0f);         glColor4f(0.0f, 1.0f,0.0f, 0.5f);        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);     glPopMatrix();

     glPushMatrix();

        glTranslatef(1.7f, 1.5f, 0.0f);         glRotatef(90.0f, 0.0f ,0.0f,1.0f);         glColor4f(0.0f, 0.0f,1.0f, 0.25f);        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);     glPopMatrix();

 

    glPushMatrix();

        glTranslatef(1.5f, 1.0f, 0.0f);         glColor4f(1.0f, 1.0f, 0.0f, 0.75f);         glDrawArrays(GL_TRIANGLE_STRIP, 0,4);     glPopMatrix();

     glFlush();     glutSwapBuffers();

}

 

menu函数中选择不同的混合处理。

     case 2 :

        ++currBlend %= 5;

        glBlendFunc(blendSrc[currBlend],blendDst[currBlend]);

        glutPostRedisplay();         break;

 

运行程序,你可以使用'b'键改变混合方式。

 

默认混合方式为( GL_ONE, GL_ZERO ),这种方式意味着目标色不起作用,仅仅用源色覆盖目标色,效果如下:

 

 

 

第二种方式为( GL_ONE, GL_ONE ),

 

 

第三种方式为(GL_ONE,GL_ONE_MINUS_DST_ALPHA)

 

 

第四种方式为(GL_SRC_ALPHA, GL_ONE)

 

 

 

(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)

 

 

opengl es灯光|Opengl-ES方法 

Android图片倒影

文章分类:移动开发 

public static Bitmap createReflectedImage(BitmaporiginalImage) {     // The gap we wantbetween the reflection and the original image    final int reflectionGap = 4;

 

    int width = originalImage.getWidth();     int height = originalImage.getHeight();

 

    // This will not scale but will flip on theY axis     Matrix matrix = newMatrix();      matrix.preScale(1, -1);

 

    // Create a Bitmap with the flip matrixapplied to it.

    // We only want the bottom half of theimage

    Bitmap reflectionImage =Bitmap.createBitmap(originalImage, 0,                 height / 2, width, height / 2,matrix, false);

 

   // Create a new bitmap with same width buttaller to fit reflection

   Bitmap bitmapWithReflection =Bitmap.createBitmap(width,

                (height + height / 2),Config.ARGB_8888); 

   // Create a new Canvas with the bitmapthat's big enough for

   // the image plus gap plus reflection

   Canvas canvas = newCanvas(bitmapWithReflection);

   // Draw in the original image

 canvas.drawBitmap(originalImage, 0, 0, null);

   // Draw in the gap

   Paint defaultPaint = new Paint();

   canvas.drawRect(0, height, width, height +reflectionGap,       defaultPaint);

   // Draw in the reflection

   canvas.drawBitmap(reflectionImage, 0, height+ reflectionGap, null);

 

 // Create a shader that is a linear gradient that covers the reflection

 Paint paint = new Paint();

 LinearGradient shader = new LinearGradient(0,               originalImage.getHeight(),0,          

bitmapWithReflection.getHeight()

       + reflectionGap, 0x70ffffff, 0x00ffffff,TileMode.CLAMP);

 // Set the paint to use this shader (linear gradient)   paint.setShader(shader);

  // Set theTransfer mode to be porter duff and destination in   paint.setXfermode(newPorterDuffXfermode(Mode.DST_IN));   //Draw a rectangle using the paint with our linear gradient   canvas.drawRect(0, height, width,bitmapWithReflection.getHeight()

+ reflectionGap, paint);

 

 return bitmapWithReflection;

}

画面

文章分类:移动开发 

Android系统开机动画包括两部分:开机显示的 ANDROID 文字; ANDROID发光动画。

这篇文章说的开机动画是第一种,下面开始正文!

1.    制作当前屏幕像素的图片(模拟器默认为320*480) 使用PS制作一张320*480的图片,保存时选“保存为 Web 所用格式”,然后在弹开的窗口上,“预设”项选择“PNG-24”,保存为android_logo.png 注:好像只支持png-24,其他格式生成的rle文件显示不正常,有兴趣大家可以再验证一下。

2.    将图片转换为raw格式

使用linux下的ImageMagick自带的convert命令,进行raw格式转换,命令为:   convert -depth 8 android_logo.pngrgb:android_logo.raw

注:ubuntu 10.04 默认已经安装ImgageMagick工具,如果当前系统没有安装,可以执行下面的命令安装:

 sudo apt-get install imagemagick

3.    将raw格式转化为rle文件

需要用到android编译后的rgb2565工具,在android/out/host/linux-x86/bin

目录下(android为当前源码所在目录),转换命令如下:

rgb2565 -rle < android_logo.raw> initlogo.rle

到目前为止,启动需要显示的图像已经做好了,就是initlogo.rle,注意文件

名必须是这个,如果想改文件名,需要修改android/system/core/init/init.h中的宏:

#define INIT_IMAGE_FILE"/initlogo.rle" 

=====================================================================

=======================

下面需要将initlogo.rle加入的android文件系统中

4.    找到ramdisk.img文件

(android/out/target/product/generic/ramdisk.img),将文件名改为ramdisk.img.gz,然后使用下面的命令解压:

gunzip ramdisk.img.gz

解压后得到ramdisk.img,可能有人要问,怎么文件名又改回去了?其实不然,使用file ramdisk.img查看一下就知道了:

解压前:ramdisk.img: gzip compresseddata, from Unix

解压后:ramdisk.img: ASCII cpio archive(SVR4 with no CRC) 跑题了,还是说正事儿。

5.    使用cpio提取文件:

新建一个temp目录:

mkdir temp cd temp

cpio -i -F ../ramdisk.img

6.    导出文件列表:

cpio -i -t -F ../ramdisk.img> list       

注:list是一个文本文件,里面存储了ramdisk.img的文件结构,我们需要在

这个文件中加入initlogo.rle这一行,修改后的文件如下: data default.propdev init init.goldfish.rc init.rc initlogo.rle proc

sbin sbin/adbd sys system

7.    生成ramdisk.img

cpio -o -H newc -O ramdisk.img< list 

注:根据list文件的描述,生成ramdisk.img文件

8.    用ramdisk.img覆盖sdk目录下的ramdisk.img(android-sdk-windows/platforms/android-2.1/images/ramdisk. img),最好先备份一下。

9.    启动模拟器,就可以看到我们自己做的的开机界面了。

/ 开机图片设置 的下载地址为:http://docs.google.com/leaf?id=0...

TIzOGQ5OWQ3&amp;hl=en

init 文件下载地址http://docs.google.com/leaf?id=0...

2RiYjZjNjM2&amp;hl=en

split_bootimg.pl 下载地址:

http://android-dls.com/files/linux/split_bootimg.zip

T卡文件下载地址:http://docs.google.com/leaf?id=0... GVjYzVhMjg4&amp;hl=en

 

开机图片设置 软件原理:

     根据android 系统 开机LOGO和开机动画的存放路径:/initlogo.rle 和 /data/local/bootanimation.zip 在init.rc 中建立两个链接:

/initlogo.rle->/data/data/com.android.e139.gallery/initlogo.rle 和

/data/local/bootanimation.zip

->/data/data/com.android.e139.gallery/bootanimation.zip  

来完成开机LOGO和开机动画的动态设定安装要求:

1.本apk文件只能安装在android2.1 或 2.0的操作系统 中

2.必须修改android 根目录下面的两个文件:init.rc 和 init 功能才能实现设置开机LOGO和开机动画的功能

 

修改init.rc 和 init 的方法:

1.修改 init.rc 和init文件需要修改手机中的 boot.img

导出方法:

cat /dev/mtd/mtd2 >/sdcard/root.img

然后

adb pull /sdcard/root.img ./

这样就把root.img拷贝到本地目录下了。

boot.img的组成结构是

+—————–+

| boot header | 1 page

+—————–+

| kernel | n pages

+—————–+

| ramdisk | m pages

+—————–+

| second stage | o pages

+—————–+

 

那我们要做的就是把这几个部分分别分离出来我们现在先进行镜像分离。用命令

./split_bootimg.pl boot.img

 

成功执行后,可以得到两个文件,一个是boot.img-kernel,另一个是 boot.img-ramdisk.gz。我们这里以修改ramdisk为例,所以将其解包

mkdir ramdisk cd ramdisk gzip-dc ../boot.img-ramdisk.gz | cpio -i cd ..

2.进入ramdisk 修改init.rc 在init.rc 中增加:

on logo-init

     mkdir /data 0775 system system

# We chown/chmod /data again sobecause mount is run as root + defaults

    mount yaffs2 mtd@userdata /data nosuid nodev     chown system system /data     #for other user can read this dir     chmod 0775 /data

    symlink/data/data/com.android.e139.gallery/initlogo.rle

/initlogo.rle

on early-boot

# copy file    

    symlink/data/data/com.android.e139.gallery/bootanimation.zip

/data/local/bootanimation.zip

    chmod 0666 /data/local/bootanimation.zip

再将已经下载的init文件覆盖到目录下面的init文件

3.生成新img 回到ramdisk的上一级目录后执行:

mkbootfs ./ramdisk | gzip > ramdisk-new.gzmkbootimg --cmdline 'no_console_suspend=1 console=null' --kernelboot.img-kernel --ramdisk ramdisk-new.gz -o boot-new.img 就会重新生成boot-new.img 3.刷入新img

生成了新的img后,我们如何在系统上应用我们的新boot.img呢?首先,把img 文件放到sdcard上去

adb push ./boot_new.img /sdcard

然后执行这两个操作

cat /dev/zero > /dev/mtd/mtd2flash_image boot /sdcard/mynewimage.img

执行第一个操作时,可能会提示你

write: No space left on device

这个信息没关系,不用管它。两个命令都执行后,最后adb shellreboot即可。如果重启顺利,那么恭喜你,你刷成功了.

 

安装步骤:

1.按上面的步骤修改手机中的init.rc和init文件

2.把下载的T卡文件放到T卡中 3.安装 开机图片设置.apk文件

修改boot.img的方法参考:

http://www.kunli.info/2009/09/14/how-to-modify-ramdisk-android/http://android-dls.com/wiki/index.php?title=HOWTO:_Unpack,_Edit,_and_Re-Pack_Boot_Images

 

3D桌面效果动画类

文章分类:移动开发 Java代码 

1.                  public class CubeAnimation extendsAnimation implements  

2.                  Animation.AnimationListener {   

3.                  public static final int FACE_LEFT =0;   

4.                  public static final int FACE_RIGHT=1;   

5.                  private int mInd;   

6.                  private float mFromDegrees;   

7.                  private float mToDegrees;   

8.                  private float mCenterX;   

9.                  private float mCenterY;   

10.               private int mHorizonType =1;   

11.               private float mHorizonValue =0.5F;    

12.               private Camera mCamera;    13.    private View mView;   

14.    

15.               public CubeAnimation(int ind){   

16.               this.mInd = ind;   

17.               this.mFromDegrees =0.0F;   

18.               this.mToDegrees =90.0F;    19.    }   

20.    

21.               public CubeAnimation(Contextcontext, AttributeSet attrs) {   

22.               super(context, attrs);   

23.               TypedArray a =context.obtainStyledAttributes(attrs,   24.                R.styleable.CubeAnimation);   

25.    

26.         this.mFromDegrees = 0.0F;    27.         this.mToDegrees = 90.0F;   

28.    

29.               Description d =Description.parseValue(a.peekValue(0));   

30.               this.mHorizonType = d.type;    31.        this.mHorizonValue = d.value;   

32.    

33.         this.mInd = a.getInt(1, 0);   

34.    

35.                     boolean t = a.getBoolean(2, true);   

36.                     if (!(t)) {   

37.                     this.mInd = (1 - this.mInd);   

38.                     this.mToDegrees =0.0F;   

39.                     this.mFromDegrees =90.0F;   

40.                     }   

41.                     a.recycle();    42.    }   

43.    

44.         public voidonAnimationStart(Animation anim) {   

45.         this.mView.setVisibility(View.VISIBLE);    46.    }   

47.    

48.               public voidonAnimationEnd(Animation anim) {   

49.               this.mView.setVisibility((this.mInd==0) ?0: 8);   

50.               this.mInd = (1 - this.mInd);   51.    }   

52.    

53.         public voidonAnimationRepeat(Animation anim) {   

54.         }   

55.    

56.                     public static voidstartCubeAnimation(Context context, int id, View view1,   

57.                     View view2) {   

58.                     XmlPullParser parser;   

59.                     try {   

60.                     parser =context.getResources().getAnimation(id);   61.            AttributeSet attrs =Xml.asAttributeSet(parser);   

62.    

63.                                               int type =parser.getEventType();   

64.                                               int depth = parser.getDepth();   

65.                                               while (true) {   

66.                                               while (true) {   

67.                                               if ((((type = parser.next()) ==3) && (parser.getDepth() <= depth))   

68.                                               || (type ==1))   

69.                                               break label172;   

70.                                               if (type ==2)   

71.                                               break;   

72.                                               }   

73.  

74.               String name =parser.getName();   

75.    

76.                                  if (name.equals("cube")){   

77.                                  CubeAnimation anim1 = newCubeAnimation(context, attrs);   

78.                                  anim1.mInd =1;   

79.                                  anim1.mView = view1;   

80.                                  anim1.setAnimationListener(anim1);   

81.                                  CubeAnimation anim2 = newCubeAnimation(context, attrs);   

82.                                  anim2.mInd =0;   

83.                                  anim2.mView = view2;   

84.                                  anim2.setAnimationListener(anim2);   

85.                                  view1.startAnimation(anim1);   

86.                                  label172: view2.startAnimation(anim2);   

87.                                  }   

88.                                  }   

89.                                  } catch(Resources.NotFoundException ex) {   

90.                                  Log.e("CubeAnimation","NotFoundException");   

91.                                  } catch (XmlPullParserException ex){   

92.                                  Log.e("CubeAnimation","XmlPullParserException");   

93.                                  } catch (IOException ex) {   

94.                                  Log.e("CubeAnimation","IOException");   

95.                                  }   96.    }   

97.    

98.                         public void initialize(int width,int height, int parentWidth,   

99.                         int parentHeight) {   

100.                      super.initialize(width, height,parentWidth, parentHeight);   

101.                      this.mCenterX = resolveSize(1,0.5F,width, parentWidth);   

102.                      this.mCenterY = resolveSize(1,0.5F,height, parentHeight);   

103.                      if (this.mHorizonType ==0) {   

104.                      this.mHorizonValue /= height;   

105.                      }   106.   

107.         this.mCamera = new Camera();    108.     }   109.    

110.                            protected voidapplyTransformation(float interpolatedTime, Transformation t) {   

111.                            float fromDegrees =this.mFromDegrees;   

112.                            float degrees = fromDegrees +(this.mToDegrees - fromDegrees)   

113.                            * interpolatedTime;   

114.  

115.               float centerX = this.mCenterX;   

116.               float centerY = this.mCenterY;   

117.               Camera camera = this.mCamera;   

118.  

119.         Matrix matrix = t.getMatrix();    120.    

121.         camera.save();    122.    

123.               float b =0.0F;   

124.               float e = -this.mHorizonValue;    125.   

126.                      if (this.mInd ==0) {   

127.                      degrees +=90.0F;   

128.                      }   129.   

130.         camera.rotateY(degrees);    131.    

132.         camera.getMatrix(matrix);    133.         camera.restore();    134.    

135.                      if (this.mInd ==0) {   

136.                      matrix.preScale(-1.0F,1.0F,centerX,0.0F);   

137.                      }   138.   

139.         float tranX = 320.0F* interpolatedTime;    140.   

141.               float tranY = -centerY * e +b;   

142.               matrix.preTranslate(0.0F, centerY * e);   

143.               matrix.postTranslate(tranX,tranY);    144.    }   145.   

146.         protected static class Description{   

147.         public int type;    148.        public float value;    149.   

150.                                   static DescriptionparseValue(TypedValue value) {   

151.                                   Description d = newDescription();   

152.                                   if (value == null) {   

153.                                   d.type =0;   

154.                                   d.value =0.0F;   

155.                                   } else {   

156.                                   if (value.type ==6) {   

157.                                   d.type = (((value.data &0xF) ==1)? 2 : 1);   

158.  

159.                                   d.value =TypedValue.complexToFloat(value.data);   

160.                                   return d;   

161.                                   }   

162.                                   if (value.type ==4) {   

163.                                   d.type =0;   

164.                                   d.value = value.getFloat();   

165.                                   return d;   

166.                                   }   

167.                                   if ((value.type >=16) && (value.type <=31)) {   

168.                                   d.type =0;   

169.                                   d.value = value.data;   

170.                                   return d;   

171.                                   }   

172.                                   }   173.   

174.             d.type = 0;    175.             d.value = 0.0F;    176.    

177.                      return d;   

178.                      }   

179.                      }   

180.                      }   

31

菱形3D实例

文章分类:移动开发 下面是具体的实现方法: 首先需要建两个array,第一 array 是用来告诉 opengl 这个图形有哪些顶点: 画一个三维的坐标轴,然后把你要画的点都算出来,然后放在这个array里。 

Java 代码 

1. floatl=1.5f;    2. float[] vertex={   

3.    

4. 0.0f,l,0.0f,   

5.    

6. l,0.0f,0.0f,   

7.    

8. 0.0f,0.0f,l,   

9.    

10. -l,0.0f,0.0f,   

11.    

12. 0.0f,0.0f,-l,   

13.    

14. 0.0f,-l,0.0f   

15.    

16. };  

 

第二个 array 是告诉 opengl 你要怎样组织这些点:  这里我要画三角形,所以每三个点是一组。 

Java 代码 

1.      byte[] edge=   

2.      {   

3.      0,1,2,   

4.      1,2,5,   

5.    

6.      0,2,3,   

7.      5,2,3,   

8.    

9. 0,3,4,    10.5,3,4,   

11.    

12. 0,4,1,    13.5,4,1  

14.    

15. };  

 

 

这里的数字,是第一个 array index  下面你要建立两个 Buffer它们是用来存放这两个 array的。 

Java 代码 

1.      ByteBuffer bb =ByteBuffer.allocateDirect(vertex.length*4);   

2.      bb.order(ByteOrder.nativeOrder());   

3.      fbv=bb.asFloatBuffer();   

4.      fbv.put(vertex);    5.fbv.position(0);   

6.    

7.      ffe=ByteBuffer.allocateDirect(edge.length);   

8.      ffe.put(edge);   

9.      ffe.position(0);  

 这样一个三维的菱形就画好了。 下面你要写一个方法能让它自己把自己画出来! 

Java 代码 

1.      public void draw(GL10 gl)   

2.      {   

3.      gl.glFrontFace(GL10.GL_CW);   

4.      gl.glVertexPointer(3, GL10.GL_FLOAT,0,fbv);   

5.      gl.glDrawElements(GL10.GL_TRIANGLES,24, GL10.GL_UNSIGNED_BYTE,ffe);   

6.    

7. }  

 

 

先说第一个 glFrontFace,物体都有一个正面一个反面,这里告诉 opengl 显示这个物体按顺时针方向(CW=>clockwise 

 

gl.glVertexPointer(3,GL10.GL_FLOAT, 0, fbv);这个方法是把本程序所用的点都传递个openglopengl 需要知道什么哪?首先是这个点是几维的(opengl支持 234维),这里是3 所以是三维的,第二个参数告诉 opengl,这个点是用什么样类型的变量来储存的,这里是 float类型。第三个是步长(stride),这个我还没弄明白,不过我看的例子都为0.最后把你建立好的三维坐标点都传给opengl 

 

gl.glDrawElements。这个方法是告诉 opengl 如果要画这个图形,应该怎么画。第一个参数,告诉 opengl用画三角形(这样opengl就以三个点为一组),然后告诉opengl你要用到多少个点(注意这个点是在第二个array里的点数)。第三个是告诉opengl 这些点(其实是三维坐标点的 reference)的类型。这里是 unsignedbyte。最后把你排列点的array放进去! 

 

第二个大的步骤是创建一个让这个三维坐标运行的环境(Renderer)。 

这是一个 interface  

首先,在 onDrawFrame 里,我们告诉本程序这个三维图形的行为: 在做任何事情之前,我们要清空所有以前内存里的东西,这个内存包括:ColorDepth 

gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT); 然后告诉opengl 你要用那个 MatrixMode 这个就比较难解释了。 

如果写程序只要记住 GL_MODELVIEW 是管理图形的缩放,移动,和转动就行了.(如果那个朋友想理解的更深一点,可以联系我,我可以把我的笔记发过去或者参考http://glasnost.itcarlow.ie/~powerk/GeneralGraphicsNotes/projection/projection_viewing.html) 

 

 

gl.glTranslatef(0, 0, -3.0f);  这个方法告诉opengl把图形沿 z 轴迁移 3 unit。这三个值分别是 xyz轴。  gl.glRotatef(angle,0, 1, 0); 

这个方法告诉我们以 y 为轴。转 angle 个度数。注意这里的 1 0 是告诉沿着那个轴转,别的值应该没有意义。 

gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 

还记得上边说的 opengl client sideserviceside 吗。这个是告诉 opengl 如果 client side调用 draw什么的时候,这个 vertexarray 是可用的。opengl有很多这样的可选项,所以需要告诉opengl,因为我们已经设置了vertex array(我们的第一个array,所以告诉opengl 它是可用的(如果不告诉,opengl会忽略)! 

 

trian.draw(gl);  这个方法是把图形画出来。 

 

angle++;  为了达到动态的效果,我们让每一个 frame angle,比上一个多一度。 当显示空间大小发生变化的时候,我们应该告诉opengl 一下信息: 

Java 代码 

1.      public void onSurfaceChanged(GL10gl, int width, int height)    

2.      {   

3.      gl.glViewport(0,0,width, height);   

4.      gl.glMatrixMode(GL10.GL_PROJECTION);   

5.      gl.glLoadIdentity();   

6.      float ratio =(float)width/height;    7.gl.glFrustumf(-ratio,ratio, -1,1,1,10);   

8.    

9. }  

 

 

首先是 opengl 可用的空间: 

gl.glViewport(0,0, width, height);  想象一下用这四个点画出来的四边形,就是opengl所能用的空间。 

 

gl.glMatrixMode(GL10.GL_PROJECTION);  这个 matrix 是如何把三维坐标转换为二维坐标并把它放在显示器上。  gl.glLoadIdentity 是告诉opengl 初始化这个 matrix 

 

gl.glFrustumf 

要把三维的东西用二维显示出来,需要知道几个东西,第一是这个显示平面有多大,你可以看多近和多远。这里的头四个参数,建立了一个四边形,告诉 opengl把图形显示在这个范围了。后两个参数告诉opengl 这里显示平面里可以显示三维空间里最近和最远的位置。 

 

当这个三维图形建立的是时候,我们可以告诉 opengl 一些基本参数。这里把能省略的都省略了(其实什么都没有也可以运行!) 

Java 代码 

1.      public void onSurfaceCreated(GL10gl, EGLConfig arg1)    

2.       {   

3.      gl.glEnable(GL10.GL_DEPTH_TEST);   

4.      gl.glClearColor(0,0,0,0);   

5.      }  

 

gl.glEnable(GL10.GL_DEPTH_TEST);告诉 opengl要检查 depth,为什么哪。在三维空间里一个

物体 A 在另一个物体 B 后面,那么这个 A B 挡住里,所以你是看不见的。我们要告诉 opengl,我们不想看见被挡住的东西。这个GL_DEPTH_TEST就是这个功能。  gl.glClearColor(0,0, 0, 0); 

设置这个背景颜色为黑色,应为我们没有给我们的三维图形设置颜色(为了简单),它的初始化颜色是白色。 

 

以下是源代码:  Java 代码 

1. packageBeta.ThreeD;   

2.    

3.      import java.nio.ByteBuffer;   

4.      import java.nio.ByteOrder;    5.import java.nio.FloatBuffer;   

6.    

7. importjavax.microedition.khronos.opengles.GL10;   

8.    

9. publicclass TriangleShape     10. {   

11.    

12. privatefinal float l=1.5f;   

13.    

14. privateFloatBuffer fbv;   

15.    

16. privateByteBuffer ffe;   

17.    

18. publicTriangleShape()   

19.    

20. {   

21.    

22. float[]vertex={   

23.    

24. 0.0f,l,0.0f,   

25.    

26. l,0.0f,0.0f,   

27.    

28. 0.0f,0.0f,l,   

29.    

30. -l,0.0f,0.0f,   

31.  

32. 0.0f,0.0f,-l,   

33.    

34. 0.0f,-l,0.0f   

35.    

36. };   

37.    

38.    

39. byte[]edge=   

40.    

41. {   

42.    

43. 0,1,2,   

44.    

45. 1,2,5,   

46.    

47.    

48.    

49. 0,2,3,   

50.    

51. 5,2,3,   

52.    

53.    

54.    

55. 0,3,4,   

56.    

57. 5,3,4,   

58.    

59.    

60.    

61. 0,4,1,   

62.    

63. 5,4,1  

64.    

65. };   

66.    

67. ByteBufferbb = ByteBuffer.allocateDirect(vertex.length*4);   

68.    

69. bb.order(ByteOrder.nativeOrder());   

70.    

71. fbv=bb.asFloatBuffer();   

72.    

73. fbv.put(vertex);   

74.    

75. fbv.position(0);   

76.    

77.    

78.    

79.    

80. ffe=ByteBuffer.allocateDirect(edge.length);   

81.    

82. ffe.put(edge);   

83.    

84. ffe.position(0);   

85.    

86. }   

87.    

88. publicvoid draw(GL10 gl)   

89.    

90. {   

91.    

92. gl.glFrontFace(GL10.GL_CW);   

93.    

94. gl.glVertexPointer(3, GL10.GL_FLOAT, 0,fbv);   

95.    

96. gl.glDrawElements(GL10.GL_TRIANGLES,24, GL10.GL_UNSIGNED_BYTE,ffe);   

97.    

98.   }   

99.   }    100.    

101.    

102. packageBeta.ThreeD;    103.    

104. importjavax.microedition.khronos.egl.EGLConfig;   105. import javax.microedition.khronos.opengles.GL10;    106.    

107. importandroid.opengl.GLSurfaceView.Renderer;   108.    

109. publicclass MySimpleRendered implements Renderer   110. {    111.    

112.private int angle=50;    113.  

114.private TriangleShape trian;    115.  

116.public MySimpleRendered()    117.  

118.{  

119.   

120. trian = newTriangleShape();    121.   122. }   123.   124.@Override  125.  

126. public voidonDrawFrame(GL10 gl)     127.    128. {    129.    

130. //TODO Auto-generated method stub    131.    

132. gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);    133.    

134. gl.glMatrixMode(GL10.GL_MODELVIEW);    135.    

136. gl.glLoadIdentity();    137.    

138. gl.glTranslatef(0, 0,-3.0f);    139.   

140. gl.glRotatef(angle,0, 1,0);    141.    

142. gl.glRotatef(angle,1, 0,0);    143.    

144. gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);    145.    

146. trian.draw(gl);    147.    148. angle++;    149.    150. }    151.    

152.    153. @Override   154.   

155. public voidonSurfaceChanged(GL10 gl, int width, int height)     156.  157. {    158.  

159.// TODO Auto-generated method stub   160.  

161. gl.glViewport(0,0, width, height);    162. 

163.gl.glMatrixMode(GL10.GL_PROJECTION);   164.  

165.gl.glLoadIdentity();    166.  

167.float ratio = (float)width/height;   168.  

169.gl.glFrustumf(-ratio, ratio, -1,1,1,10);   

170.    

171.    

172.    173. }    174.    

175.    176. @Override   177.   

178. public voidonSurfaceCreated(GL10 gl, EGLConfig arg1)    179.    180. {    181.    

182. gl.glEnable(GL10.GL_DEPTH_TEST);    183.    

184. gl.glClearColor(0,0,0,0);    185.   186. }    187.    

188.    }   

189.    packageBeta.ThreeD;    190.    

191.    importandroid.app.Activity;   

192.    importandroid.os.Bundle;   

193.    importandroid.opengl.GLSurfaceView;   

194.    publicclass Triangle extends Activity {    195.     /** Called when the activity is firstcreated. */   196.    

197.               private GLSurfaceView my_view;   

198.               @Override  

199.               public void onCreate(BundlesavedInstanceState) {   

200.               super.onCreate(savedInstanceState);   

201.               setContentView(R.layout.main);   

202.               my_view = newGLSurfaceView(this);   

203.               my_view.setRenderer(newMySimpleRendered());   

204.               this.setContentView(my_view);   

205.               }   

206.               public void onResume()   

207.               {   208.       

209.super.onResume();    210.       

211.         my_view.onResume();   

212.         }   

213.         public void onPause()    214.    {   215.        

216. super.onPause();    217.         

218.         my_view.onPause();   

219.         }   

220.         }  

镜像倒影特效Gallery

文章分类:移动开发 效果展示

 

本文档将介绍在android上如何实现一个倒影效果的Gallery。为了达到上图所示的效果,

首先,是需要有一个自定义的gallery,实现了对Gallery的继承,通过重写 getChildStaticTransformation方法来控制,每个子view有不同的缩放比例,形成阶梯状的展示。这个gallery是在坤庭的代码基础上实现的,我这里就不再重复介绍。 

接下来,gallery中的每个view,都是一个自定义的MirrorView,由它来实现了画原图及画倒影。新的算法解决了性能问题,下面就重点说一下这部分内容:

镜像特效最近还蛮流行的,尤其在HTC 的Sense 介面上,常常都可以见到。大家可以看到,加了个镜像特效后,那感觉就很立体,感觉上好像是这些图片摆立在一个玻璃桌面上。

在Android 上要帮图片加上镜像特效,会不会很麻烦?一点也不麻烦,只要几行代码,就可以搞定。

因此,在开始看答案之前,我会建议你要先有Photoshop 的使用经验。想想,如果用Photoshop 要帮图片加上镜像特效,要如何做?我想一般不外乎是先复制个图片,并将其垂直翻转,接着再对这翻转的图片,加个由灰到黑的渐层mask 即可。好了,让我们来看一下答案。底下就是帮图片加上镜像特效的程式范例。

 

Java 代码 

1. public  class MirrorView extends  View {   

2.    

3. Paintm_paint;   

4.    

5. intm_nShadowH;   

6.    

7. Drawablem_dw;   

8.    

9. Bitmapm_bitmap;   

10.    

11. MatrixmMatrix;   

12.    

13. intshadowHeight;   

14.    

15. publicMirrorView(Context context, Bitmap bitmap) {   

16.  

17. super(context);   

18.    

19. m_bitmap= bitmap;   

20.    

21. _Init();   

22.    

23. }   

24.    

25. privatevoid _Init() {   

26.    

27. //m_dw= new BitmapDrawable(BitmapFactory.decodeResource(getResources(),  R.draw able.icon));   

28.    

29. m_dw= new BitmapDrawable(m_bitmap);   

30.    

31. m_dw.setBounds(0,0,m_dw.getIntrinsicWidth(),m_dw.getIntrinsicHeight());   

32.    

33. m_nShadowH= m_dw.getIntrinsicHeight()/1;   

34.    

35. m_paint= new Paint(Paint.ANTI_ALIAS_FLAG );   

36.    

37. LinearGradientlg = new LinearGradient(0,0,0,m_nShadowH,0xB0FFFFFF,0×00000000,Shader.TileMode.CLAMP );   

38.    

39. m_paint.setShader(lg);   

40.    

41. m_paint.setXfermode(newPorterDuffXfermode(PorterDuff.Mode.MULTIPLY ));   

42.    

43. mMatrix= new Matrix();   

44.    

45. }   

46.    

47. @Override  

48.    

49. publicvoid onDraw(Canvas canvas) {   

50.    

51. super.onDraw(canvas);   

52.    

53. intnX = 0;   

54.    

55. intnY = 0;   

56.    

57. _DrawNormalImg(canvas,nX, nY);   

58.   

59. _DrawMirror(canvas,nX, nY);   

60.    

61. }   

62.    

63. privatevoid _DrawNormalImg(Canvas canvas, int nX, int nY) {   

64.    

65. canvas.save(Canvas.MATRIX_SAVE_FLAG);   

66.    

67. canvas.translate(nX,nY);   

68.    

69. m_dw.draw(canvas);   

70.    

71. canvas.restore();   

72.    

73. }   

74.    

75. privatevoid _DrawMirror(Canvas canvas, int nX, int nY) {   

76.    

77. intnW = m_dw.getIntrinsicWidth();   

78.    

79. intnH = m_dw.getIntrinsicHeight();   

80.    

81. shadowHeight=nH/2;   

82.    

83. float[] src={0, nH, nW, nH,nW,nH – m_nShadowH, 0, nH –m_nShadowH};   

84.    

85. float[] dst={ 0, nH, nW,nH,nW, shadowHeight, 0,shadowHeight };   

86.    

87. canvas.save();   

88.    

89. mMatrix.setPolyToPoly(src,0, dst, 0,src.length >> 1);   

90.    

91. canvas.concat(mMatrix);   

92.    

93. //drawmirror image   

94.    

95. canvas.save(Canvas.MATRIX_SAVE_FLAG);   

96.    

97. canvas.scale(1.0f, -1.0f);   

98.    

99. canvas.translate(nX,-(nY + nH * 2));    100.   

101. canvas.clipRect(0, nH, nW, nH – m_nShadowH);   

102.   

103. m_dw.draw(canvas);    104.    

105. canvas.restore();    106.    

107. //drawmask    108.    

109. canvas.save();    110.    

111. canvas.translate(nX,nY + nH);    112.    

113. canvas.drawRect(0, 0,nW, m_nShadowH, m_paint);    114.   

115. canvas.restore();    116.    

117. canvas.restore();    118.    119.}    120.   

121. }  

  

_DrawMirror() 方法是关键。用Photoshop要如何做出镜像特效?第一步是先画出垂直翻转的图片。

Android 绘图座标体系预设的原点在左上角,X 轴往右是越来越大的正值,而Y 轴往下,则是越来越大的正值。要画出垂直翻转的图片,其实也就是要垂直翻转

整个绘图座标体系。在 Android 中,要如何做?答案就是 canvas.scale(1.0f, -1.0f)。很简单吧,没想到给scale() 函式一个负值,就可以翻转相对应的轴。

在Photoshop 中,做镜像特效的第二步是要对这翻转的图片,加个由灰到黑的渐层mask。

在Android 中,要画渐层色,那就一定得用LinearGradient 这个类别。至于要对背景图加上个mask,就请参考一下Paint 的setXfermode() 函式。 _Init() 这个函式,就是负责生成一个由灰到黑渐层mask 的m_paint 物件。

这个控件我测试过,200张图片加入adapter,在大数据量情况下性能也没有问题。

Gallery3D各个界面可见范围计算方法

文章分类:移动开发 

computeVisibleRange算法分析: 1 步,计算出 left,right,bottom,top 

2 步,计算出 numSlots,并除于 2 赋值给 index  3 步,由 index position,判断 position 是否在第 1 步计算出的范围内,是的话,就把第 2步计算得出的中间的 index赋值给firstVisibleSlotIndexlastVisibleSlotIndex,否则,根据滑动窗口算法改变index直到求组所需 index 

4 步,在 while 循环中,用第 3 步得到的 firstVisibleSlotIndex求出 position,进行和第2步相反的判断,即 position若不在可视范围内,则将相应的 index firstVisibleSlotIndex,否则减firstVisibleSlotIndex,直到找到最小的可视范围内的index作为 firstVisibleSlotIndex 

5 步,在 while 循环中,用第 3 步得到的 lastVisibleSlotIndex求出 position,进行和第2步相反的判断,即 position若不在可视范围内,则将相应的 index lastVisibleSlotIndex,否则增lastVisibleSlotIndex,直到找到可视范围内的最大的index作为 lastVisibleSlotIndex 

6 步,进行 firstVisibleSlotIndexlastVisibleSlotIndex的越界判断。outBufferedVisibleRange对应的是可见的。outBufferedVisibleRange对应的是0~文件夹的最大数。  computeVisibleItems算法分析: 

1 步由 slot 计算出 position,set,当前 set 不为空且 slot 在有效范围,创建 bestItems,计算 sortedIntersection  2 步计算这个 slotindex 中的图片数目,取这个文件中的前 12 张图片加到bestItems. 

3  bestItems里的图片对应的displayList中的 displayItem,并赋值给 displayItems数组,同时保存position,jj bestItems 数组中一项,范围是 012 

第四步  对于每一个文件夹,要在 displayItems里有对应的 12项,当文件夹内图片不足 12时,余下的用 null填充。 当绘制缩略图界面时,有些不同 

在第 1 步中,slotindex不再表示文件夹,这时表示具体某一张图片了,所以由slot 得到的set里始终只有 1 项,且会调ArrayUtils.computeSortedIntersection(visibleItems, items, MAX_ITEMS_PER_SLOT,bestItems, sTempHash);bestItems赋值,这样第 2 步就在 bestItems 加项动作不执行。

Gallery3D中画图时调用glTranslate函数参数赋值过程

文章分类:移动开发 

GridDrawManager::drawDisplayItem(RenderViewview, GL11 gl, DisplayItem displayItem, Texture texture, int pass,TexturepreviousTexture, float mixRatio)函数有下面几句: 

       

Java 代码 

1.                  Vector3f animatedPosition =displayItem.mAnimatedPosition;   

2.                  float translateXf =animatedPosition.x * camera.mOneByScale;   

3.                  float translateYf =animatedPosition.y * camera.mOneByScale;   4.        floattranslateZf = -animatedPosition.z;  

 

调用过程: 

->computeVisibleItems(),displayItems[baseIndex + j]= displayItem;Vector3f position = pool.create();          GridCameraManager.getSlotPositionForSlotIndex(i,     camera,  layout,deltaAnchorPosition,  position);//give          position value  displayList.setPositionAndStackIndex(displayItem,position, j, true);//raletive position to item 

 

->GridLayer,mDrawManager = new GridDrawManager(context, mCamera, mDrawables, sDisplayList,sDisplayItems, sDisplaySlots); 

->GridDrawManager(),mDisplayItems = displayItems; 

->drawFocusItems,DisplayItem[] displayItems = mDisplayItems; 

->animatedPosition= displayItem.mAnimatedPosition; 

->drawDisplayItem,amAnimatedPosition 

->DisplayItem::commit()  amAnimatedPosition.set(mTargetPosition); 

->     DisplayItem::set(Vector3f      position,  int  stackIndex,     boolean   performTransition)mTargetPosition.z = 

 

Java 代码 

1.                  public voidgetPositionForSlotIndex(int slotIndex, int itemWidth, int itemHeight,Vector3f  outPosition) {   

2.                  outPosition.x = (slotIndex /mNumRows) * (itemWidth + mSpacingX);   

3.                  outPosition.y = (slotIndex %mNumRows) * (itemHeight + mSpacingY);   

4.                  int maxY = (mNumRows -1) * (itemHeight + mSpacingY);   

5.                  outPosition.y -= (maxY >>1);   

6.                  outPosition.z =0;   

7.                  Log.d("outPosition","slotIndex="+slotIndex+",mNumRows="+mNumRows+",outPosition=("+outPosition.x+","+outPosition.y+","+outPosition.z+")");    8.    }  

 

 

gallery3d 中矩阵是从上到下、从左到右排列的,在主界面时最多有3行,mNumRows3,在缩略图界面最多4mNumRows4,在查看界面只有一行mNumRows1  上面函数是计算所绘制项位置的,slotIndex /mNumRows得到的是当前处于多少列,slotIndex%

mNumRows 得到的是处于多少行。int maxY = (mNumRows - 1) * (itemHeight + mSpacingY);          outPosition.y -= (maxY >> 1);是为了在y方向对称,想成屏幕中间是分界线,以上的项 y为负,线以下的 y为正。 

deltaAnchorPosition的赋值过程:  Java代码 

1.                               int currentlyVisibleSlotIndex =getAnchorSlotIndex(ANCHOR_CENTER);->anchorItem = dis playItem.mItemRef;->newSlotIndex = i;->if (currentAnchorSlotIndex != Shared.INVALID & &newAnchorSlotIndex != Shared.INVALID) {   

2.                               layout.getPositionForSlotIndex(newAnchorSlotIndex,itemWidth, itemHeight, de ltaAnchorPosition);   

3.                               oldLayout.getPositionForSlotIndex(currentAnchorSlotIndex,itemWidth, itemHei ght, currentSlotPosition);   

4.                               currentSlotPosition.subtract(sDeltaAnchorPosition);   

5.                               deltaAnchorPosition.subtract(currentSlotPosition);   

6.                               deltaAnchorPosition.y =0;   

7.                               deltaAnchorPosition.z =0;   

8.                               }  

 

 

MediaFeed::run()  onFeedChanged(, onLayout(newSlotIndex,currentlyVisibleSlotIndex, null); onLayout, sDeltaAnchorPositionUncommited.set(deltaAnchorPosition); computeVisibleRange(),sDeltaAnchorPosition.set(sDeltaAnchorPositionUncommited); deltaAnchorPosition.set(sDeltaAnchorPosition);  deltaAnchorPosition 

Gallery3D笔记

文章分类:移动开发 

布局及特效  gallery3d 的精华

一、布局

gallery3d的界面生成和普通的应用程序不一样。普通程序一般一个界面就是一个activity,布局用xml或代码都可以实现,界面切换是activity的切换方式;而gallery3d没有用android的UI系统,而是用opengl画出来的,即界面是在同一个 activity的,如主界面,缩略图界面,单张图片查看界面,标记界面等都属于同一个activity。那么这界面布局不同的界面是如何组合到一起的呢?分析代码,可以把它看成一个状态机:   

1、 标记模式   public static final int MODE_SELECT =1;(HudLayer)

包含了主界面标记模式,缩略界面矩阵游览时标记模式、缩略图界面分类游览时标记模式3个界面

2、 普通模式  public static final int MODE_NORMAL =0;(HudLayer) 包含了

     

Java 代码 

1.                         public static final intSTATE_MEDIA_SETS =0;主界面   

2.                         public static final intSTATE_GRID_VIEW =1;缩略图矩阵浏览   

3.                         public static final intSTATE_FULL_SCREEN =2;查看界面   

4.                         public static final intSTATE_TIMELINE =3;缩略图界面分类浏览  

 

有了以上状态分类后,在渲染的时候就能根据些界面的组成来定哪些控件譔隐藏,哪些要显示了。下面是基本控件:

Java 代码 

1.      com.cooliris.media.GridLayer   

2.      com.cooliris.media.BackgroundLayer   

3.      com.cooliris.media.HudLayer   

4.      com.cooliris.media.ImageButton   

5.      com.cooliris.media.TimeBar   

6.      com.cooliris.media.MenuBar   

7.      com.cooliris.media.PopupMenu   

8.      com.cooliris.media.PathBarLayer  

 

在渲染时,每一帧所有界面上的元素都画了,由于根据上面的状态只把特定窗口的特定元素显示出来,其它窗口中的隐藏,所以不会乱。 Layer是上面控件的基类,上面控件的类也就有了下面两个方法来隐藏不譔显示的界面元素。

  

Java 代码 

1.                  public boolean isHidden() {   

2.                  return mHidden;   

3.                  }   

4.    

5.                         public void setHidden(booleanhidden) {   

6.                         if (mHidden != hidden) {   

7.                         mHidden = hidden;   

8.                         onHiddenChanged();   

9.                         }   

10.                     }  

 下面是根据上面分类来画不同元素所用的标识:

   

Java 代码 

1.           public static final int PASS_THUMBNAIL_CONTENT=0;   

2.           public static final intPASS_FOCUS_CONTENT =1;   

3.           public static final int PASS_FRAME=2;   

4.           public static final intPASS_PLACEHOLDER =3;   

5.           public static final intPASS_FRAME_PLACEHOLDER =4;   

6.           public static final intPASS_TEXT_LABEL =5;   

7.           public static final intPASS_SELECTION_LABEL =6;   

8.           public static final intPASS_VIDEO_LABEL =7;   

9.           public static final intPASS_LOCATION_LABEL =8;   

10.       public static final intPASS_MEDIASET_SOURCE_LABEL =9;  

 

Java 代码 

1.      drawDisplayItem(view, gl,displayItem, texture, PASS_THUMBNAIL_CONTENT, placeholder,displayItem.mAnimatedPlaceholderFade);画缩略图的,注掉此句,前两屏只显示框,第三屏OK   

2.      drawDisplayItem(view, gl,displayItem, texture, PASS_FOCUS_CONTENT, null,0.0f);画单张图片的,注掉,第三屏黑屏   

3.      drawDisplayItem(view, gl,itemDrawn, textureToUse, PASS_FRAME, previousTexture, ratio

);画边框的,注掉,前两屏明显没有边框,巨齿明显   

4.      drawDisplayItem(view, gl,displayItem, textureString, PASS_TEXT_LABEL, null,0);画文本标签的   

5.      drawDisplayItem(view, gl,displayItem, textureToUse, PASS_SELECTION_LABEL, null,0);画选中标记的   

6.      drawDisplayItem(view, gl,displayItem, videoTexture, PASS_VIDEO_LABEL, null,0);画视频标记的   

7.      drawDisplayItem(view, gl,displayItem, locationTexture, PASS_LOCATION_LABEL, null,0);画位置标记的   

8.      drawDisplayItem(view, gl,displayItem, locationTexture, PASS_MEDIASET_SOURCE_LABEL

,transparentTexture,0.85f);画源来源图标的(相机或一般文件夹)  

 

 

二、特效

举如何显示一张图片为例,在图片完全显示出来经过这样一个过程,附近的图片渐小渐出,当前图片渐大渐入,当前图片逐渐变大直到全屏。实现这个特效,要进行很多帧的渲染。就是说并不是只调一次onDrawFrame函数就可以了,要调用多次。可以把这个特效的实现想成一个状态变化的过程,在每一个状态,纹理的显示大小和位置都不同,这也符合动画的基本原理。放大、缩小我们只要改变顶点数据就可以做到,gallery3d也是这样做的,下面是主要代码:我们知道调用onDrawFrame来渲染,最后调到下面的drawFocusItems函数,

Java 代码 

1.                  GridQuad quad =GridDrawables.sFullscreenGrid[vboIndex];   

2.                  float u =texture.getNormalizedWidth();   

3.                  float v =texture.getNormalizedHeight();   

4.                  float imageWidth =texture.getWidth();   

5.                  float imageHeight =texture.getHeight();   

6.                  boolean portrait = ((theta /90) %2== 1);   

7.                  if (portrait) {   

8.                  viewAspect =1.0f / viewAspect;   

9.                  }   

10.               quad.resizeQuad(viewAspect, u, v,imageWidth, imageHeight);//改变用来贴图片的长方形的大小   

11.               quad.bindArrays(gl);//绑定新数据,为渲染做准备。  

 

而位置的改变有两种方式,一种是直接以顶点数据中改变,另一种是计算出在3维3个方向的偏移量,再调用gltranslate来做,从代码可以看出采用的是第二种方式来做的,比第一种方式更方便一些。代码:

Java 代码 

1. gl.glTranslatef(-translateXf,-translateYf, -translateZf);  

 

而这里的3个偏移量的计算是和camera相关的,相关文件为GridCamera.java, GridCameraManager.java,过程很复杂,理清楚后再细化吧。

 

cache管理下面是cache文件

Java 代码 

1.      /sdcard/Android/data/com.cooliris.media/cache/local-album-cache   

2.      d---rwxr-x system   sdcard_rw         2010-05-2109:56local-album-cache   

3.      d---rwxr-x system   sdcard_rw         2010-05-2109:56local-meta-cache   

4.      ----rwxr-x system   sdcard_rw  2998772010-05-2807:36local-album-cachechunk_0   

5.      d---rwxr-x system   sdcard_rw         2010-05-2109:56geocoder-cache   

6.      ----rwxr-x system   sdcard_rw     2842010-05-2807:36 local-album-cacheindex   

7.      d---rwxr-x system   sdcard_rw         2010-05-2109:56local-image-thumbs   

8.      d---rwxr-x system   sdcard_rw         2010-05-2109:56local-video-thumbs   

9.      d---rwxr-x system   sdcard_rw         2010-05-2109:56picasa-thumbs   

10.   ----rwxr-xsystem   sdcard_rw       802010-05-2807:36 local-meta-cachechunk_0   

11.   ----rwxr-xsystem   sdcard_rw      1642010-05-2807:36 local-meta-cacheindex   

12.   d---rwxr-xsystem   sdcard_rw          2010-05-2109:56hires-image-cache   

13.   ----rwxr-xsystem   sdcard_rw   6276292010-05-2807:37 local-image-thumbschunk_0   

14.   ----rwxr-xsystem   sdcard_rw     39142010-05-2109:56 local-image-thumbsindex   

15.   ----rwxr-xsystem   sdcard_rw    533432010-05-2807:34 hires-image-cache-4982941342

287215583_1024.cache   

16.   ----rwxr-xsystem   sdcard_rw   2376922010-05-2807:33 hires-image-cache36845684843 69117627_1024.cache   

17.   ----rwxr-xsystem   sdcard_rw   1331822010-05-2807:34 hires-image-cache60754254408 1226432_1024.cache   

18.   ----rwxr-xsystem   sdcard_rw    832232010-05-2807:34 hires-image-cache42754796232 10216146_1024.cache   

19.   ----rwxr-xsystem   sdcard_rw   2928372010-05-2807:34 hires-image-cache-6463165569 36433937_1024.cache   

20.   ----rwxr-xsystem   sdcard_rw   1913772010-05-2807:35 hires-image-cache26313646045 09958174_1024.cache   

21.   ----rwxr-xsystem   sdcard_rw   3669052010-05-2807:35 hires-image-cache-3280562009766080884_1024.cache   

22.   ----rwxr-xsystem   sdcard_rw   3236712010-05-2807:35 hires-image-cache57524718275 33329222_1024.cache  

 

创建cache的关键代码

Java 代码 

1.      LocalDataSource   

2.      public static final DiskCachesThumbnailCache = newDiskCache("local-image-thumbs");---------------------local-image-thumbslocal-image-thumbschunk_0 local-image-thumbsind ex   

3.      public static final DiskCachesThumbnailCacheVideo = new DiskCache("local-video-thumbs");--------------------local-video-thumbs   

4.      public static final DiskCachesAlbumCache = newDiskCache("local-album-cache");---------------------local-album-cache  local-album-cacheindex   

5.      public static final DiskCachesMetaAlbumCache = new DiskCache("local-meta-cache");----

--------------local-meta-cache  local-meta-cacheindex   

6.      getChunkFile--------------local-meta-cachechunk_0 local-album-cachechunk_0   

7.    

8.      ReverseGeocoder::  private static final DiskCache sGeoCache =new DiskCache("geocoder -cache");-------------------------geocoder-cache   

9.      PicasaDataSource:: public staticfinal DiskCache sThumbnailCache = new DiskCache("picasa-thumbs");-----------------------------picasa-thumbs   

10.   UriTexture::writeToCache --------------------------hires-image-cache-xxx_1024.cache  

 

布局补充:

在画一个界面是,是分类化的,比如第一个界面是显示所有有图片的文件夹,在代码里叫专辑.有这些元素要创建:

文本标签  显示专辑名和专辑内图片或视频数路径条 显示路径名按纽拍照按纽,放大/缩小

菜单栏 全选,取消全选,分享,删除,更多等图片边框用于显示图片的矩形在渲染时一次把一类元素画完,再画另一类.如主界面顺序为: 路径条->按纽->文本标签->图片边框->图片. 具体代码见drawBlendedComponents函数

 

 

1.CacheService.java中 写 缓 存 :sAlbumCache.put(ALBUM_CACHE_LOCALE_INDEX,

sDummyData,0); 

  第一个是 key,这里是正常数据,当然还有别的 key key分别是-1,-2,-3,-4,-5  2.DiskCache.java中,执行上面的写的过程,这里先得明白他的cache怎么装的:     它是由很多称之为的文件组成的,形成一个List形式:private final 

 

LongSparseArray<RandomAccessFile>mChunkFiles = new

LongSparseArray<RandomAccessFile>(); 

mChuckFiles 就是整个 cache,里面包括很多 chunk(即片 ),每一个 chunk大小为

1MB. 

当要写入某一个 chunk 里面的时候,先要找到他在mChuckFiles里面的索引值即chunkIndex, 

 

mChunkFiles.get(chunkIndex);来获取这个文件,chunkIndex怎么来的呢? 

privateLongSparseArray<Record> mIndexMap; 

Recordrecord = mIndexMap.get(key); 这里的 key就是上面用 put方法传过来的 

 

ALBUM_CACHE_LOCALE_INDEX的值(就是-5 

intchunkIndex = record.chunk; 

这么一步步来的。 

当然了,第一次都是空的,也就是 get 不到东西mChunkFiles.get(chunkIndex); Record

record= 

 

mIndexMap.get(key);get不到,那么第一次就先把东西放进去,mIndexMap.put(key, new

Record 

 

(chunkIndex,record.offset, data.length, record.sizeOnDisk, timestamp));(记录 key值)以及

final 

 

StringchunkFilePath = mCacheDirectoryPath + CHUNK_FILE_PREFIX + chunk; chunkFile =new 

 

RandomAccessFile(chunkFilePath,"rw");mChunkFiles.put(chunk, chunkFile);(三句代码来新建

一个 

 

chunkfile 并放到 cache列表里面) 

  

注意: Record是内部类,只是一个数据集合类而已,相当于文件描述信息。每个cache(即chunk)对应一个。 

private   final          LongSparseArray<RandomAccessFile> mChunkFiles   =      newLongSparseArray<RandomAccessFile>();mChunkFiles最大装13个,每个chunk1M,所以全部Cache13M. 

Gallery3d代码分析之渲染流程

文章分类:移动开发 

RenderView 

 

gallery3d 的渲染从 RenderView开始。RenderViewGLSurfaceView继承而来,采用了通知型绘制模式,即通过调用requestRender通知RenderView 重绘屏幕。 

 

RenderView将所有需要绘制的对象都保存一个Lists中,Lists包含了5ArrayList,其定义如下所示: 

Java 代码 

1.      public final ArrayList<Layer>updateList = new ArrayList<Layer>();   

2.      public final ArrayList<Layer>opaqueList = new ArrayList<Layer>();   

3.      public final ArrayList<Layer>blendedList = new ArrayList<Layer>();   

4.      public final ArrayList<Layer>hitTestList = new ArrayList<Layer>();   5.public final ArrayList<Layer> systemList = newArrayList<Layer>();  

 

 

 

RenderView onDrawFrame接口完成每一帧的绘制操作,绘制时遍历lists里每个list的每一个成员并调用其renderXXX函数。主要代码如下所示: 

Java 代码 

1.      ...   

2.      final Lists lists = sLists;   

3.    

4.            final ArrayList<Layer>updateList = lists.updateList;   

5.            boolean isDirty = false;   

6.            for (int i =0, size = updateList.size(); i != size; ++i) {   

7.            boolean retVal =updateList.get(i).update(this, mFrameInterval);   

8.            isDirty |= retVal;   

9.            }   

10.         if (isDirty) {   

11.         requestRender();    12.}   

13.    

14.   //Clear the depth buffer.   

15.   gl.glClear(GL11.GL_DEPTH_BUFFER_BIT);   

16.   gl.glEnable(GL11.GL_SCISSOR_TEST);    17. gl.glScissor(0, 0,getWidth(), getHeight());   

18.    

19.               // Run the opaque pass.   

20.               gl.glDisable(GL11.GL_BLEND);   

21.               final ArrayList<Layer>opaqueList = lists.opaqueList;    

22.               for (int i = opaqueList.size() -1; i >=0;--i) {   

23.               final Layer layer =opaqueList.get(i);   

24.               if (!layer.mHidden) {   

25.               layer.renderOpaque(this, gl);   

26.               }   27.}   

28.    

29.               // Run the blended pass.   

30.               gl.glEnable(GL11.GL_BLEND);   

31.               final ArrayList<Layer>blendedList = lists.blendedList;   

32.               for (int i =0, size = blendedList.size(); i != size; ++i) {   

33.               final Layer layer =blendedList.get(i);   

34.               if (!layer.mHidden) {   

35.               layer.renderBlended(this, gl);   

36.               }   

37.               }   

38.               gl.glDisable(GL11.GL_BLEND);  

 

 

 

lists 的各个 list里包含的各个 layer如下所示: 

Java 代码 

1.         lists   

2.         |------------------|-----------------|-----------------|---------------|   

3.         updateList        opaqueList        blendedList      systemList     hitTestList   

4.         |                  |                 |                 |            |   

5.         GridLayer         GridLayer         GridLayer        GridLayer      GridLayer   

6.         BackgroudLayer    BackgroudLayer    BackgroudLayer   

7.         HudLayer           HudLayer         HudLayer                        HudLayer   

8.         TimeBar                             TimeBar                         TimeBar   

9.         PathBar                             PathBar                         PathBar   

10.     XXXButton                           XXXButton                       XXXButton   

11.     XXXMenu                             XXXMenu                         XXXMenu  

 

 

 

 

Layer 类提供了update(...), renderOpaque (...), renderBlended (...)接口,从上面 RenderViewonDrawFrame绘制代码可以看到,这些接口被调用。 

Java 代码 

1.            public abstract class Layer {   

2.            ... ...   

3.  

4.   public abstract void generate(RenderViewview, RenderView.Lists lists);   

5.  

6.                  public boolean update(RenderViewview, float frameInterval) {   

7.                  return false;   

8.                  }   

9.    

10.         public void renderOpaque(RenderViewview, GL11 gl) {   

11.         }   

12.    

13.         public voidrenderBlended(RenderView view, GL11 gl) {   

14.         }   15.    ... ...   

16.    

17. }  

 

 

 

GridLayer 

 

GridLayer 中有个GridDrawManager,专门负责绘制。 

 

下面是 GridDrawManager 的构造函数,从其参数里可以看出些门道。 

Java 代码 

1. mDrawManager= new GridDrawManager(context, mCamera, mDrawables, sDisplayList, sDisplayItems,sDisplaySlots);  

Gallery 3D代码分析之GLSurfaceView

文章分类:移动开发 简介 

 

SDK 中的 android.opengl.GLSurfaceView 类提供如下功能: 

•            在 OpenGL ES View系统之间建立联系; 

•            使得 OpenGL ES 可以工作在 Activity生命周期中; 

•            可选择合适的 frame buffer 像素格式; 

•            创建并管理一个单独的渲染线程,可以实现平滑的动画; 

•            提供 debugging 工具和 API 

 

 

一个简单的GLSurfaceView 应用  Java代码 

1. packagecom.example.android.apis.graphics;   

2.

3. importjavax.microedition.khronos.egl.EGLConfig;   4. import javax.microedition.khronos.opengles.GL10;   

5.    

6.      import android.app.Activity;   

7.      import android.opengl.GLSurfaceView;    8.import android.os.Bundle;   

9.    

10.               public class ClearActivity extendsActivity {   

11.               @Override  

12.               protected void onCreate(BundlesavedInstanceState) {   

13.               super.onCreate(savedInstanceState);   

14.               mGLView = new GLSurfaceView(this);   

15.               mGLView.setRenderer(newClearRenderer());   

16.               setContentView(mGLView);   

17.               }   

18.    

19.               @Override  

20.               protected void onPause() {   

21.               super.onPause();   

22.               mGLView.onPause();    23.    }   

24.    

25.               @Override  

26.               protected void onResume() {   

27.               super.onResume();   

28.               mGLView.onResume();   

29.               }   

30.    

31.     private GLSurfaceView mGLView;    32. }   

33.    

34. classClearRenderer implements GLSurfaceView.Renderer {    35.     public void onSurfaceCreated(GL10 gl,EGLConfig config) {   

36.         // Do nothing special.    37.     }   

38.    

39.               public void onSurfaceChanged(GL10gl, int w, int h) {   

40.               gl.glViewport(0,0,w, h);   

41.               }   

42.

43.               public void onDrawFrame(GL10 gl){   

44.               gl.glClear(GL10.GL_COLOR_BUFFER_BIT| GL10.GL_DEPTH_BUFFER_BIT);   

45.               }  

46.               }这个程序功能很简单,每帧绘制时将屏幕设置成黑色。但它是一个完整的工作在Activity生命周期中的OpenGL程序。当 activity暂停时,它暂停渲染;当 activity继续时,它继续渲染。可以将这个程序用作非交互式的demo程序。可以在ClearRenderer.onDrawFrame()接口中增加 OpenGL 调用做很多的绘制。 

 

GLSurfaceView.Render接口有三个方法: 

 

*   onSurfaceCreated():该方法在渲染开始前调用,OpenGLES 的绘制上下文被重建时也会被调用。当activity 暂停时绘制上下文会丢失,当activity继续时,绘制上下文会被重建。另外,创建长期存在的OpenGL资源( texture)往往也在这里进行。 

*   onSurfaceChanged(): surface 的尺寸发生改变时该方法被调用。往往在这里设置viewport。若你的camera是固定的,也可以在这里设置camera 

*   onDrawFrame():每帧都通过该方法进行绘制。绘制时通常先调用glClear 函数来清空framebuffer,然后在调用OpenGL ES的起它的接口进行绘制。 

 

输入如何处理 

 

若是开发一个交互型的应用(如游戏),通常需要子类化GLSurfaceView,由此可以获取输入事件。下面有个例子:  Java代码 

1. packagecom.google.android.ClearTest;   

2.    

3. importjavax.microedition.khronos.egl.EGLConfig;   4. import javax.microedition.khronos.opengles.GL10;   

5.    

6.      import android.app.Activity;   

7.      importandroid.content.Context;   

8.      importandroid.opengl.GLSurfaceView;   

9.      import android.os.Bundle;    10.importandroid.view.MotionEvent;   

11.    

12.               public class ClearActivity extendsActivity {   

13.               @Override  

14.               protected void onCreate(BundlesavedInstanceState) {   

15.               super.onCreate(savedInstanceState);   

16.               mGLView = newClearGLSurfaceView(this);   

17.               setContentView(mGLView);   

18.               }   

19.

20.               @Override  

21.               protected void onPause() {   

22.               super.onPause();   

23.               mGLView.onPause();    24.    }   

25.    

26.               @Override  

27.               protected void onResume() {   

28.               super.onResume();   

29.               mGLView.onResume();   

30.               }   

31.    

32.     private GLSurfaceView mGLView;    33. }   

34.    

35.               class ClearGLSurfaceView extendsGLSurfaceView {   

36.               public ClearGLSurfaceView(Contextcontext) {   

37.               super(context);   

38.               mRenderer = newClearRenderer();   

39.               setRenderer(mRenderer);    40.    }   

41.    

42.                                        public boolean onTouchEvent(finalMotionEvent event) {   

43.                                        queueEvent(new Runnable(){   

44.                                        public void run() {   

45.                                        mRenderer.setColor(event.getX() /getWidth(),   

46.                                        event.getY() / getHeight(),1.0f);   

47.                                        }});   

48.                                        return true;   

49.                                        }   

50.    

51.         ClearRenderer mRenderer;    52. }   

53.    

54. classClearRenderer implements GLSurfaceView.Renderer {    55.     public void onSurfaceCreated(GL10 gl,EGLConfig config) {   

56.         // Do nothing special.    57.     }   

58.    

59.               public void onSurfaceChanged(GL10gl, int w, int h) {   

60.               gl.glViewport(0,0,w, h);   

61.               }   

62.

63.               public void onDrawFrame(GL10 gl){   

64.               gl.glClearColor(mRed, mGreen,mBlue,1.0f);   

65.               gl.glClear(GL10.GL_COLOR_BUFFER_BIT| GL10.GL_DEPTH_BUFFER_BIT);   

66.               }   

67.    

68.               public void setColor(float r, floatg, float b) {   

69.               mRed = r;   

70.               mGreen = g;   

71.               mBlue = b;    72.    }   

73.    

74.         private float mRed;   

75.         private float mGreen;   

76.         private float mBlue;   

77.         }  

 

其他的 GLSurfaceView 例子 

 

Android SDK API Demo例子程序中还有很多例子: 

•            GLSurfaceView 

•            Kube 

•            Translucent GLSurfaceView:透明背景 

•            Textured Triangle:纹理贴图 

•            Sprite Text:在 texture上写文本并显示在 3D场景中 

•            Touch Rotate:旋转 3D对象 

 

 

选择一个 Surface 

 

GLSurfaceView提供了接口可选择surface的类型。默认情况下,GLSurfaceView会使用一个16RGBframebuffer,带16位深度。你也可以根据自己的需要进行选择,比如在

TranslucentGLSurfaceView 例子里,需要一个Alpha通道来实现透明。GLSurfaceView提供了setEGLSurfaceChooser()方法来选择 surface 

 

选择一个 RGB (565) 16 framebuffer,接口如下: 

Java 代码 

1. setEGLConfigChooser(booleanneedDepth)  

 

 

若要定制 red, green, blue, alpha depth,则用如下接口: 

Java代码  

1. setEGLConfigChooser(intredSize, int greenSize,int blueSize, int alphaSize,int depthSize, in tstencilSize)  

 

 

使用自己实现的 EGLConfigChooser,用如下的接口: 

Java 代码 

1. setEGLConfigChooser(EGLConfigChooserconfigChooser)  

 

 

持续型渲染模式 & 通知型渲染模式 

 

大多数 3D 应用,如游戏、模拟等都是持续型渲染的动画,还有些3D应用是反应式的(reactive),它们往往先被动等待,当用户有了动作再做出反应。对于这种应用,持续渲染屏幕是浪费时间。若开发反应式的应用,可以调用下面的方法 

Java 代码 

1. GLSurfaceView.setRenderMode(RENDERMODE_WHEN_DIRTY);  

 

 

停止持续渲染。当调用 

Java 代码 

1. GLSurfaceView.requestRender()  

 

 

时,程序再渲染屏幕。  调试 

 

GLSurfaceView.setDebugFlags() 方法可以激活 log 或者错误检测,它们可以帮助调试 OpenGL ES调用。具体使用时,在GLSurfaceView 的构造函数中,调用 setRender()之前调用GLSurfaceView.setDebugFlags()就可以了。下面是个例子: 

Java 代码 

1.            public ClearGLSurfaceView(Contextcontext) {   

2.            super(context);   

3.            // Turn on error-checking andlogging   

4.            setDebugFlags(DEBUG_CHECK_GL_ERROR| DEBUG_LOG_GL_CALLS);   

5.            mRenderer = new ClearRenderer();   

6.            setRenderer(mRenderer);   

7.            }  

 

 

 


已标记关键词 清除标记
表情包
插入表情