android samples,Android Architecture Components samples analyse

1.

此 sample 需求非常简单, 使用 list 展示(持久化)数据库中的数据, 点击每个 item 可以进入到详情页(展示详情信息)

1.1MainActivity.java -- main_activity.xml

作为一个 fragment 的载体, 仅仅包括一个 fragment: 1.2ProductListFragment.java

还有个 public method 展示ProductFragment.java(一会再来看)

1.2ProductListFragment.java -- list_fragment.xml

此界面中有2个 view, 一个是加载完成前的 loading 提示view, 一个是加载完成后的 recyclerView

1.2ProductListFragment 中使用了android.databinding 进行 fragment, xml 和数据的绑定

onCreateView() 中 init:

private ListFragmentBinding mBinding;

mBinding = DataBindingUtil.inflate(inflater, R.layout.list_fragment, container, false);

在 list_fragment.xml 中,

--1.使用 标签,声明 var

--2.使用 app:visibleGone="@{isLoading}" 对 view 进行动态控制

xmlns:app="http://schemas.android.com/apk/res-auto">

name="isLoading"

type="boolean" />

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@color/cardview_light_background"

android:orientation="vertical">

android:id="@+id/loading_tv"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:gravity="center_vertical|center_horizontal"

android:text="@string/loading_products"

android:textAlignment="center"

app:visibleGone="@{isLoading}"

/>

android:id="@+id/products_list"

android:contentDescription="@string/cd_products_list"

android:layout_width="match_parent"

android:layout_height="match_parent"

app:layoutManager="LinearLayoutManager"

app:visibleGone="@{!isLoading}"/>

--3.${visibleGone} 关键字在 BindingAdapters.java 中被自定义, 然后 showHide() 方法对 view 进行动态控制

public class BindingAdapters {

@BindingAdapter("visibleGone")

public static void showHide(View view, boolean show) {

view.setVisibility(show ? View.VISIBLE : View.GONE);

}

}

--4. 而 showHide() 是在ListFragmentBinding.java 中被调用, 是自动生成的

public class ListFragmentBinding extends android.databinding.ViewDataBinding {

...

com.example.android.persistence.ui.BindingAdapters.showHide(this.loadingTv, isLoading);

com.example.android.persistence.ui.BindingAdapters.showHide(this.productsList, IsLoading1);

...

}

--5.适配器 ProductAdapter.java 对数据和 fragment 进行关联

mProductAdapter = new ProductAdapter(mProductClickCallback);

--6.获取数据

在onActivityCreated() 中, 获取数据:

final ProductListViewModel viewModel = ViewModelProviders.of(this).get(ProductListViewModel.class);

// Update the list when the data changes

viewModel.getProducts().observe(this, new Observer>() {

@Override

public void onChanged(@Nullable List myProducts) {

if (myProducts != null) {

mBinding.setIsLoading(false);

mProductAdapter.setProductList(myProducts);

} else {

mBinding.setIsLoading(true);

}

}

});

这段代码使用了新的方式获取数据库中的数据:ViewModelProviders.of(this).get(ProductListViewModel.class);

--7.ProductListViewModel.java

ViewModelProviders为arch 中的方法;

此处我们需要实现如下: 在 apply() 中有 loadAllProducts()的方法, 此方法实现在 Dao 中

public class ProductListViewModel extends AndroidViewModel {

private static final MutableLiveData ABSENT = new MutableLiveData();

{

//noinspection unchecked

ABSENT.setValue(null);

}

private final LiveData> mObservableProducts;

public ProductListViewModel(Application application) {

super(application);

final DatabaseCreator databaseCreator = DatabaseCreator.getInstance(this.getApplication());

LiveData databaseCreated = databaseCreator.isDatabaseCreated();

mObservableProducts = Transformations.switchMap(databaseCreated,

new Function>>() {

@Override

public LiveData> apply(Boolean isDbCreated) {

if (!Boolean.TRUE.equals(isDbCreated)) { // Not needed here, but watch out for null

//noinspection unchecked

return ABSENT;

} else {

//noinspection ConstantConditions

return databaseCreator.getDatabase().productDao().loadAllProducts();

}

}

});

databaseCreator.createDb(this.getApplication());

}

/**

* Expose the LiveData Products query so the UI can observe it.

*/

public LiveData> getProducts() {

return mObservableProducts;

}

}

--8.ProductEntity.java

@Entity 是 新的包 arch.room 中的

此类是Product 的实体类:

@Entity(tableName = "products"): 表名为"products"

@PrimaryKey private int id; : primary key 为 id

@Entity(tableName = "products")

public class ProductEntity implements Product {

@PrimaryKey

private int id;

private String name;

private String description;

private int price;

@Override

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

@Override

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

@Override

public String getDescription() {

return description;

}

public void setDescription(String description) {

this.description = description;

}

@Override

public int getPrice() {

return price;

}

public void setPrice(int price) {

this.price = price;

}

public ProductEntity() {

}

public ProductEntity(Product product) {

this.id = product.getId();

this.name = product.getName();

this.description = product.getDescription();

this.price = product.getPrice();

}

}

