dede电影网站模板下载,怎样把网站建设在国外,wordpress 使用mysql添加文章,有什么网站可以接单做兼职的简介 在Android应用开发中#xff0c;Fragment和ViewModel是两个非常重要的概念#xff0c;它们分别属于架构组件库的一部分#xff0c;旨在帮助开发者构建更加模块化、健壮且易维护的应用。
Fragment Fragment是Android系统提供的一种可重用的UI组件#xff0c;它能够作为…简介 在Android应用开发中Fragment和ViewModel是两个非常重要的概念它们分别属于架构组件库的一部分旨在帮助开发者构建更加模块化、健壮且易维护的应用。
Fragment Fragment是Android系统提供的一种可重用的UI组件它能够作为活动Activity的一部分具有自己的生命周期并且可以在多个Activity中使用。Fragment的设计初衷是为了支持更灵活的屏幕布局特别是在需要适配不同屏幕尺寸和方向时。通过组合多个Fragment开发者可以创建丰富的用户界面并且每个Fragment都可以独立地处理用户输入、保存状态等从而提高代码的复用性和模块化。
ViewModel ViewModel是Android架构组件库中的一个核心类用于存储和管理UI相关的数据。它的主要目的是分离视图View和数据使得数据能够在配置变更如屏幕旋转时保持避免了因Activity或Fragment重建而导致的数据丢失问题。ViewModel的生命周期独立于UI控制器Activity或Fragment确保了数据的持久性。此外ViewModel还可以与LiveData等组件结合使用实现数据变化的自动通知简化了UI更新的逻辑。
Fragment与ViewModel的协同工作
在实际开发中为了实现Fragment的数据持久化和解耦通常会为Fragment关联一个ViewModel。这样做有以下几个好处 数据共享如果多个Fragment需要共享数据可以将这些数据放在一个共享的ViewModel中。这样即使Fragment被重建数据仍然保持不变而且Fragment之间可以直接访问这些共享数据无需通过Activity传递。 生命周期解耦ViewModel不依赖于UI组件的生命周期因此即使Fragment销毁并重新创建比如由于配置变更ViewModel仍然存在保证了数据的连续性。 简化数据管理ViewModel负责数据的获取、存储和处理而Fragment专注于展示数据和处理用户交互这使得代码结构更加清晰易于维护。
一、开启绑定Binding
Step 1: 打开build.gradleModule级别文件。 Step 2: 在android闭包内确保buildFeatures块存在然后添加viewBinding属性并设为true。 buildFeatures
android {...buildFeatures {viewBinding true // 注意新版一定要有}
}
这是启用ViewBinding的推荐方式特别是在较新的Android Gradle插件版本中。buildFeatures是一个集合了各种构建特性的开关通过在这里设置viewBinding为true你告诉Gradle在构建时生成ViewBinding类。这些类让你能够以类型安全的方式访问XML布局中的视图无需手动调用findViewById。
dataBinding:
android {...dataBinding {enabled true // 注意新版一定要有}
}
类似地这是启用DataBinding的方式。通过在dataBinding块内设置enabled为true你激活了DataBinding特性。DataBinding比ViewBinding更进一步提供了数据和视图之间的双向绑定能力允许在布局文件中直接使用数据对象并支持表达式来处理数据变化实现更复杂的UI逻辑。
viewBinding:
android {...viewBinding {enabled true // 注意新版一定要有}
}
正确的配置应该遵循上述第一条提到的buildFeatures { viewBinding true }。实际上推荐使用buildFeatures块来配置ViewBinding。选择哪种绑定技术取决于你的项目需求简单视图绑定用ViewBinding需要更复杂数据逻辑处理则使用DataBinding。
二、加载布局
ActivityMain: // 定义MainActivity类继承自AppCompatActivity这是Android提供的一个Activity基类用于兼容旧版设备
public class MainActivity extends AppCompatActivity {// 声明一个私有成员变量binding类型为ActivityMainBinding用于存储由Data Binding生成的绑定对象private ActivityMainBinding binding;// 重写onCreate()方法这是Activity生命周期的第一个回调方法用于初始化ActivityOverrideprotected void onCreate(Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState); // 调用父类的onCreate()方法执行基本的初始化工作// 使用Data Binding的inflate方法从XML布局文件创建一个绑定对象// getLayoutInflater()返回LayoutInflater实例用于将XML布局转换为View对象// ActivityMainBinding.inflate()方法将布局文件转换为ActivityMainBinding对象binding ActivityMainBinding.inflate(getLayoutInflater());// 设置Activity的内容视图即将绑定对象的根视图设置为Activity的布局// binding.getRoot()返回inflate生成的View对象即整个布局的根ViewsetContentView(binding.getRoot());}
}
在这个过程中以下步骤发生 声明Binding对象在MainActivity类中声明了一个ActivityMainBinding类型的私有变量bindingActivityMainBinding是Data Binding自动生成的类用于封装和管理XML布局文件中的所有视图。 加载布局在onCreate()方法中首先调用super.onCreate()来执行父类的初始化过程。然后使用ActivityMainBinding.inflate()方法加载布局文件getLayoutInflater()提供了创建布局的能力。 设置内容视图调用setContentView()方法并传入binding.getRoot()返回的根视图将该视图设置为MainActivity的布局视图。这意味着MainActivity的界面将按照ActivityMainBinding所绑定的XML布局文件来渲染。
通过使用Data Binding开发者可以直接通过binding对象访问布局文件中的所有视图而无需调用findViewById()方法这使得代码更加简洁、可读性更强同时也避免了一些常见的错误如空指针异常
ViewModel: // 定义一个继承自ViewModel的类用于存储界面相关的数据保证数据在配置变化时不会丢失
public class SyFragmentViewModel extends ViewModel {// 声明一个私有成员变量mText类型为MediatorLiveDataString用于存储和分发字符串数据private MediatorLiveDataString mText;// 构造函数初始化mText并设置其初始值public SyFragmentViewModel() {// 创建并初始化MediatorLiveData实例mText new MediatorLiveData();// 设置mText的初始值mText.setValue(第一个页面);}// 公共方法返回mText允许外部组件观察mText的数据变化public LiveDataString getText() {return mText;}
}
通过上述代码SyFragmentViewModel可以被Fragment或Activity使用以观察和响应数据变化从而实现实时更新UI的效果。
Fragment // 定义SyFragment类继承自Fragment这是Android中用于构建可重用UI块的类。
public class SyFragment extends Fragment {// 声明一个私有成员变量binding类型为SyActivityBinding。这是Data Binding自动生成的类// 它包含了对SyFragment所使用的XML布局文件中所有View的引用。private SyActivityBinding binding;// 重写onCreateView()方法这是Fragment生命周期的一部分用于创建并返回Fragment的用户界面视图。NullableOverridepublic View onCreateView(NonNull LayoutInflater inflater, Nullable ViewGroup container, Nullable Bundle savedInstanceState) {// 使用Data Binding的inflate方法从XML布局文件创建一个绑定对象。// 第一个参数是LayoutInflater用于将XML布局转换为View对象// 第二个参数是ViewGroup表示inflate出的View是否应立即附加到该ViewGroup// 第三个参数是一个布尔值如果为trueinflate出的View将附加到container否则不会。// 这里inflate方法会根据XML布局文件生成相应的View对象并将这些View对象封装进binding对象中。binding SyActivityBinding.inflate(inflater, container, false);// 获取inflate生成的View对象即整个布局的根View以便返回给onCreateView()方法。View root binding.getRoot();// 从binding中获取TextView的引用这一步利用了Data Binding的便利性可以直接通过属性名访问View。final TextView textView binding.textView;// 创建并获取SyFragmentViewModel的实例。ViewModelProvider是一个工具类用于创建和管理ViewModel实例。// 这里的this参数告诉ViewModelProvider当前Fragment需要哪个ViewModel。SyFragmentViewModel syFragmentViewModel new ViewModelProvider(this).get(SyFragmentViewModel.class);// 观察SyFragmentViewModel中getText()返回的LiveData对象。// observe()方法用于注册观察者getViewLifecycleOwner()确保观察者只在Fragment可见时生效。// textView::setText是一种方法引用表示当LiveData数据改变时自动调用TextView的setText()方法更新UI。syFragmentViewModel.getText().observe(getViewLifecycleOwner(), textView::setText);// 返回inflate生成的根View这将是Fragment的用户界面。return root;}// 重写onDestroy()方法这是Fragment生命周期的一部分当Fragment不可见时调用。// 这里设置binding为null有助于回收资源防止内存泄漏。Overridepublic void onDestroy() {super.onDestroy();binding null;}
} 这段代码展示了如何在一个Fragment中使用Data Binding和ViewModel来构建UI并响应数据变化。通过使用Data Binding我们可以更简洁地访问布局中的View通过ViewModel和LiveData我们可以在数据变化时自动更新UI同时保证数据在配置变更时的持久性。
ViewGroup ViewGroup是一个非常重要的概念它是View体系结构中的基础组件之一负责组织和管理子View包括其他ViewGroup。简单来说ViewGroup就是一种特殊的View它不仅自己可以显示内容还可以包含多个子View并且能够控制这些子View的布局方式。
在SyFragment的onCreateView()方法中ViewGroup主要体现在inflater.inflate()方法的第二个参数——container。这里的container实际上就是一个ViewGroup它是指定用于容纳由LayoutInflater从XML布局文件中解析出来的View组件的父容器。
当你调用SyActivityBinding.inflate(inflater, container, false)时
inflater是LayoutInflater的实例它负责读取XML布局文件并将其转换为实际的View对象。container是ViewGroup的实例代表了onCreateView()方法中返回的View将要被添加到的父容器。通常情况下container是Fragment将要附加到的Activity的主布局。false作为第三个参数意味着从XML布局文件中inflate出来的View不会立即被添加到container中。这是因为Fragment的View应该由FragmentManager来管理而不是直接由ViewGroup来管理。FragmentManager会在适当的时机将View添加到container中。
所以在这个特定的上下文中ViewGroup的作用主要是作为Fragment视图层次结构的一部分为Fragment的布局提供一个容器。当Fragment变得可见时其视图将被FragmentManager添加到指定的ViewGroup即container中。
这里SyActivityBinding.inflate()方法通过LayoutInflater和ViewGroupcontainer实现了从XML布局文件到View对象的转换并通过Data Binding的方式将这些View对象封装进SyActivityBinding对象中便于后续的代码访问和操作。
三、布局加载比较 binding ActivityMainBinding.inflate(getLayoutInflater()); 和 binding YourActivityBinding.inflate(inflater, container, false); 都使用了 Android 的 Data Binding 库来从 XML 布局文件生成对应的 Java 对象但它们之间存在一些关键区别主要在于 inflate 方法的调用方式和参数上。
第一种情况:
binding ActivityMainBinding.inflate(getLayoutInflater()); 这里使用的是 ActivityMainBinding 类的 inflate 方法这个方法不需要额外的容器参数。它直接使用 getLayoutInflater() 来获取 LayoutInflater 实例然后调用 inflate 方法生成布局。这种情况下inflate 方法会自动找到一个合适的根视图并且返回一个 ActivityMainBinding 类型的对象该对象包含了布局中的所有 View。
第二种情况:
binding YourActivityBinding.inflate(inflater, container, false); 这个版本的 inflate 方法接收三个参数
inflater: 这是一个 LayoutInflater 实例通常从父视图或者 Activity 中获取。container: 这是一个可选的父视图容器如果你想要将这个布局添加到某个已存在的 View 组中时你需要提供这个容器。如果布局是要作为独立的视图则可以忽略此参数。attachToRoot: 这个布尔值参数决定了是否将生成的布局视图自动添加到 container 参数指定的容器中。如果设置为 false则不会自动添加如果设置为 true则会自动添加到 container 中。
总结:
如果你的布局是要直接设置为 Activity 的根布局通常使用第一种方法因为不需要考虑容器问题。如果你的布局是要作为子布局添加到某个容器中比如在 Fragment 或者自定义 View 中那么你应该使用第二种方法并且要确保 attachToRoot 参数设置正确以便于控制布局是否应该被自动添加到容器中。
在大多数情况下Activity 的布局会直接设置为 Activity 的根视图因此第一种情况更为常见。然而在更复杂的场景下例如在 Fragment 中使用 Data Binding第二种情况则更为适用。
四、navigation
navigation创建 布局加载 代码完善 五、menu菜单
menu创建 Vector图标 new创建 颜色、名称等设定 finsh完成 添加item项 代码完善 切记一定要与navigation的xml代码中fragment的id一致
六、导航实现
BottomNavigationView: fragment: 一定要将NavHostFragment改fragment
activity中代码实现 public class MainActivity extends AppCompatActivity {// 定义一个 ActivityMainBinding 类型的成员变量 binding// ActivityMainBinding 是由 Data Binding 自动生成的类用于绑定 XML 布局文件中的元素到 Java 代码。private ActivityMainBinding binding;Overrideprotected void onCreate(Nullable Bundle savedInstanceState) {// 调用父类的 onCreate 方法这是每个 Activity 的 onCreate 方法都应该做的。super.onCreate(savedInstanceState);// 使用 Data Binding 的 inflate 方法从 XML 文件加载布局。// getLayoutInflater() 返回 LayoutInflater 实例用于加载布局。// ActivityMainBinding.inflate 方法会解析 res/layout/activity_main.xml 文件// 并返回一个 ActivityMainBinding 实例其中包含布局文件中的所有视图组件。binding ActivityMainBinding.inflate(getLayoutInflater());// 设置 Activity 的内容视图。binding.getRoot() 方法返回布局文件中的根视图。setContentView(binding.getRoot());// 通过 Data Binding 访问 BottomNavigationView 视图其 ID 在 activity_main.xml 文件中定义。BottomNavigationView bottomNavigationView binding.BottomNavi;// 创建 NavController 实例用于管理应用中的导航。// Navigation.findNavController 方法需要传入一个 Context 和一个 View 的 ID// 这里使用 R.id.fragmentContainerView 表示要查找的 NavController 管理的 Fragment 容器。NavController navController Navigation.findNavController(this, R.id.fragmentContainerView);// 创建 AppBarConfiguration 实例用于配置 App Bar 的行为这里使用默认配置。// AppBarConfiguration 的构造函数可以接收多个参数来配置不同的行为// 但在这个例子中使用了默认的构造函数没有进行任何配置。AppBarConfiguration appBarConfiguration new AppBarConfiguration.Builder().build();// 使用 NavigationUI.setupActionBarWithNavController 方法设置 ActionBar 与 NavController 的关联// 这样 ActionBar 就可以根据 NavController 的状态显示相应的标题和导航项。// 第一个参数是当前 Activity第二个参数是 NavController第三个参数是 AppBarConfiguration。NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);// 使用 NavigationUI.setupWithNavController 方法设置 BottomNavigationView 与 NavController 的关联// 这样 BottomNavigationView 就可以响应 NavController 的变化显示正确的菜单项。// 第一个参数是 BottomNavigationView第二个参数是 NavController。NavigationUI.setupWithNavController(bottomNavigationView, navController);}
}
最终效果