Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/204.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Invalidate()不';事实上,我没有重画孩子_Android_Android Layout_Android View - Fatal编程技术网

Android Invalidate()不';事实上,我没有重画孩子

Android Invalidate()不';事实上,我没有重画孩子,android,android-layout,android-view,Android,Android Layout,Android View,所以,我有一个非常奇怪的设置,我从中得到一些奇怪的视觉错误。基本上,我在一个相对的布局中有两个视图:第一个是ImageView背景图像;第二个是相同的背景图像,但模糊以产生一种磨砂玻璃后的效果: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/pr

所以,我有一个非常奇怪的设置,我从中得到一些奇怪的视觉错误。基本上,我在一个相对的布局中有两个视图:第一个是ImageView背景图像;第二个是相同的背景图像,但模糊以产生一种磨砂玻璃后的效果:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/profile_holder"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <!-- background -->
    <ImageView
        android:id="@+id/backgroundImage"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="0dp"
        android:layout_marginTop="0dp"
        android:scaleType="centerCrop"
        android:src="@drawable/default_logo" />

    <!-- blurry background -->
    <com.custom.MaskedBlurredBackgroundView_
        android:id="@+id/blurred_background"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="0dp"
        android:layout_marginTop="0dp" />

<ScrollView
    android:id="@+id/scrolly"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true" >

            <com.custom.HalvedLinearLayout_
                android:paddingTop="100dp"
                android:id="@+id/profileHolder"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                 >

                <Button
                    android:id="@+id/profileButtonTracks"
                    style="@style/ProfileButtons"
                    android:drawableLeft="@drawable/ic_profile_menu_music"
                    android:text="@string/profile_button_tracks" />

...
现在的问题是,一切都正常工作,除了滚动滚动滚动视图时,模糊的背景实际上覆盖了一半的线性布局,抹去了其中的按钮。(但有时只能半途而废。有时会很好,有时按钮的一半会被拉掉,另一半会保留下来……各种奇怪的故障。)

我开始调试,我注意到了一些有趣的事情:在rootView上调用invalidate()实际上并不会使所有子项失效()。我用一些日志文件覆盖了所有的invalidate和draw函数:

public class MaskedBlurredBackgroundView extends BlurredBackgroundView {
    /***
     * Sets the mask to cover everything above the given Y coordinate
     * @param t Y Coordinate in pixels
     */
    public void setMaskBottom(int y) {
        maskBottom  = y;
    }

    private void clipCanvas(Canvas canvas) {
        Logger.d(TAG, "dispatchDraw clipping: " + maskBottom + ", " + getWidth() + "," + getHeight());
        canvas.clipRect(0, maskBottom, getWidth(), getHeight(), Region.Op.REPLACE);
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        canvas.save();
        clipCanvas(canvas);
        super.dispatchDraw(canvas);

        canvas.restore();
    }
    @Override
    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
        Logger.d(TAG, "drawChild: " + child + getWidth() + "," + getHeight());

        return super.drawChild(canvas, child, drawingTime);
    }

    @Override
    public void invalidate() {
        Logger.d(TAG, "invalidate: " + getWidth() + "," + getHeight());
        super.invalidate();
    }
现在,当我查看日志时,当我滚动时,rootView.invalidate()会启动,但子项从不重新绘制:

07-23 12:36:49.328: D/BandDetailFrag(12982): positionMask() 2131165298
07-23 12:36:49.348: D/BandDetailFrag(12982): positionMask() 2131165298
07-23 12:36:49.348: D/BandDetailFrag(12982): positionMask() 2131165298
07-23 12:36:49.368: D/BandDetailFrag(12982): positionMask() 2131165298
07-23 12:36:49.368: D/BandDetailFrag(12982): positionMask() 2131165298
07-23 12:36:49.378: D/BandDetailFrag(12982): positionMask() 2131165298
07-23 12:36:49.398: D/BandDetailFrag(12982): positionMask() 2131165298
07-23 12:36:49.418: D/BandDetailFrag(12982): positionMask() 2131165298
07-23 12:36:49.448: D/BandDetailFrag(12982): positionMask() 2131165298
07-23 12:36:49.478: D/BandDetailFrag(12982): positionMask() 2131165298
我如何强制孩子们按照正确的顺序重新绘制?现在我猜他们画得很乱,这就是为什么模糊的背景画得比其他东西都好

以下是该故障的屏幕截图:


好的,我找到了解决问题的方法,至少:我所要做的就是将“Region.Op.REPLACE”改为“Region.Op.INTERSECT”,现在它可以工作了


Invalidate()仍然没有重新绘制子项,但我想现在我可以顺其自然了。

我在
Invalidate()中遇到了同样的问题,因为其他地方没有好的答案,所以我想我应该发布我的解决方案

这是一个递归函数,将在
视图组的所有子视图中循环。如果子对象是
视图组
,它将递归并搜索子对象。否则,它将对子级调用
invalidate()
(这是终止情况)

public void invalidater草书(视图组布局){
int count=layout.getChildCount();
看孩子;
for(int i=0;i
参数
layout
应该可以是
ViewGroup
类型的任何对象(
LinearLayout
RelativeLayout
等),这是一个非常通用的解决方案


它符合我的目的,但我还没有对它进行彻底的测试。如果有任何错误,请评论并让我知道。

您是否尝试过requestLayout()?这应该也会刷新子视图。当触发滚动事件时,您可以为模糊背景设置可见性(View.INVISIBLE)。@Cata:我刚刚尝试了requestLayout()。她看起来很可爱。
invalidate
不会重画任何东西。它只是将区域标记为无效,这导致Android开始在绘图管道中重新绘制。
07-23 12:36:49.328: D/BandDetailFrag(12982): positionMask() 2131165298
07-23 12:36:49.348: D/BandDetailFrag(12982): positionMask() 2131165298
07-23 12:36:49.348: D/BandDetailFrag(12982): positionMask() 2131165298
07-23 12:36:49.368: D/BandDetailFrag(12982): positionMask() 2131165298
07-23 12:36:49.368: D/BandDetailFrag(12982): positionMask() 2131165298
07-23 12:36:49.378: D/BandDetailFrag(12982): positionMask() 2131165298
07-23 12:36:49.398: D/BandDetailFrag(12982): positionMask() 2131165298
07-23 12:36:49.418: D/BandDetailFrag(12982): positionMask() 2131165298
07-23 12:36:49.448: D/BandDetailFrag(12982): positionMask() 2131165298
07-23 12:36:49.478: D/BandDetailFrag(12982): positionMask() 2131165298
public void invalidateRecursive(ViewGroup layout) {
    int count = layout.getChildCount();
    View child;
    for (int i = 0; i < count; i++) {
        child = layout.getChildAt(i);
        if(child instanceof ViewGroup)
            invalidateRecursive((ViewGroup) child);
        else
            child.invalidate();
    }
}