Android中LayoutParams总结和用法

对于在某种类型的ViewGroup中的View/ViewGroup,在getLayoutParams()时, LayoutParams只能转换

为父ViewGroup的LayoutParams类型,

原因在于LinearLayout(或其他继承自ViewGroup的layout,如:RelativeLayout)在进行递归布局的时候,LinearLayout会获取子View的LayoutParams,并强制转换成LinearLayout.LayoutParams


From: http://blog.csdn.net/liuhaomatou/article/details/22899925


日积月累第三周第四天。又是忙碌的一天,昨天看了两集老罗的Android 视频教程,感觉讲的很基础。继续坚持一天一集视频。今天上班接触了一下Android 的LayoutParams今天加以整理和梳理。

先查看一下API 中是如何介绍的,以搜索太多了。就挑一个ViewGroup.LayoutParams 看一下吧

http://developer.android.com/reference/android/view/ViewGroup.LayoutParams.html

LayoutParams are used by views to tell their parents how they want to be laid out. See ViewGroup Layout Attributes for a list of all child view attributes that this class supports.

The base LayoutParams class just describes how big the view wants to be for both width and height. For each dimension, it can specify one of:

  • FILL_PARENT (renamed MATCH_PARENT in API Level 8 and higher), which means that the view wants to be as big as its parent (minus padding)
  • WRAP_CONTENT, which means that the view wants to be just big enough to enclose its content (plus padding)
  • an exact number
There are subclasses of LayoutParams for different subclasses of ViewGroup. For example, AbsoluteLayout has its own subclass of LayoutParams which adds an X and Y value.

Developer Guides

For more information about creating user interface layouts, read the XML Layouts developer guide.

我在这里看了一篇别人博客对于LayoutParams 的解释,我觉的很到位,所以就继续拿来主义。

其实这个LayoutParams类是用于child view(子视图) 向 parent view(父视图)传达自己的意愿的一个东西(孩子想变成什么样向其父亲说明)其实子视图父视图可以简单理解成
一个LinearLayout 和 这个LinearLayout里边一个 TextView 的关系 TextView 就算LinearLayout的子视图 child view 。需要注意的是LayoutParams只是ViewGroup的一个内部类这里边这个也就是ViewGroup里边这个LayoutParams类是 base class 基类实际上每个不同的ViewGroup都有自己的LayoutParams子类
比如LinearLayout 也有自己的 LayoutParams 大家打开源码看几眼就知道了
myeclipse 怎么查看源码 请看http://byandby.iteye.com/blog/814277
下边来个例子


 

Java代码 :
  1.       //创建一个线性布局   
  2.        private LinearLayout mLayout;      
  3.        mLayout = (LinearLayout) findViewById(R.id.layout);      
  4.       //现在我要往mLayout里边添加一个TextView    
  5.      //你可能会想直接在布局文件里边配置不就O 了 那是 但是这里为了说明问题我们用代码实现   
  6.       TextView textView = new TextView(Activity01.this);      
  7.            textView.setText("Text View " );   
  8.            //这里请不要困惑这里是设置 这个textView的布局 FILL_PARENT WRAP_CONTENT 和在xml文件里边设置是一样的如   
  9.     
  10. //在xml里边怎么配置高宽大家都会的。   
  11.   //第一个参数为宽的设置,第二个参数为高的设置。   
  12.            LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(      
  13.                    LinearLayout.LayoutParams.FILL_PARENT,      
  14.                    LinearLayout.LayoutParams.WRAP_CONTENT      
  15.            );      
  16.            //调用addView()方法增加一个TextView到线性布局中   
  17.            mLayout.addView(textView, p);      
  18.           //比较简单的一个例子  


如果还不能理解下边在来一段直白的说明:
LayoutParams继承于Android.View.ViewGroup.LayoutParams.
LayoutParams相当于一个Layout的信息包,它封装了Layout的位置、高、宽等信息。假设在屏幕上一块区域是由一个Layout占领的,如果将一个View添加到一个Layout中,最好告诉Layout用户期望的布局方式,也就是将一个认可的layoutParams传递进去。
可以这样去形容LayoutParams,在象棋的棋盘上,每个棋子都占据一个位置,也就是每个棋子都有一个位置的信息,如这个棋子在4行4列,这里的“4行4列”就是棋子的LayoutParams。
但LayoutParams类也只是简单的描述了宽高,宽和高都可以设置成三种值:
1,一个确定的值;
2,FILL_PARENT,即填满(和父容器一样大小);
3,WRAP_CONTENT,即包裹住组件就好。

关于setLayoutParams报错

 

  在继承BaseAdapter的时候,用getView返回View的时候,用代码控制布局,需要用到View.setLayoutParams,但是报错了,报的是类型转换错误,经过研究,发现,这里不能使用ViewGroup.LayoutParams而必须使用对应父View的LayoutParams类型。如:某View被LinearLayout包含,则该View的setLayoutParams参数类型必须是LinearLayout.LayoutParams。原因在于LinearLayout(或其他继承自ViewGroup的layout,如:RelativeLayout)在进行递归布局的时候,LinearLayout会获取子View的LayoutParams,并强制转换成LinearLayout.LayoutParams,如

