2017-04-19 6 views
0

のようなカスタムリストビューを書く:私が知っているように、ListViewをスクロールすると、なぜonLayoutメソッドがListViewで呼び出されないのですか?

public class MyListView extends ListView { 
    public MyListView(Context context) { 
     super(context); 
    } 

    public MyListView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public MyListView(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
    } 

    @Override 
    protected void onLayout(boolean changed, int l, int t, int r, int b) { 
     super.onLayout(changed, l, t, r, b); 
     Log.d("onLayout","onLayout====="); 
    } 
} 

ビューのレイアウト属性が変更された場合、変更(invalide()またはrequestLayoutを())を適用するためには、その親のonLayout方法があるべきその子を呼び出す。

ListViewをスクロールすると、子ビューのレイアウト属性は変更されましたが、onLayoutはまったく呼び出されません。どうして?

+0

このソリューションをチェックしてみてください。0120-919-066_android_when-onlayout-calls –

+0

スクロールでは_layout_、表示されているListViewの部分だけです。したがって、子を再レイアウトする必要はありません。リストビューが占める_size_を変更すると、通常は子のレイアウトを再計算する必要があるため、onLayoutを呼び出す必要があります。 – TripeHound

+0

リストビューをスクロールしても、それは変更されません。ビューの下にビューを追加して、そのビューの表示を切り替えて、 'onLayout'コールを参照してください。 –

答えて

0

最後に、ViewGroupは必ずonLayout()/ layout()メソッドを呼び出す必要はありません。ViewGroupのビュー位置を変更する方法はたくさんありますが、それぞれの方法でonDraw()を呼び出して、 。画面にそれを表示するために、フレームバッファ(私はこれで間違っているかどうかを教えてください) リストビューでは、私はソースコードをデバッグ、およびときに、スクロールリストビューいた、スタックトレースは次のとおりです。 `

trackMotionScroll:5023, AbsListView (android.widget) 
scrollIfNeeded:3424, AbsListView (android.widget) 
startScrollIfNeeded:3352, AbsListView (android.widget) 
onTouchMove:3793, AbsListView (android.widget) 
onTouchEvent:3651, AbsListView (android.widget) 
dispatchTouchEvent:9294, View (android.view) 

trackMotionScrollで、ViewGroup#offsetChildrenTopAndBottom(incrementalDeltaY)を呼び出します。

public void offsetChildrenTopAndBottom(int offset) { 
    final int count = mChildrenCount; 
    final View[] children = mChildren; 
    boolean invalidate = false; 

    for (int i = 0; i < count; i++) { 
     final View v = children[i]; 
     v.mTop += offset; 
     v.mBottom += offset; 
     if (v.mRenderNode != null) { 
      invalidate = true; 
      v.mRenderNode.offsetTopAndBottom(offset); 
     } 
    } 

    if (invalidate) { 
     invalidateViewProperty(false, false); 
    } 
    notifySubtreeAccessibilityStateChangedIfNeeded(); 
} 

これにより、ListViewのreLayoutが発生します。 私は結論を得ました。フレームワークのmeasure() - layout() - draw()プロシージャに従う必要はなく、ビューのレイアウト属性を変更して無効にするだけで、ビューのレイアウトも変更されます。 そして、ListViewがレイアウトを取り除くと思いますが、スクロールで効率が向上すると思います。

関連する問題