以下示例代码搬运自android 开发者官方网站
可观测的数据持有类。它是生命周期感知的,确保 LiveData 只观测并更新处于活动生命周期状态的应用程序组件
LiveData 的子类,包含 postValue(T value) 方法和 setValue(T value) 方法,其中 setValue 在主线程中直接调用赋值, postValue 在子线程中将数据传递到主线程
public class MyViewModel extends ViewModel {
private MutableLiveData> users; //储存并修改数据
public LiveData> getUsers() {
if (users == null) {
users = new MutableLiveData>();
loadUsers();
}
return users;
}
private void loadUsers() {
// Do an asynchronous operation to fetch users.
}
}
public class MyActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
// Create a ViewModel the first time the system calls an activity's onCreate() method.
// Re-created activities receive the same MyViewModel instance created by the first activity.
MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
model.getUsers().observe(this, new Observer () {
@Override
public void onChanged(@Nullable users entity) {
// update UI
}
});
}
}
getUsers() 获取 LiveData 对象,设置 observe ,在 onChanged 中更新UI
用于修改LiveData观察对象的值或类型,包含 map(LiveData source, Function
LiveData userLiveData = ...;
LiveData userName = Transformations.map(userLiveData, user -> {
return user.firstName + " " + user.lastName
});
观察userName这个LiveData对象,从userLiveData数据中提取姓名并传递给它的观察者
MutableLiveData userIdLiveData = ...;
LiveData userLiveData = Transformations.switchMap(userIdLiveData, new Function() {
@Override
public LiveData apply(final LiveData id) {
repository.getUserById(id);
}
});
void setUserId(String userId) {
this.userIdLiveData.setValue(userId);
}
返回观察者的是一个LiveData对象,可以方便的转换对象类型或值并持续观察
包含一个列表的UI类 MyFavoriteFragment 中,实例化 GLRefreshLayout 对象 refreshLayout , 调用 refreshLayout.attachRefresh(this, getRefreshable()); 设置下拉刷新与上拉加载
FeedListBaseFragment 类实现 getRefreshable ,其中维护一个 GLRefreshableLD 类型的 refreshable 如下
protected GLRefreshableLD getRefreshable() {
if (refreshable == null) {
refreshable = buildRefreshable();
}
return refreshable;
}
@NonNull
protected GLRefreshableLD buildRefreshable() {
return new GLRefreshableLD() {
@Override
public LiveData refresh() {
setRefresh(true);
return LiveDataStream.from(dataSourceViewModel.refresh())
.observe(FeedListBaseFragment.this, refreshFeedsObserver)
.getLiveData();
}
@Override
public LiveData loadMore() {
return LiveDataStream.from(dataSourceViewModel.loadMore())
.observe(FeedListBaseFragment.this, loadMoreFeedsObserver)
.getLiveData();
}
};
}
observer
protected Observer>> refreshFeedsObserver = new Observer>>() {
@Override
public void onChanged(@Nullable GLResult> listGLResult) {
onHandleResult(listGLResult, true);
handleResult(listGLResult, true);
if (listGLResult.getResult().isSuccess()) {
List refreshData = hookFeedUnActive(listGLResult.getSpecific());
showUpdateTip(refreshData, feedAdapter.getLastData());
feedAdapter.replaceAll(dataSourceViewModel.hookIFeedData(refreshData), autoLoadMore.isTouchEnd(), getEmptyTips());
}
}
};
protected Observer>> loadMoreFeedsObserver = new Observer>>() {
@Override
public void onChanged(@Nullable GLResult> listGLResult) {
onHandleResult(listGLResult, false);
handleResult(listGLResult, true);
if (listGLResult.getResult().isSuccess()) {
feedAdapter.replaceAll(hookFeedUnActive(dataSourceViewModel.getDataSource().getList()), autoLoadMore.isTouchEnd(), getEmptyTips());
}
}
};
// onHandleResult 没实现= =
handleResult 在UI层处理返回结果,设置toast
// showUpdateTip 没实现,显示更新数据数量(?)
Adapter.replaceAll 全局更新列表数据
View层的类 MyFavoriteFragment 类继承自 FeedListBaseFragment ,在后者中设置
private FeedViewModel viewModel;
public MyFavoriteViewModel dataSourceViewModel;
……
dataSourceViewModel = getViewModel(MyFavoriteViewModel.class);
viewModel = getViewModel(FeedViewModel.class);
viewModel.attachDataSource(dataSourceViewModel.getDataSource());
EventbusUtil.register(this);
刷新时调用
dataSourceViewModel.refreshRepo(); //拿数据
viewModel.refreshRepo(); //拿数据
refreshable.refresh(); // 更新UI
FeedRepo 类拉取本地数据库中用户相关数据,提供网络请求动态等信息的api参数
用户动态数据获取:从网络直接请求固定数量动态
调用 GLProtoExecutor.execute 发起网络请求( okhttp 3封装的 GLClient 类, http 请求, json 数据)
回调 onPostExecute 监听请求结果,执行保存到本地数据库之类的操作
observe 监听
回调 onChanged 更新数据
By mingfeng
执行的操作就是
用户点击 -> View 调用自己的 ViewModel -> 执行 Viewmodel 中的业务逻辑 -> 调用 Model 的数据操作方法,并且以监听的形式交给 LiveData -> LiveData 以回调方式执行 ViewModel 的逻辑, ViewModel 控制 View 刷新
By mingfeng
以下内容搬运自官方文档
@BindView(R.id.feed_list) VideoList feedList;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_activity);
ButterKnife.bind(this);
// TODO Use fields...
}
这种绑定方式可应用于多个需要使用 findViewById 的地方,比如在 adapter 的内部类中使用
static class ViewHolder {
@BindView(R.id.title)
TextView name;
@BindView(R.id.job_title) TextView jobTitle;
public ViewHolder(View view) {
ButterKnife.bind(this, view);
}
}
@BindViews({ R.id.first_name, R.id.middle_name, R.id.last_name })
List nameViews;
apply 函数一次在列表中所有 view 上执行相同的动作
ButterKnife.apply(nameViews, DISABLE);
ButterKnife.apply(nameViews, ENABLED, false);
或设置property属性:ButterKnife.apply(nameViews, View.ALPHA, 0.0f);
Action/Setter 接口一次在列表中所有 view 上指定相同的动作或设置,其中 Setter 可以传入设置参数的值
static final ButterKnife.Action DISABLE = new ButterKnife.Action() {
@Override public void apply(View view, int index) {
view.setEnabled(false);
}
};
static final ButterKnife.Setter ENABLED = new ButterKnife.Setter() {
@Override public void set(View view, Boolean value, int index) {
view.setEnabled(value);
}
};
@OnClick(R.id.submit)
public void submit(VIEW) {
// TODO
}
上面代码中的VIEW 可以是 view 或置空或特定的类型,如 button
同样的,支持同时为多个 view 绑定相同行为的监视器
自定义 view 中的监视器不需要指定 id
public class FancyButton extends Button {
@OnClick
public void onClick() {
// TODO do something!
}
}
public class FancyFragment extends Fragment {
private Unbinder unbinder;
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fancy_fragment, container, false);
unbinder = ButterKnife.bind(this, view);
// TODO Use fields...
return view;
}
@Override public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
}
注解库中 @Nullable 用于注解可能为空的变量、参数或返回值
反之, @NonNull 用于注解不可为空的变量、参数或返回值