Android MotionLayout 运动布局的使用

2023-05-16

Google 在 2018 年开发者大会上推出一种新的布局组件 MotionLayout。其官方定义如下:

MotionLayout is a layout type that helps you manage motion and widget animation in your app. MotionLayout is a subclass of ConstraintLayout and builds upon its rich layout capabilities.

简单翻译过来:MotionLayout 是一个能够帮助我们在 APP 中管理手势和控件动画的布局组件。它是 ConstraintLayout 的子类,同时可以基于自身丰富的布局功能来进行构建。

MotionLayout 从字面意思可以理解为运动布局。与传统布局组件相比(如 FrameLayout、LinearLayout 等),几乎可以说 MotionLayout 是布局组件中的一个里程碑,因为从此开始告别了 xml 文件只能静态操作 UI 的现状。通过 MotionLayout,我们可以更加轻易地处理其内部子 View 的手势操作和动画效果。


文章目录

  • 一、准备工作
    • 1.1 导入依赖
    • 1.2 将布局转换为 MotionLayout
  • 二、创建普通过渡动画
    • 2.1 创建动画元素
    • 2.2 定义 View 动画开始与结束状态
    • 2.3 过渡 Transition
      • 2.3.1 OnClick
      • 2.3.2 OnSwipe
  • 三、创建属性过渡动画
    • 3.1 透明度属性
    • 3.2 旋转属性
    • 3.3 自定义属性
  • 四、创建关键帧动画
    • 4.1 KeyPosition
      • 4.1.1 parentRelative
      • 4.1.2 deltaRelative
      • 4.1.3 pathRelative
    • 4.2 KeyAttribute
    • 4.3 KeyCycle
    • 4.4 KeyTimeCycle
    • 4.5 KeyTrigger
  • 五、最后


一、准备工作

1.1 导入依赖

implementation 'androidx.constraintlayout:constraintlayout:2.0.1'

1.2 将布局转换为 MotionLayout

MotionLayout 是 ConstraintLayout 的子类,可以直接由 ConstraintLayout 转化。打开 activity_main.xml 布局文件,在 Component Tree 栏选中选择 ConstraintLayout 右击,在菜单栏中点击 Covert to MotionLayout 选项。

在这里插入图片描述
在 res 目录下出现 xml 目录,目录下有一个 activity_main_scene.xml 文件,如图:

在这里插入图片描述

内容为:

<?xml version="1.0" encoding="utf-8"?>
<MotionScene 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:motion="http://schemas.android.com/apk/res-auto">

    <Transition
        motion:constraintSetEnd="@+id/end"
        motion:constraintSetStart="@id/start"
        motion:duration="1000">
        <KeyFrameSet>
        </KeyFrameSet>
    </Transition>

    <ConstraintSet android:id="@+id/start">
    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
    </ConstraintSet>
</MotionScene>

同时 activity_main.xml 的 Design 界面出现 MotionLayout 工作台:

在这里插入图片描述

其中:
① 普通状态,选中后预览视图显示原始的状态;
② 表示 id=“start” 的 ConstraintSet(约束集),选中后预览视图会显示开始约束集的布局,对应 xml 中代码:

<ConstraintSet android:id="@+id/start">
</ConstraintSet>

③ 表示 id=“end” 的 ConstraintSet(约束集),选中后预览视图会显示结束约束集的布局,对应 xml 中代码:

<ConstraintSet android:id="@+id/end">
</ConstraintSet>

④ 表示从开始约束集到结束约束集的过渡,对应 xml 中代码:

<Transition
    motion:constraintSetEnd="@+id/end"
    motion:constraintSetStart="@id/start"
    motion:duration="1000">
</Transition>

⑤ 用于创建一个新的约束集 ConstraintSet
⑥ 用于创建一个新的过渡 Transition
⑦ 用于创建触发转场的行为,是点击 Click 还是滑动 Swipe
⑧ 表示约束集中的元素


二、创建普通过渡动画

2.1 创建动画元素

在布局中创建一个 View 如下:

