Search code examples
androidredrawcustom-view

Custom view unnecessarily redrawn


I have created a custom view com.mydomain.android.KTab, as the XML shown below, I have a FrameLayout on top and my custom view at the bottom.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/radialback">

<FrameLayout
    android:id="@+id/contentFrame" 
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    android:layout_gravity="top"
    android:background="#ffcccccc"/>

<view
    class="com.mydomain.android.KTab"
    android:id="@+id/kTab"
    android:layout_width = "fill_parent"
    android:layout_height = "80dip"/>


</LinearLayout>

I programmatically add a ScrollView to the FrameLayout as in the following code:

TextView tv = new TextView(this);
tv.setText("a long long string...");
ScrollView sv = new ScrollView(this);
sv.addView(tv);
FrameLayout fl = (FrameLayout)findViewById(R.id.contentFrame);
fl.addView(sv);

Now it works good when seen from the surface, but the onDraw() method of my custom view(KTab in this case) is constantly called when I scroll contentFrame, I don't understand why my custom view is affected by the scrolling, it's unnecessary.

Anyone could give a clue on this?


Solution

  • Alright, I have solved this problem.

    It's quite a subtle problem, when I put the FrameLayout and my custom view in adjacent to each other, my custom view will be invalidated(and then onDraw() being called) when I scroll the ScrollView in the FrameLayout. I guess it is because the two views are next to each other and there's 1 pixel overlapped, when the ScrollView is scrolled and then invalidated, so will be my custom view.

    The trick is to ensure that there's at least 1 pixel gap between the FrameLayout and my custom view, adding the following to FrameLayout properties saves my life.

    android:layout_marginBottom="1px"