setWillNotDraw和setFillViewport


Romain Guy write a little info about a ScrollView attribute that is missing  from documentation : android:fillViewport=”true” .

It must be set to ScrollView and has the following efect : when set to true, this attribute causes the scroll view’s child to expand to the height of the ScrollView if needed. When the child is taller than the ScrollView, the attribute has no effect.

当你想让一个高度值不足scrollview的子控件fillparent的时候,单独的定义android:layout_height="fill_parent"是不起作用的,必须加上fillviewport属性,当子控件的高度值大于scrollview的高度时,这个标签就没有任何意义了。



.引言:

想必大家以前也遇到过这个问题:出于项目的需要,我们有时需要新建一个直接或者间接继承View的类,以便复写View提供的onDraw()方法,但有时我们反而得不到我们想要的结果,今天就说一下onDraw()方法不被执行的解决方法。你可能也在onDraw()方法里面设置了断点或log,却发现程序并没有执行onDraw()方法,那么你需要在你直接或者间接继承View的类的构造函数中加入下面的语句:

        setWillNotDraw(false);

.解释:

那么加这条语句的作用是什么?先看API:

        If this view doesn't do any drawing on its own, set this flag to allow further optimizations. By default, this flag is not set on View, but could be set on some View subclasses such as ViewGroup. Typically, if you override onDraw(Canvas) you should clear this flag.

本人外语基础不是很好,简要翻译一下,如果翻译的不好,不要扔砖啊,重复一句我的语言:要想象,没有了想象,世界会是什么样。嘿嘿:

        如果在当前的view上面不做任何的绘制操作,需要设置这个标记以便将来的更好的需要,默认的,这个标记在View里是不设定的。但是像View的一些子类如ViewGroup是可以设定的,典型的,你如果复写了onDraw(Canvas)方法,你需要清除此标记。

那么正好,我们所实现的就是View的子类:LinearLayout,当然你也可以继承其他的子类如:

AbsoluteLayout,AdapterView<T extends Adapter>,FrameLayout,LinearLayout,RelativeLayout,SlidingDrawer,子类就不说了,你可以自己去查文档。

这条语句要放在继承类的构造函数中,如:

 

  1. public classBackgroundLayout extendsLinearLayout {  
  2.   
  3.         publicBackgroundLayout(Context context, intposition) {  
  4.   
  5.                 super(context);  
  6.   
  7.                 // TODOAuto-generated constructor stub   
  8.   
  9.                 setWillNotDraw(false);  
  10.   
  11.         }  
  12.   
  13.         @Override  
  14.   
  15.         protected voidonDraw(Canvas canvas) {  
  16.   
  17.                 // TODOAuto-generated method stub   
  18.   
  19.                 super.onDraw(canvas);  
  20.   
  21.                 }  
  22.   
  23.         }  
  24.   
  25. }  
        public classBackgroundLayout extendsLinearLayout {

                publicBackgroundLayout(Context context, intposition) {

                        super(context);

                        // TODOAuto-generated constructor stub

                        setWillNotDraw(false);

                }

                @Override

                protected voidonDraw(Canvas canvas) {

                        // TODOAuto-generated method stub

                        super.onDraw(canvas);

                        }

                }

        }


 

三,扩展看法:

eoeandroid上面Little关于这条语句的看法是:

       设置view是否更改,如果开发者用自定义的view,重写ondraw()应该将调用此方法设置为false,这样程序会调用自定义的布局。

在此引用一下。

       其实从这条语句的字面意思上可以看出:setWillNotDraw(false);就是设置将不绘画吗?你重写了onDraw()当然是要进行绘画了,所以应将此语句参数置为false.


Android中,Surface是一个用于绘制图形的对象,特别是对于游戏、视频播放等需要实时更新UI的场景非常重要。有时候,可能会遇到Surface绘制的内容未能完全清除,导致残留图像的问题。这种现象通常出现在SurfaceView或者GLSurfaceView中,特别是在绘制完成后没有正确地调用`draw()`方法或者清理缓冲区。 解决这个问题通常涉及以下几个步骤: 1. **在`onDraw()`方法结束时清空缓冲区**:在绘制完毕后,你需要调用`Canvas`的`drawColor()`或`clear()`方法将画布颜色设置回默认背景色,如黑色或透明。 ```java @Override protected void onDraw(Canvas canvas) { // ...绘制操作... canvas.drawColor(Color.TRANSPARENT); // 或者 canvas.clear(); } ``` 2. **考虑使用`setWillNotDraw(false)``setWillNotDraw(true)`**:如果你不需要SurfaceView继续接收输入事件,但在后续会重新开始绘制,可以临时设置`willNotDraw`为`true`,这可以让系统回收资源并减少残留的可能性。 ```java view.setWillNotDraw(true); // ...其他处理... view.setWillNotDraw(false); ``` 3. **避免无限循环**:如果`onDraw()`方法被意外地触发,可能导致死循环,应检查并防止这种情况。 4. **及时刷新Surface**:确保Surface的所有更改都被及时更新到显示设备上,你可以调用`requestLayout()``invalidate()`方法来完成。 5. **使用`GLSurfaceView`时的注意事项**:对于OpenGL ES渲染,确保在每次绘制之前都调用了`glClear(GL_COLOR_BUFFER_BIT)`来清除颜色缓冲区。 以上是一般性的建议,具体问题可能需要针对你的应用代码进行排查。如果以上方法都不能解决问题,可能需要查看日志或者进一步分析Surface的工作机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值