@@ -274,12 +274,177 @@ public virtual void ApplyTo(ConstraintLayout constraintLayout)
274
274
}
275
275
276
276
constraintLayout . mConstraintSet . IsChanged = true ;
277
+ constraintLayout . mConstraintSet . IsForAnimation = false ;
277
278
278
279
UIThread . Invoke ( ( ) =>
279
280
{
280
281
constraintLayout . RequestReLayout ( ) ;
281
282
} , constraintLayout ) ;
283
+ }
284
+
285
+ /// <summary>
286
+ /// 为动画获得坐标,不造成重新Layout
287
+ /// </summary>
288
+ /// <param name="constraintLayout"></param>
289
+ /// <exception cref="Exception"></exception>
290
+ /// <exception cref="NotImplementedException"></exception>
291
+ public virtual void ApplyToForAnim ( ConstraintLayout constraintLayout )
292
+ {
293
+ int parentID = constraintLayout . GetId ( ) ;
294
+
295
+ int count = constraintLayout . ChildCount ;
296
+ List < int > used = mConstraints . Keys . ToList ( ) ; //已经设置了约束的id
297
+ if ( count != used . Count ) Debug . WriteLine ( "The count of ConstraintLayout children is not equal to temprary constraints list, maybe you not use clone." , TAG ) ;
298
+ for ( int i = 0 ; i < count ; i ++ ) //查看layout的child
299
+ {
300
+ View view = constraintLayout . GetChildAt ( i ) ;
301
+
302
+ int id = view . GetId ( ) ;
303
+ if ( ! mConstraints . ContainsKey ( id ) )
304
+ {
305
+ Debug . WriteLine ( $ "id unknown { view } ", TAG ) ;
306
+ continue ;
307
+ }
308
+
309
+ if ( mForceId && id == - 1 )
310
+ {
311
+ throw new Exception ( "All children of ConstraintLayout must have ids to use ConstraintSet" ) ;
312
+ }
313
+ if ( id == - 1 )
314
+ {
315
+ continue ;
316
+ }
317
+
318
+ if ( mConstraints . ContainsKey ( id ) )
319
+ {
320
+ used . Remove ( id ) ;
321
+ Constraint constraint = mConstraints [ id ] ;
322
+ if ( constraint == null )
323
+ {
324
+ continue ;
325
+ }
326
+ if ( view is Barrier )
327
+ {
328
+ constraint . layout . mHelperType = BARRIER_TYPE ;
329
+ Barrier barrier = ( Barrier ) view ;
330
+ //barrier.Id = id;
331
+ barrier . ConstrainType = constraint . layout . mBarrierDirection ;
332
+ barrier . ConstrainMargin = constraint . layout . mBarrierMargin ;
333
+
334
+ barrier . AllowsGoneWidget = constraint . layout . mBarrierAllowsGoneWidgets ;
335
+ if ( constraint . layout . mReferenceIds != null )
336
+ {
337
+ barrier . ReferencedIds = constraint . layout . mReferenceIds ;
338
+ }
339
+ }
340
+
341
+ //将新的约束更新到ConstraintLayout的ConstraintSet中
342
+ var param = constraintLayout . mConstraintSet . Constraints [ id ] ;
343
+ param . layout . Validate ( ) ;
344
+ constraint . ApplyTo ( param . layout ) ; //Android源码ApplyTo是应用到Params,Params中具有负责View布局的属性,其中Margin,Width,Height是ViewGroup自带的,其他是ConstraintLayout中新增的,也就是说,这里使用ConstraintSet替代Params,需要添加ViewGroup的属性
345
+
346
+ //设置原本在ViewGroup.Params中的属性,这些属性影响Android中View的Measure值,因此我们需要在其他平台单独设置
347
+ #if __MAUI__
348
+ //view.SetWidth(constraint.layout.mWidth);
349
+ view . SetWidth ( ConstraintSet . Unset ) ;
350
+ //view.SetHeight(constraint.layout.mHeight);
351
+ view . SetHeight ( ConstraintSet . Unset ) ;
352
+ //view.SetMinWidth(ConstraintSet.Unset);
353
+ //view.SetMinHeight(constraint.layout.matchConstraintMinHeight);
354
+ //view.SetMaxWidth(constraint.layout.matchConstraintMaxWidth);
355
+ //view.SetMaxHeight(constraint.layout.matchConstraintMaxHeight);
356
+ #else
357
+ //view.SetSizeAndMargin(constraint.layout.mWidth, constraint.layout.mHeight, constraint.layout.matchConstraintMinWidth, constraint.layout.matchConstraintMinHeight, constraint.layout.matchConstraintMaxWidth, constraint.layout.matchConstraintMaxHeight, constraint.layout.leftMargin, constraint.layout.topMargin, constraint.layout.rightMargin, constraint.layout.bottomMargin);
358
+ #endif
359
+
360
+ if ( view is Guideline ) //不像Android一样用户提供指定约束是isGuideline就创建Guideline,必须通过Guideline控件实现
361
+ {
362
+ if ( constraint . layout . orientation != Unset ) //如果用户设置了新的orientation
363
+ {
364
+ //Orientation在这里设置的原因是在Measure中当约束update到widget时,其他的widget需要对齐Guideline的widget,如果guideline没有设置orientation,那么widget找不到对应的边的Anchor,因为Guideline需要方向才有正确的Anchor
365
+ ( view as Guideline ) . mGuideline . Orientation = constraint . layout . orientation ;
366
+ }
367
+ }
368
+
369
+ /*if (applyPostLayout)
370
+ {
371
+ ConstraintAttribute.setAttributes(view, constraint.mCustomConstraints);
372
+ }*/
373
+
374
+ if ( constraint . propertySet . mVisibilityMode == VisibilityModeNormal )
375
+ {
376
+ //view.Visibility = constraint.propertySet.visibility;
377
+ param . propertySet . visibility = constraint . propertySet . visibility ; //这里我变成设置constraint
378
+ view . SetViewVisibility ( constraint . propertySet . visibility ) ;
379
+ }
380
+ if ( constraint . propertySet . visibility != ConstraintSet . Invisible ) //在可见性为Invisible时,设置可见性时会将Alpha设置为0,再设置Alpha会造成冲突
381
+ view . SetAlphaProperty ( constraint . propertySet ) ;
382
+ view . SetTransform ( constraint . transform ) ;
383
+ }
384
+ else
385
+ {
386
+ Debug . WriteLine ( TAG , "WARNING NO CONSTRAINTS for view " + id ) ;
387
+ }
388
+ }
389
+
390
+ foreach ( int id in used ) //剩下的约束不在ConstraintLayout的Children中,找出特殊的,如Barrier,Guideline,但是这里我们不弄,因为添加新的View有新的Id,那么就需要更新全部的约束,费时
391
+ {
392
+ if ( id == ConstraintSet . ParentId || id == constraintLayout . GetId ( ) ) //还要处理下layout
393
+ mConstraints [ id ] . ApplyTo ( constraintLayout . mConstraintSet . Constraints [ id ] . layout ) ;
394
+ else
395
+ throw new NotImplementedException ( "如果还有约束身下而且是重要的,那么需要新建View插入原来的布局中,那么但是id怎么办,新建的有新的哈希,而约束是相对旧的哈希." ) ;
396
+ /*Constraint constraint = mConstraints[id];
397
+ if (constraint == null)
398
+ {
399
+ continue;
400
+ }
401
+ if (constraint.layout.mHelperType == BARRIER_TYPE)
402
+ {
403
+ Barrier barrier = new Barrier();
404
+ barrier.Id = id;
405
+ if (constraint.layout.mReferenceIds != null)
406
+ {
407
+ barrier.ReferencedIds = constraint.layout.mReferenceIds;
408
+ }
409
+ else if (!string.ReferenceEquals(constraint.layout.mReferenceIdString, null))
410
+ {
411
+ constraint.layout.mReferenceIds = convertReferenceString(barrier, constraint.layout.mReferenceIdString);
412
+ barrier.ReferencedIds = constraint.layout.mReferenceIds;
413
+ }
414
+ barrier.Type = constraint.layout.mBarrierDirection;
415
+ barrier.Margin = constraint.layout.mBarrierMargin;
416
+ LayoutParams param = constraintLayout.generateDefaultLayoutParams();
417
+ barrier.validateParams();
418
+ constraint.applyTo(param);
419
+ constraintLayout.addView(barrier, param);
420
+ }
421
+ if (constraint.layout.mIsGuideline)
422
+ {
423
+ Guideline g = new Guideline(constraintLayout.Context);
424
+ g.Id = id;
425
+ ConstraintLayout.LayoutParams param = constraintLayout.generateDefaultLayoutParams();
426
+ constraint.applyTo(param);
427
+ constraintLayout.addView(g, param);
428
+ }*/
429
+ }
430
+ for ( int i = 0 ; i < count ; i ++ )
431
+ {
432
+ View view = constraintLayout . GetChildAt ( i ) ;
433
+
434
+ if ( view is ConstraintHelper )
435
+ {
436
+ ConstraintHelper constraintHelper = ( ConstraintHelper ) view ;
437
+ constraintHelper . applyLayoutFeaturesInConstraintSet ( constraintLayout ) ;
438
+ }
439
+ }
440
+
441
+ constraintLayout . mConstraintSet . IsChanged = true ;
442
+ constraintLayout . mConstraintSet . IsForAnimation = true ;
282
443
444
+ //UIThread.Invoke(() =>
445
+ //{
446
+ // constraintLayout.RequestReLayout();
447
+ //}, constraintLayout);
283
448
}
284
449
285
450
/// <summary>
0 commit comments