范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

Compose动画艺术探索之可见性动画

  本篇文章是此专栏的第二篇文章,上一篇文章简单写了下  Compose   的动画,让大家先看了下 Compose   开箱即用的动画效果,效果还是挺好的,感兴趣的可以去看下:Compose 动画艺术探索之瞅下 Compose 的动画从可见性动画看起
  可见性动画在上一篇文章中介绍过,不过只是简单使用,没看过上一篇文章的也不用担心,给大家看下可见性动画的实际效果。
  实现代码也很简单,来回顾下: val visible = remember { mutableStateOf(true) } AnimatedVisibility(visible = visible.value,) {     Text(text = "天青色等烟雨,而我在等你,炊烟袅袅升起,隔江千万里") }
  上一篇文章主要介绍了  Compose   动画的便携之处,例如上面代码,确实非常简单就能实现之前原生安卓中比较难实现的动画效果,今天咱们就来稍微深入一点看看,从小节标题也能知道,就从可见性动画来看!
  怎么看呢?直接点进去源码来看!先来看看  AnimatedVisibility   的函数定义吧!@Composable fun AnimatedVisibility(     visible: Boolean,     modifier: Modifier = Modifier,     enter: EnterTransition = fadeIn() + expandIn(),     exit: ExitTransition = shrinkOut() + fadeOut(),     label: String = "AnimatedVisibility",     content: @Composable() AnimatedVisibilityScope.() -> Unit ) {     val transition = updateTransition(visible, label)     AnimatedEnterExitImpl(transition, { it }, modifier, enter, exit, content) }
  其实可组合项  AnimatedVisibility   不是只有这一个,目前 Compose 1.3.0-beta02   版本中有六个,这个咱们待会再说,先看这一个,也是第一个,可以看到函数中一共可以接收六个参数,下面先来看看这六个参数分别有什么作用吧:visible :定义内容是否应该可见,true 为可见,false 为不可见modifier :修饰符,这个就不多说了,在 Compose   中 Modifier   简直随处可见enter :内容出现时的动画,可以看到这个参数有默认值,默认值为 fadeIn() + expandIn()   ,大致意思为淡入并扩展开exit :内容由可见变为不可见时的动画,同样的,这个参数也有默认值,默认值为 shrinkOut() + fadeOut()   ,大致意思为缩小并淡出消失label :字面意思理解为标签,默认值为 AnimatedVisibility   ,可以自定义做标记,用于区分不同动画content :需要添加可见性动画的可组合项。
  上面这些参数除了  enter   和 exit   外都比较好理解,这里就不做过多解释,重点来看下 enter   和 exit   ,可以看到 enter   的类型为 EnterTransition   ,exit   的类型为 ExitTransition   ,那么接下来咱们来分别看看 EnterTransition   和 ExitTransition   吧!
  这里其实有一个小问题,可以看到上面 Gif 图中并不是淡入并扩展和缩小并消失,这是为什么呢?继续往下看就能找到答案!  进入过渡——EnterTransition
  顾名思义,这个类主要是为了做进入过渡的,来简单看下它的源码吧: @Immutable sealed class EnterTransition {     internal abstract val data: TransitionData      // 组合不同的进入转换。组合的顺序并不重要,因为这些将同时启动     @Stable     operator fun plus(enter: EnterTransition): EnterTransition {         return EnterTransitionImpl(             TransitionData(                 fade = data.fade ?: enter.data.fade,                 slide = data.slide ?: enter.data.slide,                 changeSize = data.changeSize ?: enter.data.changeSize,                 scale = data.scale ?: enter.data.scale             )         )     }        companion object {         // 当不需要输入转换时,可以使用此函数。         val None: EnterTransition = EnterTransitionImpl(TransitionData())     } }
  可以看到  EnterTransition   是一个密封类, 类中有一个抽象的不可变值 data   ,类型为 TransitionData   ,这个放到下面来说;类中还有一个函数,而且该函数有 operator   前缀, 这表示运算符重载,重载了"+"号,所以就可以使用"+"来组合不同的输入动画了,函数接收的参数也是 EnterTransition   ,然后直接返回 EnterTransitionImpl   ,又没见过,怎么办?继续看看 EnterTransitionImpl   是个啥!@Immutable private class EnterTransitionImpl(override val data: TransitionData) : EnterTransition()
  可以看到  EnterTransitionImpl   类很简单,是一个私有类,继承自 EnterTransition   ,注意类上有 Immutable   注解, Immutable   注解可用于将类标记为生成不可变实例,但类的不变性没有得到验证,它是类型的一种承诺,即在构造实例之后,所有公开可访问的属性和字段都不会更改。 EnterTransitionImpl   还需要实现父类的抽象值,所有有 TransitionData   类型的参数 data   ,上面咱们简单提到了 TransitionData   ,这里来看下吧!@Immutable internal data class TransitionData(     val fade: Fade? = null,     val slide: Slide? = null,     val changeSize: ChangeSize? = null,     val scale: Scale? = null )
  可以看到  TransitionData   类也有 Immutable   注解,这里就不做过多介绍,这是一个包内可见的数据类,里面有四个不可变值,分别是 Fade   、Slide   、ChangeSize   、Scale   ,其实从名称就能看出这几个参数分别代表的意思,不过还是来看下它们的源码吧!@Immutable internal data class Fade(val alpha: Float, val animationSpec: FiniteAnimationSpec)   @Immutable internal data class Slide(     val slideOffset: (fullSize: IntSize) -> IntOffset,     val animationSpec: FiniteAnimationSpec )   @Immutable internal data class ChangeSize(     val alignment: Alignment,     val size: (fullSize: IntSize) -> IntSize = { IntSize(0, 0) },     val animationSpec: FiniteAnimationSpec,     val clip: Boolean = true )   @Immutable internal data class Scale(     val scale: Float,     val transformOrigin: TransformOrigin,     val animationSpec: FiniteAnimationSpec )
  可以看到这四个类都是不可变的数据类,分别表示颜色转变、滑动、大小变化及缩放。这几个类有一个共同点,都有一个共同的参数  animationSpec   ,参数类型为 FiniteAnimationSpec   ,来看看 FiniteAnimationSpec   是个啥?interface FiniteAnimationSpec : AnimationSpec {     override fun  vectorize(         converter: TwoWayConverter     ): VectorizedFiniteAnimationSpec }
  可以看到  FiniteAnimationSpec   是一个接口,继承自 AnimationSpec   ,简单理解就是有限动画规格,定义了动画的时长及动画效果等,类似于原生安卓中的什么呢?嗯…差值器吧!FiniteAnimationSpec   是所有非无限动画实现的接口,包括: TweenSpec  , SpringSpec  , KeyframesSpec  , RepeatableSpec  , SnapSpec   等等,上一篇文章中说到的无限循环动画 InfiniteRepeatableSpec   没有继承这个接口,其实从名字看就知道了,InfiniteRepeatableSpec   也继承自 AnimationSpec   …
  不行不行,扯太远了,其实看源码就是这样,看着看着一直往下看就会迷失了最初的目标,越看越多,越看越多,这里就先不接着往下看了,再看就没完没了了,这里咱们知道这四个类大概存储了什么数据就行了。动画规格咱们放到之后的文章中慢慢看,今天主要来过一遍可见性动画!
  简单总结下,  EnterTransition   类中有一个函数,进行了运算符重载,可以有多个动画同时进行。关闭过渡——ExitTransition
  其实看完刚才的  EnterTransition   类再来看 ExitTransition   就会觉得很简单了,不信的话咱们来看下 ExitTransition   的源码:@Immutable sealed class ExitTransition {     internal abstract val data: TransitionData       // 结合不同的退出转换,组合顺序并不重要     @Stable     operator fun plus(exit: ExitTransition): ExitTransition {         return ExitTransitionImpl(             TransitionData(                 fade = data.fade ?: exit.data.fade,                 slide = data.slide ?: exit.data.slide,                 changeSize = data.changeSize ?: exit.data.changeSize,                 scale = data.scale ?: exit.data.scale             )         )     }       companion object {         // 当不需要内置动画时使用         val None: ExitTransition = ExitTransitionImpl(TransitionData())     } }
  是不是基本一致,连抽象不可变值都一摸一样,甚至值的名称都没变!唯一不同的是  EnterTransition   的实现类为 EnterTransitionImpl   ,而 ExitTransition   的子类为 ExitTransitionImpl   ,那就再看看 ExitTransitionImpl   !@Immutable private class ExitTransitionImpl(override val data: TransitionData) : ExitTransition()
  和  EnterTransitionImpl   不能说相似,只能说一摸一样…所以就不做过多介绍…过渡——Transition
  文章开头的时候看  AnimatedVisibility   函数中只有下面的两行代码,val transition = updateTransition(visible, label) AnimatedEnterExitImpl(transition, { it }, modifier, enter, exit, content)
  这一小节咱们先来看第一行,可以看到调用了  updateTransition   函数, 传入了当前显示状态和标签,来具体看下这个函数吧!@Composable fun  updateTransition(     targetState: T,     label: String? = null ): Transition {     val transition = remember { Transition(targetState, label = label) }     transition.animateTo(targetState)     DisposableEffect(transition) {         onDispose {             // 出去的时候清理干净,确保观察者不会被困在中间状态             transition.onTransitionEnd()         }     }     return transition }
  可以看到这个函数也是一个可组合项,返回值为  Transition   ,函数中先记住并构建了一个 Transition   ,然后调用了 Transition   的 animateTo   函数来执行过渡动画,然后调用了需要清理的效应 DisposableEffect   ,之后在 onDispose   中调用了 onTransitionEnd   函数,以防卡在这里,最后返回刚才构建的 Transition   。
  函数中的内容不难理解,现在唯一困惑的是  Transition   是个什么东西!那就来看看!@Stable class Transition @PublishedApi internal constructor(     private val transitionState: MutableTransitionState,     val label: String? = null )
  这就是  Transition   的类声明,Transition   在状态级别上管理所有子动画。子动画可以使用Transition   以声明的方式创建。animateFloat  、animateValue  、animateColor   animateColor  等。当 targetState   改变时,Transition   将自动启动或调整其所有子动画的路线,使其动画到为每个动画定义的新目标值。
  可以看到  Transition   构造函数中接收一个 MutableTransitionState   类型的参数和一个 lable   ,但咱们看到上面传入的并不是 MutableTransitionState   类型的参数,肯定还有别的构造函数!internal constructor(     initialState: S,     label: String? ) : this(MutableTransitionState(initialState), label)
  没错,确实还有一个构造函数,接下来看下  MutableTransitionState   吧!class MutableTransitionState(initialState: S) {     // 当前的状态     var currentState: S by mutableStateOf(initialState)         internal set       // 过渡的目标状态     var targetState: S by mutableStateOf(initialState)       // 是否空闲     val isIdle: Boolean         get() = (currentState == targetState) && !isRunning       // 是否运行     internal var isRunning: Boolean by mutableStateOf(false) }
  可以看到  MutableTransitionState   中构建了几个需要的状态,具体表示什么在上面代码中添加了注释。过渡动画实现——AnimatedEnterExitImpl
  刚才看了  AnimatedVisibility   函数中的第一行代码,下面咱们来看下第二行代码:AnimatedEnterExitImpl(transition, { it }, modifier, enter, exit, content)
  这块调用了一个实现函数,将刚构建好的  Transition   和之前的 EnterTransition   、ExitTransition   统统传了进去,下面就来看下 AnimatedEnterExitImpl   !@Composable private fun  AnimatedEnterExitImpl(     transition: Transition,visible: (T) -> Boolean,     modifier: Modifier,enter: EnterTransition,     exit: ExitTransition,content: @Composable() AnimatedVisibilityScope.() -> Unit ) {     val isAnimationVisible = remember(transition) {         mutableStateOf(visible(transition.currentState))     }       if (visible(transition.targetState) || isAnimationVisible.value || transition.isSeeking) {         val childTransition = transition.createChildTransition(label = "EnterExitTransition") {             transition.targetEnterExit(visible, it)         }           LaunchedEffect(childTransition) {             snapshotFlow {                 childTransition.currentState == EnterExitState.Visible ||                     childTransition.targetState == EnterExitState.Visible             }.collect {                 isAnimationVisible.value = it             }         }           AnimatedEnterExitImpl(childTransition,modifier,             enter = enter,exit = exit,content = content         )     } }
  这块代码有点多啊,但不要害怕,可以看到基本上这里使用到的类在刚才咱们都看过了,接下来需要的就是一行一行往下看,看看哪个没见过咱们再看!
  函数中先记录了当前的状态,然后判断当前的状态值是否为 true,如果为 true 的话则创建子过渡,老规矩,来看看  createChildTransition   !@Composable inline fun  Transition.createChildTransition(     label: String = "ChildTransition",     transformToChildState: @Composable (parentState: S) -> T, ): Transition {     val initialParentState = remember(this) { this.currentState }     val initialState = transformToChildState(if (isSeeking) currentState else initialParentState)     val targetState = transformToChildState(this.targetState)     return createChildTransitionInternal(initialState, targetState, label) }
  可以看到  createChildTransition   是 Transition   的一个扩展函数,还是一个高阶函数,函数内获取了高阶函数中的返回值,然后直接返回调用了 createChildTransitionInternal   ,并传入获取的值,这个值目前还不知道是什么,只知道是 targetEnterExit   返回的数据,这个一会再看,先接着看 createChildTransitionInternal   函数:@Composable internal fun  Transition.createChildTransitionInternal(     initialState: T,     targetState: T,     childLabel: String, ): Transition {     val transition = remember(this) {         Transition(MutableTransitionState(initialState), "${this.label} > $childLabel")     }     DisposableEffect(transition) {         addTransition(transition)         onDispose {             removeTransition(transition)         }     }     if (isSeeking) {         transition.setPlaytimeAfterInitialAndTargetStateEstablished(             initialState,             targetState,             this.lastSeekedTimeNanos         )     } else {         transition.updateTarget(targetState)         transition.isSeeking = false     }     return transition }
  可以看到  createChildTransitionInternal   也是 Transition   的一个扩展函数,然后函数中也使用了需要清理的效应,之后判断 isSeeking   的值是,isSeeking   的值在 setPlaytimeAfterInitialAndTargetStateEstablished   函数中会被置为 true,如果 isSeeking   值为 true 则调用 setPlaytimeAfterInitialAndTargetStateEstablished   函数,用来设置初始状态和目标状态建立后的时间,如果为 false,则更新状态值。
  到这里  createChildTransition   函数咱们大概看了下,但刚才还有一个扣,刚才说了不知道目标值是什么,因为那是 targetEnterExit   的返回值,现在咱们来看看!@Composable private fun  Transition.targetEnterExit(     visible: (T) -> Boolean,     targetState: T ): EnterExitState = key(this) {       if (this.isSeeking) {         if (visible(targetState)) {             Visible         } else {             if (visible(this.currentState)) {                 PostExit             } else {                 PreEnter             }         }     } else {         val hasBeenVisible = remember { mutableStateOf(false) }         if (visible(currentState)) {             hasBeenVisible.value = true         }         if (visible(targetState)) {             EnterExitState.Visible         } else {             // If never been visible, visible = false means PreEnter, otherwise PostExit             if (hasBeenVisible.value) {                 EnterExitState.PostExit             } else {                 EnterExitState.PreEnter             }         }     } }
  同样的, targetEnterExit   也是一个扩展函数,返回值为 EnterExitState   。这里也使用了 isSeeking   来进行判断,然后根据当前的值来设置不同的 EnterExitState   。EnterExitState   又是个啥呢???接着来看!enum class EnterExitState {     // 自定义进入动画的初始状态。     PreEnter,       // 自定义进入动画的目标状态,也是动画过程中自定义退出动画的初始状态。     Visible,       // 自定义退出动画的目标状态。     PostExit }
  奥, EnterExitState   只是一个枚举类,定义了三种状态:初始状态、进入动画的状态和退出动画的状态。
  下面接着来看  AnimatedEnterExitImpl   :LaunchedEffect(childTransition) {             snapshotFlow {                 childTransition.currentState == EnterExitState.Visible ||                     childTransition.targetState == EnterExitState.Visible             }.collect {                 isAnimationVisible.value = it             }         }   AnimatedEnterExitImpl(childTransition,modifier,             enter = enter,exit = exit,content = content         )
  这里使用了  LaunchedEffect   效应,并使用 snapshotFlow   将 State   转为了 Flow   ,然后将值设置到 isAnimationVisible   。
  后面又调用了相同名字的一个函数  AnimatedEnterExitImpl   :@Composable private inline fun AnimatedEnterExitImpl(     transition: Transition,     modifier: Modifier,     enter: EnterTransition,     exit: ExitTransition,     content: @Composable AnimatedVisibilityScope.() -> Unit ) {     if (transition.currentState == EnterExitState.Visible ||         transition.targetState == EnterExitState.Visible     ) {         val scope = remember(transition) { AnimatedVisibilityScopeImpl(transition) }         Layout(             content = { scope.content() },             modifier = modifier.then(transition.createModifier(enter, exit, "Built-in")),             measurePolicy = remember { AnimatedEnterExitMeasurePolicy(scope) }         )     } }
  函数名字一样,但参数不同,这里将刚才构建好的  Transition   传了进来,然后函数内先对状态进行了过滤,然后构建了 Layout   。
  Layout   中设置了 modifier   ,modifier   调用了 then   函数,then   函数用于将此修饰符与另一个修饰符连接,然后连接了 transition.createModifier(enter, exit, "Built-in")   ,大家发现点什么没有,这里使用到了上面咱们构建好了所有东西…那么…哈哈哈哈!柳暗花明
  下面咱们就来看看  transition.createModifier   这个函数,先来看下函数体:@Composable internal fun Transition.createModifier(     enter: EnterTransition,     exit: ExitTransition,     label: String ): Modifier
  嗯,没错,是  Transition   的一个扩展函数,也是一个可组合项!接着往下看几行代码:var modifier: Modifier = Modifier   modifier = modifier.slideInOut(     this,     rememberUpdatedState(enter.data.slide),     rememberUpdatedState(exit.data.slide),     label ).shrinkExpand(     this,     rememberUpdatedState(enter.data.changeSize),     rememberUpdatedState(exit.data.changeSize),     label )
  构建了一个  Modifier   ,然后调用了 slideInOut   和 shrinkExpand   ,没错,这是滑动和缩小放大!接着来!var shouldAnimateAlpha by remember(this) { mutableStateOf(false) } var shouldAnimateScale by remember(this) { mutableStateOf(false) } if (currentState == targetState && !isSeeking) {     shouldAnimateAlpha = false     shouldAnimateScale = false } else {     if (enter.data.fade != null || exit.data.fade != null) {         shouldAnimateAlpha = true     }     if (enter.data.scale != null || exit.data.scale != null) {         shouldAnimateScale = true     } }
  创建两个值来记录是否需要透明度的转换和缩放!下面来看下执行的代码: if (shouldAnimateScale) {     ......     modifier = modifier.graphicsLayer {         this.alpha = alpha         this.scaleX = scale         this.scaleY = scale         this.transformOrigin = transformOrigin     } } else if (shouldAnimateAlpha) {     modifier = modifier.graphicsLayer {         this.alpha = alpha     } }
  嗯呢,是不是豁然开朗!但是  slideInOut   和 shrinkExpand   函数也是可见性动画这里定义的 Modifier   的扩展函数,里面还有一些自定义的东西,但这不是本文的重点了。别的可见性动画
  文章开头说了,可见性动画目前一共有六个,听着很吓人,其实大同小异,来简单看下不同吧! @Composable fun RowScope.AnimatedVisibility(     visible: Boolean,     modifier: Modifier = Modifier,     enter: EnterTransition = fadeIn() + expandHorizontally(),     exit: ExitTransition = fadeOut() + shrinkHorizontally(),     label: String = "AnimatedVisibility",     content: @Composable() AnimatedVisibilityScope.() -> Unit ) {     val transition = updateTransition(visible, label)     AnimatedEnterExitImpl(transition, { it }, modifier, enter, exit, content) }   @Composable fun ColumnScope.AnimatedVisibility(     visible: Boolean,     modifier: Modifier = Modifier,     enter: EnterTransition = fadeIn() + expandVertically(),     exit: ExitTransition = fadeOut() + shrinkVertically(),     label: String = "AnimatedVisibility",     content: @Composable AnimatedVisibilityScope.() -> Unit ) {     val transition = updateTransition(visible, label)     AnimatedEnterExitImpl(transition, { it }, modifier, enter, exit, content) }
  上面这两个和咱们上面说的基本一样,只不过一个是  RowScope   的扩展函数,另一个是 ColumnScope   的扩展函数,并且在默认动画上还有些区别,RowScope   默认是横向的扩展和收缩,ColumnScope   是纵向的扩展和收缩,更加方便咱们日常调用!这也就解释了文章开头提出的小问题!
  接着再来看别的! @Composable fun AnimatedVisibility(     visibleState: MutableTransitionState,     modifier: Modifier = Modifier,     enter: EnterTransition = fadeIn() + expandIn(),     exit: ExitTransition = fadeOut() + shrinkOut(),     label: String = "AnimatedVisibility",     content: @Composable() AnimatedVisibilityScope.() -> Unit ) {     val transition = updateTransition(visibleState, label)     AnimatedEnterExitImpl(transition, { it }, modifier, enter, exit, content) }
  这个和之前的就有点区别了,第一个参数就不同了,参数类型为  MutableTransitionState   ,其实是一样的,咱们上面也都说到了,MutableTransitionState   的使用方法在上一篇文章中也介绍过,感兴趣的可以去看一下。
  剩下的两个还是  RowScope   和 ColumnScope   的扩展函数,也是参数类型改为了 MutableTransitionState   ,这里也就不做过多介绍。突兀的结尾
  本篇文章带大家看了可见性动画的一些源码,很多其实都是点到为止,并没有一致不断深入,一直深入就会陷入其中,忘了看源码的本意,本文所有源码基于  Compose 1.3.0-beta02   。
  本文至此结束,有用的地方大家可以参考,当然如果能帮助到大家,哪怕是一点也足够了。就这样。

2023,不要再亏待自己!文泠泠2023,新的一年,终于明白一个道理,人首先要学会爱自己,要学会善待自己,要懂得对自己好,才能有能力去爱别人,去照顾别人。或许我们很多时候都是为了照顾别人的感受,顾虑别人,反眼下即为天下头条创作挑战赛不与当下的事情做了结,就难以在长远的事情上投入。眼下重要紧急的事情不完成,后续的工作便是开展不起来。一个事物没有尽头,另一个事物就不会开始。总是关注太遥远的未来,却不绝了!史诗级3换1交易方案,威少赴公牛,湖人为总冠军的最后一搏名记ZachLowe报道,随着赛季的进行,有一个名字变得更有趣了。而且越来越明显的一点是,公牛并不打算留下他,那个人就是拉文。ZachLowe还透露,湖人内部有些人士把拉文当做潜在名记雄鹿四处开价阿伦次轮签希望得到千万级别防守型前锋直播吧1月28日讯据雅虎体育名记JakeFischer报道,消息人士透露,雄鹿近期在各种交易谈判中报价格雷森阿伦次轮选秀权,希望得到一位年薪在千万美元左右的防守型前锋。据报道,雄鹿斯特鲁斯谈末节防守末段把球给巴特勒把胜利带回家直播吧1月28日讯NBA常规赛,热火主场110105逆转战胜魔术。赛后热火球员斯特鲁斯总结了第四节的内容防守,打停并反超,在比赛末段把球交给巴特勒,他会让我们带着胜利回家。此役,斯英足杯前瞻分析阿克宁顿VS利兹联!英足杯赛程转播LDSPORTS阿克林顿在英甲联赛中排名在20。阿克林顿老将华利本赛季在英甲只攻入了一个球,但在足总杯中攻入了三个球,是球队的最佳球员。利兹联的客场表现差强人意。本赛季的18个英超36人获评2021和2022年度朝阳区最美科技工作者他们中既有数十年如一日深耕科普领域弘扬科学精神的研究员,也有面向国家重大需求为建设网络强国贡献力量的科技工作者既有倾尽所能,只为给患者解除病痛的医务人员,也有将科技强则国家强作为己米体国米有意免签菲尔米诺薪水成本比续租卢卡库更划算根据米兰体育报国米跟队记者FilippoConticello以及著名转会记者CarloLaudisa的报道,国米考虑今年夏天免签利物浦前锋菲尔米诺,将他视为了卢卡库的潜在替代者。菲暑假玩遍西安今年暑假七月份的时候,和朋友们去了一趟西安,因为哥们几个都喜欢打篮球,也就想去西安看看野球帝,顺便玩一玩,在出发前做的攻略是玩三天,没想到玩了七八天还没逛完西安,真不愧是古都!西安2023畅游洛阳城,若问古今兴废事,请君只看洛阳城千年帝都,牡丹花城,若问古今兴废事,请君只看洛阳城。生活在洛阳的历代科学泰斗鸿生巨儒翰墨精英,灿若繁星。中国传统文化儒佛道的产生和发展都与洛阳密切相关,洛阳更是中国古代四大发明中的太阳报独家马丁内利新合同包含1条款,周薪增长至18万镑根据英国太阳报阿森纳方面记者MarkIrwin的独家报道,(其实是伦敦方面,但Mark每次都会出席阿森纳的赛前,所以普遍被认为属于是不算太靠谱的一线记者,他的消息都有待佐证),他跟
话匣君说财经魔都商业地产江湖前几天,上海一位负责区里招商的领导给陆燕发了一条微信,请她帮忙向全球客户推介本区的高端办公楼宇,促进本区的招商工作。陆燕供职于全球最大的商业地产服务咨询机构之一世邦魏理仕CBRE,万里界河任尔通,全国民间棋王争霸赛总决赛拉开帷幕本周末,2022中国体育彩票好运弈棋来全国象棋民间棋王争霸赛总决赛在成都拉开帷幕。本次赛事由国家体育总局棋牌运动管理中心国家体育总局体育彩票管理中心中国象棋协会联合举办,自2022寿命长短,饭量先知?多吃点好还是少吃点好?医生给出了答案来源医者真言(IDgha7f468bf9614)相信子女们看到父母能吃能喝都比较开心,因为有句话叫能吃是福。可是,饭量大真的更健康吗?或许和你想正本清源再现大型江湖名局七星聚会的精妙变化以飨读者我们知道,七星聚会是流传于民间的四大江湖名局之一。在巜竹香斋象戏谱中叫七星拱斗。心武残篇中叫七星同庆。渊深海阔中叫七星耀彩。百局象棋谱中叫七星聚会。此残局构思精妙,陷阱四伏。乍一看民间金融对经济高质量发展起积极作用,可通过劳动力转移实现绪论本文研究表明民间金融会对经济的高质量发展起到积极作用,这一作用可以通过劳动力转移和技术进步这两条中介渠道实现,且民间金融对经济高质量发展的作用路径在东中西部存在空间上的异质性。詹姆斯加杜兰特荣誉正好等于乔丹,库里加张伯伦荣誉等于贾巴尔比较球员历史地位时,我们首先看的就是总冠军MVP和FMVP的数量,至于得分王最佳阵容一阵等荣誉则是对比麦迪艾弗森哈登这个级别球星才会出现的事情,结果对比过程中我们发现一名球星的荣誉狂轰61分13板7助5断!女版乔丹上演超级时刻,值得入围五人国家队在WCBA进行的一场季后赛中,新疆女篮最终以99104不敌上海女篮,球队大比分02不敌上海女篮,无缘季后赛四强,不过在本场比赛来自新疆女篮的王丽丽,几乎用个人的一己之力帮助着新疆女维金斯和库妈谣言真离谱!但乔丹儿子和皮蓬前妻是真处朋友由于勇士正处在争夺季后赛席位的关键时刻,原本伤愈归来的维金斯却在全明星赛后接连缺席了两场球队的比赛并且极有可能还将继续请假,而请假的原因至今未对外公布。向来以敬业为名片的嘴哥,生涯多款新风格亮相,坦克世界战斗通行证赛季X蓄势待发!正所谓一年之计在于春,作为新年的第一季度,春季的游戏市场目前堪称神仙斗法,而坦克世界也准备了一些特别行动。前几天WG刚公布的开发计划相当于总纲,如今官方又正式发布了战斗通行证赛季X7天的早餐风格的男士搭配周一,一周的开始,一条白色宽松休闲裤一件蓝色的轻薄衬衫一双舒适的拖鞋,下班后漫步海边,在夕阳照射下,你和大海一样闪闪发光。星期二换上职业的衬衫去开会每天早上的在线会议,不可避免的消威少球队的投篮对控卫非常友好,我就是用篮球智慧来创造机会快船以175176不敌国王。赛后,快船球员拉塞尔威斯布鲁克接受媒体采访,谈到了自己的快船首秀。我就是努力用不同的方式来影响比赛。威斯布鲁克在采访中表示。我就是利用我的篮球智慧来为队