<androidx.constraintlayout.motion.widget.MotionLayout 
    ...
    app:showPaths="true"
    app:layoutDescription="@xml/activity_main_scene">

    <View
        android:id="@+id/rect"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:background="@color/colorPrimary" />
  
</androidx.constraintlayout.motion.widget.MotionLayout>

app:showPaths=“true” 用于显示运动轨迹。

2.2 定义 View 动画开始与结束状态

在 activity_main_scene.xml 中,在 id=“start” 的 ConstraintSet 里添加该 View 的约束,令 View 位于左侧中间位置:

<ConstraintSet android:id="@+id/start">
    <Constraint
        android:id="@+id/rect"
        android:layout_width="70dp"
        android:layout_height="70dp"
        motion:layout_constraintBottom_toBottomOf="parent"
        motion:layout_constraintStart_toStartOf="parent"
        motion:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>

同理,在 id=“end” 的 ConstraintSet 里添加该 View 的约束,令 View 位于右侧中间位置:

<ConstraintSet android:id="@+id/end">
    <Constraint
        android:id="@+id/rect"
        android:layout_width="70dp"
        android:layout_height="70dp"
        motion:layout_constraintBottom_toBottomOf="parent"
        motion:layout_constraintEnd_toEndOf="parent"
        motion:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>

2.3 过渡 Transition

Transition 标签如下:

<Transition
    motion:constraintSetEnd="@+id/end"
    motion:constraintSetStart="@id/start"
    motion:duration="1000">
    <KeyFrameSet></KeyFrameSet>
</Transition>

Transition 标签有以下几个属性:

  1. motion:constraintSetStart:指定运动开始状态,值为 ConstrainSet 的 id;
  2. motion:constraintSetEnd:指定运动结束状态,值为 ConstrainSet 的 id;
  3. motion:duration:指定动画执行的时间;
  4. KeyFrameSet:关键帧标签,这个之后再讲。

但是 Transition 只是定义了 ConstraintSet 开始和结束的状态,要让用户去触发,还要在 Transition 标签下添加触发条件:点击(OnClick) 或滑动(OnSwipe)。

2.3.1 OnClick

表示由用户点击触发,示例如下:

<Transition
    motion:constraintSetEnd="@+id/end"
    motion:constraintSetStart="@id/start"
    motion:duration="1000">
    <OnClick
        motion:clickAction="toggle"
        motion:targetId="@+id/rect" />
</Transition>

OnClick 标签有以下几个属性:

  1. motion:targetId,对应目标 View 的 id;
  2. motion:clickAction,对应点击后进行的行为,可以设置如下几个值:
    1. toggle:通过过渡动画在 motion:constraintSetStart 和 motion:constraintSetEnd 状态之间切换;
    2. transitionToStart:通过过渡动画过渡到 motion:constraintSetStart 属性指定的状态;
    3. transitionToEnd:通过过渡动画过渡到 motion:constraintSetEnd 属性指定的状态;
    4. jumpToStart:直接跳转到 motion:constraintSetStart 属性指定的状态;
    5. jumpToEnd:直接跳转到 motion:constraintSetEnd 属性指定的状态。

预览效果如下:

在这里插入图片描述

2.3.2 OnSwipe

表示由用户滑动触发,它会根据用户滑动行为调整动画的进度,示例如下:

<Transition
    motion:constraintSetEnd="@+id/end"
    motion:constraintSetStart="@id/start"
    motion:duration="1000">
    <OnSwipe
        motion:dragDirection="dragRight"
        motion:touchAnchorId="@+id/rect"
        motion:touchAnchorSide="right" />
</Transition>

OnSwipe 标签有以下几个属性:

  1. motion:touchAnchorId,对应目标 View 的 id;
  2. motion:touchAnchorSide,从目标 View 相对位置拖动 View,示例即 View 右侧;
  3. motion:dragDirection,表示拖动的方向,值可为 “dragLeft”、“dragRight”、“dragUp” 和 “dragDown”。
  4. motion:dragScale, 用户滑动长度 × dragScale = View 移动距离,默认值为 1;
  5. motion:maxVelocity,目标 View 的最大速度;
  6. motion:maxAcceleration,目标 View 的最大加速度。

