Android开发:碎片Fragment完全解析fragment_main.xml/activity_main.xml

本文介绍Android开发中Fragment的概念及其应用。Fragment类似Activity,可嵌入Activity中,以适应不同屏幕尺寸,如平板。文章通过实例展示了Fragment的基本使用方法及动态添加过程。
 

为了让界面可以在平板上更好地展示,Android在3.0版本引入了Fragment(碎片)功能,它非常类似于Activity,可以像 Activity一样包含布局。Fragment通常是嵌套在Activity中使用的,现在想象这种场景:有两个 Fragment,Fragment 1包含了一个ListView,每行显示一本书的标题。Fragment 2包含了TextView和 ImageView,来显示书的详细内容和图片。

AD:51CTO学院:IT精品课程在线看!

 

我们都知道,Android上的界面展示都是通过Activity实现的,Activity实在是太常用了,我相信大家都已经非常熟悉了,这里就不再赘述。

但是Activity也有它的局限性,同样的界面在手机上显示可能很好看,在平板上就未必了,因为平板的屏幕非常大,手机的界面放在平板上可能会有过分被拉 长、控件间距过大等情况。这个时候更好的体验效果是在Activity中嵌入"小Activity",然后每个"小Activity"又可以拥有自己的布 局。因此,我们今天的主角Fragment登场了。

Fragment初探

为了让界面可以在平板上更好地展示,Android在3.0版本引入了Fragment(碎片)功能,它非常类似于Activity,可以像 Activity一样包含布局。Fragment通常是嵌套在Activity中使用的,现在想象这种场景:有两个 Fragment,Fragment 1包含了一个ListView,每行显示一本书的标题。Fragment 2包含了TextView和 ImageView,来显示书的详细内容和图片。

如果现在程序运行竖屏模式的平板或手机上,Fragment 1可能嵌入在一个Activity中,而Fragment 2可能嵌入在另一个Activity中,如下图所示:

而如果现在程序运行在横屏模式的平板上,两个Fragment就可以嵌入在同一个Activity中了,如下图所示:

由此可以看出,使用Fragment可以让我们更加充分地利用平板的屏幕空间,下面我们一起来探究下如何使用Fragment。

首先需要注意,Fragment是在3.0版本引入的,如果你使用的是3.0之前的系统,需要先导入android-support-v4的jar包才能使用Fragment功能。

新建一个项目叫做Fragments,然后在layout文件夹下新建一个名为fragment1.xml的布局文件:

 
    
  1. "http://schemas.android.com/apk/res/android" 
  2. android:layout_width="match_parent" 
  3. android:layout_height="match_parent" 
  4. android:background="#00ff00"> 
  5. android:layout_width="wrap_content" 
  6. android:layout_height="wrap_content" 
  7. android:text="This is fragment 1" 
  8. android:textColor="#000000" 
  9. android:textSize="25sp"/> 
  10.  

可以看到,这个布局文件非常简单,只有一个LinearLayout,里面加入了一个TextView。我们如法炮制再新建一个fragment2.xml :

 
    
  1. "http://schemas.android.com/apk/res/android" 
  2. android:layout_width="match_parent" 
  3. android:layout_height="match_parent" 
  4. android:background="#ffff00"> 
  5. android:layout_width="wrap_content" 
  6. android:layout_height="wrap_content" 
  7. android:text="This is fragment 2" 
  8. android:textColor="#000000" 
  9. android:textSize="25sp"/> 
  10.  

然后新建一个类Fragment1,这个类是继承自Fragment的:

 
    
  1. publicclass Fragment1 extends Fragment {   
  2. @Override 
  3. public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {   
  4. return inflater.inflate(R.layout.fragment1, container, false);   
  5.     }   
  6. }   

我们可以看到,这个类也非常简单,主要就是加载了我们刚刚写好的fragment1.xml布局文件并返回。同样的方法,我们再写好Fragment2 :

 
    
  1. publicclass Fragment2 extends Fragment {   
  2. @Override 
  3. public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {   
  4. return inflater.inflate(R.layout.fragment2, container, false);   
  5.     }   
  6. }   

然后打开或新建activity_main.xml作为主Activity的布局文件,在里面加入两个Fragment的引用,使用android:name前缀来引用具体的Fragment:

 
    
  1. "http://schemas.android.com/apk/res/android" 
  2. android:layout_width="match_parent" 
  3. android:layout_height="match_parent" 
  4. android:baselineAligned="false"> 
  5. android:id="@+id/fragment1" 
  6. android:name="com.example.fragmentdemo.Fragment1" 
  7. android:layout_width="0dip" 
  8. android:layout_height="match_parent" 
  9. android:layout_weight="1"/> 
  10. android:id="@+id/fragment2" 
  11. android:name="com.example.fragmentdemo.Fragment2" 
  12. android:layout_width="0dip" 
  13. android:layout_height="match_parent" 
  14. android:layout_weight="1"/> 
  15.  

