全部 文章 问答 分享 共找到18个相关内容
安卓MVVM的实战教程
大锯哥啥时候出一个MVVM的实战案例教程呀,如同喜马拉雅那种的-------超级期待-------
Mvvm架构初使用,编译报错!
我在各个activity里面使用MVVM架构,绑定数据后运行到真机报错,以下是我的代码 以下我是点击运行到真机后的报错 请问我是哪里错了
Jetpack我们先从MVVM开始讲起
Jetpack我们先从MVVM开始讲起 在开始Jetpack相关的课程之前,我们先从MVVM开始讲起。google推荐我们的应用架构是MVVM。 原连接地址:应用架构指南 为了达到实现这个架构,我们
因为在自学安卓就用vmmv架构学着写了一遍领券联盟
把梭,最近才又开始重新学安卓,学的是谷歌jetpack MVVM。 看了大锯哥jetpack视频我才知道mvp的开发模式。我以前也学了一段时间的后端,是早就淘汰的东西。 我写这个其实也不知道什么套路,
创建android项目,如何搭建一个好的架构?
1.我认为的架构是,MVP、MVC或者MVVM这些加上设计模式等,就能搭建一个比较好的架构出来。 那么请教一下大家,你们是以什么思想搭建这个架构的?
协程提前退出
) } 跟着学康师傅MVVM写的代码,发现这段代码在执行完 val homeArticleData: HomeArticleBean = myRepository.getHomeArticles(
Cvte二面 android实习生面经
启动流程?() 在4里面,Activity的生命周期是怎么被监听的。 Handler H 了解吗?(这是启动流程里面的一个东西) 说说自己的项目? MVC,MVP,MVVM,MVC可以弄成MVP吗?
Kotlin项目实战——天气预报类APP
城市,可以查看天气 可以提供某地近几日的天气情况与生活指数 项目截图 项目架构 采用了MVVM的架构,将逻辑层与表现层分开,使得代码更加清晰。 采用了谷歌推荐的MaterialDesign控件。 总结
【完结】Android开发Jeptack系列之Navigation
先学习完Jetpack我们从MVVM开始讲起-ViewModel LiveData Lifecycle再学习此课程 课程地址 课程地址 课程下载地址 课程下载 在线学习地址 B站: Android
最近的一些计划(2021-2-22)
我们的应用要升级的呀,对吧。这个时候我们就需要这个系统来帮助我们管理升级包了。 接着有了这个OTA系统以后,我们就会写MVVM的项目了,升级也可以验证了是吧。 by the way,AOSP的课程也会
7、Android开发Jetpack-DatabindingUI绑定类
绑定类 同学们可以理解为每一个xml可以对应生成一个binding类。比如说你的Activity里的布局 ,比如说列表的item,这些都可以生成对应的binding类。 前面的话,我们的绑定类都是自动生成的,比如说activity_main.xml的对应绑定类是ActivityMainBinding,也就是默认情况下以布局的名称改成驼峰命名法+Binding 修改绑定类的的名称 这个难搞吗? 不难搞,在data标签上,修改class属性即可,比如说我们的main_activity.xml布局里 点击Build->Make Project一下,重新构建,就会生成MainBinding的类了 这个类生成在什么目录呢? 获取到绑定类 两种方式,一种是通过DataBindingUtil来绑定,一种是通过Binding类的静态方法来获取到绑定类实例 手动方式来绑定 val inflate = ActivityMainBinding.inflate(layoutInflater) setContentView(inflate.root) 这样子,返回的是ActivityMainBinding,并且,可以拿到View,设置到Activity里去。 当然啦,这个inflate也有重载的方法,其实跟我们以前使用的LayoutInflater差不多。 val binding = ActivityMainBinding.inflate(getLayoutInflater(), viewGroup, false) 最后一个参数true或者false的意思同学们应该知道的吧,不知道的话去看一下自定义控件的课程。 Android开发自定义控件系列课程 可以直接bind到View上 val binding = ActivityMainBinding.bind(viewRoot) 使用DataBindingUtil来绑定 //把布局交给DataBindingUtil val activityMainBinding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main) 我们在Activity里两种方法都可以,我们在RecyclerView的适配器,或者其他条目类的布局,可以通过Binding类的静态方法来获取到实例对象。 绑定类的结构 前面我们已经告诉大家绑定类在哪个目录下了! 它继承自ViewDataBinding 并且是一个抽象类:public abstract class MainBinding extends ViewDataBinding 那么它的实现类是谁呢? public class MainBindingImpl extends MainBinding 在哪个目录下呢? 路径,同学们就看看上面这个图吧。 具体的代码同学们可以去看看,不难。
3、Android开发Jetpack-Databinding事件处理
Android开发Jetpack-Databinding事件处理 事件处理主要有两种 一种是方法引用,另外一种则是监听绑定 官方的说法叫做:Method references 和 Listener bindings 这两种方式的不同是什么呢? 创建时机不同 官方文档原话: The major difference between method references and listener bindings is that the actual listener implementation is created when the data is bound, not when the event is triggered. If you prefer to evaluate the expression when the event happens, you should use listener binding. 监听绑定是在在事件发生的时候创建的,而方法引用的方式是在数据绑定的时候创建的。 前期准备 数据 EventActivity.kt class EventActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val eventBinding = DataBindingUtil.setContentView(this, R.layout.activity_event) eventBinding.textInfo = "点击复制内容" eventBinding.eventHandler = EventHandlers() } } 方法处理类 class EventHandlers { fun onFistButtonClick(view: View) { println("第一个按钮点击了...") } fun onTextClickToCopy(text: String) { println("复制的内容是:$text") } } 方法引用 方法引用很简单,我们前面引入了EventHandlers,这其实是个类,类里面有方法,当然啦,你也可以传Activity进来,把方法写在Activity里即可
4、Android开发Jetpack-Databinding-import,variables,and includes
import,variables,and includes 导入[类],变量,包含(引入[布局]) import 我们一般用于导入类,比如说前面我们导入UserInfo,导入List类,而java.lang.*是默认导入的。 variables,变量的意思,也就是我们的数据bean类 include,包含,引入另外一个布局,子布局。达到某些布局可共用,减少重复代码。 import 官方的例子是这样 使用的时候就可以用值View里的常量了 别名 如果我们导入两个同名的类,不同包名嘛。 这个时候 我们可以通过起别名的方式来使用。 比如说,两个都是View 使用可以通过别名来使用 Variables Variables是变量的意思,你可以引入多个变量,这些在前面的代码里已经显示过了。 比如说: Includes 使用场景,当我们当前这个xml布局include另外一个布局时,比如说: 这样子,它包含了一个子布局,Include的方式添加进来 所包含的内容是这样子的 Activity的代码 class IncludeActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val includeBinding = DataBindingUtil.setContentView(this, R.layout.activity_include) includeBinding.user = User("TrillGates", 30, Gender.MALE) } } 运行结果
5、Android开发Jetpack-Databinding数据更新->UI更新
数据更新->UI更新 以前我们刷新数据,去服务器获取新的数据,然后数据回来,接着重新设置数据,更新UI。那使用Databinding还需要那样更新UI吗? 当然不需要咯! 通过使用实现Observable的数据,当数据更新的时候,自动更新UI。 监听字段变化更新 常用的Observable ObservableBoolean ObservableByte ObservableChar ObservableShort ObservableInt ObservableLong ObservableFloat ObservableDouble ObservableParcelable ObservableArrayMap ObservableArrayList 比如说我们有一个User,里面有name,age。 我们可以这么写 布局
Jetpack-Lifecycle
Jetpack-Lifecycle 相关课程: Jetpack我们从MVVM开始讲起 官方文档地址: 使用生命周期感知型组件处理生命周期 LifecycleOwner public
6、Android开发Jetpack-DatabindingUI更新->数据更新
UI更新->数据更新 前面我们是数据更新了,UI跟着更新,接下来我们是UI更新,数据跟着更新。这跟我们前面学习到的Vue.js是不是很像呀,不过我们需要做一些处理。当我们输入框变化的时候,当我们数字选择器内容改变的时候,单选框状态改变的时候,我们的数据也要跟着变化了。 应用场景,比如说我们在交易股票的时候,你输入数量,会动态地计算你的成交以后的钱是多少。 使用传统的做法,我们得监听输入股票数量的输入框的内容变化,然后再进行计算,设置到最终成交金额的控件上。 如果使用DataBinding,这个怎么做呢? UI布局 Activity代码 class TwoWayBindingActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val contentView = DataBindingUtil.setContentView( this, R.layout.activity_tow_way_binding ) val stock = ObservableStock() contentView.stock = stock stock.addOnPropertyChangedCallback(object : Observable.OnPropertyChangedCallback() { override fun onPropertyChanged(sender: Observable?, propertyId: Int) { if (sender is ObservableStock) { sender.totalPrise = sender.sellCount * sender.currentPrise } } }) } } 相关的Bean类 class ObservableStock : BaseObservable() { var sellCount: Int = 0 set(value) { if (value != field) { field = value notifyChange() } } var currentPrise: Float = 11.0f var totalPrise: Float = 0.0f } 转换器,EditText只接受String,所以我们需要一个转换器,来把String转成int类型,把int类型转成String类型 object Converter { @InverseMethod("string2Int") @JvmStatic fun int2String( value: Int ): String { return value.toString() } @JvmStatic fun string2Int(value: String): Int { if (value.isEmpty()) { return 0 } return value.toInt() } } 运行结果:
2、Android开发Jetpack-Databinding布局和绑定表达式
Android开发Jetpack-Databinding布局和绑定表达式 在布局中,我们可以通过@{}来绑定我们的控件与数据,我们看看在这个坑里我们可以做些什么东西呢? 常用运算符 在这里面,可以使用多种表达式,比如说: 官方文档:grouping、cast这些不用管,知道是分组、强转就行了,官方文档也是狗屎一样,也没有详细的说明。知道常用的基本上满足我们的日常开发了。 Mathematical + - / * % String concatenation + Logical && || Binary & | ^ Unary + - ! ~ Shift >> >>> << Comparison == > < >= <= (Note that < needs to be escaped as <) instanceof Grouping () Literals - character, String, numeric, null Cast Method calls Field access Array access [] Ternary operator ?: 算术运算符 + - / * % 字符串连接 + 逻辑 && || 二元 & | ^ 一元 + - ! ~ 移位运算符 >> >>> << 比较运算符 == > < >= <= Instanceof Grouping () 文字 - character, String, numeric, null Cast 方法调用 Field 访问字段 Array 访问数组 三元运算符 ?: 判空null 官方例子: android:text="@{user.displayName ?? user.lastName}" 如果左边为null,那么会显示右边的内容 等价于这一行代码 android:text="@{user.displayName != null ? user.displayName : user.lastName}" 获取对象属性 比如前面我们代码显示用户的名称 我们直接写: android:text="@{user.name}" 这里面访问对象的属性,就类似于我们的getter方法 避免空指针异常 databinding会自动地检查null,避免控制真异常。如果是为null的话则会显示默认值。 比如说前面的user.name,如果user为null,那么这个name是字符串类型,会显示null,如果前面的user.age,如果user为null,那么age是int类型,会显示默认值0 其他控件引用 比如说你在你的布局里有一个EditText,它的id为input_box,你还有一个TextView,如果它要显示EditText的内容,可以这么做 这里面注意一下名字,ID用下划线隔开,然后使用的是驼峰命名。 集合数据 这种情况一般不用,知道就行。因为我们集合的话一般对应着列表,列表的话我们会集合适配器来渲染,后面我们再用例子来说明一下吧。 官方的文档: … android:text="@{list[index]}" … android:text="@{sparse[index]}" … android:text="@{map[key]}" 接下来我们用一个例子来说说明一下吧 布局代码 CollectionActivity.kt代码 class CollectionActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val collectionBinding: ActivityCollectionBinding = DataBindingUtil.setContentView(this, R.layout.activity_collection) //List集合 collectionBinding.userList = listOf("TrillGates") //Map集合 collectionBinding.scoreMap = hashMapOf("TrillGates" to 100) //index collectionBinding.index = 0 } } 资源引用 也就是我们的表达式里也可以引用资源内容 ResourceActivity.kt的代码 class ResourcesActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val resourcesBinding = DataBindingUtil.setContentView( this, R.layout.activity_resources ) resourcesBinding.user = User("拉大锯", 30, Gender.MALE) } } 运行效果 某些资源需要特定的类型,请参考下图
1、Android开发Jetpack-Databinding基本使用
Android开发Jetpack-Databinding基本使用 官方文档地址:https://developer.android.com/topic/libraries/data-binding 人类自从有Android系统以来,我们绑定数据从findViewById开始,需要强转控件类型,随着SDK的升级,不再需要强转类型。顺带还有黄油刀,就是为了简化我们的开发。 我们可以不再使用findViewById去找控件,然后再设置数据了。如果数据更新了,还得重新设置。接下来我们就了解一下Databinding吧。 所以接下来我们要通过Databinding实现一般页面的数据绑定,列表的数据绑定,图片的数据绑定等常见的场景。 让你的项目支持Databinding android { ... dataBinding { enabled = true } } 基本使用 先来一个布局,我们要显示用户的信息,包括姓名,年龄和性别 创建bean类,用于封装用户数据 package com.sunofbeaches.databindingdemo.domain data class User(var name: String, var age: Int, var gender: Gender) enum class Gender { FEMALE, MALE } 布局代码 MainActivity.kt的代码 class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) //把布局交给DataBindingUtil val activityMainBinding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main) //设置数据 activityMainBinding.user = User("TrillGates", 30, Gender.MALE) } } 运行结果 由此,我们就完成了数据的绑定,我们没有给控件起id,里面的id是自动生成的,我们不用也行。这是不是跟vue.js里一样呀,绑定数据就可以了,非常简单。 说明 这里面我们布局最外层使用Layout标签进行包裹 layout你可以手动写,或者按alt+回车提示你自动改 data标签 这里面我们用于置顶bean类,也可以这样写: ActivityMainBinding是自动生成的类,大家可以看看以下代码,对应着以上的布局代码 // Generated by data binding compiler. Do not edit! package com.sunofbeaches.databindingdemo.databinding; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.constraintlayout.widget.Guideline; import androidx.databinding.Bindable; import androidx.databinding.DataBindingUtil; import androidx.databinding.ViewDataBinding; import com.sunofbeaches.databindingdemo.R; import com.sunofbeaches.databindingdemo.domain.User; import java.lang.Deprecated; import java.lang.Object; public abstract class ActivityMainBinding extends ViewDataBinding { @NonNull public final Guideline guideline; @NonNull public final Guideline guideline2; @NonNull public final Guideline guideline3; @NonNull public final Guideline guideline4; @NonNull public final TextView textView; @NonNull public final TextView textView2; @NonNull public final TextView textView3; @NonNull public final TextView textView4; @NonNull public final TextView textView6; @NonNull public final TextView textView7; @Bindable protected User mUser; protected ActivityMainBinding(Object _bindingComponent, View _root, int _localFieldCount, Guideline guideline, Guideline guideline2, Guideline guideline3, Guideline guideline4, TextView textView, TextView textView2, TextView textView3, TextView textView4, TextView textView6, TextView textView7) { super(_bindingComponent, _root, _localFieldCount); this.guideline = guideline; this.guideline2 = guideline2; this.guideline3 = guideline3; this.guideline4 = guideline4; this.textView = textView; this.textView2 = textView2; this.textView3 = textView3; this.textView4 = textView4; this.textView6 = textView6; this.textView7 = textView7; } public abstract void setUser(@Nullable User user); @Nullable public User getUser() { return mUser; } @NonNull public static ActivityMainBinding inflate(@NonNull LayoutInflater inflater, @Nullable ViewGroup root, boolean attachToRoot) { return inflate(inflater, root, attachToRoot, DataBindingUtil.getDefaultComponent()); } /** * This method receives DataBindingComponent instance as type Object instead of * type DataBindingComponent to avoid causing too many compilation errors if * compilation fails for another reason. * https://issuetracker.google.com/issues/116541301 * @Deprecated Use DataBindingUtil.inflate(inflater, R.layout.activity_main, root, attachToRoot, component) */ @NonNull @Deprecated public static ActivityMainBinding inflate(@NonNull LayoutInflater inflater, @Nullable ViewGroup root, boolean attachToRoot, @Nullable Object component) { return ViewDataBinding.inflateInternal(inflater, R.layout.activity_main, root, attachToRoot, component); } @NonNull public static ActivityMainBinding inflate(@NonNull LayoutInflater inflater) { return inflate(inflater, DataBindingUtil.getDefaultComponent()); } /** * This method receives DataBindingComponent instance as type Object instead of * type DataBindingComponent to avoid causing too many compilation errors if * compilation fails for another reason. * https://issuetracker.google.com/issues/116541301 * @Deprecated Use DataBindingUtil.inflate(inflater, R.layout.activity_main, null, false, component) */ @NonNull @Deprecated public static ActivityMainBinding inflate(@NonNull LayoutInflater inflater, @Nullable Object component) { return ViewDataBinding.inflateInternal(inflater, R.layout.activity_main, null, false, component); } public static ActivityMainBinding bind(@NonNull View view) { return bind(view, DataBindingUtil.getDefaultComponent()); } /** * This method receives DataBindingComponent instance as type Object instead of * type DataBindingComponent to avoid causing too many compilation errors if * compilation fails for another reason. * https://issuetracker.google.com/issues/116541301 * @Deprecated Use DataBindingUtil.bind(view, component) */ @Deprecated public static ActivityMainBinding bind(@NonNull View view, @Nullable Object component) { return (ActivityMainBinding)bind(component, view, R.layout.activity_main); } }
  • 1