【Interface&navigation】通过《include/》重新使用布局(9)

虽然Android提供了各种小部件来提供小型且可重用的交互元素,但您可能还需要重新使用需要特殊布局的较大组件。为了有效地重新使用完整的布局,可以使用<include/>和<merge/>标签在当前布局中嵌入另一个布局。

重复使用布局非常强大,因为它允许您创建可重用的复杂布局。例如,是/否按钮面板,或带有说明文字的自定义进度栏。这也意味着您的应用程序的任何元素都可以在多个布局中提取,分别管理,然后包含在每个布局中。因此,尽管可以通过编写自定义来创建各个UI组件,View但通过重新使用布局文件,您可以更轻松地完成此任务。

创建一个可重用的布局


如果您已经知道要重新使用的布局,请创建一个新的XML文件并定义布局。例如,以下是定义要包含在每个活动(titlebar.xml)中的标题栏的布局:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/titlebar_bg"
    tools:showIn="@layout/activity_main" >

    <ImageView android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:src="@drawable/gafricalogo" />
</FrameLayout>

根目录View应完全按照您希望它出现在添加此布局的每个布局中。

注意:tools:showIn上述XML中 的属性是一个特殊属性,在编译期间会被删除,并且仅在Android Studio的设计时使用 - 它指定包含此文件的布局,因此您可以在出现文件时预览(并编辑)该文件同时嵌入父级布局中。

使用<include>标签


在要添加可重用组件的布局中,添加 <include/>标签。例如,这是一个包含上面标题栏的布局:

这是布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/app_bg"
    android:gravity="center_horizontal">

    <include layout="@layout/titlebar"/>

    <TextView android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:text="@string/hello"
              android:padding="10dp" />

    ...

</LinearLayout>

您也可以android:layout_*通过在<include/>标签中指定包含布局的根视图的所有布局参数(任何属性)。例如:

<include android:id="@+id/news_title"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         layout="@layout/title"/>

但是,如果要使用<include>标签覆盖布局属性,则必须覆盖两者 android:layout_height并使android:layout_width其他布局属性生效。

使用<merge>标签


将<merge />标签包含在另一个布局中时,该标签有助于消除视图层次结构中的冗余视图组。例如,如果您的主布局是LinearLayout可以在多个布局中重新使用两个连续视图的垂直布局,则放置两个视图的可重用布局需要具有其自己的根视图。但是,使用另一个LinearLayout作为可重用布局的根目录会导致垂直LinearLayout内部出现垂直LinearLayout。嵌套LinearLayout 服务没有真正的目的,除了减慢你的UI性能。

为了避免包含这样的冗余视图组,您可以改为使用该 <merge>元素作为可重用布局的根视图。例如:

<merge xmlns:android="http://schemas.android.com/apk/res/android">

    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/add"/>

    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/delete"/>

</merge>

现在,当您在另一个布局(使用<include/>标签)中包含此布局时,系统会忽略该<merge>元素,并将两个按钮直接放置在布局中,而不是<include/>标签。

有关与此主题相关的更多信息,请参阅 布局资源。

联系我

QQ:94297366
微信打赏:https://pan.baidu.com/s/1dSBXk3eFZu3mAMkw3xu9KQ

公众号推荐:

【Interface&navigation】通过《include/》重新使用布局(9)

转载于:https://blog.51cto.com/4789781/2133070