最后打开或新建MainActivity作为程序的主Activity,里面的代码非常简单,都是自动生成的:

 
    
  1. publicclass MainActivity extends Activity {   
  2. @Override 
  3. protectedvoid onCreate(Bundle savedInstanceState) {   
  4. super.onCreate(savedInstanceState);   
  5.         setContentView(R.layout.activity_main);   
  6.     }   
  7. }   

现在我们来运行一次程序,就会看到,一个Activity很融洽地包含了两个Fragment,这两个Fragment平分了整个屏幕,效果图如下:

动态添加Fragment

你已经学会了如何在XML中使用Fragment,但是这仅仅是Fragment最简单的功能而已。Fragment真正的强大之处在于可以动态地添加到 Activity当中,因此这也是你必须要掌握的东西。当你学会了在程序运行时向Activity添加Fragment,程序的界面就可以定制的更加多样 化。下面我们立刻来看看,如何动态添加Fragment。

还是在上一节代码的基础上修改,打开activity_main.xml,将其中对Fragment的引用都删除,只保留最外层的LinearLayout,并给它添加一个id,因为我们要动态添加Fragment,不用在XML里添加了,删除后代码如下:

 
    
  1. "http://schemas.android.com/apk/res/android" 
  2. android:id="@+id/main_layout" 
  3. android:layout_width="match_parent" 
  4. android:layout_height="match_parent" 
  5. android:baselineAligned="false"> 
  6.  

然后打开MainActivity,修改其中的代码如下所示:

 
    
  1.     publicclass MainActivity extends Activity {   
  2.     @Override 
  3.     protectedvoid onCreate(Bundle savedInstanceState) {   
  4.     super.onCreate(savedInstanceState);   
  5.             setContentView(R.layout.activity_main);   
  6.             Display display = getWindowManager().getDefaultDisplay();   
  7.     if (display.getWidth() > display.getHeight()) {   
  8.                 Fragment1 fragment1 = new Fragment1();   
  9. getFragmentManager().beginTransaction().replace(R.id.main_layout, fragment1).commit();   
  10.             } else {   
  11.                 Fragment2 fragment2 = new Fragment2();   
  12. getFragmentManager().beginTransaction().replace(R.id.main_layout, fragment2).commit();   
  13.             }   
  14.         }   
  15.     }   

首先,我们要获取屏幕的宽度和高度,然后进行判断,如果屏幕宽度大于高度就添加fragment1,如果高度大于宽度就添加fragment2。动态添加Fragment主要分为4步:

1.获取到FragmentManager,在Activity中可以直接通过getFragmentManager得到。

2.开启一个事务,通过调用beginTransaction方法开启。

3.向容器内加入Fragment,一般使用replace方法实现,需要传入容器的id和Fragment的实例。

4.提交事务,调用commit方法提交。

现在运行一下程序,效果如下图所示:

 

如果你是在使用模拟器运行,按下ctrl + F11切换到竖屏模式。效果如下图所示:

 

 

 

转载于:https://www.cnblogs.com/rainey-forrest/p/3782237.html