预览效果如下:

在这里插入图片描述


三、创建属性过渡动画

之前提到,ConstraintSet 的 Constraint 中可以指定约束,上面例子中只用到了位置约束,接下来可以尝试添加某些属性,可添加的属性有:

  1. alpha:透明度;
  2. visibility:可见;
  3. elevation:抬升;
  4. rotation、rotationX、rotationY:旋转;
  5. translationX、translationY、translationZ:偏移;
  6. scaleX、scaleY:缩放。

这里以透明度和旋转作为示例。

3.1 透明度属性

在动画开始位置设置 android:alpha=“1” 结束位置设置 android:alpha=“0.1”,MotionLayout 会自动过渡。

<ConstraintSet android:id="@+id/start">
    <Constraint
        android:id="@+id/rect"
        ...
        android:alpha="1"
        ... />
</ConstraintSet>

<ConstraintSet android:id="@+id/end">
    <Constraint
        android:id="@+id/rect"
        ...
        android:alpha="0.1"
        ... />
</ConstraintSet>

预览效果如下:

在这里插入图片描述

3.2 旋转属性

在动画开始位置设置 android:rotationX=“0” 结束位置设置 android:rotationX=“180”,旋转 180 度,MotionLayout 会自动过渡。

<ConstraintSet android:id="@+id/start">
    <Constraint
        android:id="@+id/rect"
        ...
        android:rotationX="0"
        ... />
</ConstraintSet>

<ConstraintSet android:id="@+id/end">
    <Constraint
        android:id="@+id/rect"
        ...
        android:rotationX="180"
        ... />
</ConstraintSet>

预览效果如下:

在这里插入图片描述

3.3 自定义属性

在 Constraint 中,还可以使用 CustomAttribute 元素为 View 添加自定义属性。一个 CustomAttribute 本身包含两个属性:

  1. motion:attributeName:自定义属性名(必需),并且需要与具有 getter/setter 方法的对象匹配。例如 backgroundColor,因为 View 具有 getBackgroundColor() 和 setBackgroundColor() 方法。
  2. 对应属性的属性值,如下:
    1. motion:customColorValue:颜色值;
    2. motion:customIntegerValue:整数值;
    3. motion:customFloatValue:浮点值;
    4. motion:customStringValue:字符串值;
    5. motion:customDimension:尺寸值;
    6. motion:customBoolean:布尔值。

更改背景颜色示例如下:

<ConstraintSet android:id="@+id/start">
    <Constraint
        android:id="@+id/rect"
        ...
        <CustomAttribute
            motion:attributeName="backgroundColor"
            motion:customColorValue="#F9A825" />
    </Constraint>
</ConstraintSet>

<ConstraintSet android:id="@+id/end">
    <Constraint
        android:id="@+id/rect"
        ...
        <CustomAttribute
            motion:attributeName="backgroundColor"
            motion:customColorValue="#AD1457" />
    </Constraint>
</ConstraintSet>

预览效果如下:

在这里插入图片描述


四、创建关键帧动画

上面的所有动画,我们都只定义了开始与结束两个状态,中间的过渡由 MotionLayout 自己完成。但如果想要改变过渡到中间某一时刻的状态呢,那就需要使用之前还没讲的 KeyFrameSet 关键帧。使用 KeyFrameSet 标签,可以对动画过渡过程中的某些点设置约束或属性,而点与点之间的过渡,仍由 MotionLayout 完成。

可以看 MotionLayout 工作台:

在这里插入图片描述

点击选中 ①,工作台会出现时间轴工具,点击 ② 处播放按钮可以直接在编辑器预览动画效果,点击 ③ 处就可以看到添加 KeyFrameSet 子元素的选项,下面对这几种元素进行分析。

4.1 KeyPosition

KeyPosition 即关键帧位置,如下示例,在 Transition 中添加 KeyPosition 相关设置:

<Transition
    ...>
    <OnClick
        ... />
    <KeyFrameSet>
        <KeyPosition
            motion:framePosition="50"
            motion:keyPositionType="parentRelative"
            motion:motionTarget="@id/rect"
            motion:percentX="0.7"
            motion:percentY="0.2" />
    </KeyFrameSet>
</Transition>

预览效果如下:

在这里插入图片描述

KeyPosition 标签中添加了以下几个属性:

  1. motion:framePosition:表示关键帧在动画执行的百分比进度,取值范围为 [0, 100]。示例中的 50 表示动画进度执行到 50% 时有一帧关键帧;
  2. motion:motionTarget:表示目标视图 id;
  3. motion:keyPositionType:表示坐标系类型,取值可以为 “parentRelative”、“deltaRelative”、“pathRelative”;
  4. motion:percentY 和 motion:percentX:表示相对参考系的纵向和横向的比例。

重点看一下 keyPositionType 的取值。

4.1.1 parentRelative

<KeyPosition
    ...
    motion:keyPositionType="parentRelative"
    motion:percentX="0.7"
    motion:percentY="0.2" />

parentRelative 表示以 MotionLayout 布局为参考系,布局左上角为 (0, 0),右下角为 (1, 1)。motion:percentX=“0.7”、motion:percentY=“0.2” 就是 (0.7, 0.2) 的位置,如下图所示:

在这里插入图片描述

4.1.2 deltaRelative

<KeyPosition
    ...
    motion:keyPositionType="deltaRelative"
    motion:percentX="0.7"
    motion:percentY="0.2" />

deltaRelative 表示以该 View 的起始点作为 (0, 0),结束点作为 (1, 1),motion:percentX=“0.7”、motion:percentY=“0.2” 就是 (0.7, 0.2) 的位置,(本示例调整了结束点),如下图所示:

在这里插入图片描述

4.1.3 pathRelative

<KeyPosition
    ...
    motion:keyPositionType="pathRelative"
    motion:percentX="0.7"
    motion:percentY="0.2" />

pathRelative 是以 View 的起始点、结束点连线作为 x 轴,两个点分别为 (0, 0) 和 (1, 0)。x 轴顺时针旋转 90° 作为 y 轴,等长距离作为刻度,如下图所示:

在这里插入图片描述

4.2 KeyAttribute

KeyAttribute 即关键帧属性,如下示例,在 Transition 中添加 KeyAttribute 相关设置:

<Transition
    ...>
    <OnClick
        ... />
    <KeyFrameSet>
        <KeyAttribute
            android:alpha="0.1"
            android:rotationY="180"
            motion:framePosition="50"
            motion:motionTarget="@id/rect" />
    </KeyFrameSet>
</Transition>

预览效果如下:

在这里插入图片描述

可以看到 View 先沿 Y 从 0° 旋转到 180° 再旋转回 0°,透明度也由 1 到 0.5 再到 1。

KeyAttribute 标签中添加了以下几个属性:

  1. motion:framePosition:同上,表示关键帧在动画执行的百分比进度,取值范围为 [0, 100]。示例中的 50 表示动画进度执行到 50% 时有一帧关键帧。
  2. motion:motionTarget:表示目标视图 id;
  3. 支持对 View 的所有原生属性如 alpha、rotation 等以及自定义属性 CustomAttribute。

4.3 KeyCycle

KeyCycle 可以让 View 在动画的过程中按照一些周期函数,周期性的改变其属性值。跟某一帧没有关系,影响的是部分动画过程。如下示例,在 Transition 中添加 KeyCycle 相关设置:

<Transition
    ...>
    <OnClick
        ... />
    <KeyFrameSet>
        <KeyCycle
            android:translationY="30dp"
            motion:framePosition="50"
            motion:motionTarget="@+id/rect"
            motion:wavePeriod="1"
            motion:waveShape="sin" />
    </KeyFrameSet>
</Transition>

预览效果如下:

在这里插入图片描述