1 LinearLayout.LayoutParams lp  =  (LinearLayout.LayoutParams) child.getLayoutParams();

或者是如下定义:

1 LayoutParams lp  =  (LayoutParams) child.getLayoutParams();

以转换成内部类型LinearLayout.LayoutParams。

 

自己测试运行的时候报空指针,原因为child.getLayoutParams();这里没有获得到子控件所在的布局,查看代码发现parent.addView(child);应该写在上面,之后child才能getLayoutParams();



点击PopupWindow 外部区域消失
//view 是自定义的点击PopupWindow 样式
pop = new PopupWindow(view, ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                pop.setBackgroundDrawable(new BitmapDrawable());
                pop.setOutsideTouchable(true);
pop = new PopupWindow(view, ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                pop.setBackgroundDrawable(new BitmapDrawable());
                pop.setOutsideTouchable(true);
上面两句位置不能颠倒,不然无效!(经本机测试 不知道别人如何)必须设置backgroundDrawable()


  WindowManager.LayoutParams 是 WindowManager 接口的嵌套类;继承于 ViewGroup.LayoutParams 。
         它的内容十分丰富。其实WindowManager.java的主要内容就是由这个类定义构成。下面来分析一下这个类:

         定义
         public static class WindowManager.LayoutParams extends ViewGroup.LayoutParams implements Parcelable

         继承关系
        java.lang.Object
        android.view.ViewGroup.LayoutParams
        android.view.WindowManager.LayoutParams

        继承来的属性与常量
        从ViewManager.LayoutParams 继承来的属性:
        android:layout_height
        Specifies the basic height of the view.
        android:layout_width
        Specifies the basic width of the view.

        从ViewManager.LayoutParams继承的常量:
        FILL_PARENT
        WRAP_CONTENT
        MATCH_PARENT

        两个变量:
        width
        height

        属性及可用的常量定义

       1. public int x;
       如果忽略gravity属性,那么它表示窗口的绝对X位置。
       什么是gravity属性呢?简单地说,就是窗口如何停靠。
       当设置了 Gravity.LEFT 或 Gravity.RIGHT 之后,x值就表示到特定边的距离。

       2. public int y;
       如果忽略gravity属性,那么它表示窗口的绝对Y位置。
       当设置了 Gravity.TOP 或 Gravity.BOTTOM 之后,y值就表示到特定边的距离。

       3. public float horizontalWeight;
       public float verticalWeight;
       在纵/横向上,为关联的view预留了多少扩展空间(像素)。如果是0,那么此view不能被拉伸。
       其他情况下,扩展空间(像素)将被widget所均分。

       4. public int type;
        窗口类型。

        有3种主要类型:

        Applicationwindows:
        取值在 FIRST_APPLICATION_WINDOW 和 LAST_APPLICATION_WINDOW 之间。
        是通常的、顶层的应用程序窗口。必须将 token 设置成 activity 的 token 。

       Sub_windows:
        取值在 FIRST_SUB_WINDOW 和 LAST_SUB_WINDOW 之间。
        与顶层窗口相关联,token 必须设置为它所附着的宿主窗口的 token。

        Systemwindows:
        取值在 FIRST_SYSTEM_WINDOW 和 LAST_SYSTEM_WINDOW 之间。
        用于特定的系统功能。它不能用于应用程序,使用时需要特殊权限。

        下面定义了 type 的取值:

//应用程序窗口。
public static final int FIRST_APPLICATION_WINDOW = 1; 


//所有程序窗口的“基地”窗口,其他应用程序窗口都显示在它上面。 
public static final int TYPE_BASE_APPLICATION =1;


//普通应用功能程序窗口。token必须设置为Activity的token,以指出该窗口属谁。
public static final int TYPE_APPLICATION = 2;


//用于应用程序启动时所显示的窗口。应用本身不要使用这种类型。
//它用于让系统显示些信息,直到应用程序可以开启自己的窗口。 
public static final int TYPE_APPLICATION_STARTING = 3; 


//应用程序窗口结束。
public static final int LAST_APPLICATION_WINDOW = 99;


//子窗口。子窗口的Z序和坐标空间都依赖于他们的宿主窗口。
public static final int FIRST_SUB_WINDOW = 1000;


//面板窗口,显示于宿主窗口上层。
public static final int TYPE_APPLICATION_PANEL = FIRST_SUB_WINDOW;


//媒体窗口,例如视频。显示于宿主窗口下层。
public static final int TYPE_APPLICATION_MEDIA = FIRST_SUB_WINDOW+1;


//应用程序窗口的子面板。显示于所有面板窗口的上层。(GUI的一般规律,越“子”越靠上)
public static final int TYPE_APPLICATION_SUB_PANEL = FIRST_SUB_WINDOW +2;


//对话框。类似于面板窗口,绘制类似于顶层窗口,而不是宿主的子窗口。
public static final int TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW +3;


//媒体信息。显示在媒体层和程序窗口之间,需要实现透明(半透明)效果。(例如显示字幕)
public static final int TYPE_APPLICATION_MEDIA_OVERLAY = FIRST_SUB_WINDOW +4;


//子窗口结束。( End of types of sub-windows )
public static final int LAST_SUB_WINDOW = 1999;


//系统窗口。非应用程序创建。
public static final int FIRST_SYSTEM_WINDOW = 2000;


//状态栏。只能有一个状态栏;它位于屏幕顶端,其他窗口都位于它下方。
public static final int TYPE_STATUS_BAR = FIRST_SYSTEM_WINDOW;


//搜索栏。只能有一个搜索栏;它位于屏幕上方。
public static final int TYPE_SEARCH_BAR = FIRST_SYSTEM_WINDOW+1;


//电话窗口。它用于电话交互(特别是呼入)。它置于所有应用程序之上,状态栏之下。
public static final int TYPE_PHONE = FIRST_SYSTEM_WINDOW+2;


//系统提示。它总是出现在应用程序窗口之上。
public static final int TYPE_SYSTEM_ALERT = FIRST_SYSTEM_WINDOW +3;


//锁屏窗口。
public static final int TYPE_KEYGUARD = FIRST_SYSTEM_WINDOW +4;


//信息窗口。用于显示toast。
public static final int TYPE_TOAST = FIRST_SYSTEM_WINDOW +5;


//系统顶层窗口。显示在其他一切内容之上。此窗口不能获得输入焦点,否则影响锁屏。
public static final int TYPE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW +6;


//电话优先,当锁屏时显示。此窗口不能获得输入焦点,否则影响锁屏。
public static final int TYPE_PRIORITY_PHONE = FIRST_SYSTEM_WINDOW +7;


//系统对话框。(例如音量调节框)。
public static final int TYPE_SYSTEM_DIALOG = FIRST_SYSTEM_WINDOW +8;


//锁屏时显示的对话框。
public static final int TYPE_KEYGUARD_DIALOG = FIRST_SYSTEM_WINDOW +9;


//系统内部错误提示,显示于所有内容之上。
public static final int TYPE_SYSTEM_ERROR = FIRST_SYSTEM_WINDOW +10;


//内部输入法窗口,显示于普通UI之上。应用程序可重新布局以免被此窗口覆盖。
public static final int TYPE_INPUT_METHOD = FIRST_SYSTEM_WINDOW +11;


//内部输入法对话框,显示于当前输入法窗口之上。
public static final int TYPE_INPUT_METHOD_DIALOG= FIRST_SYSTEM_WINDOW +12;


//墙纸窗口。
public static final int TYPE_WALLPAPER = FIRST_SYSTEM_WINDOW +13;


//状态栏的滑动面板。
public static final int TYPE_STATUS_BAR_PANEL = FIRST_SYSTEM_WINDOW +14;


//系统窗口结束。
public static final int LAST_SYSTEM_WINDOW = 2999;

 5. public int memoryType;
       指出窗口所使用的内存缓冲类型。默认为 NORMAL 。

       下面定义了 memoryType 的取值:

       窗口缓冲位于主内存。
       public static final int MEMORY_TYPE_NORMAL = 0;
       窗口缓冲位于可以被DMA访问,或者硬件加速的内存区域。
       public static final int MEMORY_TYPE_HARDWARE = 1;
       窗口缓冲位于可被图形加速器访问的区域。
       public static final int MEMORY_TYPE_GPU = 2;
       窗口缓冲不拥有自己的缓冲区,不能被锁定。缓冲区由本地方法提供。
       public static final int MEMORY_TYPE_PUSH_BUFFERS = 3;

       6.  public int flags;
       行为选项/旗标,默认为 none .下面定义了 flags 的取值:

//窗口之后的内容变暗。
public static final int FLAG_DIM_BEHIND = 0x00000002;


//窗口之后的内容变模糊。
public static final int FLAG_BLUR_BEHIND = 0x00000004; 


不许获得焦点。
不能获得按键输入焦点,所以不能向它发送按键或按钮事件。那些时间将发送给它后面的可以获得焦点的窗口。此选项还会设置FLAG_NOT_TOUCH_MODAL选项。设置此选项,意味着窗口不能与软输入法进行交互,所以它的Z序独立于任何活动的输入法(换句话说,它可以全屏显示,如果需要的话,可覆盖输入法窗口)。要修改这一行为,可参考FLAG_ALT_FOCUSALBE_IM选项。
public static final int FLAG_NOT_FOCUSABLE = 0x00000008;


//不接受触摸屏事件。
public static final int FLAG_NOT_TOUCHABLE = 0x00000010;


当窗口可以获得焦点(没有设置 FLAG_NOT_FOCUSALBE 选项)时,仍然将窗口范围之外的点设备事件(鼠标、触摸屏)发送给后面的窗口处理。否则它将独占所有的点设备事件,而不管它们是不是发生在窗口范围内。
public static final int FLAG_NOT_TOUCH_MODAL = 0x00000020;


如果设置了这个标志,当设备休眠时,点击触摸屏,设备将收到这个第一触摸事件。
通常第一触摸事件被系统所消耗,用户不会看到他们点击屏幕有什么反应。
public static final int FLAG_TOUCHABLE_WHEN_WAKING = 0x00000040;


当此窗口为用户可见时,保持设备常开,并保持亮度不变。
public static final int FLAG_KEEP_SCREEN_ON = 0x00000080;


窗口占满整个屏幕,忽略周围的装饰边框(例如状态栏)。此窗口需考虑到装饰边框的内容。
public static final int FLAG_LAYOUT_IN_SCREEN =0x00000100;


允许窗口扩展到屏幕之外。
public static final int FLAG_LAYOUT_NO_LIMITS =0x00000200;


窗口显示时,隐藏所有的屏幕装饰(例如状态条)。使窗口占用整个显示区域。
public static final int FLAG_FULLSCREEN = 0x00000400;


此选项将覆盖FLAG_FULLSCREEN选项,并强制屏幕装饰(如状态条)弹出。
public static final int FLAG_FORCE_NOT_FULLSCREEN =0x00000800;


抖动。指 对半透明的显示方法。又称“点透”。图形处理较差的设备往往用“点透”替代Alpha混合。
public static final int FLAG_DITHER = 0x00001000;


//不允许屏幕截图。
public static final int FLAG_SECURE = 0x00002000;


//一种特殊模式,布局参数用于指示显示比例。
public static final int FLAG_SCALED = 0x00004000;


//当屏幕有可能贴着脸时,这一选项可防止面颊对屏幕造成误操作。
public static final int FLAG_IGNORE_CHEEK_PRESSES = 0x00008000;


//当请求布局时,你的窗口可能出现在状态栏的上面或下面,从而造成遮挡。当设置这一选项后,窗口管理器将确保窗口内容不会被装饰条(状态栏)盖住。
public static final int FLAG_LAYOUT_INSET_DECOR = 0x00010000;


//反转FLAG_NOT_FOCUSABLE选项。
//如果同时设置了FLAG_NOT_FOCUSABLE选项和本选项,窗口将能够与输入法交互,允许输入法窗口覆盖;
如果FLAG_NOT_FOCUSABLE没有设置而设置了本选项,窗口不能与输入法交互,可以覆盖输入法窗口。
public static final int FLAG_ALT_FOCUSABLE_IM = 0x00020000;


//如果你设置了FLAG_NOT_TOUCH_MODAL,那么当触屏事件发生在窗口之外事,可以通过设置此标志接收到一个MotionEvent.ACTION_OUTSIDE事件。注意,你不会收到完整的down/move/up事件,只有第一次down事件时可以收到ACTION_OUTSIDE。
public static final int FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000;


//当屏幕锁定时,窗口可以被看到。这使得应用程序窗口优先于锁屏界面。可配合FLAG_KEEP_SCREEN_ON选项点亮屏幕并直接显示在锁屏界面之前。可使用FLAG_DISMISS_KEYGUARD选项直接解除非加锁的锁屏状态。此选项只用于最顶层的全屏幕窗口。
public static final int FLAG_SHOW_WHEN_LOCKED = 0x00080000;


//请求系统墙纸显示在你的窗口后面。窗口必须是半透明的。
public static final int FLAG_SHOW_WALLPAPER = 0x00100000;


//窗口一旦显示出来,系统将点亮屏幕,正如用户唤醒设备那样。
public static final int FLAG_TURN_SCREEN_ON = 0x00200000;


//解除锁屏。只有锁屏界面不是加密的才能解锁。如果锁屏界面是加密的,那么用户解锁之后才能看到此窗口,除非设置了FLAG_SHOW_WHEN_LOCKED选项。
public static final int FLAG_DISMISS_KEYGUARD = 0x00400000;


//锁屏界面淡出时,继续运行它的动画。
public static final int FLAG_KEEP_SURFACE_WHILE_ANIMATING =0x10000000;


//以原始尺寸显示窗口。用于在兼容模式下运行程序。
public static final int FLAG_COMPATIBLE_WINDOW = 0x20000000;


//用于系统对话框。设置此选项的窗口将无条件获得焦点。
public static final int FLAG_SYSTEM_ERROR = 0x40000000;

      7. public int softInputMode;
       软输入法模式选项:以下选项与 softInputMode 有关:


//软输入区域是否可见。
public static final int SOFT_INPUT_MASK_STATE = 0x0f;


//未指定状态。
public static final int SOFT_INPUT_STATE_UNSPECIFIED = 0;


//不要修改软输入法区域的状态。
public static final int SOFT_INPUT_STATE_UNCHANGED = 1;


//隐藏输入法区域(当用户进入窗口时)。
public static final int SOFT_INPUT_STATE_HIDDEN = 2;


//当窗口获得焦点时,隐藏输入法区域。
public static final int SOFT_INPUT_STATE_ALWAYS_HIDDEN = 3;


//显示输入法区域(当用户进入窗口时)。
public static final int SOFT_INPUT_STATE_VISIBLE = 4;


//当窗口获得焦点时,显示输入法区域。
public static final int SOFT_INPUT_STATE_ALWAYS_VISIBLE = 5;


//窗口应当主动调整,以适应软输入窗口。
public static final int SOFT_INPUT_MASK_ADJUST = 0xf0;


//未指定状态,系统将根据窗口内容尝试选择一个输入法样式。
public static final int SOFT_INPUT_ADJUST_UNSPECIFIED = 0x00;


//当输入法显示时,允许窗口重新计算尺寸,使内容不被输入法所覆盖。
//不可与SOFT_INPUT_ADJUSP_PAN混合使用,如果两个都没有设置,系统将根据窗口内容自动设置一个选项。
public static final int SOFT_INPUT_ADJUST_RESIZE = 0x10;


//输入法显示时平移窗口。它不需要处理尺寸变化,框架能够移动窗口以确保输入焦点可见。
//不可与SOFT_INPUT_ADJUST_RESIZE混合使用;如果两个都没设置,系统将根据窗口内容自动设置一个选项。
public static final int SOFT_INPUT_ADJUST_PAN = 0x20;


//当用户转至此窗口时,由系统自动设置,所以你不要设置它。
//当窗口显示之后该标志自动清除。
public static final int SOFT_INPUT_IS_FORWARD_NAVIGATION = 0x100;

  8. public int gravity;
       gravity 属性。什么是gravity属性呢?简单地说,就是窗口如何停靠。

       9. public float horizontalMargin;
       水平边距,容器与widget之间的距离,占容器宽度的百分率。

       10. public float verticalMargin;
       纵向边距。

       11. public int format;
       期望的位图格式。默认为不透明。参考android.graphics.PixelFormat。

       12. public int windowAnimations;
       窗口所使用的动画设置。它必须是一个系统资源而不是应用程序资源,因为窗口管理器不能访问应用程序。

       13. public float alpha = 1.0f;
       整个窗口的半透明值,1.0表示不透明,0.0表示全透明。

       14. public float dimAmount = 1.0f;
       当FLAG_DIM_BEHIND设置后生效。该变量指示后面的窗口变暗的程度。
       1.0表示完全不透明,0.0表示没有变暗。

       15. public float screenBrightness = -1.0f;
       用来覆盖用户设置的屏幕亮度。表示应用用户设置的屏幕亮度。
       从0到1调整亮度从暗到最亮发生变化。

       16. public IBinder token = null;
       窗口的标示符。( Identifier for this window. This will usually be filled in for you. )

       17. public String packageName = null;
       此窗口所在的包名。

       18. public int screenOrientation =ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
       屏幕方向,参见android.content.pm.ActivityInfo#screenOrientation。

       19. 在兼容模式下,备份/恢复参数所使用的内部缓冲区。
       public int[] mCompatibilityParamsBackup = null;


layoutanimation,顾名思义,是用来设置给viewgroup类型的animation,是子view来执行的。可以是

[java]  view plain copy
  1. android:layoutAnimation="@anim/popinlayout"   
也可以是javacode的

[java]  view plain copy
  1. viewgroup.setLayoutAnimation(layoutnaimationcontroller);  

和Animation类似,Layout Animation也支持Animation Listener,具体的就不多说了。layoutanimation会在View Group第一次进行布局的时候执行一次。

具体来说,layoutanimation支持三个参数,

1,anim就不多说了,

2,animationOrder,这个是说子view按照什么顺序来执行anim,可以使normal(正常,0-n),reverse(反序,n-0),random。一般不要太乱的还是normal

3,delay,用于延迟的每个子view的动画开始动画持续时间的浮点数。越大间隔越长。0.3或者30%的字样。


另外,LayoutAnimationController包含一个内部类,LayoutAnimationController.AnimationParameters,这个类主要包括了count和index两个参数。这些参数用于计算每个单独的视图动画的开始时间。

ViewGroup.LayoutParams这个类大家都一定很熟悉的,主要是height和width。其中还有一个字段,就是LayoutAnimationController.AnimationParameters,Used to animate layouts


layoutanimation一般可以用在listview等adapterview中,显得比较炫一些。

比如:

[html]  view plain copy
  1.     <ListView  
  2.         android:id="@+id/listview"  
  3.         android:layout_width="fill_parent"  
  4.         android:layout_height="fill_parent"  
  5. <strong>        android:persistentDrawingCache="animation|scrolling"   
  6.         android:layoutAnimation="@anim/scale_controller"</strong>  
  7.         >  
  8.     </ListView>  


listview中还有一个viewgroup的属性,android:persistentDrawingCache 

Defines the persistence of the drawing cache. The drawing cache might be enabled by a ViewGroup for all its children in specific situations (for instance during a scrolling.) This property lets you persist the cache in memory after its initial usage. Persisting the cache consumes more memory but may prevent frequent garbage collection is the cache is created over and over again. By default the persistence is set to scrolling. 

 定义绘图的高速缓存的持久性。 绘图缓存可能由一个 ViewGroup 在特定情况下为其所有的子类启用,例如在一个滚动的过程中。 此属性可以保留在内存中的缓存后其初始的使用。 坚持缓存会消耗更多的内存,但可能会阻止频繁的垃圾回收是反复创建缓存。 默认情况下持续存在设置为滚动。

其属性值只有以下几种:

ConstantValueDescription
none 0x0  The drawing cache is not persisted after use.
animation 0x1  The drawing cache is persisted after a layout animation.
scrolling 0x2The drawing cache is persisted after a scroll.
all 0x3  The drawing cache is always persisted.


一般默认的有scrolling属性,我们在有layoutAnimation动画的时候添加上animation属性会更流通些。


LayoutAnimationController用于为一个layout里面的控件,或者是一个ViewGroup里面的控件设置动画效果,可以在XML文件中设置,亦可以在Java代码中设置。

一种直接在XML文件中设置

1.  res/anim文件夹下新建一个XML文件,名为list_anim_layout.xml,

[java]  view plain copy
  1. <layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"  
  2.         android:delay="30%"  
  3.         android:animationOrder="reverse"  
  4.         android:animation="@anim/slide_right" />  

android:delay  子类动画时间间隔 (延迟)   70% 也可以是一个浮点数 如“1.2”等

android:animationOrder="random"   子类的显示方式 random表示随机

android:animationOrder 的取值有 

normal0   默认
reverse1  倒序
random2  随机

android:animation="@anim/slide_right" 表示孩子显示时的具体动画是什么


说明:其中delay的单位为秒;animation为设置动画的文件。animationOrder为进入方式

2.  res/anim文件夹下新建一个XML文件,名为slide_right,即上面用到的文件。

[html]  view plain copy
  1.     <set xmlns:android="http://schemas.android.com/apk/res/android"   
  2.         android:interpolator="@android:anim/accelerate_interpolator">  
  3.     <translate android:fromXDelta="-100%p" android:toXDelta="0"  
  4.             android:duration="@android:integer/config_shortAnimTime" />  
  5. </set>  

 显示的效果为ListView第一次出现的时候为 item随机出现 每个Item都是从左不可见(-100%p)的区域向右滑动到显示的地方

3.  在主布局文件中为控件添加如下配置:

android:layoutAnimation="@anim/list_anim_layout",即第一步的布局文件。


第二种设置方法:在Java代码中设置

1. 同上;

2. 同上;

4.  Acitivty中添加如下代码:


//通过加载XML动画设置文件来创建一个Animation对象;

       Animation animation=AnimationUtils.loadAnimation(this, R.anim.list_anim);

       //得到一个LayoutAnimationController对象;

       LayoutAnimationController lac=new LayoutAnimationController(animation);

       //设置控件显示的顺序;

       lac.setOrder(LayoutAnimationController.ORDER_REVERSE);

       //设置控件显示间隔时间;

       lac.setDelay(1);

       //ListView设置LayoutAnimationController属性;

   datalist.setLayoutAnimation(lac);


有两种用法,我的通常写在代码中,像下面这样: 

Java代码   收藏代码
  1. /** 
  2.      * Layout动画 
  3.      *  
  4.      * @return 
  5.      */  
  6.     protected LayoutAnimationController getAnimationController() {  
  7.         int duration=300;  
  8.         AnimationSet set = new AnimationSet(true);  
  9.   
  10.         Animation animation = new AlphaAnimation(0.0f, 1.0f);  
  11.         animation.setDuration(duration);  
  12.         set.addAnimation(animation);  
  13.   
  14.         animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,  
  15.                 Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,  
  16.                 -1.0f, Animation.RELATIVE_TO_SELF, 0.0f);  
  17.         animation.setDuration(duration);  
  18.         set.addAnimation(animation);  
  19.   
  20.         LayoutAnimationController controller = new LayoutAnimationController(set, 0.5f);  
  21.         controller.setOrder(LayoutAnimationController.ORDER_NORMAL);  
  22.         return controller;  
  23.     }  


应用的时候只需这样: 
Java代码   收藏代码
  1. listView = (ListView) findViewById(R.id.listView);  
  2. listView.setLayoutAnimation(getAnimationController());  
  3. adapter = new ListViewAdapter(stores);  
  4. listView.setAdapter(adapter);  


这样一个简单的LayoutAnimation就完成了。 

别看到这里就以为文章就完了,以上都是些小玩意。呵呵,还有更厉害的! 

你想设置更炫的动画吗?LayoutAnimation通常是Item一个一个的出现,有某种规律的。想让每个Item都有自己的动画吗?那就继续看下去。 
Java代码   收藏代码
  1. .......  
  2. private int duration=1000;  
  3.         private Animation push_left_in,push_right_in;  
  4.         private Animation slide_top_to_bottom,slide_bottom_to_top;  
  5.         public ListViewAdapter(ArrayList<Store> list) {  
  6.             this.list = list;  
  7.             push_left_in=AnimationUtils.loadAnimation(context, R.anim.push_left_in);  
  8.             push_right_in=AnimationUtils.loadAnimation(context, R.anim.push_right_in);  
  9.             slide_top_to_bottom=AnimationUtils.loadAnimation(context, R.anim.slide_top_to_bottom);  
  10.             slide_bottom_to_top=AnimationUtils.loadAnimation(context, R.anim.slide_bottom_to_top);  
  11.         }  
  12. ........  
  13.   
  14. @Override  
  15.         public View getView(int position, View convertView, ViewGroup parent) {  
  16.             // TODO Auto-generated method stub  
  17.             ViewHodler hodler;  
  18.             if (convertView == null) {  
  19.                 hodler = new ViewHodler();  
  20.                 convertView = LayoutInflater.from(context).inflate(  
  21.                         R.layout.simple_item_7_for_main, null);  
  22.                 ........  
  23.                   
  24.                   
  25.                 convertView.setTag(hodler);  
  26.                   
  27.                 if (position % 2 == 0) {  
  28.                     push_left_in.setDuration(duration);  
  29.                     convertView.setAnimation(push_left_in);  
  30.                 } else {  
  31.                     push_right_in.setDuration(duration);  
  32.                     convertView.setAnimation(push_right_in);  
  33.                 }  
  34.                   
  35.                 /*if(position==0){ 
  36.                     slide_bottom_to_top.setDuration(duration); 
  37.                     convertView.setAnimation(slide_bottom_to_top); 
  38.                 } 
  39.                 else{ 
  40.                     slide_top_to_bottom.setDuration(duration); 
  41.                     convertView.setAnimation(slide_top_to_bottom); 
  42.                 }*/  
  43.                   
  44.             }else{  
  45.                 hodler = (ViewHodler) convertView.getTag();  
  46.             }  
  47. ........  
  48.               
  49.               
  50.             return convertView;  
  51.         }  

看见上面的动画设置了吗?将动画写在getView()中,这样可以设置很多不同的动画。其实这不属于LayoutAnimation的范畴了。 
你可以试一下,如果设计好的话,可以有比LayoutAnimation更酷的效果。 
我这里只试了两种效果。 
下面是我的动画文件,共四个: 
第一种效果:item分别从左右两侧滑入效果。 
push_left_in.xml 
Xml代码   收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <set xmlns:android="http://schemas.android.com/apk/res/android">  
  3.     <translate android:fromXDelta="-100%p" android:toXDelta="0" android:duration="300"/>  
  4.     <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="300" />  
  5. </set>  

push_right_in.xml 
Xml代码   收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <set xmlns:android="http://schemas.android.com/apk/res/android">  
  3.     <translate android:fromXDelta="100%p" android:toXDelta="0" android:duration="300"/>  
  4.     <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="300" />  
  5. </set>  


第2种效果:第一个item从下往上滑入,其他Item从上往下滑入效果,这个效果如果单个Item比较高(height)的话效果非常酷(卡牛的老版本好像用的就是这种效果)。 
slide_bottom_to_top.xml 
Xml代码   收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator">  
  3.     <translate android:fromYDelta="100%" android:toXDelta="0" android:duration="300" />  
  4.     <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="300" />  
  5. </set>  

slide_top_to_bottom.xml 
Xml代码   收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator">  
  3.     <translate android:fromYDelta="-100%" android:toXDelta="0" android:duration="300" />  
  4.     <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="300" />  
  5. </set>  


另外一篇: 
这个不是我写的。 
GridView的item从上下左右飞入  
Java代码   收藏代码
  1. import java.util.Random;  
  2. import android.app.Activity;  
  3. import android.content.Context;  
  4. import android.os.Bundle;  
  5. import android.view.LayoutInflater;  
  6. import android.view.View;  
  7. import android.view.View.OnClickListener;  
  8. import android.view.ViewGroup;  
  9. import android.view.animation.Animation;  
  10. import android.view.animation.TranslateAnimation;  
  11. import android.widget.BaseAdapter;  
  12. import android.widget.Button;  
  13. import android.widget.GridView;  
  14. import android.widget.ImageView;  
  15. public class ZdemoActivity extends Activity {  
  16.    
  17.  private GridView gv;  
  18.  private Button btn;  
  19.  private TranslateAnimation taLeft, taRight, taTop, taBlow;  
  20.  private int[] imgList = new int[15];  
  21.  private MyAdapter mAdapter;  
  22.  private LayoutInflater mInflater;  
  23.  @Override  
  24.  public void onCreate(Bundle savedInstanceState) {  
  25.   super.onCreate(savedInstanceState);  
  26.   setContentView(R.layout.main);  
  27.   this.InitView();  
  28.   this.InitAnima();  
  29.   this.InitData();  
  30.  }  
  31.  private void InitAnima() {  
  32.   // TODO Auto-generated method stub  
  33.   taLeft = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 1.0f,  
  34.     Animation.RELATIVE_TO_PARENT, 0.0f,  
  35.     Animation.RELATIVE_TO_PARENT, 0.0f,  
  36.     Animation.RELATIVE_TO_PARENT, 0.0f);  
  37.   taRight = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, -1.0f,  
  38.     Animation.RELATIVE_TO_PARENT, 0.0f,  
  39.     Animation.RELATIVE_TO_PARENT, 0.0f,  
  40.     Animation.RELATIVE_TO_PARENT, 0.0f);  
  41.   taTop = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 0.0f,  
  42.     Animation.RELATIVE_TO_PARENT, 0.0f,  
  43.     Animation.RELATIVE_TO_PARENT, 1.0f,  
  44.     Animation.RELATIVE_TO_PARENT, 0.0f);  
  45.   taBlow = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 0.0f,  
  46.     Animation.RELATIVE_TO_PARENT, 0.0f,  
  47.     Animation.RELATIVE_TO_PARENT, -1.0f,  
  48.     Animation.RELATIVE_TO_PARENT, 0.0f);  
  49.   taLeft.setDuration(1000);  
  50.   taRight.setDuration(1000);  
  51.   taTop.setDuration(1000);  
  52.   taBlow.setDuration(1000);  
  53.  }  
  54.  private void InitData() {  
  55.   // TODO Auto-generated method stub  
  56.   for (int i = 0; i < 15; i++) {  
  57.    imgList[i] = R.drawable.ic_launcher;  
  58.   }  
  59.   mAdapter = new MyAdapter();  
  60.   gv.setAdapter(mAdapter);  
  61.  }  
  62.  private void InitView() {  
  63.   // TODO Auto-generated method stub  
  64.   gv = (GridView) findViewById(R.id.gridView1);  
  65.   btn = (Button) findViewById(R.id.button1);  
  66.   btn.setOnClickListener(new OnClickListener() {  
  67.    @Override  
  68.    public void onClick(View v) {  
  69.     // TODO Auto-generated method stub  
  70.     mAdapter = null;  
  71.     mAdapter = new MyAdapter();  
  72.     gv.setAdapter(mAdapter);  
  73.     mAdapter.notifyDataSetChanged();  
  74.    }  
  75.   });  
  76.   mInflater = (LayoutInflater) this  
  77.     .getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
  78.  }  
  79.  private class MyAdapter extends BaseAdapter {  
  80.   @Override  
  81.   public int getCount() {  
  82.    // TODO Auto-generated method stub  
  83.    return imgList.length;  
  84.   }  
  85.   @Override  
  86.   public Object getItem(int position) {  
  87.    // TODO Auto-generated method stub  
  88.    return imgList[position];  
  89.   }  
  90.   @Override  
  91.   public long getItemId(int position) {  
  92.    // TODO Auto-generated method stub  
  93.    return position;  
  94.   }  
  95.   @Override  
  96.   public View getView(int position, View convertView, ViewGroup parent) {  
  97.    // TODO Auto-generated method stub  
  98.    ViewHolder holder = null;  
  99.    if (convertView == null) {  
  100.     convertView = mInflater.inflate(R.layout.item, null);  
  101.     holder = new ViewHolder();  
  102.     holder.image = (ImageView) convertView  
  103.       .findViewById(R.id.imageView1);  
  104.     convertView.setTag(holder);  
  105.    } else {  
  106.     holder = (ViewHolder) convertView.getTag();  
  107.    }  
  108.    int imgID = imgList[position];  
  109.    holder.image.setImageResource(imgID);  
  110.    Random ran = new Random();  
  111.    int rand = ran.nextInt(4);  
  112.    switch (rand) {  
  113.    case 0:  
  114.     convertView.startAnimation(taLeft);  
  115.     break;  
  116.    case 1:  
  117.     convertView.startAnimation(taRight);  
  118.     break;  
  119.    case 2:  
  120.     convertView.startAnimation(taTop);  
  121.     break;  
  122.    case 3:  
  123.     convertView.startAnimation(taBlow);  
  124.     break;  
  125.    }  
  126.    return convertView;  
  127.   }  
  128.   class ViewHolder {  
  129.    public ImageView image;  
  130.   }  
  131.  }  



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值