--9.ProductDao.java

@Dao 是新的包 arch.room 中的

形如 retrofit2的接口请求, 实现起来的方式和retrofit 很像

@Dao

public interface ProductDao {

@Query("SELECT * FROM products")

LiveData> loadAllProducts();

@Insert(onConflict = OnConflictStrategy.REPLACE)

void insertAll(List products);

@Query("select * from products where id = :productId")

LiveData loadProduct(int productId);

@Query("select * from products where id = :productId")

ProductEntity loadProductSync(int productId);

}

--10.上一张图简单理解下 View ViewModel model 的关系

d9efc9154b09

final-architecture.png

2.advanced sample that uses the Architecture components, Dagger and the Github API. Requires Android Studio 3.0 canary 1

--1.MainActivity.java

implements LifecycleRegistryOwner

@Override

public LifecycleRegistry getLifecycle() {

return lifecycleRegistry;

}

implements HasSupportFragmentInjector

@Override

public DispatchingAndroidInjector supportFragmentInjector() {

return dispatchingAndroidInjector;

}

通过注入NavigationController 控制 fragment

@Inject

NavigationController navigationController;

@Inject

public NavigationController(MainActivity mainActivity) {

this.containerId = R.id.container;

this.fragmentManager = mainActivity.getSupportFragmentManager();

}

public void navigateToSearch() {

SearchFragment searchFragment = new SearchFragment();

fragmentManager.beginTransaction()

.replace(containerId, searchFragment)

.commitAllowingStateLoss();

}

--2.SearchFragment.java

dataBinding

SearchFragmentBinding dataBinding = DataBindingUtil

.inflate(inflater, R.layout.search_fragment, container, false,

dataBindingComponent);

extends LifecycleFragment

功能1:searching function:

private void doSearch(View v) {

//get query key word

String query = binding.get().input.getText().toString();

// Dismiss keyboard

dismissKeyboard(v.getWindowToken());

binding.get().setQuery(query);

searchViewModel.setQuery(query);

}

--3.SearchViewModel.java

extends ViewModel

功能1:refresh()

void refresh() {

if (query.getValue() != null) {

query.setValue(query.getValue());

}

}

功能2:loadNextPage()

void loadNextPage() {

String value = query.getValue();

if (value == null || value.trim().length() == 0) {

return;

}

nextPageHandler.queryNextPage(value);

}

--4.DAO @Dao

RepoDao.java

UserDao.java

--5.Entity @Entity

RepoEntity.java

UserEntity.java

RepoSearchResultEntity.java

ContributorEntity.java

--6.GithubService.java

@GET("users/{login}")

LiveData> getUser(@Path("login") String login);

@GET("users/{login}/repos")

LiveData>> getRepos(@Path("login") String login);

@GET("repos/{owner}/{name}")

LiveData> getRepo(@Path("owner") String owner, @Path("name") String name);

@GET("repos/{owner}/{name}/contributors")

LiveData>> getContributors(@Path("owner") String owner, @Path("name") String name);

@GET("search/repositories")

LiveData> searchRepos(@Query("q") String query);

@GET("search/repositories")

Call searchRepos(@Query("q") String query, @Query("page") int page);

--7.repository

RepoRepository.java

GithubDb db;

//操作数据库

RepoDao repoDao;

//网络操作

GithubService githubService;

AppExecutors appExecutors;

UserRepository.java

//操作数据库

UserDao userDao;

//网络操作

GithubService githubService;

AppExecutors appExecutors;

--8.AppComponent.java

@Singleton

@Component(modules = {

AndroidInjectionModule.class,

AppModule.class,

MainActivityModule.class

})

public interface AppComponent {

@Component.Builder

interface Builder {

@BindsInstance Builder application(Application application);

AppComponent build();

}

void inject(GithubApp githubApp);

}

--9.AppModule.java

@Module(includes = ViewModelModule.class)

@Singleton @Provides

GithubService provideGithubService() {

return new Retrofit.Builder()

.baseUrl("https://api.github.com/")

.addConverterFactory(GsonConverterFactory.create())

.addCallAdapterFactory(new LiveDataCallAdapterFactory())

.build()

.create(GithubService.class);

}

@Singleton @Provides

GithubDb provideDb(Application app) {

return Room.databaseBuilder(app, GithubDb.class,"github.db").build();

}

@Singleton @Provides

UserDao provideUserDao(GithubDb db) {

return db.userDao();

}

@Singleton @Provides

RepoDao provideRepoDao(GithubDb db) {

return db.repoDao();

}

--10.MainActivityModule.java

@ContributesAndroidInjector(modules = FragmentBuildersModule.class)

abstract MainActivity contributeMainActivity();

--11.FragmentBuildersModule.java

@ContributesAndroidInjector

abstract RepoFragment contributeRepoFragment();

@ContributesAndroidInjector

abstract UserFragment contributeUserFragment();

@ContributesAndroidInjector

abstract SearchFragment contributeSearchFragment();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值