AndroidコーディネートレイアウトCoordinatorLayoutイメージノート

6734 ワード

1.題記
この記事では、一般的な調整レイアウトCoordinatorLayoutの内部viewの関係を簡単に説明します.
2.本文
最も一般的なレイアウトの例を挙げます




    

        

            

            

        
    

    

        

    


最初はこのレイアウトを見てぼんやりしていて、タイトルバーがこんなに複雑で、何層もネストされていて、とても不合理だと思います.私はそれらのケースを1つ1つ取り除いて実行して効果を見てみました(申し訳ありませんが、新しい私は効果を見てから具体的な原因を分析しています)、走ってみると、
2.1 AppBarLayoutについて
では、このAppBarLayoutが何なのかを見てみましょう.それがなければ、タイトルバーは次のNestedScrollViewと調整できません.apiを見て、LinearLayoutに継承されていることを知っています.
@CoordinatorLayout.DefaultBehavior(AppBarLayout.Behavior.class)
public class AppBarLayout extends LinearLayout {
  //...todo
}

ああ、不思議なものが現れました.AppBarLayoutは注釈でBehaviorをバインドしました.BehaviorはCoordinatorLayoutの非常に重要な特性と言えます.Behaviorを通じてコントロール子Viewの動作を監視し、カスタマイズすることができます.これがポイントです.AppBarLayoutがあってこそスクロールを調整することができ、AppBarLayoutのタイトルバーがなければ固定できない理由でもあります.引き続きBehaviorを見て、AppBarLayoutの内部クラスであることを発見しました.
 public static class Behavior extends HeaderBehavior {//TODO...}

BehaviorはHeaderBehaviorから継承され、HeaderBehaviorの中でタッチイベントを書き換え、リスナーのリアルタイム変化を伴う.
        
abstract class HeaderBehavior extends ViewOffsetBehavior {
    @Override
    public boolean onTouchEvent(CoordinatorLayout parent, V child, MotionEvent ev) {
        switch (MotionEventCompat.getActionMasked(ev)) {
            case MotionEvent.ACTION_DOWN: {
                final int x = (int) ev.getX();
                final int y = (int) ev.getY();

                if (parent.isPointInChildBounds(child, x, y) && canDragView(child)) {
                    mLastMotionY = y;
                    mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
                    ensureVelocityTracker();
                } else {
                    return false;
                }
                break;
            }

            case MotionEvent.ACTION_MOVE: {
                final int activePointerIndex = MotionEventCompat.findPointerIndex(ev,
                        mActivePointerId);
                if (activePointerIndex == -1) {
                    return false;
                }

                final int y = (int) MotionEventCompat.getY(ev, activePointerIndex);
                int dy = mLastMotionY - y;

                if (!mIsBeingDragged && Math.abs(dy) > mTouchSlop) {
                    mIsBeingDragged = true;
                    if (dy > 0) {
                        dy -= mTouchSlop;
                    } else {
                        dy += mTouchSlop;
                    }
                }

                if (mIsBeingDragged) {
                    mLastMotionY = y;
                    // We're being dragged so scroll the ABL
                    scroll(parent, child, dy, getMaxDragOffset(child), 0);
                }
                break;
            }

            case MotionEvent.ACTION_UP:
                if (mVelocityTracker != null) {
                    mVelocityTracker.addMovement(ev);
                    mVelocityTracker.computeCurrentVelocity(1000);
                    float yvel = VelocityTrackerCompat.getYVelocity(mVelocityTracker,
                            mActivePointerId);
                    fling(parent, child, -getScrollRangeForDragFling(child), 0, yvel);
                }
                // $FALLTHROUGH
            case MotionEvent.ACTION_CANCEL: {
                mIsBeingDragged = false;
                mActivePointerId = INVALID_POINTER;
                if (mVelocityTracker != null) {
                    mVelocityTracker.recycle();
                    mVelocityTracker = null;
                }
                break;
            }
        }

        if (mVelocityTracker != null) {
            mVelocityTracker.addMovement(ev);
        }

        return true;
    }
    private class FlingRunnable implements Runnable {
        private final CoordinatorLayout mParent;
        private final V mLayout;

        FlingRunnable(CoordinatorLayout parent, V layout) {
            mParent = parent;
            mLayout = layout;
        }

        @Override
        public void run() {
            if (mLayout != null && mScroller != null) {
                if (mScroller.computeScrollOffset()) {
                    setHeaderTopBottomOffset(mParent, mLayout, mScroller.getCurrY());
                    // Post ourselves so that we run on the next animation
                    ViewCompat.postOnAnimation(mLayout, this);
                } else {
                    onFlingFinished(mParent, mLayout);
                }
            }
        }
    }
}

コードが完全に貼られていないので、興味があるのはapiと次の流れを見ることができて、総合的に、この比較的特別なAppBarLayoutの特別なところはそれが特別なBehaviorを縛って、このBehaviorはOnTouch事件を書き直して、親レイアウト(CoordinatorLayout)の変化の動態を傍受して、そのため内部は対応する変化の調整をすることができます.
2.2 CollapsingToolbarLayoutについて
CollapsingToolbarrayoutについて、csdnにはよく説明されている文章があります.ここにリンクを貼ります.CollapsingToolbarrayout詳しく教えてください.
3.まとめ
以上、村の通電は間もなく、書くのがとても乱れて、頑張って頑張ります.