[-] Android toolchain - develop for Android devices • Android SDK at D:\Android\sdk ✗ Android SDK is missing command line tools; download from https://goo.gl/XxQghQ • Try re-installing or updating your Android SDK, visit https://flutter.dev/setup/#android-setup for detailed instructions.
publicinterfaceNestedScrollingChild{ voidsetNestedScrollingEnabled(boolean enabled); booleanisNestedScrollingEnabled(); booleanstartNestedScroll(@ScrollAxisint axes); voidstopNestedScroll(); booleanhasNestedScrollingParent(); booleandispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, @Nullableint[] offsetInWindow); booleandispatchNestedPreScroll(int dx, int dy, @Nullableint[] consumed, @Nullableint[] offsetInWindow) ...... }
NestedScrollingParent(省略了Fling相关的方法):
1 2 3 4 5 6 7 8 9
publicinterfaceNestedScrollingParent{ booleanonStartNestedScroll(@NonNull View child, @NonNull View target, @ScrollAxisint axes); voidonNestedScrollAccepted(@NonNull View child, @NonNull View target, @ScrollAxisint axes); voidonStopNestedScroll(@NonNullView target); voidonNestedScroll(@NonNull View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed); voidonNestedPreScroll(@NonNull View target, int dx, int dy, @NonNullint[] consumed); ...... intgetNestedScrollAxes(); }
第二版接口相比于第一版,主要区别是,其中一些方法添加了一个滑动类型参数(触摸、惯性滑动)
NestedScrollingChild2:
1 2 3 4 5 6 7
publicinterfaceNestedScrollingChild2extendsNestedScrollingChild{ booleanstartNestedScroll(@ScrollAxisint axes, @NestedScrollTypeint type); voidstopNestedScroll(@NestedScrollTypeint type); booleanhasNestedScrollingParent(@NestedScrollTypeint type); booleandispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, @Nullableint[] offsetInWindow, @NestedScrollTypeint type); booleandispatchNestedPreScroll(int dx, int dy, @Nullableint[] consumed, @Nullableint[] offsetInWindow, @NestedScrollTypeint type); }
NestedScrollingParent2:
1 2 3 4 5 6 7
publicinterfaceNestedScrollingParent2extendsNestedScrollingParent{ booleanonStartNestedScroll(@NonNull View child, @NonNull View target, @ScrollAxisint axes, @NestedScrollTypeint type); voidonNestedScrollAccepted(@NonNull View child, @NonNull View target, @ScrollAxisint axes, @NestedScrollTypeint type); voidonStopNestedScroll(@NonNullView target, @NestedScrollTypeint type); voidonNestedScroll(@NonNull View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, @NestedScrollTypeint type); voidonNestedPreScroll(@NonNull View target, int dx, int dy, @NonNullint[] consumed, @NestedScrollTypeint type); }
第三版接口再一次添加了一个记录已消耗的滑动距离的参数
NestedScrollingChild3:
1 2 3
publicinterfaceNestedScrollingChild3extendsNestedScrollingChild2{ voiddispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, @Nullableint[] offsetInWindow, @NestedScrollTypeint type, @NonNullint[] consumed); }
NestedScrollingParent3:
1 2 3
publicinterfaceNestedScrollingParent3extendsNestedScrollingParent2{ voidonNestedScroll(@NonNull View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, @NestedScrollTypeint type, @NonNullint[] consumed); }
privatefungetLayoutRange(itemCount: Int): Pair<Int, Int> { var headIndex = -1 var tailIndex = -1 for (i in (0 until itemCount)) { val childTop = getLayoutTop(i) val childBottom = childTop + requiredItemHeight if (isLayoutInVisibleArea(childTop, childBottom)) { headIndex = i break } } for (i in (headIndex + 1 until itemCount)) { val childTop = getLayoutTop(i) if (childTop > height) { tailIndex = i - 1 break } } if (tailIndex < 0) { tailIndex = itemCount - 1 } return headIndex to tailIndex }
privatefunfindClosestItemPosition(): Int { var estimatedPosition = -1 var minDistance = Int.MAX_VALUE for (i in (0 until itemCount)) { val distance = Math.abs(getRequiredScrollOffset(i) - scrollOffsetY) if (distance < minDistance) { minDistance = distance estimatedPosition = i } } return estimatedPosition }
privatefungetNegativeLayoutRange(itemCount: Int): Pair<Int, Int> { var headIndex = -1 var tailIndex = -1 for (i in (itemCount - 1 downTo 0)) { val childTop = getNegativeLayoutTop(i, itemCount) val childBottom = childTop + requiredItemHeight if (isLayoutInVisibleArea(childTop, childBottom)) { tailIndex = i break } }
for (i in (tailIndex - 1 downTo 0)) { val childTop = getNegativeLayoutTop(i, itemCount) val childBottom = childTop + requiredItemHeight if (childBottom < 0) { headIndex = i + 1 break } } if (headIndex < 0) { headIndex = 0 } return headIndex to tailIndex }
<!DOCTYPE html> <html> <head> <metacharset = "UTF-8"> <title>Hello Electron!</title> </head> <body> <h1>Hello Electron!</h1> We are using node <script>document.write(process.versions.node)</script>, Chrome <script>document.write(process.versions.chrome)</script>, and Electron <script>document.write(process.versions.electron)</script>. </body> </html>
val widthMode = View.MeasureSpec.getMode(widthMeasureSpec) val heightMode = View.MeasureSpec.getMode(heightMeasureSpec) val widthSize = View.MeasureSpec.getSize(widthMeasureSpec) val heightSize = View.MeasureSpec.getSize(heightMeasureSpec)
var maxLineWidth = 0//最大行宽 var maxLineHeight = 0//最大行高 var lineWidth = 0//行宽 var totalHeight = 0//所有行占用的总高度 var columnIndex = 0//列顺序 var rowIndex = 0//行顺序
(0 until childCount).forEach { val childView = getChildAt(it) measureChildWithMargins(childView, widthMeasureSpec, 0, heightMeasureSpec, 0) val layoutParams = childView.layoutParams as FlowLayout.LayoutParams
val childWidth = childView.measuredWidth + layoutParams.marginStart + layoutParams.marginEnd val childHeight = childView.measuredHeight + layoutParams.topMargin + layoutParams.bottomMargin