该示例就是在动画 [0%, 50%] 这个过程中以 sin 这个周期函数,周期性的改变 android:translationY 属性。

KeyCycle 标签中添加了以下几个属性:

  1. motion:framePosition:与之前有细微差别,这里表示 KeyCycle 作用范围在动画执行的 [0%, 50%]。
  2. motion:motionTarget:表示目标视图 id;
  3. motion:wavePeriod:表示运动的周期数;
  4. motion:waveShape:表示周期类型,示例中指定了 sin,就会按 sin 周期函数变化。

4.4 KeyTimeCycle

KeyTimeCycle 可以在关键帧上按照一些周期函数,周期性的改变其属性值。如下示例,在 Transition 中添加 KeyTimeCycle 相关设置:

<Transition
    ...>
    <OnClick
        ... />
    <KeyFrameSet>
        <KeyTimeCycle
            android:translationY="30dp"
            motion:motionTarget="@+id/rect"
            motion:wavePeriod="1"
            motion:waveShape="sin" />
    </KeyFrameSet>
</Transition>

预览效果如下:

在这里插入图片描述

可以看到 KeyTimeCycle 与 KeyCycle 比较,KeyTimeCycle 是在帧上做周期性,KeyCycle 是在动画过程中做周期性。

KeyTimeCycle 标签中的属性与 KeyCycle 基本一致。

4.5 KeyTrigger

KeyTrigger 可以在动画的过程中触发 View 中的函数。
比如自定义一个 TextView 类 MyTextView,在 MyTextView 中定义两个函数 showHello() 和 showWorld(),代码如下:

class MyTextView(context: Context, attrs: AttributeSet) : AppCompatTextView(context, attrs) {
    fun showHello() {
        text = "Hello"
    }

    fun showWorld() {
        text = "World"
    }
}

修改 activity_main.xml 布局如下:

<androidx.constraintlayout.motion.widget.MotionLayout 
    ...
    app:showPaths="true"
    app:layoutDescription="@xml/activity_main_scene">

    <com.example.motionlayoutdemo.MyTextView
        android:id="@+id/rect"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:background="@color/colorPrimary"
        android:gravity="center"
        android:textSize="20sp"
        android:textColor="@android:color/white" />
  
</androidx.constraintlayout.motion.widget.MotionLayout>

在 activity_main_scene.xml 中 Transition 标签中添加 KeyTrigger 相关设置:

<Transition
    ...>
    <OnClick
        ... />
    <KeyFrameSet>
        <KeyTrigger
            motion:framePosition="20"
            motion:motionTarget="@id/rect"
            motion:onCross="showHello" />
        <KeyTrigger
            motion:framePosition="80"
            motion:motionTarget="@id/rect"
            motion:onCross="showWorld" />
    </KeyFrameSet>
</Transition>

预览效果如下:

在这里插入图片描述

可以看到,在动画进度 20% 的时候触发 id rect 视图的 showHello 方法,80% 的时候触发 id rect 视图的 showWorld 方法。

KeyTrigger 标签中添加了以下几个属性:

  1. motion:framePosition:表示关键帧在动画执行的百分比进度,取值范围为 [0, 100];
  2. motion:motionTarget:表示目标视图 id;
  3. motion:onCross:表示要触发的函数名;

注意,onCross 在动画不论是正向还是逆向,只要到达设置的 framePosition 就会触发。还有两个属性:

  1. motion:onPositiveCross:只有正向执行动画时到达设置的 framePosition 才会执行;
  2. motion:onNegativeCross:只有逆向执行动画时到达设置的 framePosition 才会执行。

五、最后

  1. MotionLayout 的知识点很多,而且可以与 RecyclerViewAppBarLayout 等许多组件联合使用。上面只是对一些属性的简单演示,要想实现复杂的动画,还需要对各种属性多组合多尝试多练习。
  2. MotionLayout 功能还是比较强大的,可以直接实现许多常见的动画效果,比如下面这个搜索框动画:

