提交 313f8c8c 编写于 作者: M mxdl

init commit

上级
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with NO BOM" />
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<compositeConfiguration>
<compositeBuild compositeDefinitionSource="SCRIPT" />
</compositeConfiguration>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>
\ No newline at end of file
<component name="MarkdownNavigator.ProfileManager">
<settings default="" pdf-export="" plain-text-search-scope="Project Files" />
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CMakeSettings">
<configurations>
<configuration PROFILE_NAME="Debug" CONFIG_NAME="Debug" />
</configurations>
</component>
<component name="MarkdownProjectSettings" wasCopied="true">
<PreviewSettings splitEditorLayout="SPLIT" splitEditorPreview="PREVIEW" useGrayscaleRendering="false" zoomFactor="1.0" maxImageWidth="0" showGitHubPageIfSynced="false" allowBrowsingInPreview="false" synchronizePreviewPosition="true" highlightPreviewType="NONE" highlightFadeOut="5" highlightOnTyping="true" synchronizeSourcePosition="true" verticallyAlignSourceAndPreviewSyncPosition="true" showSearchHighlightsInPreview="false" showSelectionInPreview="true" openRemoteLinks="true" replaceUnicodeEmoji="false" lastLayoutSetsDefault="false">
<PanelProvider>
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.panel" providerName="Default - Swing" />
</PanelProvider>
</PreviewSettings>
<ParserSettings gitHubSyntaxChange="false" emojiShortcuts="1" emojiImages="0">
<PegdownExtensions>
<option name="ABBREVIATIONS" value="false" />
<option name="ANCHORLINKS" value="true" />
<option name="ASIDE" value="false" />
<option name="ATXHEADERSPACE" value="true" />
<option name="AUTOLINKS" value="true" />
<option name="DEFINITIONS" value="false" />
<option name="DEFINITION_BREAK_DOUBLE_BLANK_LINE" value="false" />
<option name="FENCED_CODE_BLOCKS" value="true" />
<option name="FOOTNOTES" value="false" />
<option name="HARDWRAPS" value="false" />
<option name="HTML_DEEP_PARSER" value="false" />
<option name="INSERTED" value="false" />
<option name="QUOTES" value="false" />
<option name="RELAXEDHRULES" value="true" />
<option name="SMARTS" value="false" />
<option name="STRIKETHROUGH" value="true" />
<option name="SUBSCRIPT" value="false" />
<option name="SUPERSCRIPT" value="false" />
<option name="SUPPRESS_HTML_BLOCKS" value="false" />
<option name="SUPPRESS_INLINE_HTML" value="false" />
<option name="TABLES" value="true" />
<option name="TASKLISTITEMS" value="true" />
<option name="TOC" value="false" />
<option name="WIKILINKS" value="false" />
</PegdownExtensions>
<ParserOptions>
<option name="ADMONITION_EXT" value="false" />
<option name="ATTRIBUTES_EXT" value="false" />
<option name="COMMONMARK_LISTS" value="true" />
<option name="DUMMY" value="false" />
<option name="EMOJI_SHORTCUTS" value="true" />
<option name="ENUMERATED_REFERENCES_EXT" value="false" />
<option name="FLEXMARK_FRONT_MATTER" value="false" />
<option name="GFM_LOOSE_BLANK_LINE_AFTER_ITEM_PARA" value="false" />
<option name="GFM_TABLE_RENDERING" value="true" />
<option name="GITBOOK_URL_ENCODING" value="false" />
<option name="GITHUB_LISTS" value="false" />
<option name="GITHUB_WIKI_LINKS" value="false" />
<option name="GITLAB_EXT" value="false" />
<option name="GITLAB_MATH_EXT" value="false" />
<option name="GITLAB_MERMAID_EXT" value="false" />
<option name="HEADER_ID_NON_ASCII_TO_LOWERCASE" value="false" />
<option name="HEADER_ID_NO_DUPED_DASHES" value="false" />
<option name="JEKYLL_FRONT_MATTER" value="false" />
<option name="MACROS_EXT" value="false" />
<option name="NO_TEXT_ATTRIBUTES" value="false" />
<option name="PARSE_HTML_ANCHOR_ID" value="false" />
<option name="PLANTUML_FENCED_CODE" value="false" />
<option name="PUML_FENCED_CODE" value="false" />
<option name="SIM_TOC_BLANK_LINE_SPACER" value="true" />
</ParserOptions>
</ParserSettings>
<HtmlSettings headerTopEnabled="false" headerBottomEnabled="false" bodyTopEnabled="false" bodyBottomEnabled="false" embedUrlContent="false" addPageHeader="true" embedImages="false" embedHttpImages="false" imageUriSerials="false" addDocTypeHtml="true" noParaTags="false" plantUmlConversion="0" mathConversion="-1">
<GeneratorProvider>
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.generator" providerName="Default Swing HTML Generator" />
</GeneratorProvider>
<headerTop />
<headerBottom />
<bodyTop />
<bodyBottom />
</HtmlSettings>
<CssSettings previewScheme="UI_SCHEME" cssUri="" isCssUriEnabled="false" isCssUriSerial="true" isCssTextEnabled="false" isDynamicPageWidth="true">
<StylesheetProvider>
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.css" providerName="Default Swing Stylesheet" />
</StylesheetProvider>
<ScriptProviders />
<cssText />
<cssUriHistory />
</CssSettings>
<AnnotatorSettings targetHasSpaces="true" linkCaseMismatch="true" wikiCaseMismatch="true" wikiLinkHasDashes="true" notUnderWikiHome="true" targetNotWikiPageExt="true" notUnderSourceWikiHome="true" targetNameHasAnchor="true" targetPathHasAnchor="true" wikiLinkHasSlash="true" wikiLinkHasSubdir="true" wikiLinkHasOnlyAnchor="true" linkTargetsWikiHasExt="true" linkTargetsWikiHasBadExt="true" notUnderSameRepo="true" targetNotUnderVcs="false" linkNeedsExt="true" linkHasBadExt="true" linkTargetNeedsExt="true" linkTargetHasBadExt="true" wikiLinkNotInWiki="true" imageTargetNotInRaw="true" repoRelativeAcrossVcsRoots="true" multipleWikiTargetsMatch="true" unresolvedLinkReference="true" linkIsIgnored="true" anchorIsIgnored="true" anchorIsUnresolved="true" anchorLineReferenceIsUnresolved="true" anchorLineReferenceFormat="true" anchorHasDuplicates="true" abbreviationDuplicates="true" abbreviationNotUsed="true" attributeIdDuplicateDefinition="true" attributeIdNotUsed="true" footnoteDuplicateDefinition="true" footnoteUnresolved="true" footnoteDuplicates="true" footnoteNotUsed="true" macroDuplicateDefinition="true" macroUnresolved="true" macroDuplicates="true" macroNotUsed="true" referenceDuplicateDefinition="true" referenceUnresolved="true" referenceDuplicates="true" referenceNotUsed="true" referenceUnresolvedNumericId="true" enumRefDuplicateDefinition="true" enumRefUnresolved="true" enumRefDuplicates="true" enumRefNotUsed="true" enumRefLinkUnresolved="true" enumRefLinkDuplicates="true" simTocUpdateNeeded="true" simTocTitleSpaceNeeded="true" />
<HtmlExportSettings updateOnSave="false" parentDir="" targetDir="" cssDir="css" scriptDir="js" plainHtml="false" imageDir="" copyLinkedImages="false" imageUniquifyType="0" targetPathType="2" targetExt="" useTargetExt="false" noCssNoScripts="false" useElementStyleAttribute="false" linkToExportedHtml="true" exportOnSettingsChange="true" regenerateOnProjectOpen="false" linkFormatType="HTTP_ABSOLUTE" />
<LinkMapSettings>
<textMaps />
</LinkMapSettings>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.mxdl.mvvm"
minSdkVersion 16
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
dataBinding {
enabled true
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation project(":implementation")
implementation "android.arch.lifecycle:runtime:$rootProject.lifecycleRuntime"
implementation "android.arch.lifecycle:extensions:$rootProject.lifecycle"
annotationProcessor "android.arch.lifecycle:compiler:$rootProject.lifecycle"
// LiveData adapter rxjava2
implementation "android.arch.lifecycle:reactivestreams:$rootProject.lifecycle"
// room
implementation "android.arch.persistence.room:runtime:$rootProject.room"
annotationProcessor "android.arch.persistence.room:compiler:$rootProject.room"
// retrofit
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
// RxJava2
implementation 'io.reactivex.rxjava2:rxjava:2.1.5'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
// retrofit-adapter
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
// dagger
annotationProcessor "com.google.dagger:dagger-compiler:$rootProject.dagger"
implementation "com.google.dagger:dagger-android:$rootProject.dagger"
implementation "com.google.dagger:dagger-android-support:$rootProject.dagger" // if you use the support libraries
annotationProcessor "com.google.dagger:dagger-android-processor:$rootProject.dagger"
implementation 'com.android.support:recyclerview-v7:28.0.0'
}
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
package com.mxdl.mvvm;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.mxdl.mvvm", appContext.getPackageName());
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.mxdl.mvvm">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".livedata.LoginActivity">
</activity>
<activity android:name=".lifecycle.LifecycleTestActivity">
</activity>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name=".lifecycle.LifecycleTestActivity"
tools:ignore="DuplicateActivity"/>
<activity android:name=".application.ApplicationActivity" />
<activity android:name=".application.a_hello.UserActivity" />
<activity android:name=".application.b_repository.features.user.UserActivity" />
<activity android:name=".application.c_cache.features.user.UserActivity" />
<activity android:name=".application.d_state_lcee.features.user.UserActivity" />
<activity android:name=".application.e_simple_data_source.features.user.UserActivity" />
<activity android:name=".application.f_load_more.features.projects.ProjectsActivity" />
<activity android:name=".application.g_data_binding.features.user.UserActivity" />
<activity android:name=".application.h_rxjava2.features.user.UserActivity" />
<activity android:name=".application.i_dagger2.features.user.UserActivity"/>
<activity android:name=".implementation.ImplementationActivity"/>
<activity android:name=".implementation.a_my_livedata.MyLiveDataActivity"/>
</application>
</manifest>
\ No newline at end of file
package com.mxdl.mvvm;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import com.mxdl.mvvm.application.i_dagger2.common.dagger.component.DaggerBaseApplicationComponent;
import javax.inject.Inject;
import dagger.android.AndroidInjector;
import dagger.android.DispatchingAndroidInjector;
import dagger.android.HasActivityInjector;
/**
* Created by mxdl on 2017/11/6.
*/
public class BaseApplication extends Application implements HasActivityInjector {
@Inject
DispatchingAndroidInjector<Activity> dispatchingActivityInjector;
private static Context appContext;
public static Context getAppContext() {
return appContext;
}
@Override
public void onCreate() {
super.onCreate();
appContext = getApplicationContext();
DaggerBaseApplicationComponent.create().inject(this);
}
@Override
public AndroidInjector<Activity> activityInjector() {
return dispatchingActivityInjector;
}
}
package com.mxdl.mvvm;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import com.mxdl.mvvm.implementation.ImplementationActivity;
import com.mxdl.mvvm.application.ApplicationActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_application: {
startActivity(new Intent(this, ApplicationActivity.class));
break;
}
case R.id.btn_implementation: {
startActivity(new Intent(this, ImplementationActivity.class));
break;
}
}
}
}
package com.mxdl.mvvm.application;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import com.mxdl.mvvm.R;
/**
* Created by mxdl on 2017/10/23.
*/
public class ApplicationActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_application);
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_a: {
startActivity(new Intent(this, com.mxdl.mvvm.application.a_hello.UserActivity.class));
break;
}
case R.id.btn_b: {
startActivity(new Intent(this, com.mxdl.mvvm.application.b_repository.features.user.UserActivity.class));
break;
}
case R.id.btn_c: {
startActivity(new Intent(this, com.mxdl.mvvm.application.c_cache.features.user.UserActivity.class));
break;
}
case R.id.btn_d: {
startActivity(new Intent(this, com.mxdl.mvvm.application.d_state_lcee.features.user.UserActivity.class));
break;
}
case R.id.btn_e: {
startActivity(new Intent(this, com.mxdl.mvvm.application.e_simple_data_source.features.user.UserActivity.class));
break;
}
case R.id.btn_f: {
startActivity(new Intent(this, com.mxdl.mvvm.application.f_load_more.features.projects.ProjectsActivity.class));
break;
}
case R.id.btn_g: {
startActivity(new Intent(this, com.mxdl.mvvm.application.g_data_binding.features.user.UserActivity.class));
break;
}
case R.id.btn_h: {
startActivity(new Intent(this, com.mxdl.mvvm.application.h_rxjava2.features.user.UserActivity.class));
break;
}
case R.id.btn_i: {
startActivity(new Intent(this, com.mxdl.mvvm.application.i_dagger2.features.user.UserActivity.class));
break;
}
}
}
}
package com.mxdl.mvvm.application.a_hello;
import java.io.Serializable;
/**
* Created by mxdl on 2017/10/4.
*/
public class User implements Serializable {
private int id;
private String name;
public User() {
}
public User(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
package com.mxdl.mvvm.application.a_hello;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;
import com.mxdl.mvvm.R;
/**
* Created by mxdl on 2017/10/4.
*/
public class UserActivity extends AppCompatActivity {
private UserViewModel userViewModel;
private TextView tvId;
private TextView tvName;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.a_activity_user);
initView();
initData();
}
private void initView() {
tvId = (TextView) findViewById(R.id.tv_id);
tvName = (TextView) findViewById(R.id.tv_name);
}
private void initData() {
userViewModel = ViewModelProviders.of(this).get(UserViewModel.class);
userViewModel.getUser().observe(this, new Observer<User>() {
@Override
public void onChanged(@Nullable User user) {
Log.v("MYTAG","user:"+user.toString());
updateView(user);
}
});
userViewModel.setUsername("ittianyu");
}
private void updateView(User user) {
tvId.setText(user.getId() + "");
tvName.setText(user.getName());
}
}
package com.mxdl.mvvm.application.a_hello;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import android.arch.lifecycle.ViewModel;
/**
* Created by mxdl on 2017/10/4.
*/
public class UserViewModel extends ViewModel {
private MutableLiveData<User> user;
public LiveData<User> getUser() {
if (user == null)
user = new MutableLiveData<>();
return user;
}
public void setUsername(String username) {
user.setValue(new User(1, username));
}
}
package com.mxdl.mvvm.application.b_repository.common.bean;
import java.io.Serializable;
/**
* Created by mxdl on 2017/10/4.
*/
public class User implements Serializable {
/**
* login : ittianyu
* id : 16226068
* avatar_url : https://avatars0.githubusercontent.com/u/16226068?v=4
* gravatar_id :
* url : https://api.github.com/users/ittianyu
* html_url : https://github.com/ittianyu
* followers_url : https://api.github.com/users/ittianyu/followers
* following_url : https://api.github.com/users/ittianyu/following{/other_user}
* gists_url : https://api.github.com/users/ittianyu/gists{/gist_id}
* starred_url : https://api.github.com/users/ittianyu/starred{/owner}{/repo}
* subscriptions_url : https://api.github.com/users/ittianyu/subscriptions
* organizations_url : https://api.github.com/users/ittianyu/orgs
* repos_url : https://api.github.com/users/ittianyu/repos
* events_url : https://api.github.com/users/ittianyu/events{/privacy}
* received_events_url : https://api.github.com/users/ittianyu/received_events
* type : User
* site_admin : false
* name : ittianyu
* company : null
* blog : www.ittianyu.com
* location : null
* email : null
* hireable : true
* bio : null
* public_repos : 4
* public_gists : 0
* followers : 56
* following : 2
* created_at : 2015-12-09T14:37:30Z
* updated_at : 2017-09-14T10:08:07Z
*/
private String login;
private int id;
private String avatar_url;
private String gravatar_id;
private String url;
private String html_url;
private String followers_url;
private String following_url;
private String gists_url;
private String starred_url;
private String subscriptions_url;
private String organizations_url;
private String repos_url;
private String events_url;
private String received_events_url;
private String type;
private boolean site_admin;
private String name;
private Object company;
private String blog;
private Object location;
private Object email;
private boolean hireable;
private Object bio;
private int public_repos;
private int public_gists;
private int followers;
private int following;
private String created_at;
private String updated_at;
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAvatar_url() {
return avatar_url;
}
public void setAvatar_url(String avatar_url) {
this.avatar_url = avatar_url;
}
public String getGravatar_id() {
return gravatar_id;
}
public void setGravatar_id(String gravatar_id) {
this.gravatar_id = gravatar_id;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getHtml_url() {
return html_url;
}
public void setHtml_url(String html_url) {
this.html_url = html_url;
}
public String getFollowers_url() {
return followers_url;
}
public void setFollowers_url(String followers_url) {
this.followers_url = followers_url;
}
public String getFollowing_url() {
return following_url;
}
public void setFollowing_url(String following_url) {
this.following_url = following_url;
}
public String getGists_url() {
return gists_url;
}
public void setGists_url(String gists_url) {
this.gists_url = gists_url;
}
public String getStarred_url() {
return starred_url;
}
public void setStarred_url(String starred_url) {
this.starred_url = starred_url;
}
public String getSubscriptions_url() {
return subscriptions_url;
}
public void setSubscriptions_url(String subscriptions_url) {
this.subscriptions_url = subscriptions_url;
}
public String getOrganizations_url() {
return organizations_url;
}
public void setOrganizations_url(String organizations_url) {
this.organizations_url = organizations_url;
}
public String getRepos_url() {
return repos_url;
}
public void setRepos_url(String repos_url) {
this.repos_url = repos_url;
}
public String getEvents_url() {
return events_url;
}
public void setEvents_url(String events_url) {
this.events_url = events_url;
}
public String getReceived_events_url() {
return received_events_url;
}
public void setReceived_events_url(String received_events_url) {
this.received_events_url = received_events_url;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public boolean isSite_admin() {
return site_admin;
}
public void setSite_admin(boolean site_admin) {
this.site_admin = site_admin;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object getCompany() {
return company;
}
public void setCompany(Object company) {
this.company = company;
}
public String getBlog() {
return blog;
}
public void setBlog(String blog) {
this.blog = blog;
}
public Object getLocation() {
return location;
}
public void setLocation(Object location) {
this.location = location;
}
public Object getEmail() {
return email;
}
public void setEmail(Object email) {
this.email = email;
}
public boolean isHireable() {
return hireable;
}
public void setHireable(boolean hireable) {
this.hireable = hireable;
}
public Object getBio() {
return bio;
}
public void setBio(Object bio) {
this.bio = bio;
}
public int getPublic_repos() {
return public_repos;
}
public void setPublic_repos(int public_repos) {
this.public_repos = public_repos;
}
public int getPublic_gists() {
return public_gists;
}
public void setPublic_gists(int public_gists) {
this.public_gists = public_gists;
}
public int getFollowers() {
return followers;
}
public void setFollowers(int followers) {
this.followers = followers;
}
public int getFollowing() {
return following;
}
public void setFollowing(int following) {
this.following = following;
}
public String getCreated_at() {
return created_at;
}
public void setCreated_at(String created_at) {
this.created_at = created_at;
}
public String getUpdated_at() {
return updated_at;
}
public void setUpdated_at(String updated_at) {
this.updated_at = updated_at;
}
@Override
public String toString() {
return "User{" +
"login='" + login + '\'' +
", id=" + id +
", avatar_url='" + avatar_url + '\'' +
", gravatar_id='" + gravatar_id + '\'' +
", url='" + url + '\'' +
", html_url='" + html_url + '\'' +
", followers_url='" + followers_url + '\'' +
", following_url='" + following_url + '\'' +
", gists_url='" + gists_url + '\'' +
", starred_url='" + starred_url + '\'' +
", subscriptions_url='" + subscriptions_url + '\'' +
", organizations_url='" + organizations_url + '\'' +
", repos_url='" + repos_url + '\'' +
", events_url='" + events_url + '\'' +
", received_events_url='" + received_events_url + '\'' +
", type='" + type + '\'' +
", site_admin=" + site_admin +
", name='" + name + '\'' +
", company=" + company +
", blog='" + blog + '\'' +
", location=" + location +
", email=" + email +
", hireable=" + hireable +
", bio=" + bio +
", public_repos=" + public_repos +
", public_gists=" + public_gists +
", followers=" + followers +
", following=" + following +
", created_at='" + created_at + '\'' +
", updated_at='" + updated_at + '\'' +
'}';
}
}
package com.mxdl.mvvm.application.b_repository.common.repository;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* Created by yu on 2017/2/21.
*/
public class RetrofitFactory {
private static OkHttpClient client;
private static Retrofit retrofit;
private static final String HOST = "https://api.github.com";
static {
client = new OkHttpClient.Builder()
.connectTimeout(9, TimeUnit.SECONDS)
.build();
retrofit = new Retrofit.Builder()
.baseUrl(HOST)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
public static Retrofit getInstance() {
return retrofit;
}
}
package com.mxdl.mvvm.application.b_repository.common.repository;
import com.mxdl.mvvm.application.b_repository.common.bean.User;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Path;
/**
* Created by mxdl on 2017/10/6.
*/
public interface UserApi {
@GET("/users/{username}")
Call<User> queryUserByUsername(@Path("username") String username);
}
package com.mxdl.mvvm.application.b_repository.common.repository;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import com.mxdl.mvvm.application.b_repository.common.bean.User;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Created by mxdl on 2017/10/6.
*/
public class UserRepository {
private static final UserRepository instance = new UserRepository();
private UserRepository() {
}
public static UserRepository getInstance() {
return instance;
}
private UserApi userApi = RetrofitFactory.getInstance().create(UserApi.class);
public LiveData<User> getUser(String username) {
final MutableLiveData<User> user = new MutableLiveData<>();
userApi.queryUserByUsername(username)
.enqueue(new Callback<User>() {
@Override
public void onResponse(Call<User> call, Response<User> response) {
user.setValue(response.body());
}
@Override
public void onFailure(Call<User> call, Throwable t) {
t.printStackTrace();
}
});
return user;
}
}
package com.mxdl.mvvm.application.b_repository.features.user;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;
import com.mxdl.mvvm.R;
import com.mxdl.mvvm.application.b_repository.common.bean.User;
/**
* Created by mxdl on 2017/10/4.
*/
public class UserActivity extends AppCompatActivity {
private static final String TAG = UserActivity.class.getName();
private UserViewModel userViewModel;
private TextView tvId;
private TextView tvName;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.b_activity_user);
initView();
initData();
}
private void initView() {
tvId = (TextView) findViewById(R.id.tv_id);
tvName = (TextView) findViewById(R.id.tv_name);
}
private void initData() {
userViewModel = ViewModelProviders.of(this).get(UserViewModel.class);
userViewModel.getUser("ittianyu").observe(this, new Observer<User>() {
@Override
public void onChanged(@Nullable User user) {
updateView(user);
}
});
}
private void updateView(User user) {
Log.d(TAG, user.toString());
tvId.setText(user.getId() + "");
tvName.setText(user.getName());
}
}
package com.mxdl.mvvm.application.b_repository.features.user;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.ViewModel;
import com.mxdl.mvvm.application.b_repository.common.bean.User;
import com.mxdl.mvvm.application.b_repository.common.repository.UserRepository;
/**
* Created by mxdl on 2017/10/4.
*/
public class UserViewModel extends ViewModel {
private UserRepository userRepository = UserRepository.getInstance();
private LiveData<User> user;
public LiveData<User> getUser(String username) {
if (null == user)
user = userRepository.getUser(username);
return user;
}
}
package com.mxdl.mvvm.application.c_cache.common.bean;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.PrimaryKey;
import java.io.Serializable;
/**
* Created by mxdl on 2017/10/4.
*/
@Entity(tableName = "user")
public class User implements Serializable {
/**
* login : ittianyu
* id : 16226068
* avatar_url : https://avatars0.githubusercontent.com/u/16226068?v=4
* gravatar_id :
* url : https://api.github.com/users/ittianyu
* html_url : https://github.com/ittianyu
* followers_url : https://api.github.com/users/ittianyu/followers
* following_url : https://api.github.com/users/ittianyu/following{/other_user}
* gists_url : https://api.github.com/users/ittianyu/gists{/gist_id}
* starred_url : https://api.github.com/users/ittianyu/starred{/owner}{/repo}
* subscriptions_url : https://api.github.com/users/ittianyu/subscriptions
* organizations_url : https://api.github.com/users/ittianyu/orgs
* repos_url : https://api.github.com/users/ittianyu/repos
* events_url : https://api.github.com/users/ittianyu/events{/privacy}
* received_events_url : https://api.github.com/users/ittianyu/received_events
* type : User
* site_admin : false
* name : ittianyu
* company : null
* blog : www.ittianyu.com
* location : null
* email : null
* hireable : true
* bio : null
* public_repos : 4
* public_gists : 0
* followers : 56
* following : 2
* created_at : 2015-12-09T14:37:30Z
* updated_at : 2017-09-14T10:08:07Z
*/
@PrimaryKey
private int id;
private String login;
private String avatar_url;
private String gravatar_id;
private String url;
private String html_url;
private String followers_url;
private String following_url;
private String gists_url;
private String starred_url;
private String subscriptions_url;
private String organizations_url;
private String repos_url;
private String events_url;
private String received_events_url;
private String type;
private boolean site_admin;
private String name;
private String company;
private String blog;
private String location;
private String email;
private boolean hireable;
private String bio;
private int public_repos;
private int public_gists;
private int followers;
private int following;
private String created_at;
private String updated_at;
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAvatar_url() {
return avatar_url;
}
public void setAvatar_url(String avatar_url) {
this.avatar_url = avatar_url;
}
public String getGravatar_id() {
return gravatar_id;
}
public void setGravatar_id(String gravatar_id) {
this.gravatar_id = gravatar_id;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getHtml_url() {
return html_url;
}
public void setHtml_url(String html_url) {
this.html_url = html_url;
}
public String getFollowers_url() {
return followers_url;
}
public void setFollowers_url(String followers_url) {
this.followers_url = followers_url;
}
public String getFollowing_url() {
return following_url;
}
public void setFollowing_url(String following_url) {
this.following_url = following_url;
}
public String getGists_url() {
return gists_url;
}
public void setGists_url(String gists_url) {
this.gists_url = gists_url;
}
public String getStarred_url() {
return starred_url;
}
public void setStarred_url(String starred_url) {
this.starred_url = starred_url;
}
public String getSubscriptions_url() {
return subscriptions_url;
}
public void setSubscriptions_url(String subscriptions_url) {
this.subscriptions_url = subscriptions_url;
}
public String getOrganizations_url() {
return organizations_url;
}
public void setOrganizations_url(String organizations_url) {
this.organizations_url = organizations_url;
}
public String getRepos_url() {
return repos_url;
}
public void setRepos_url(String repos_url) {
this.repos_url = repos_url;
}
public String getEvents_url() {
return events_url;
}
public void setEvents_url(String events_url) {
this.events_url = events_url;
}
public String getReceived_events_url() {
return received_events_url;
}
public void setReceived_events_url(String received_events_url) {
this.received_events_url = received_events_url;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public boolean isSite_admin() {
return site_admin;
}
public void setSite_admin(boolean site_admin) {
this.site_admin = site_admin;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public String getBlog() {
return blog;
}
public void setBlog(String blog) {
this.blog = blog;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public boolean isHireable() {
return hireable;
}
public void setHireable(boolean hireable) {
this.hireable = hireable;
}
public String getBio() {
return bio;
}
public void setBio(String bio) {
this.bio = bio;
}
public int getPublic_repos() {
return public_repos;
}
public void setPublic_repos(int public_repos) {
this.public_repos = public_repos;
}
public int getPublic_gists() {
return public_gists;
}
public void setPublic_gists(int public_gists) {
this.public_gists = public_gists;
}
public int getFollowers() {
return followers;
}
public void setFollowers(int followers) {
this.followers = followers;
}
public int getFollowing() {
return following;
}
public void setFollowing(int following) {
this.following = following;
}
public String getCreated_at() {
return created_at;
}
public void setCreated_at(String created_at) {
this.created_at = created_at;
}
public String getUpdated_at() {
return updated_at;
}
public void setUpdated_at(String updated_at) {
this.updated_at = updated_at;
}
@Override
public String toString() {
return "User{" +
"login='" + login + '\'' +
", id=" + id +
", avatar_url='" + avatar_url + '\'' +
", gravatar_id='" + gravatar_id + '\'' +
", url='" + url + '\'' +
", html_url='" + html_url + '\'' +
", followers_url='" + followers_url + '\'' +
", following_url='" + following_url + '\'' +
", gists_url='" + gists_url + '\'' +
", starred_url='" + starred_url + '\'' +
", subscriptions_url='" + subscriptions_url + '\'' +
", organizations_url='" + organizations_url + '\'' +
", repos_url='" + repos_url + '\'' +
", events_url='" + events_url + '\'' +
", received_events_url='" + received_events_url + '\'' +
", type='" + type + '\'' +
", site_admin=" + site_admin +
", name='" + name + '\'' +
", company=" + company +
", blog='" + blog + '\'' +
", location=" + location +
", email=" + email +
", hireable=" + hireable +
", bio=" + bio +
", public_repos=" + public_repos +
", public_gists=" + public_gists +
", followers=" + followers +
", following=" + following +
", created_at='" + created_at + '\'' +
", updated_at='" + updated_at + '\'' +
'}';
}
}
package com.mxdl.mvvm.application.c_cache.common.repository;
import android.arch.lifecycle.LiveData;
import com.mxdl.mvvm.application.c_cache.common.bean.User;
/**
* Created by mxdl on 2017/10/6.
*/
public interface UserDataSource {
LiveData<User> queryUserByUsername(String username);
}
package com.mxdl.mvvm.application.c_cache.common.repository;
import android.arch.lifecycle.LiveData;
import android.content.Context;
import com.mxdl.mvvm.application.c_cache.common.bean.User;
import com.mxdl.mvvm.application.c_cache.common.repository.local.LocalUserDataSource;
import com.mxdl.mvvm.application.c_cache.common.repository.remote.RemoteUserDataSource;
import com.mxdl.mvvm.application.c_cache.common.utils.NetworkUtils;
/**
* Created by mxdl on 2017/10/6.
*/
public class UserRepository {
private static final UserRepository instance = new UserRepository();
private UserRepository() {
}
public static UserRepository getInstance() {
return instance;
}
private Context context;
private UserDataSource remoteUserDataSource = RemoteUserDataSource.getInstance();
private UserDataSource localUserDataSource = LocalUserDataSource.getInstance();
public void init(Context context) {
this.context = context.getApplicationContext();
}
public LiveData<User> getUser(String username) {
if (NetworkUtils.isConnected(context)) {
return remoteUserDataSource.queryUserByUsername(username);
} else {
return localUserDataSource.queryUserByUsername(username);
}
}
}
package com.mxdl.mvvm.application.c_cache.common.repository.local;
import android.arch.lifecycle.LiveData;
import com.mxdl.mvvm.application.c_cache.common.bean.User;
import com.mxdl.mvvm.application.c_cache.common.repository.UserDataSource;
import com.mxdl.mvvm.application.c_cache.common.repository.local.service.UserService;
import com.mxdl.mvvm.application.c_cache.common.repository.local.service.UserServiceImpl;
/**
* Created by mxdl on 2017/10/6.
*/
public class LocalUserDataSource implements UserDataSource {
private static final LocalUserDataSource instance = new LocalUserDataSource();
private LocalUserDataSource() {
}
public static LocalUserDataSource getInstance() {
return instance;
}
private UserService userService = UserServiceImpl.getInstance();
@Override
public LiveData<User> queryUserByUsername(String username) {
return userService.queryByUsername(username);
}
public LiveData<Long> addUser(User user) {
return userService.add(user);
}
}
package com.mxdl.mvvm.application.c_cache.common.repository.local.dao;
import android.arch.lifecycle.LiveData;
import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.OnConflictStrategy;
import android.arch.persistence.room.Query;
import com.mxdl.mvvm.application.c_cache.common.bean.User;
/**
* Created by mxdl on 2017/10/7.
*/
@Dao
public interface UserDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)// cache need update
Long add(User user);
@Query("select * from user where login = :username")
LiveData<User> queryByUsername(String username);
}
package com.mxdl.mvvm.application.c_cache.common.repository.local.db;
import android.arch.persistence.room.Database;
import android.arch.persistence.room.RoomDatabase;
import com.mxdl.mvvm.application.c_cache.common.bean.User;
import com.mxdl.mvvm.application.c_cache.common.repository.local.dao.UserDao;
/**
* Created by mxdl on 2017/10/7.
*/
@Database(entities = {User.class}, version = 1, exportSchema = false)
public abstract class DB extends RoomDatabase {
public abstract UserDao getUserDao();
}
package com.mxdl.mvvm.application.c_cache.common.repository.local.db;
import android.arch.persistence.room.Room;
import android.content.Context;
/**
* Created by mxdl on 2017/10/7.
*/
public class DBHelper {
private static final DBHelper instance = new DBHelper();
private static final String DATABASE_NAME = "c_cache";
private DBHelper() {
}
public static DBHelper getInstance() {
return instance;
}
private DB db;
public void init(Context context) {
db = Room.databaseBuilder(context.getApplicationContext(), DB.class, DATABASE_NAME).build();
}
public DB getDb() {
return db;
}
}
package com.mxdl.mvvm.application.c_cache.common.repository.local.service;
import android.arch.lifecycle.LiveData;
import com.mxdl.mvvm.application.c_cache.common.bean.User;
/**
* Created by mxdl on 2017/10/7.
*/
public interface UserService {
LiveData<Long> add(User user);
LiveData<User> queryByUsername(String username);
}
package com.mxdl.mvvm.application.c_cache.common.repository.local.service;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import android.os.AsyncTask;
import com.mxdl.mvvm.application.c_cache.common.bean.User;
import com.mxdl.mvvm.application.c_cache.common.repository.local.dao.UserDao;
import com.mxdl.mvvm.application.c_cache.common.repository.local.db.DBHelper;
/**
* Created by mxdl on 2017/10/7.
*/
public class UserServiceImpl implements UserService {
private static final UserServiceImpl instance = new UserServiceImpl();
private UserServiceImpl() {
}
public static UserServiceImpl getInstance() {
return instance;
}
private UserDao userDao = DBHelper.getInstance().getDb().getUserDao();
@Override
public LiveData<Long> add(final User user) {
// transfer long to LiveData<Long>
final MutableLiveData<Long> data = new MutableLiveData<>();
new AsyncTask<Void, Void, Long>() {
@Override
protected Long doInBackground(Void... voids) {
return userDao.add(user);
}
@Override
protected void onPostExecute(Long rowId) {
data.setValue(rowId);
}
}.execute();
return data;
}
@Override
public LiveData<User> queryByUsername(String username) {
return userDao.queryByUsername(username);
}
}
package com.mxdl.mvvm.application.c_cache.common.repository.remote;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import com.mxdl.mvvm.application.c_cache.common.bean.User;
import com.mxdl.mvvm.application.c_cache.common.repository.UserDataSource;
import com.mxdl.mvvm.application.c_cache.common.repository.local.LocalUserDataSource;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Created by mxdl on 2017/10/6.
*/
public class RemoteUserDataSource implements UserDataSource {
private static final RemoteUserDataSource instance = new RemoteUserDataSource();
private RemoteUserDataSource() {
}
public static RemoteUserDataSource getInstance() {
return instance;
}
private UserApi userApi = RetrofitFactory.getInstance().create(UserApi.class);
@Override
public LiveData<User> queryUserByUsername(String username) {
final MutableLiveData<User> data = new MutableLiveData<>();
userApi.queryUserByUsername(username)
.enqueue(new Callback<User>() {
@Override
public void onResponse(Call<User> call, Response<User> response) {
User user = response.body();
if (null == user)
return;
data.setValue(user);
// update cache
LocalUserDataSource.getInstance().addUser(user);
}
@Override
public void onFailure(Call<User> call, Throwable t) {
t.printStackTrace();
}
});
return data;
}
}
package com.mxdl.mvvm.application.c_cache.common.repository.remote;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* Created by yu on 2017/2/21.
*/
public class RetrofitFactory {
private static OkHttpClient client;
private static Retrofit retrofit;
private static final String HOST = "https://api.github.com";
static {
client = new OkHttpClient.Builder()
.connectTimeout(9, TimeUnit.SECONDS)
.build();
retrofit = new Retrofit.Builder()
.baseUrl(HOST)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
public static Retrofit getInstance() {
return retrofit;
}
}
package com.mxdl.mvvm.application.c_cache.common.repository.remote;
import com.mxdl.mvvm.application.c_cache.common.bean.User;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Path;
/**
* Created by mxdl on 2017/10/6.
*/
public interface UserApi {
@GET("/users/{username}")
Call<User> queryUserByUsername(@Path("username") String username);
}
package com.mxdl.mvvm.application.c_cache.common.utils;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
public class NetworkUtils {
public static boolean isConnected(Context context) {
if (context != null) {
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
if (mNetworkInfo != null) {
return mNetworkInfo.isAvailable();
}
}
return false;
}
}
package com.mxdl.mvvm.application.c_cache.features.user;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;
import com.mxdl.mvvm.R;
import com.mxdl.mvvm.application.c_cache.common.bean.User;
import com.mxdl.mvvm.application.c_cache.common.repository.UserRepository;
import com.mxdl.mvvm.application.c_cache.common.repository.local.db.DBHelper;
/**
* Created by mxdl on 2017/10/4.
*/
public class UserActivity extends AppCompatActivity {
private static final String TAG = UserActivity.class.getName();
private UserViewModel userViewModel;
private TextView tvId;
private TextView tvName;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.c_activity_user);
initView();
initData();
}
private void initView() {
tvId = (TextView) findViewById(R.id.tv_id);
tvName = (TextView) findViewById(R.id.tv_name);
}
private void initData() {
DBHelper.getInstance().init(this);
UserRepository.getInstance().init(this);
userViewModel = ViewModelProviders.of(this).get(UserViewModel.class);
userViewModel.getUser("ittianyu").observe(this, new Observer<User>() {
@Override
public void onChanged(@Nullable User user) {
updateView(user);
}
});
}
private void updateView(User user) {
Log.d(TAG, user.toString());
tvId.setText(user.getId() + "");
tvName.setText(user.getName());
}
}
package com.mxdl.mvvm.application.c_cache.features.user;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.ViewModel;
import com.mxdl.mvvm.application.c_cache.common.bean.User;
import com.mxdl.mvvm.application.c_cache.common.repository.UserRepository;
/**
* Created by mxdl on 2017/10/4.
*/
public class UserViewModel extends ViewModel {
private UserRepository userRepository = UserRepository.getInstance();
private LiveData<User> user;
public LiveData<User> getUser(String username) {
if (null == user)
user = userRepository.getUser(username);
return user;
}
}
package com.mxdl.mvvm.application.d_state_lcee.common.bean;
/**
* Created by mxdl on 2017/10/12.
*/
public class Lcee<T> {
public final Status status;
public final T data;
public final Throwable error;
public Lcee(Status status, T data, Throwable error) {
this.status = status;
this.data = data;
this.error = error;
}
public static <T> Lcee<T> content(T data) {
return new Lcee<>(Status.Content, data, null);
}
public static <T> Lcee<T> error(T data, Throwable error) {
return new Lcee<>(Status.Error, data, error);
}
public static <T> Lcee<T> error(Throwable error) {
return error(null, error);
}
public static <T> Lcee<T> empty(T data) {
return new Lcee<>(Status.Empty, data, null);
}
public static <T> Lcee<T> empty() {
return empty(null);
}
public static <T> Lcee<T> loading(T data) {
return new Lcee<>(Status.Loading, data, null);
}
public static <T> Lcee<T> loading() {
return loading(null);
}
}
package com.mxdl.mvvm.application.d_state_lcee.common.bean;
/**
* Created by mxdl on 2017/10/12.
*/
public enum Status {
Loading,
Content,
Empty,
Error,
}
package com.mxdl.mvvm.application.d_state_lcee.common.bean;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.PrimaryKey;
import java.io.Serializable;
/**
* Created by mxdl on 2017/10/4.
*/
@Entity(tableName = "user")
public class User implements Serializable {
/**
* login : ittianyu
* id : 16226068
* avatar_url : https://avatars0.githubusercontent.com/u/16226068?v=4
* gravatar_id :
* url : https://api.github.com/users/ittianyu
* html_url : https://github.com/ittianyu
* followers_url : https://api.github.com/users/ittianyu/followers
* following_url : https://api.github.com/users/ittianyu/following{/other_user}
* gists_url : https://api.github.com/users/ittianyu/gists{/gist_id}
* starred_url : https://api.github.com/users/ittianyu/starred{/owner}{/repo}
* subscriptions_url : https://api.github.com/users/ittianyu/subscriptions
* organizations_url : https://api.github.com/users/ittianyu/orgs
* repos_url : https://api.github.com/users/ittianyu/repos
* events_url : https://api.github.com/users/ittianyu/events{/privacy}
* received_events_url : https://api.github.com/users/ittianyu/received_events
* type : User
* site_admin : false
* name : ittianyu
* company : null
* blog : www.ittianyu.com
* location : null
* email : null
* hireable : true
* bio : null
* public_repos : 4
* public_gists : 0
* followers : 56
* following : 2
* created_at : 2015-12-09T14:37:30Z
* updated_at : 2017-09-14T10:08:07Z
*/
@PrimaryKey
private int id;
private String login;
private String avatar_url;
private String gravatar_id;
private String url;
private String html_url;
private String followers_url;
private String following_url;
private String gists_url;
private String starred_url;
private String subscriptions_url;
private String organizations_url;
private String repos_url;
private String events_url;
private String received_events_url;
private String type;
private boolean site_admin;
private String name;
private String company;
private String blog;
private String location;
private String email;
private boolean hireable;
private String bio;
private int public_repos;
private int public_gists;
private int followers;
private int following;
private String created_at;
private String updated_at;
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAvatar_url() {
return avatar_url;
}
public void setAvatar_url(String avatar_url) {
this.avatar_url = avatar_url;
}
public String getGravatar_id() {
return gravatar_id;
}
public void setGravatar_id(String gravatar_id) {
this.gravatar_id = gravatar_id;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getHtml_url() {
return html_url;
}
public void setHtml_url(String html_url) {
this.html_url = html_url;
}
public String getFollowers_url() {
return followers_url;
}
public void setFollowers_url(String followers_url) {
this.followers_url = followers_url;
}
public String getFollowing_url() {
return following_url;
}
public void setFollowing_url(String following_url) {
this.following_url = following_url;
}
public String getGists_url() {
return gists_url;
}
public void setGists_url(String gists_url) {
this.gists_url = gists_url;
}
public String getStarred_url() {
return starred_url;
}
public void setStarred_url(String starred_url) {
this.starred_url = starred_url;
}
public String getSubscriptions_url() {
return subscriptions_url;
}
public void setSubscriptions_url(String subscriptions_url) {
this.subscriptions_url = subscriptions_url;
}
public String getOrganizations_url() {
return organizations_url;
}
public void setOrganizations_url(String organizations_url) {
this.organizations_url = organizations_url;
}
public String getRepos_url() {
return repos_url;
}
public void setRepos_url(String repos_url) {
this.repos_url = repos_url;
}
public String getEvents_url() {
return events_url;
}
public void setEvents_url(String events_url) {
this.events_url = events_url;
}
public String getReceived_events_url() {
return received_events_url;
}
public void setReceived_events_url(String received_events_url) {
this.received_events_url = received_events_url;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public boolean isSite_admin() {
return site_admin;
}
public void setSite_admin(boolean site_admin) {
this.site_admin = site_admin;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public String getBlog() {
return blog;
}
public void setBlog(String blog) {
this.blog = blog;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public boolean isHireable() {
return hireable;
}
public void setHireable(boolean hireable) {
this.hireable = hireable;
}
public String getBio() {
return bio;
}
public void setBio(String bio) {
this.bio = bio;
}
public int getPublic_repos() {
return public_repos;
}
public void setPublic_repos(int public_repos) {
this.public_repos = public_repos;
}
public int getPublic_gists() {
return public_gists;
}
public void setPublic_gists(int public_gists) {
this.public_gists = public_gists;
}
public int getFollowers() {
return followers;
}
public void setFollowers(int followers) {
this.followers = followers;
}
public int getFollowing() {
return following;
}
public void setFollowing(int following) {
this.following = following;
}
public String getCreated_at() {
return created_at;
}
public void setCreated_at(String created_at) {
this.created_at = created_at;
}
public String getUpdated_at() {
return updated_at;
}
public void setUpdated_at(String updated_at) {
this.updated_at = updated_at;
}
@Override
public String toString() {
return "User{" +
"login='" + login + '\'' +
", id=" + id +
", avatar_url='" + avatar_url + '\'' +
", gravatar_id='" + gravatar_id + '\'' +
", url='" + url + '\'' +
", html_url='" + html_url + '\'' +
", followers_url='" + followers_url + '\'' +
", following_url='" + following_url + '\'' +
", gists_url='" + gists_url + '\'' +
", starred_url='" + starred_url + '\'' +
", subscriptions_url='" + subscriptions_url + '\'' +
", organizations_url='" + organizations_url + '\'' +
", repos_url='" + repos_url + '\'' +
", events_url='" + events_url + '\'' +
", received_events_url='" + received_events_url + '\'' +
", type='" + type + '\'' +
", site_admin=" + site_admin +
", name='" + name + '\'' +
", company=" + company +
", blog='" + blog + '\'' +
", location=" + location +
", email=" + email +
", hireable=" + hireable +
", bio=" + bio +
", public_repos=" + public_repos +
", public_gists=" + public_gists +
", followers=" + followers +
", following=" + following +
", created_at='" + created_at + '\'' +
", updated_at='" + updated_at + '\'' +
'}';
}
}
package com.mxdl.mvvm.application.d_state_lcee.common.repository;
import android.arch.lifecycle.LiveData;
import com.mxdl.mvvm.application.d_state_lcee.common.bean.Lcee;
import com.mxdl.mvvm.application.d_state_lcee.common.bean.User;
/**
* Created by mxdl on 2017/10/6.
*/
public interface UserDataSource {
LiveData<Lcee<User>> queryUserByUsername(String username);
}
package com.mxdl.mvvm.application.d_state_lcee.common.repository;
import android.arch.lifecycle.LiveData;
import android.content.Context;
import com.mxdl.mvvm.application.d_state_lcee.common.bean.Lcee;
import com.mxdl.mvvm.application.d_state_lcee.common.bean.User;
import com.mxdl.mvvm.application.d_state_lcee.common.repository.local.LocalUserDataSource;
import com.mxdl.mvvm.application.d_state_lcee.common.repository.remote.RemoteUserDataSource;
import com.mxdl.mvvm.application.d_state_lcee.common.utils.NetworkUtils;
/**
* Created by mxdl on 2017/10/6.
*/
public class UserRepository {
private static final UserRepository instance = new UserRepository();
private UserRepository() {
}
public static UserRepository getInstance() {
return instance;
}
private Context context;
private UserDataSource remoteUserDataSource = RemoteUserDataSource.getInstance();
private UserDataSource localUserDataSource = LocalUserDataSource.getInstance();
public void init(Context context) {
this.context = context.getApplicationContext();
}
public LiveData<Lcee<User>> getUser(String username) {
if (NetworkUtils.isConnected(context)) {
return remoteUserDataSource.queryUserByUsername(username);
} else {
return localUserDataSource.queryUserByUsername(username);
}
}
}
package com.mxdl.mvvm.application.d_state_lcee.common.repository.local;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MediatorLiveData;
import android.arch.lifecycle.Observer;
import android.support.annotation.Nullable;
import com.mxdl.mvvm.application.d_state_lcee.common.bean.Lcee;
import com.mxdl.mvvm.application.d_state_lcee.common.bean.User;
import com.mxdl.mvvm.application.d_state_lcee.common.repository.UserDataSource;
import com.mxdl.mvvm.application.d_state_lcee.common.repository.local.service.UserService;
import com.mxdl.mvvm.application.d_state_lcee.common.repository.local.service.UserServiceImpl;
/**
* Created by mxdl on 2017/10/6.
*/
public class LocalUserDataSource implements UserDataSource {
private static final LocalUserDataSource instance = new LocalUserDataSource();
private LocalUserDataSource() {
}
public static LocalUserDataSource getInstance() {
return instance;
}
private UserService userService = UserServiceImpl.getInstance();
@Override
public LiveData<Lcee<User>> queryUserByUsername(String username) {
final MediatorLiveData<Lcee<User>> data = new MediatorLiveData<>();
data.setValue(Lcee.<User>loading());
data.addSource(userService.queryByUsername(username), new Observer<User>() {
@Override
public void onChanged(@Nullable User user) {
if (null == user) {
data.setValue(Lcee.<User>empty());
} else {
data.setValue(Lcee.content(user));
}
}
});
return data;
}
public LiveData<Long> addUser(User user) {
return userService.add(user);
}
}
package com.mxdl.mvvm.application.d_state_lcee.common.repository.local.dao;
import android.arch.lifecycle.LiveData;
import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.OnConflictStrategy;
import android.arch.persistence.room.Query;
import com.mxdl.mvvm.application.d_state_lcee.common.bean.User;
/**
* Created by mxdl on 2017/10/7.
*/
@Dao
public interface UserDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)// cache need update
Long add(User user);
@Query("select * from user where login = :username")
LiveData<User> queryByUsername(String username);
}
package com.mxdl.mvvm.application.d_state_lcee.common.repository.local.db;
import android.arch.persistence.room.Database;
import android.arch.persistence.room.RoomDatabase;
import com.mxdl.mvvm.application.d_state_lcee.common.bean.User;
import com.mxdl.mvvm.application.d_state_lcee.common.repository.local.dao.UserDao;
/**
* Created by mxdl on 2017/10/7.
*/
@Database(entities = {User.class}, version = 1, exportSchema = false)
public abstract class DB extends RoomDatabase {
public abstract UserDao getUserDao();
}
package com.mxdl.mvvm.application.d_state_lcee.common.repository.local.db;
import android.arch.persistence.room.Room;
import android.content.Context;
/**
* Created by mxdl on 2017/10/7.
*/
public class DBHelper {
private static final DBHelper instance = new DBHelper();
private static final String DATABASE_NAME = "c_cache";
private DBHelper() {
}
public static DBHelper getInstance() {
return instance;
}
private DB db;
public void init(Context context) {
db = Room.databaseBuilder(context.getApplicationContext(), DB.class, DATABASE_NAME).build();
}
public DB getDb() {
return db;
}
}
package com.mxdl.mvvm.application.d_state_lcee.common.repository.local.service;
import android.arch.lifecycle.LiveData;
import com.mxdl.mvvm.application.d_state_lcee.common.bean.User;
/**
* Created by mxdl on 2017/10/7.
*/
public interface UserService {
LiveData<Long> add(User user);
LiveData<User> queryByUsername(String username);
}
package com.mxdl.mvvm.application.d_state_lcee.common.repository.local.service;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import android.os.AsyncTask;
import com.mxdl.mvvm.application.d_state_lcee.common.bean.User;
import com.mxdl.mvvm.application.d_state_lcee.common.repository.local.dao.UserDao;
import com.mxdl.mvvm.application.d_state_lcee.common.repository.local.db.DBHelper;
/**
* Created by mxdl on 2017/10/7.
*/
public class UserServiceImpl implements UserService {
private static final UserServiceImpl instance = new UserServiceImpl();
private UserServiceImpl() {
}
public static UserServiceImpl getInstance() {
return instance;
}
private UserDao userDao = DBHelper.getInstance().getDb().getUserDao();
@Override
public LiveData<Long> add(final User user) {
// transfer long to LiveData<Long>
final MutableLiveData<Long> data = new MutableLiveData<>();
new AsyncTask<Void, Void, Long>() {
@Override
protected Long doInBackground(Void... voids) {
return userDao.add(user);
}
@Override
protected void onPostExecute(Long rowId) {
data.setValue(rowId);
}
}.execute();
return data;
}
@Override
public LiveData<User> queryByUsername(String username) {
return userDao.queryByUsername(username);
}
}
package com.mxdl.mvvm.application.d_state_lcee.common.repository.remote;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import com.mxdl.mvvm.application.d_state_lcee.common.bean.Lcee;
import com.mxdl.mvvm.application.d_state_lcee.common.bean.User;
import com.mxdl.mvvm.application.d_state_lcee.common.repository.UserDataSource;
import com.mxdl.mvvm.application.d_state_lcee.common.repository.local.LocalUserDataSource;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Created by mxdl on 2017/10/6.
*/
public class RemoteUserDataSource implements UserDataSource {
private static final RemoteUserDataSource instance = new RemoteUserDataSource();
private RemoteUserDataSource() {
}
public static RemoteUserDataSource getInstance() {
return instance;
}
private UserApi userApi = RetrofitFactory.getInstance().create(UserApi.class);
@Override
public LiveData<Lcee<User>> queryUserByUsername(String username) {
final MutableLiveData<Lcee<User>> data = new MutableLiveData<>();
data.setValue(Lcee.<User>loading());
userApi.queryUserByUsername(username)
.enqueue(new Callback<User>() {
@Override
public void onResponse(Call<User> call, Response<User> response) {
User user = response.body();
if (null == user) {
data.setValue(Lcee.<User>empty());
return;
}
data.setValue(Lcee.content(user));
// update cache
LocalUserDataSource.getInstance().addUser(user);
}
@Override
public void onFailure(Call<User> call, Throwable t) {
t.printStackTrace();
data.setValue(Lcee.<User>error(t));
}
});
return data;
}
}
package com.mxdl.mvvm.application.d_state_lcee.common.repository.remote;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* Created by yu on 2017/2/21.
*/
public class RetrofitFactory {
private static OkHttpClient client;
private static Retrofit retrofit;
private static final String HOST = "https://api.github.com";
static {
client = new OkHttpClient.Builder()
.connectTimeout(9, TimeUnit.SECONDS)
.build();
retrofit = new Retrofit.Builder()
.baseUrl(HOST)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
public static Retrofit getInstance() {
return retrofit;
}
}
package com.mxdl.mvvm.application.d_state_lcee.common.repository.remote;
import com.mxdl.mvvm.application.d_state_lcee.common.bean.User;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Path;
/**
* Created by mxdl on 2017/10/6.
*/
public interface UserApi {
@GET("/users/{username}")
Call<User> queryUserByUsername(@Path("username") String username);
}
package com.mxdl.mvvm.application.d_state_lcee.common.utils;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
public class NetworkUtils {
public static boolean isConnected(Context context) {
if (context != null) {
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
if (mNetworkInfo != null) {
return mNetworkInfo.isAvailable();
}
}
return false;
}
}
package com.mxdl.mvvm.application.d_state_lcee.features.user;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import com.mxdl.mvvm.R;
import com.mxdl.mvvm.application.d_state_lcee.common.bean.Lcee;
import com.mxdl.mvvm.application.d_state_lcee.common.bean.User;
import com.mxdl.mvvm.application.d_state_lcee.common.repository.UserRepository;
import com.mxdl.mvvm.application.d_state_lcee.common.repository.local.db.DBHelper;
/**
* Created by mxdl on 2017/10/4.
*/
public class UserActivity extends AppCompatActivity {
private static final String TAG = UserActivity.class.getName();
// vm
private UserViewModel userViewModel;
// view
private View vContent;
private View vError;
private View vLoading;
private View vEmpty;
private TextView tvId;
private TextView tvName;
private EditText etUsername;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.d_activity_user);
initView();
initData();
initEvent();
}
private void initView() {
vContent = findViewById(R.id.v_content);
vError = findViewById(R.id.v_error);
vLoading = findViewById(R.id.v_loading);
vEmpty = findViewById(R.id.v_empty);
tvId = (TextView) findViewById(R.id.tv_id);
tvName = (TextView) findViewById(R.id.tv_name);
etUsername = (EditText) findViewById(R.id.et_username);
}
private void initData() {
DBHelper.getInstance().init(this);
UserRepository.getInstance().init(this);
userViewModel = ViewModelProviders.of(this).get(UserViewModel.class);
userViewModel.getUser().observe(this, new Observer<Lcee<User>>() {
@Override
public void onChanged(@Nullable Lcee<User> data) {
updateView(data);
}
});
reload();
}
private void initEvent() {
View.OnClickListener reloadClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
hideKeyboard();
reload();
}
};
vError.setOnClickListener(reloadClickListener);
vEmpty.setOnClickListener(reloadClickListener);
findViewById(R.id.btn_search).setOnClickListener(reloadClickListener);
etUsername.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_ENTER) {
hideKeyboard();
reload();
return true;
}
return false;
}
});
}
private void hideKeyboard() {
((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE))
.hideSoftInputFromWindow(UserActivity.this.getCurrentFocus().getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
}
private void reload() {
// reload
userViewModel.reload(getUsername());
}
private void updateView(Lcee<User> lcee) {
switch (lcee.status) {
case Content: {
showContent();
tvId.setText(lcee.data.getId() + "");
tvName.setText(lcee.data.getName());
break;
}
case Empty: {
showEmpty();
break;
}
case Error: {
showError();
break;
}
case Loading: {
showLoading();
break;
}
}
}
private void showContent() {
vContent.setVisibility(View.VISIBLE);
vEmpty.setVisibility(View.GONE);
vError.setVisibility(View.GONE);
vLoading.setVisibility(View.GONE);
}
private void showEmpty() {
vContent.setVisibility(View.GONE);
vEmpty.setVisibility(View.VISIBLE);
vError.setVisibility(View.GONE);
vLoading.setVisibility(View.GONE);
}
private void showError() {
vContent.setVisibility(View.GONE);
vEmpty.setVisibility(View.GONE);
vError.setVisibility(View.VISIBLE);
vLoading.setVisibility(View.GONE);
}
private void showLoading() {
vContent.setVisibility(View.GONE);
vEmpty.setVisibility(View.GONE);
vError.setVisibility(View.GONE);
vLoading.setVisibility(View.VISIBLE);
}
private String getUsername() {
return etUsername.getText().toString();
}
}
package com.mxdl.mvvm.application.d_state_lcee.features.user;
import android.arch.core.util.Function;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import android.arch.lifecycle.Transformations;
import android.arch.lifecycle.ViewModel;
import com.mxdl.mvvm.application.d_state_lcee.common.bean.Lcee;
import com.mxdl.mvvm.application.d_state_lcee.common.bean.User;
import com.mxdl.mvvm.application.d_state_lcee.common.repository.UserRepository;
/**
* Created by mxdl on 2017/10/4.
*/
public class UserViewModel extends ViewModel {
private UserRepository userRepository = UserRepository.getInstance();
private MutableLiveData<String> ldUsername;
private LiveData<Lcee<User>> ldUser;
public LiveData<Lcee<User>> getUser() {
if (null == ldUser) {
ldUsername = new MutableLiveData<>();
ldUser = Transformations.switchMap(ldUsername, new Function<String, LiveData<Lcee<User>>>() {
@Override
public LiveData<Lcee<User>> apply(String username) {
return userRepository.getUser(username);
}
});
}
return ldUser;
}
public void reload(String username) {
ldUsername.setValue(username);
}
}
package com.mxdl.mvvm.application.e_simple_data_source.common.bean;
/**
* Created by mxdl on 2017/10/12.
*/
public class Lcee<T> {
public final Status status;
public final T data;
public final Throwable error;
public Lcee(Status status, T data, Throwable error) {
this.status = status;
this.data = data;
this.error = error;
}
public static <T> Lcee<T> content(T data) {
return new Lcee<>(Status.Content, data, null);
}
public static <T> Lcee<T> error(T data, Throwable error) {
return new Lcee<>(Status.Error, data, error);
}
public static <T> Lcee<T> error(Throwable error) {
return error(null, error);
}
public static <T> Lcee<T> empty(T data) {
return new Lcee<>(Status.Empty, data, null);
}
public static <T> Lcee<T> empty() {
return empty(null);
}
public static <T> Lcee<T> loading(T data) {
return new Lcee<>(Status.Loading, data, null);
}
public static <T> Lcee<T> loading() {
return loading(null);
}
}
package com.mxdl.mvvm.application.e_simple_data_source.common.bean;
/**
* Created by mxdl on 2017/10/12.
*/
public enum Status {
Loading,
Content,
Empty,
Error,
}
package com.mxdl.mvvm.application.e_simple_data_source.common.bean;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.PrimaryKey;
import java.io.Serializable;
/**
* Created by mxdl on 2017/10/4.
*/
@Entity(tableName = "user")
public class User implements Serializable {
/**
* login : ittianyu
* id : 16226068
* avatar_url : https://avatars0.githubusercontent.com/u/16226068?v=4
* gravatar_id :
* url : https://api.github.com/users/ittianyu
* html_url : https://github.com/ittianyu
* followers_url : https://api.github.com/users/ittianyu/followers
* following_url : https://api.github.com/users/ittianyu/following{/other_user}
* gists_url : https://api.github.com/users/ittianyu/gists{/gist_id}
* starred_url : https://api.github.com/users/ittianyu/starred{/owner}{/repo}
* subscriptions_url : https://api.github.com/users/ittianyu/subscriptions
* organizations_url : https://api.github.com/users/ittianyu/orgs
* repos_url : https://api.github.com/users/ittianyu/repos
* events_url : https://api.github.com/users/ittianyu/events{/privacy}
* received_events_url : https://api.github.com/users/ittianyu/received_events
* type : User
* site_admin : false
* name : ittianyu
* company : null
* blog : www.ittianyu.com
* location : null
* email : null
* hireable : true
* bio : null
* public_repos : 4
* public_gists : 0
* followers : 56
* following : 2
* created_at : 2015-12-09T14:37:30Z
* updated_at : 2017-09-14T10:08:07Z
*/
@PrimaryKey
private int id;
private String login;
private String avatar_url;
private String gravatar_id;
private String url;
private String html_url;
private String followers_url;
private String following_url;
private String gists_url;
private String starred_url;
private String subscriptions_url;
private String organizations_url;
private String repos_url;
private String events_url;
private String received_events_url;
private String type;
private boolean site_admin;
private String name;
private String company;
private String blog;
private String location;
private String email;
private boolean hireable;
private String bio;
private int public_repos;
private int public_gists;
private int followers;
private int following;
private String created_at;
private String updated_at;
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAvatar_url() {
return avatar_url;
}
public void setAvatar_url(String avatar_url) {
this.avatar_url = avatar_url;
}
public String getGravatar_id() {
return gravatar_id;
}
public void setGravatar_id(String gravatar_id) {
this.gravatar_id = gravatar_id;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getHtml_url() {
return html_url;
}
public void setHtml_url(String html_url) {
this.html_url = html_url;
}
public String getFollowers_url() {
return followers_url;
}
public void setFollowers_url(String followers_url) {
this.followers_url = followers_url;
}
public String getFollowing_url() {
return following_url;
}
public void setFollowing_url(String following_url) {
this.following_url = following_url;
}
public String getGists_url() {
return gists_url;
}
public void setGists_url(String gists_url) {
this.gists_url = gists_url;
}
public String getStarred_url() {
return starred_url;
}
public void setStarred_url(String starred_url) {
this.starred_url = starred_url;
}
public String getSubscriptions_url() {
return subscriptions_url;
}
public void setSubscriptions_url(String subscriptions_url) {
this.subscriptions_url = subscriptions_url;
}
public String getOrganizations_url() {
return organizations_url;
}
public void setOrganizations_url(String organizations_url) {
this.organizations_url = organizations_url;
}
public String getRepos_url() {
return repos_url;
}
public void setRepos_url(String repos_url) {
this.repos_url = repos_url;
}
public String getEvents_url() {
return events_url;
}
public void setEvents_url(String events_url) {
this.events_url = events_url;
}
public String getReceived_events_url() {
return received_events_url;
}
public void setReceived_events_url(String received_events_url) {
this.received_events_url = received_events_url;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public boolean isSite_admin() {
return site_admin;
}
public void setSite_admin(boolean site_admin) {
this.site_admin = site_admin;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public String getBlog() {
return blog;
}
public void setBlog(String blog) {
this.blog = blog;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public boolean isHireable() {
return hireable;
}
public void setHireable(boolean hireable) {
this.hireable = hireable;
}
public String getBio() {
return bio;
}
public void setBio(String bio) {
this.bio = bio;
}
public int getPublic_repos() {
return public_repos;
}
public void setPublic_repos(int public_repos) {
this.public_repos = public_repos;
}
public int getPublic_gists() {
return public_gists;
}
public void setPublic_gists(int public_gists) {
this.public_gists = public_gists;
}
public int getFollowers() {
return followers;
}
public void setFollowers(int followers) {
this.followers = followers;
}
public int getFollowing() {
return following;
}
public void setFollowing(int following) {
this.following = following;
}
public String getCreated_at() {
return created_at;
}
public void setCreated_at(String created_at) {
this.created_at = created_at;
}
public String getUpdated_at() {
return updated_at;
}
public void setUpdated_at(String updated_at) {
this.updated_at = updated_at;
}
@Override
public String toString() {
return "User{" +
"login='" + login + '\'' +
", id=" + id +
", avatar_url='" + avatar_url + '\'' +
", gravatar_id='" + gravatar_id + '\'' +
", url='" + url + '\'' +
", html_url='" + html_url + '\'' +
", followers_url='" + followers_url + '\'' +
", following_url='" + following_url + '\'' +
", gists_url='" + gists_url + '\'' +
", starred_url='" + starred_url + '\'' +
", subscriptions_url='" + subscriptions_url + '\'' +
", organizations_url='" + organizations_url + '\'' +
", repos_url='" + repos_url + '\'' +
", events_url='" + events_url + '\'' +
", received_events_url='" + received_events_url + '\'' +
", type='" + type + '\'' +
", site_admin=" + site_admin +
", name='" + name + '\'' +
", company=" + company +
", blog='" + blog + '\'' +
", location=" + location +
", email=" + email +
", hireable=" + hireable +
", bio=" + bio +
", public_repos=" + public_repos +
", public_gists=" + public_gists +
", followers=" + followers +
", following=" + following +
", created_at='" + created_at + '\'' +
", updated_at='" + updated_at + '\'' +
'}';
}
}
package com.mxdl.mvvm.application.e_simple_data_source.common.repository;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* Created by yu on 2017/2/21.
*/
public class RetrofitFactory {
private static OkHttpClient client;
private static Retrofit retrofit;
private static final String HOST = "https://api.github.com";
static {
client = new OkHttpClient.Builder()
.connectTimeout(9, TimeUnit.SECONDS)
.build();
retrofit = new Retrofit.Builder()
.baseUrl(HOST)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
public static Retrofit getInstance() {
return retrofit;
}
}
package com.mxdl.mvvm.application.e_simple_data_source.common.repository;
import com.mxdl.mvvm.application.e_simple_data_source.common.bean.User;
/**
* Created by mxdl on 2017/10/6.
*/
public interface UserDataSource {
interface Result<T> {
void onSuccess(T data);
void onFailed(Throwable throwable);
}
void queryUserByUsername(String username, Result<User> result);
}
package com.mxdl.mvvm.application.e_simple_data_source.common.repository.local;
import android.os.AsyncTask;
import com.mxdl.mvvm.application.e_simple_data_source.common.bean.User;
import com.mxdl.mvvm.application.e_simple_data_source.common.repository.UserDataSource;
import com.mxdl.mvvm.application.e_simple_data_source.common.repository.local.service.UserService;
import com.mxdl.mvvm.application.e_simple_data_source.common.repository.local.service.UserServiceImpl;
/**
* Created by mxdl on 2017/10/6.
*/
public class LocalUserDataSource implements UserDataSource {
private static final LocalUserDataSource instance = new LocalUserDataSource();
private LocalUserDataSource() {
}
public static LocalUserDataSource getInstance() {
return instance;
}
private UserService userService = UserServiceImpl.getInstance();
public void addUser(final User user) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids) {
userService.add(user);
return null;
}
}.execute();
}
@Override
public void queryUserByUsername(final String username, final Result<User> result) {
new AsyncTask<Void, Void, Object>() {
@Override
protected Object doInBackground(Void... voids) {
try {
User user = userService.queryByUsername(username);
return user;
} catch (Exception e) {
e.printStackTrace();
return e;
}
}
@Override
protected void onPostExecute(Object obj) {
if (obj instanceof User)
result.onSuccess((User) obj);
else if (obj instanceof Exception)
result.onFailed((Throwable) obj);
else
result.onFailed(null);
}
}.execute();
}
}
package com.mxdl.mvvm.application.e_simple_data_source.common.repository.local.dao;
import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.OnConflictStrategy;
import android.arch.persistence.room.Query;
import com.mxdl.mvvm.application.e_simple_data_source.common.bean.User;
/**
* Created by mxdl on 2017/10/7.
*/
@Dao
public interface UserDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)// cache need update
Long add(User user);
@Query("select * from user where login = :username")
User queryByUsername(String username) throws Exception;
}
package com.mxdl.mvvm.application.e_simple_data_source.common.repository.local.db;
import android.arch.persistence.room.Database;
import android.arch.persistence.room.RoomDatabase;
import com.mxdl.mvvm.application.e_simple_data_source.common.bean.User;
import com.mxdl.mvvm.application.e_simple_data_source.common.repository.local.dao.UserDao;
/**
* Created by mxdl on 2017/10/7.
*/
@Database(entities = {User.class}, version = 1, exportSchema = false)
public abstract class DB extends RoomDatabase {
public abstract UserDao getUserDao();
}
package com.mxdl.mvvm.application.e_simple_data_source.common.repository.local.db;
import android.arch.persistence.room.Room;
import android.content.Context;
/**
* Created by mxdl on 2017/10/7.
*/
public class DBHelper {
private static final DBHelper instance = new DBHelper();
private static final String DATABASE_NAME = "c_cache";
private DBHelper() {
}
public static DBHelper getInstance() {
return instance;
}
private DB db;
public void init(Context context) {
db = Room.databaseBuilder(context.getApplicationContext(), DB.class, DATABASE_NAME).build();
}
public DB getDb() {
return db;
}
}
package com.mxdl.mvvm.application.e_simple_data_source.common.repository.local.service;
import com.mxdl.mvvm.application.e_simple_data_source.common.bean.User;
/**
* Created by mxdl on 2017/10/7.
*/
public interface UserService {
Long add(User user);
User queryByUsername(String username) throws Exception;
}
package com.mxdl.mvvm.application.e_simple_data_source.common.repository.local.service;
import com.mxdl.mvvm.application.e_simple_data_source.common.bean.User;
import com.mxdl.mvvm.application.e_simple_data_source.common.repository.local.dao.UserDao;
import com.mxdl.mvvm.application.e_simple_data_source.common.repository.local.db.DBHelper;
/**
* Created by mxdl on 2017/10/7.
*/
public class UserServiceImpl implements UserService {
private static final UserServiceImpl instance = new UserServiceImpl();
private UserServiceImpl() {
}
public static UserServiceImpl getInstance() {
return instance;
}
private UserDao userDao = DBHelper.getInstance().getDb().getUserDao();
@Override
public Long add(final User user) {
return userDao.add(user);
}
@Override
public User queryByUsername(String username) throws Exception{
return userDao.queryByUsername(username);
}
}
package com.mxdl.mvvm.application.e_simple_data_source.common.repository.remote;
import com.mxdl.mvvm.application.e_simple_data_source.common.bean.User;
import com.mxdl.mvvm.application.e_simple_data_source.common.repository.RetrofitFactory;
import com.mxdl.mvvm.application.e_simple_data_source.common.repository.UserDataSource;
import com.mxdl.mvvm.application.e_simple_data_source.common.repository.local.LocalUserDataSource;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Created by mxdl on 2017/10/6.
*/
public class RemoteUserDataSource implements UserDataSource {
private static final RemoteUserDataSource instance = new RemoteUserDataSource();
private RemoteUserDataSource() {
}
public static RemoteUserDataSource getInstance() {
return instance;
}
private UserApi userApi = RetrofitFactory.getInstance().create(UserApi.class);
@Override
public void queryUserByUsername(String username, final Result<User> result) {
userApi.queryUserByUsername(username)
.enqueue(new Callback<User>() {
@Override
public void onResponse(Call<User> call, Response<User> response) {
User user = response.body();
result.onSuccess(user);
// update cache
LocalUserDataSource.getInstance().addUser(user);
}
@Override
public void onFailure(Call<User> call, Throwable t) {
t.printStackTrace();
result.onFailed(t);
}
});
}
}
package com.mxdl.mvvm.application.e_simple_data_source.common.repository.remote;
import com.mxdl.mvvm.application.e_simple_data_source.common.bean.User;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Path;
/**
* Created by mxdl on 2017/10/6.
*/
public interface UserApi {
@GET("/users/{username}")
Call<User> queryUserByUsername(@Path("username") String username);
}
package com.mxdl.mvvm.application.e_simple_data_source.common.repository.remote;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import android.content.Context;
import com.mxdl.mvvm.application.e_simple_data_source.common.bean.Lcee;
import com.mxdl.mvvm.application.e_simple_data_source.common.bean.User;
import com.mxdl.mvvm.application.e_simple_data_source.common.repository.UserDataSource;
import com.mxdl.mvvm.application.e_simple_data_source.common.repository.local.LocalUserDataSource;
import com.mxdl.mvvm.application.e_simple_data_source.common.utils.NetworkUtils;
/**
* Created by mxdl on 2017/10/6.
*/
public class UserRepository {
private static final UserRepository instance = new UserRepository();
private UserRepository() {
}
public static UserRepository getInstance() {
return instance;
}
private Context context;
private UserDataSource remoteUserDataSource = RemoteUserDataSource.getInstance();
private UserDataSource localUserDataSource = LocalUserDataSource.getInstance();
public void init(Context context) {
this.context = context.getApplicationContext();
}
public LiveData<Lcee<User>> getUser(String username) {
if (NetworkUtils.isConnected(context)) {
return getUserFromRemote(username);
} else {
return getUserFromLocal(username);
}
}
private LiveData<Lcee<User>> getUserFromRemote(String username) {
return getUserFromDataSource(remoteUserDataSource, username);
}
private LiveData<Lcee<User>> getUserFromLocal(String username) {
return getUserFromDataSource(localUserDataSource, username);
}
private LiveData<Lcee<User>> getUserFromDataSource(UserDataSource dataSource, String username) {
final MutableLiveData<Lcee<User>> data = new MutableLiveData<>();
data.setValue(Lcee.<User>loading());
dataSource.queryUserByUsername(username, new UserDataSource.Result<User>() {
@Override
public void onSuccess(User user) {
if (null == data)
data.setValue(Lcee.<User>empty());
else
data.setValue(Lcee.content(user));
}
@Override
public void onFailed(Throwable throwable) {
data.setValue(Lcee.<User>error(throwable));
}
});
return data;
}
}
package com.mxdl.mvvm.application.e_simple_data_source.common.utils;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
public class NetworkUtils {
public static boolean isConnected(Context context) {
if (context != null) {
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
if (mNetworkInfo != null) {
return mNetworkInfo.isAvailable();
}
}
return false;
}
}
package com.mxdl.mvvm.application.e_simple_data_source.features.user;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import com.mxdl.mvvm.R;
import com.mxdl.mvvm.application.e_simple_data_source.common.bean.Lcee;
import com.mxdl.mvvm.application.e_simple_data_source.common.bean.User;
import com.mxdl.mvvm.application.e_simple_data_source.common.repository.remote.UserRepository;
import com.mxdl.mvvm.application.e_simple_data_source.common.repository.local.db.DBHelper;
/**
* Created by mxdl on 2017/10/4.
*/
public class UserActivity extends AppCompatActivity {
private static final String TAG = UserActivity.class.getName();
// vm
private UserViewModel userViewModel;
// view
private View vContent;
private View vError;
private View vLoading;
private View vEmpty;
private TextView tvId;
private TextView tvName;
private EditText etUsername;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.e_activity_user);
initView();
initData();
initEvent();
}
private void initView() {
vContent = findViewById(R.id.v_content);
vError = findViewById(R.id.v_error);
vLoading = findViewById(R.id.v_loading);
vEmpty = findViewById(R.id.v_empty);
tvId = (TextView) findViewById(R.id.tv_id);
tvName = (TextView) findViewById(R.id.tv_name);
etUsername = (EditText) findViewById(R.id.et_username);
}
private void initData() {
DBHelper.getInstance().init(this);
UserRepository.getInstance().init(this);
userViewModel = ViewModelProviders.of(this).get(UserViewModel.class);
userViewModel.getUser().observe(this, new Observer<Lcee<User>>() {
@Override
public void onChanged(@Nullable Lcee<User> data) {
updateView(data);
}
});
reload();
}
private void initEvent() {
View.OnClickListener reloadClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
hideKeyboard();
reload();
}
};
vError.setOnClickListener(reloadClickListener);
vEmpty.setOnClickListener(reloadClickListener);
findViewById(R.id.btn_search).setOnClickListener(reloadClickListener);
etUsername.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_ENTER) {
hideKeyboard();
reload();
return true;
}
return false;
}
});
}
private void hideKeyboard() {
((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE))
.hideSoftInputFromWindow(UserActivity.this.getCurrentFocus().getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
}
private void reload() {
// reload
userViewModel.reload(getUsername());
}
private void updateView(Lcee<User> lcee) {
switch (lcee.status) {
case Content: {
showContent();
tvId.setText(lcee.data.getId() + "");
tvName.setText(lcee.data.getName());
break;
}
case Empty: {
showEmpty();
break;
}
case Error: {
showError();
break;
}
case Loading: {
showLoading();
break;
}
}
}
private void showContent() {
vContent.setVisibility(View.VISIBLE);
vEmpty.setVisibility(View.GONE);
vError.setVisibility(View.GONE);
vLoading.setVisibility(View.GONE);
}
private void showEmpty() {
vContent.setVisibility(View.GONE);
vEmpty.setVisibility(View.VISIBLE);
vError.setVisibility(View.GONE);
vLoading.setVisibility(View.GONE);
}
private void showError() {
vContent.setVisibility(View.GONE);
vEmpty.setVisibility(View.GONE);
vError.setVisibility(View.VISIBLE);
vLoading.setVisibility(View.GONE);
}
private void showLoading() {
vContent.setVisibility(View.GONE);
vEmpty.setVisibility(View.GONE);
vError.setVisibility(View.GONE);
vLoading.setVisibility(View.VISIBLE);
}
private String getUsername() {
return etUsername.getText().toString();
}
}
package com.mxdl.mvvm.application.e_simple_data_source.features.user;
import android.arch.core.util.Function;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import android.arch.lifecycle.Transformations;
import android.arch.lifecycle.ViewModel;
import com.mxdl.mvvm.application.e_simple_data_source.common.bean.Lcee;
import com.mxdl.mvvm.application.e_simple_data_source.common.bean.User;
import com.mxdl.mvvm.application.e_simple_data_source.common.repository.remote.UserRepository;
/**
* Created by mxdl on 2017/10/4.
*/
public class UserViewModel extends ViewModel {
private UserRepository userRepository = UserRepository.getInstance();
private MutableLiveData<String> ldUsername;;
private LiveData<Lcee<User>> ldUser;
public LiveData<Lcee<User>> getUser() {
if (null == ldUser) {
ldUsername = new MutableLiveData<>();
ldUser = Transformations.switchMap(ldUsername, new Function<String, LiveData<Lcee<User>>>() {
@Override
public LiveData<Lcee<User>> apply(String username) {
return userRepository.getUser(username);
}
});
}
return ldUser;
}
public void reload(String username) {
ldUsername.setValue(username);
}
}
package com.mxdl.mvvm.application.f_load_more.common.bean;
/**
* Created by mxdl on 2017/10/12.
*/
public class Lcee<T> {
public final Status status;
public final T data;
public final Throwable error;
private Lcee(Status status, T data, Throwable error) {
this.status = status;
this.data = data;
this.error = error;
}
public static <T> Lcee<T> content(T data) {
return new Lcee<>(Status.Content, data, null);
}
public static <T> Lcee<T> error(T data, Throwable error) {
return new Lcee<>(Status.Error, data, error);
}
public static <T> Lcee<T> error(Throwable error) {
return error(null, error);
}
public static <T> Lcee<T> empty(T data) {
return new Lcee<>(Status.Empty, data, null);
}
public static <T> Lcee<T> empty() {
return empty(null);
}
public static <T> Lcee<T> loading(T data) {
return new Lcee<>(Status.Loading, data, null);
}
public static <T> Lcee<T> loading() {
return loading(null);
}
}
package com.mxdl.mvvm.application.f_load_more.common.bean;
/**
* Created by mxdl on 2017/10/19.
*/
public enum ListStatus {
Refreshing,
LoadingMore,
Content,
}
package com.mxdl.mvvm.application.f_load_more.common.bean;
/**
* Created by mxdl on 2017/10/12.
*/
public enum Status {
Loading,
Content,
Empty,
Error,
}
package com.mxdl.mvvm.application.f_load_more.common.bean.project;
/**
* Created by mxdl on 2017/10/18.
*/
public class ProjectOwner {
/**
* login : daniel-e
* id : 5294331
* avatar_url : https://avatars2.githubusercontent.com/u/5294331?v=4
* gravatar_id :
* url : https://api.github.com/users/daniel-e
* html_url : https://github.com/daniel-e
* followers_url : https://api.github.com/users/daniel-e/followers
* following_url : https://api.github.com/users/daniel-e/following{/other_user}
* gists_url : https://api.github.com/users/daniel-e/gists{/gist_id}
* starred_url : https://api.github.com/users/daniel-e/starred{/owner}{/repo}
* subscriptions_url : https://api.github.com/users/daniel-e/subscriptions
* organizations_url : https://api.github.com/users/daniel-e/orgs
* repos_url : https://api.github.com/users/daniel-e/repos
* events_url : https://api.github.com/users/daniel-e/events{/privacy}
* received_events_url : https://api.github.com/users/daniel-e/received_events
* type : User
* site_admin : false
*/
private String login;
private int id;
private String avatar_url;
private String gravatar_id;
private String url;
private String html_url;
private String followers_url;
private String following_url;
private String gists_url;
private String starred_url;
private String subscriptions_url;
private String organizations_url;
private String repos_url;
private String events_url;
private String received_events_url;
private String type;
private boolean site_admin;
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAvatar_url() {
return avatar_url;
}
public void setAvatar_url(String avatar_url) {
this.avatar_url = avatar_url;
}
public String getGravatar_id() {
return gravatar_id;
}
public void setGravatar_id(String gravatar_id) {
this.gravatar_id = gravatar_id;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getHtml_url() {
return html_url;
}
public void setHtml_url(String html_url) {
this.html_url = html_url;
}
public String getFollowers_url() {
return followers_url;
}
public void setFollowers_url(String followers_url) {
this.followers_url = followers_url;
}
public String getFollowing_url() {
return following_url;
}
public void setFollowing_url(String following_url) {
this.following_url = following_url;
}
public String getGists_url() {
return gists_url;
}
public void setGists_url(String gists_url) {
this.gists_url = gists_url;
}
public String getStarred_url() {
return starred_url;
}
public void setStarred_url(String starred_url) {
this.starred_url = starred_url;
}
public String getSubscriptions_url() {
return subscriptions_url;
}
public void setSubscriptions_url(String subscriptions_url) {
this.subscriptions_url = subscriptions_url;
}
public String getOrganizations_url() {
return organizations_url;
}
public void setOrganizations_url(String organizations_url) {
this.organizations_url = organizations_url;
}
public String getRepos_url() {
return repos_url;
}
public void setRepos_url(String repos_url) {
this.repos_url = repos_url;
}
public String getEvents_url() {
return events_url;
}
public void setEvents_url(String events_url) {
this.events_url = events_url;
}
public String getReceived_events_url() {
return received_events_url;
}
public void setReceived_events_url(String received_events_url) {
this.received_events_url = received_events_url;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public boolean isSite_admin() {
return site_admin;
}
public void setSite_admin(boolean site_admin) {
this.site_admin = site_admin;
}
@Override
public String toString() {
return "ProjectOwner{" +
"login='" + login + '\'' +
", id=" + id +
", avatar_url='" + avatar_url + '\'' +
", gravatar_id='" + gravatar_id + '\'' +
", url='" + url + '\'' +
", html_url='" + html_url + '\'' +
", followers_url='" + followers_url + '\'' +
", following_url='" + following_url + '\'' +
", gists_url='" + gists_url + '\'' +
", starred_url='" + starred_url + '\'' +
", subscriptions_url='" + subscriptions_url + '\'' +
", organizations_url='" + organizations_url + '\'' +
", repos_url='" + repos_url + '\'' +
", events_url='" + events_url + '\'' +
", received_events_url='" + received_events_url + '\'' +
", type='" + type + '\'' +
", site_admin=" + site_admin +
'}';
}
}
package com.mxdl.mvvm.application.f_load_more.common.repository;
import android.arch.lifecycle.LiveData;
import com.mxdl.mvvm.application.f_load_more.common.bean.Lcee;
import com.mxdl.mvvm.application.f_load_more.common.bean.project.Projects;
/**
* Created by mxdl on 2017/10/6.
*/
public interface ProjectDataSource {
LiveData<Lcee<Projects>> queryProjects(int page);
}
package com.mxdl.mvvm.application.f_load_more.common.repository;
import android.arch.lifecycle.LiveData;
import android.content.Context;
import com.mxdl.mvvm.application.f_load_more.common.bean.Lcee;
import com.mxdl.mvvm.application.f_load_more.common.bean.project.Projects;
import com.mxdl.mvvm.application.f_load_more.common.repository.local.LocalProjectDataSource;
import com.mxdl.mvvm.application.f_load_more.common.repository.remote.RemoteProjectDataSource;
import com.mxdl.mvvm.application.f_load_more.common.utils.NetworkUtils;
/**
* Created by mxdl on 2017/10/6.
*/
public class ProjectsRepository {
private static final ProjectsRepository instance = new ProjectsRepository();
private ProjectsRepository() {
}
public static ProjectsRepository getInstance() {
return instance;
}
private Context context;
private ProjectDataSource remoteProjectDataSource = RemoteProjectDataSource.getInstance();
private ProjectDataSource localProjectDataSource = LocalProjectDataSource.getInstance();
public void init(Context context) {
this.context = context.getApplicationContext();
}
public LiveData<Lcee<Projects>> getProjects(int page) {
if (NetworkUtils.isConnected(context)) {
return remoteProjectDataSource.queryProjects(page);
} else {
return localProjectDataSource.queryProjects(page);
}
}
}
package com.mxdl.mvvm.application.f_load_more.common.repository.local.dao;
import android.arch.lifecycle.LiveData;
import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.OnConflictStrategy;
import android.arch.persistence.room.Query;
import com.mxdl.mvvm.application.f_load_more.common.bean.project.Projects;
/**
* Created by mxdl on 2017/10/7.
*/
@Dao
public interface ProjectsDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)// cache need update
Long add(Projects projects);
@Query("select * from projects where page=:page")
LiveData<Projects> queryProjects(int page);
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册