/home/ubuntu/work_space/catkin_navigation/src/planner/plan_manage/src/display.cpp: In function ‘void NextGoalCallback(const String&)’: /home/ubuntu/work_space/catkin_navigation/src/planner/plan_manage/src/display.cpp:16:9: error: ‘IsNearby’ was not declared in this scope 16 | if (IsNearby(curr_pose, init_pose)) { | ^~~~~~~~ /home/ubuntu/work_space/catkin_navigation/src/planner/plan_manage/src/display.cpp: In function ‘bool IsNearby(geometry_msgs::PoseStamped, geometry_msgs::PoseStamped)’: /home/ubuntu/work_space/catkin_navigation/src/planner/plan_manage/src/display.cpp:40:113: error: no matching function for call to ‘sqrt(geometry_msgs::Point_<std::allocator<void> >::_x_type, geometry_msgs::Point_<std::allocator<void> >::_y_type)’ 40 | return sqrt(pose_a.pose.position.x - pose_b.pose.position.x, pose_a.pose.position.y - pose_b.pose.position.y) < 1 ? : true : false; | ^ In file included from /usr/include/features.h:461, from /usr/include/x86_64-linux-gnu/c++/9/bits/os_defines.h:39, from /usr/include/x86_64-linux-gnu/c++/9/bits/c++config.h:528, from /usr/include/c++/9/iostream:38, from /home/ubuntu/work_space/catkin_navigation/src/planner/plan_manage/src/display.cpp:1: /usr/include/x86_64-linux-gnu/bits/mathcalls.h:143:1: note: candidate: ‘double sqrt(double)’ 143 | __MATHCALL (sqrt,, (_Mdouble_ __x)); | ^~~~~~~~~~ /usr/include/x86_64-linux-gnu/bits/mathcalls.h:143:1: note: candidate expects 1 argument, 2 provided In file included from /opt/ros/noetic/include/ros/time.h:55, from /opt/ros/noetic/include/ros/ros.h:38, from /home/ubuntu/work_space/catkin_navigation/src/planner/plan_manage/src/display.cpp:2: /usr/include/c++/9/cmath:475:5: note: candidate: ‘template<class _Tp> constexpr typename __gnu_cxx::__enable_if<
03-21
<think>嗯,用户遇到了C++编译错误,包括未定义的函数‘IsNearby’和sqrt函数参数不匹配的问题。首先,我需要分析这两个错误的可能原因和解决方法。 首先,‘IsNearby’未定义的错误通常是因为函数没有正确声明或链接。用户可能在代码中调用了IsNearby函数,但编译器找不到它的定义。这时候需要检查是否在头文件中声明了该函数,或者在源文件中实现了但没有包含相应的头文件。另外,如果IsNearby是另一个类或命名空间中的成员函数,可能需要检查作用域是否正确,或者是否遗漏了类名或命名空间的限定符。例如,正确的调用应该是ClassName::IsNearby或者namespace::IsNearby。 然后是sqrt函数参数不匹配的问题。C++标准库中的sqrt有多个重载版本,接受float、double等参数。如果传入的是整数,编译器可能无法确定正确的重载,尤其是在包含<cmath>头文件的情况下。这时候需要将参数显式转换为double,比如使用sqrt(static_cast<double>(x)),或者在调用时直接使用浮点数,如sqrt(2.0)。此外,检查是否正确包含了<cmath>头文件,并且没有使用旧的C语言头文件<math.h>,因为后者可能导致命名空间问题。 接下来,用户提到他们是在ROS环境下编译,所以还需要考虑ROS的依赖和编译配置。例如,CMakeLists.txt是否正确添加了包含IsNearby函数的源文件,是否在add_executable和target_link_libraries中正确链接了相关的库。此外,检查是否有拼写错误,函数名称是否一致,比如大小写是否正确。 对于sqrt的问题,可能需要确认编译器是否启用了C++11或更高标准,因为某些数学函数的处理方式可能有变化。另外,检查是否有自定义的sqrt函数或宏,导致与标准库冲突。 总结下来,解决步骤可能包括: 1. 检查IsNearby函数的声明和定义,确保作用域正确,并在CMakeLists中添加相应的源文件。 2. 将sqrt的参数显式转换为double,并包含正确的头文件。 3. 验证ROS包的依赖和编译配置,确保所有必要的库都被正确链接。 同时,用户提供的引用[1]和[2]提到未定义符号错误通常与依赖配置有关,可能需要检查CMakeLists.txt中的find_package和catkin_package配置,确保所有依赖项都被正确包含。例如,是否缺少geometry_msgs的依赖,或者tf相关的库没有被正确链接。 最后,生成相关问题,帮助用户进一步排查可能的其他问题,比如链接错误或编译器设置。</think>### 分步解决方案 #### 问题1: `&#39;IsNearby&#39;`未定义错误 **步骤1: 确认函数声明与作用域** - 检查是否在头文件(如`xxx.h`)中正确声明了`IsNearby`函数,例如: ```cpp // 类成员函数需在类定义中声明 class MyClass { public: bool IsNearby(const geometry_msgs::PoseStamped& pose1, const geometry_msgs::PoseStamped& pose2); }; ``` - 若为全局函数,需确保在调用前声明: ```cpp bool IsNearby(const geometry_msgs::PoseStamped& pose1, const geometry_msgs::PoseStamped& pose2); ``` **步骤2: 链接实现文件** - 在`CMakeLists.txt`中,将包含`IsNearby`实现的源文件添加到`add_executable`: ```cmake add_executable(your_node src/main.cpp src/your_implementation.cpp # 包含IsNearby定义的源文件 ) ``` **步骤3: 检查命名空间和类限定符** - 若`IsNearby`属于某个类或命名空间,调用时需添加限定符: ```cpp MyClass obj; if (obj.IsNearby(pose1, pose2)) { ... } // 类成员函数 ``` #### 问题2: `sqrt`函数参数不匹配 **步骤1: 强制转换参数类型** - 确保传递给`sqrt`的参数为`double`类型,例如: ```cpp double distance = sqrt(static_cast<double>(x*x + y*y)); ``` **步骤2: 包含正确的头文件** - 添加`#include <cmath>`以使用标准数学函数[^1]。 **步骤3: 验证C++标准版本** - 在`CMakeLists.txt`中设置C++11或更高标准: ```cmake add_compile_options(-std=c++11) ``` #### 综合验证 **检查ROS依赖配置** - 在`CMakeLists.txt`中确认已添加`geometry_msgs`依赖: ```cmake find_package(catkin REQUIRED COMPONENTS roscpp geometry_msgs # 确保包含此依赖 ) ``` **完整CMake片段示例** ```cmake add_executable(my_node src/main.cpp src/pose_utils.cpp # 包含IsNearby实现的文件 ) target_link_libraries(my_node ${catkin_LIBRARIES} ) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值