在这里插入图片描述

  1. MotionLayout 自带一个处理动画的图形化工具如下,如果直接从 xml 上手,可能会比较生疏,可以借助图形化工具进行编辑、预览,再比对生成的 xml,加深理解。

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android MotionLayout 运动布局的使用 的相关文章

  • BottomNavigationView - 如何获取选定的菜单项?

    我使用BottomNavigationView来切换片段 如何获取当前选定的菜单项 以防止重新打开片段 BottomNavigationView bottomNavigationView BottomNavigationView findV
  • getItem 与 getItemAtPosition

    有两种方法可以获取列表视图中的选定项目 list getAdapter getItem position list getItemAtPosition position 我的问题是 哪一种是首选的做法 我见过人们同时使用这两种方法 您可以使
  • 如何更新 Firebase 中的节点密钥?

    如何重命名14 04 2017 node 没有用于重命名节点的 API 您必须获取节点的值 使用新名称将其保存到数据库并删除旧节点
  • 如何将安卓手机从睡眠状态唤醒?

    如何以编程方式将 Android 手机从睡眠状态唤醒 挂起至内存 我不想获取任何唤醒锁 这意味着手机在禁用 CPU 的情况下进入 真正的 睡眠状态 我想我可以使用某种RTC 实时时钟 机制 有人有例子吗 Thanks 为了让Activity
  • Phonegap - 如何将.txt文件保存在Android手机的根目录中

    我正在尝试使用phonegap 将 txt 文件保存在Android 手机的根目录中 我已经安装了这些插件 cordova plugin file 和 cordova plugin file transfer 在 config xml 文件
  • 菜单未显示在应用程序中

    由于某种原因 我的操作菜单在我的 Android Studio 应用程序中消失了 我正在按照教程学习如何创建 Android 应用程序 但最终遇到了这个问题 我正在使用 atm 的教程 http www raywenderlich com
  • 如果我们使用后退按钮退出,为什么 Android 应用程序会重新启动?

    按住主页按钮并返回应用程序时 应用程序不会重新启动 为什么使用后退按钮会重新启动 如果我们使用后退按钮退出 有什么方法可以解决在不重新启动的情况下获取应用程序的问题吗 请帮忙 当您按下Home按钮 应用程序将暂停并保存当前状态 最后应用程序
  • 在 Google Analytics 中跟踪应用程序版本

    我正在使用谷歌分析模块 https marketplace appcelerator com apps 5081 2014113336 https marketplace appcelerator com apps 5081 2014113
  • Android Studio 在编译时未检测到支持库

    由于 Android Studio 将成为 Android 开发的默认 IDE 因此我决定将现有项目迁移到 Android studio 中 项目结构似乎不同 我的项目中的文件夹层次结构如下 Complete Project gt idea
  • 在意图过滤器中使用多个操作时的默认值

    尝试理解 Android 中的意图和操作并查看文档 http developer android com guide topics intents intents filters html 但我一直看到的一件事是定义了多个操作的意图过滤器
  • TextView 之间有分隔线

    我正在尝试在 android studio 中创建以下布局 因为我对 android 东西还很陌生 所以我第一次尝试使用 LinearLayout 并认为这可能无法实现 现在我正在尝试使用RelativeLayout 我已经用颜色创建了这个
  • OnClick 事件中的 finish() 如何工作?

    我有一个Activity一键退出Activity 通过layout xml我必须设置OnClick事件至cmd exit调用 this finish 效果很好 public void cmd exit View editLayout thi
  • 请求位置更新参数

    这就是 requestLocationUpdates 的样子 我使用它的方式 requestLocationUpdates String provider long minTime float minDistance LocationLis
  • Android Studio:无法启动守护进程

    当我尝试在 Android Studio 中导入 gradle 项目时 遇到以下错误 Unable to start the daemon process This problem might be caused by incorrect
  • Android Webview 图像未加载

    我制作了一个简单的应用程序WebView 但有些图片无法加载 正确 在我的电脑上 错误 在模拟器中 Correct 错误 没有横幅 于是我用Chrome debug进行调试 发现我的代码被改变了 我不添加像noscript or style
  • 在 Android 上按下电源按钮时,如何防止先调用 onDestroy() 再调用 onCreate()

    我正在记录每个 onCreate 和 onDestroy 调用 我发现 一旦我单击 Android 上的电源按钮 以及模拟器上的电源按钮 我的活动中就会拨打电话 gt onDestroy gt onCreate 这会杀死我的游戏 然后立即从
  • 通过 ADB 拔出设备:“找不到服务”

    我必须测试我的应用程序在打瞌睡模式下的行为 根据文档 https developer android com training monitoring device state doze standby html testing doze 我
  • 下载后从谷歌照片库检索图像

    我正在发起从图库中获取照片的意图 当我在图库中使用 Nexus 谷歌照片应用程序时 一切正常 但如果图像不在手机上 在 Google Photos 在线服务上 它会为我下载 选择图像后 我将图像发送到另一个活动进行裁剪 但在下载的情况下 发
  • 将 JSON 参数从 java 发布到 sinatra 服务

    我有一个 Android 应用程序发布到我的 sinatra 服务 早些时候 我无法读取 sinatra 服务上的参数 但是 在我将内容类型设置为 x www form urlencoded 之后 我能够看到参数 但不完全是我想要的 我在
  • 使用 Espresso 检查 EditText 的字体大小、高度和宽度

    如何使用 Espresso 检查 EditText 的字体大小 高度和宽度 目前要分割我使用的文本 onView withId R id editText1 perform clearText typeText Amr 并阅读文本 onVi