Android resource linking failed com.oplus.aiunit.demo.app-mergeDebugResources-34:/layout/content_main.xml:18: error: attribute navGraph (aka com.oplus.aiunit.demo:navGraph) not found. com.oplus.aiunit.demo.app-mergeDebugResources-34:/layout/content_main.xml:18: error: attribute defaultNavHost (aka com.oplus.aiunit.demo:defaultNavHost) not found. com.oplus.aiunit.demo.app-mergeDebugResources-34:/layout/fragment_first.xml:22: error: resource string/next (aka com.oplus.aiunit.demo:string/next) not found. com.oplus.aiunit.demo.app-mergeDebugResources-34:/layout/fragment_first.xml:33: error: resource string/lorem_ipsum (aka com.oplus.aiunit.demo:string/lorem_ipsum) not found. com.oplus.aiunit.demo.app-mergeDebugResources-34:/layout/fragment_second.xml:22: error: resource string/previous (aka com.oplus.aiunit.demo:string/previous) not found. com.oplus.aiunit.demo.app-mergeDebugResources-34:/layout/fragment_second.xml:33: error: resource string/lorem_ipsum (aka com.oplus.aiunit.demo:string/lorem_ipsum) not found. com.oplus.aiunit.demo.app-main-37:/navigation/nav_graph.xml:6: error: attribute startDestination (aka com.oplus.aiunit.demo:startDestination) not found. com.oplus.aiunit.demo.app-main-37:/navigation/nav_graph.xml:12: error: resource string/first_fragment_label (aka com.oplus.aiunit.demo:string/first_fragment_label) not found. com.oplus.aiunit.demo.app-main-37:/navigation/nav_graph.xml:16: error: attribute destination (aka com.oplus.aiunit.demo:destination) not found. com.oplus.aiunit.demo.app-main-37:/navigation/nav_graph.xml:22: error: resource string/second_fragment_label (aka com.oplus.aiunit.demo:string/second_fragment_label) not found. com.oplus.aiunit.demo.app-main-37:/navigation/nav_graph.xml:26: error: attribute destination (aka com.oplus.aiunit.demo:destination) not found. error: failed linking file resources.
最新发布
08-23
<think>我们面对的是Android资源链接失败的错误,具体错误包括: 1. `attribute navGraph not found` - 通常在Navigation相关布局中出现 2. `defaultNavHost not found` - 同样与Navigation组件相关 3. `string resources not found` - 字符串资源未找到 根据引用中提供的错误信息,我们注意到类似的问题(如引用[1][2][3])通常由以下原因引起: - 缺少必要的依赖(如引用[4]提到缺少AndroidX依赖) - 使用了较高版本的API属性但未正确设置编译版本或主题 - 资源名称拼写错误或资源未定义 ## 解决方案 ### 1. 添加Navigation组件依赖 `navGraph`和`defaultNavHost`属性属于Navigation组件,首先确保添加了正确的依赖: ```gradle dependencies { def nav_version = "2.5.3" // 使用最新稳定版本 implementation "androidx.navigation:navigation-fragment-ktx:$nav_version" implementation "androidx.navigation:navigation-ui-ktx:$nav_version" } ``` ### 2. 确保使用正确的主题 在`res/values/styles.xml`中,确保你的应用主题继承自`Theme.MaterialComponents`(或`Theme.AppCompat`)且包含Navigation组件所需的属性: ```xml <style name="Theme.MyApp" parent="Theme.MaterialComponents.DayNight"> <!-- 其他属性 --> </style> ``` ### 3. 检查布局文件中属性的使用 在布局文件(如`activity_main.xml`)中,使用`app:navGraph`和`app:defaultNavHost`时,确保已声明命名空间: ```xml <androidx.fragment.app.FragmentContainerView android:id="@+id/nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="match_parent" app:navGraph="@navigation/nav_graph" <!-- 确保存在nav_graph.xml --> app:defaultNavHost="true" /> ``` > 注意:`app`命名空间必须定义:`xmlns:app="http://schemas.android.com/apk/res-auto"`[^5]。 ### 4. 解决字符串资源未找到的问题 - **检查字符串名称**:确认`@string/res_name`中的`res_name`在`res/values/strings.xml`中正确定义。 - **清理项目**:删除`build`目录并重新构建(`Build > Clean Project`)。 ### 5. 更新Gradle和Android Gradle插件 在`build.gradle`中: ```gradle dependencies { classpath 'com.android.tools.build:gradle:7.4.2' // 使用最新稳定版本 } ``` 在`gradle-wrapper.properties`中: ```properties distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip ``` ### 6. 同步项目配置 执行: - `File > Sync Project with Gradle Files` - 重启Android Studio ### 7. 检查资源合并冲突 如果存在多个模块,检查是否有重复的字符串资源定义(引用[5])。 ## 错误示例分析 根据引用[1][3]中的错误(如`dialogCornerRadius`、`fontVariationSettings`未找到),通常是因为: - **编译版本过低**:在`app/build.gradle`中设置`compileSdkVersion`至少为28(解决`dialogCornerRadius`)或更高(30+解决`fontVariationSettings`): ```gradle android { compileSdkVersion 33 defaultConfig { targetSdkVersion 33 } } ``` ## 总结流程 ```mermaid graph TD A[资源链接失败] --> B[检查依赖] B --> C[Navigation组件依赖?] C -->|是| D[添加依赖并同步] C -->|否| E[检查属性使用] E --> F[命名空间和属性拼写正确?] F -->|是| G[检查编译版本] F -->|否| H[修正布局文件] G --> I[compileSdkVersion≥28?] I -->|否| J[升级至33] I -->|是| K[清理并重建项目] ``` §§相关问题§§ 1. 如何为不同API级别配置兼容性资源? 2. Navigation组件与其他UI组件(如BottomNavigationView)如何集成? 3. 如何解决多模块项目中的资源重复问题? 4. 升级`compileSdkVersion`后出现新弃用警告如何处理? > 提示:90%的`资源链接失败`错误可通过升级依赖和`compileSdkVersion`解决[^4][^5]。若问题持续,请提供`build.gradle`文件内容。</think>针对您遇到的 Android 资源链接错误(包括 `navGraph`、`defaultNavHost` 属性未找到和字符串资源缺失问题),以下是系统化的解决方案: --- ### 一、核心原因分析 1. **属性未找到错误**(如 `navGraph`、`defaultNavHost`): - Navigation 组件依赖未正确配置 - 未使用兼容的 AppCompat 主题 - `compileSdkVersion` 版本过低(低于属性引入的 API 级别) 2. **字符串资源未找到**: - 资源名称拼写错误 - 未在对应构建变体(flavor)中声明资源 - 资源文件编码问题(尤其含特殊字符时) --- ### 二、分步解决方案 #### 1. 解决 Navigation 属性缺失问题 **步骤 1:添加 Navigation 组件依赖** 在 `app/build.gradle` 中添加: ```gradle dependencies { def nav_version = "2.5.3" // 使用最新稳定版本 implementation "androidx.navigation:navigation-fragment-ktx:$nav_version" implementation "androidx.navigation:navigation-ui-ktx:$nav_version" } ``` **步骤 2:检查主题继承关系** 在 `res/values/themes.xml` 中确保主题继承自 AppCompat: ```xml <style name="Theme.MyApp" parent="Theme.MaterialComponents.DayNight"> <!-- 必须包含 Navigation 所需属性 --> </style> ``` **步骤 3:升级编译版本** 在 `app/build.gradle` 中设置: ```gradle android { compileSdkVersion 33 // 必须 ≥ 28(dialogCornerRadius 引入版本) defaultConfig { targetSdkVersion 33 } } ``` #### 2. 解决字符串资源缺失问题 **步骤 1:验证资源存在性** 在 `res/values/strings.xml` 中确认资源已定义: ```xml <resources> <string name="app_name">MyApp</string> <!-- 确保引用的名称完全匹配 --> </resources> ``` **步骤 2:检查多模块引用** 如果使用多模块,在 `build.gradle` 中声明资源可见性: ```gradle android { sourceSets { main { res.srcDirs += ['../module_name/res'] } } } ``` **步骤 3:清理并重建项目** ```bash ./gradlew clean && ./gradlew --stop # 删除 .gradle 和 build 目录后重启 Android Studio ``` --- ### 三、针对引用错误的特别处理 #### 1. 解决 `dialogCornerRadius` 等属性缺失(引用 [1][3]) ```gradle android { compileSdkVersion 33 // 此属性在 API 28+ 引入 defaultConfig { vectorDrawables.useSupportLibrary = true // 解决 srcCompat 问题 } } ``` #### 2. 解决 `srcCompat` 属性缺失(引用 [2]) 添加矢量图支持库: ```gradle dependencies { implementation 'androidx.appcompat:appcompat:1.6.1' // ≥ 1.1.0 } ``` 在布局中正确使用: ```xml <androidx.appcompat.widget.AppCompatImageView app:srcCompat="@drawable/ic_vector" /> ``` #### 3. 解决字体属性缺失(引用 [3]) 升级 AndroidX 核心库: ```gradle dependencies { implementation 'androidx.core:core-ktx:1.10.0' // 包含 fontVariationSettings } ``` --- ### 四、配置检查清单 1. **依赖一致性检查**: ```bash ./gradlew :app:dependencies --configuration releaseRuntimeClasspath ``` 确保所有 AndroidX 库版本一致(避免 `appcompat` 和 `material` 版本冲突) 2. **资源合并验证**: ```gradle android { buildFeatures { buildConfig = true resValues = true } } ``` 3. **启用详细错误日志**: ```gradle android { aaptOptions { additionalParameters("--warn-mode", "strict") } } ``` --- ### 五、备用方案 若问题仍未解决,尝试强制使用 AndroidX: ```gradle android { defaultConfig { vectorDrawables.useSupportLibrary = true } } configurations.all { resolutionStrategy { force 'androidx.core:core:1.10.0' force 'androidx.appcompat:appcompat:1.6.1' } } ``` > **关键提示**:90% 的资源链接错误可通过升级 `compileSdkVersion` 和统一 AndroidX 库版本解决[^4][^5]。若问题持续,请提供 `build.gradle` 文件片段。 --- ### 流程图解 ```mermaid graph TD A[资源链接失败] --> B{错误类型} B -->|属性未找到| C[检查Navigation依赖] B -->|字符串缺失| D[验证资源文件] C --> E[升级compileSdkVersion≥28] D --> F[检查多模块资源路径] E --> G[添加AndroidX依赖] F --> G G --> H[清理并重建项目] H --> I[问题解决?] I -->|是| J[完成] I -->|否| K[检查合并资源] K --> L[查看merged/res/values文件] ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值