随机推荐

  • 深入解读四轴飞行器的硬件设计

    xfeff xfeff 转载自 xff1a http www openedv com posts list 20892 htm 传感器之一 xff1a 角速度传感器应用科里奥利力原理 xff1a 科里奥利力来自于物体运动所具有的惯性 xff
  • 【GIT】使用Vscode同步git仓库,错误和解决方法记录

    这里写目录标题 命令行操作仓库常见命令1 报错 在签出前 xff0c 请清理存储库工作树 2 报错 fatal unable to access 39 https github com 39 OpenSSL SSL read Connect
  • 基于k近邻(KNN)的手写数字识别

    作者 xff1a faaronzheng 转载请注明出处 xff01 最近再看Machine Learning in Action k近邻算法这一章节提供了不少例子 xff0c 本着Talk is cheap的原则 xff0c 我们用手写数
  • 机器学习算法地图(转自SIGAI)

    转自 xff1a http sigai cn paper 18 html 下面先看这张图 xff1a 图的左半部分列出了常用的机器学习算法与它们之间的演化关系 xff0c 分为有监督学习 xff0c 无监督学习 xff0c 强化学习 3 大
  • 一个非常适合单片机的滤波算法

    连接 xff1a http bbs 21ic com icview 170880 1 1 html 以下为原文 连接 xff1a http bbs 21ic com icview 170880 1 1 html 单片机大多资源小 xff0c
  • 6.蒙特卡洛方法(TSP)

    定义 xff1a 旅行商问题 xff0c 即TSP问题 xff08 Traveling Salesman Problem xff09 又译为旅行推销员问题 货郎担问题 xff0c 是数学领域中著名问题之一 假设有一个旅行商人要拜访n个城市
  • 云和AI时代下,需要怎样的存储?

    数字化浪潮席卷而来 xff0c 颠覆着传统的生产和生活方式 xff0c 随之产生的新经济和新应用给传统业务模式和产业结构带来前所未有的冲击 特别是云计算 人工智能 AI 和物联网 IoT 的兴起 xff0c 加快了传统产业升级改造的步伐 在
  • 人工智能6个核心技术

    机械学习 机械学习是多领域交叉的学科 xff0c 可以从学习模式和学习方法上面进行分类 xff0c 学习模式将机器学习分类为监督学习 无监督学习和强化学习等 xff0c 学习方法可以将机器学习分为传统机器学习和深度学习 机器学习按学习方式分
  • CAN总线的标准(二)

    一 OSI参考模型 CAN总线标准规定了物理层和数据链路层 xff0c 至于应用层需要用户自定义 不同的CAN标准仅物理层不同 物理层和数据链路层ISO11898 xff1b 应用层 xff1a 不同的应用领域使用不同的应用层标准 二 各层
  • 数据通信--ASCII码通信&16进制通信的区别

    16进制通信一般用于网络传输等的通信上 xff0c 传输效率高 数据量大是二进制通信 ASCII码通信一般用与串口通信等通信上 xff0c 数据量小 易于处理 便于调试 xff0c 它虽然是文本模式 xff0c 但本质仍然是二进制通信 在使
  • ubuntu下安装boost

    boost中 xff0c 用到了别的函数库 xff0c 所以为了使用boost中相应的功能 xff0c 需要先安装系统中可能缺失的库 第一步 安装依赖库 sudo apt get install mpi default dev 安装mpi库
  • 数据结构实验快速排序、冒泡排序算法(交换排序),使用STM32单片机测试(学计算机综合考试408悟单片机系列)

    快速排序和冒泡排序均属于交换排序范畴 xff0c 意味着其基本操作是交换两数 快速排序 xff0c 顾名思义快速的排序 xff0c 毫无遮拦得介绍了自己得特征 而冒泡排序也正如其名称 xff0c 如同养鱼冒泡一样慢条斯理锝排序 xff08
  • 操作系统-13-程序员应如何理解中断

    在这一节中我们聊一聊 xff0c 操作系统管理外设的中断机制 为什么要在这一节聊一聊操作系统如何管理外设呢 xff0c 外设管理是操作系统的核心任务之一 xff0c 理解操作系统的外设管理机制对于我们理解操作系统工作原理至关重要 通过第二章
  • Gitee实现本地代码上传他人的远程仓库

    前言 xff1a 需要下载git bash xff0c 并拥有自己的Gitee账号哦 关于git下载可以看这个博客 xff08 CSDN有很多 xff09 xff1a git git bash 下载与安装 娄笙悦的博客 CSDN博客 Git
  • 关于用elsevier-cas模板的一些问题

    关于用elsevier cas模板的一些问题 关于graphical abstract和highlight 这俩东西可能跟具体的期刊有关 xff0c 在我要投的这个期刊里边 xff0c 这俩是不需要的 xff0c 可以直接从模板中删除 关于
  • 几种供电总线技术

    PowerBus技术 PowerBus为可供电总线技术 xff0c 是业内唯一可以支持大功率负载供电和高速通讯的总线技术 xff0c 相比其他可供电总线技术 xff1a PowerBus供电效率高 xff0c 通过两根电源线最大可提供单个设
  • 使用dd复制将乌班图系统(Ubuntu22.04)完整迁移到新硬盘并扩容

    我的折磨历程 开始的时候用乌班图的时候 xff0c 不懂事 xff0c 根目录太小了 xff0c 后来就满了 xff0c 就就感觉完全没法用 xff0c 看着现在硬盘贼便宜 xff0c 去狗东买了个新的硬盘 感觉挂载硬盘并不能解决我的问题
  • 《剑指offer》面试题 12:矩阵中的路径(C++实现)

    题目 请设计一个函数 xff0c 用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径 路径可以从矩阵中任意一格开始 xff0c 每一步可以在矩阵中向左 右 上 下移动一格 如果一条路径经过了矩阵的某一格 xff0c 那么该路径不能再
  • CocosCreator项目实战(13):功能-排行榜

    文章目录 一 主域设置二 子域设置三 其他相关设置 参考Cocos接入微信小游戏官方文档 xff0c 为了保护其社交关系链数据 xff0c 微信小游戏增加了开放数据域的概念 只有在开放数据域中才能访问微信提供的wx getFriendClo
  • Android MotionLayout 运动布局的使用

    Google 在 2018 年开发者大会上推出一种新的布局组件 MotionLayout 其官方定义如下 xff1a MotionLayout is a layout type that helps you manage motion an