diff --git a/CHANGELOG.md b/CHANGELOG.md
index d95d9f1..e30c163 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,17 +1,37 @@
-## 1.3.1(2017-20-2)
+## 1.4.0(2019-02-13)
+
+- Migrate to AndroidX
+
+## 1.3.5(2018-03-07)
+
+- Updated dependencies (Support library, build tools, Gradle).
+
+## 1.3.4(2017-11-02)
+
+- Update Gradle plugin. Fix Nullable annotation in getBinding().
+
+## 1.3.3(2017-08-21)
+
+- Fix issue where viewmodels with generic types would not work correctly.
+
+## 1.3.2(2017-08-21)
+
+- Updated dependencies (Support library, build tools, gradle)
+
+## 1.3.1(2017-02-20)
- Critical issue fixed that was introduced two days ago in 1.3.0 - please update to 1.3.1 (issue is related to the new getViewOptional() method).
-## 1.3.0(2017-18-2)
+## 1.3.0(2017-02-18)
- Added ``getViewOptional()`` method which is guaranteed to be non-null. It will return a dummy implemenation in case the View is not null.
- Removed the need to override ```getViewModelClass```, the ViewModel class is now automatically extracted from the ViewModel class definition.
-## 1.2.3(2017-4-1)
+## 1.2.3(2017-01-4)
- Fix ProGuard settings.
-## 1.2.2(2017-2-1)
+## 1.2.2(2017-01-02)
- Remove wrong jetbrains annotations import.
diff --git a/README.md b/README.md
index 998dadb..d7dee4a 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,12 @@
AndroidViewModel
================
+Important notice: Deprecated
+--------
+This library served it's purpose for over 3 years. We believe that Google's Android [Architecture Components](https://developer.android.com/topic/libraries/architecture/index.html) are the preferred setup now for new projects.
+[INLOOPX](http://www.inloopx.com) is dedicated to continue maintaining this library (no deadline on support end). So rest assured that your existing projects don't need be migrated from AndroidViewModel because of this deprecation. We are only stopping new feature development and don't recommend using it for new projects.
+
+
Separating data and state handling from Fragments or Activities without lots of boilerplate-code. Reducing them to simple dumb views.
Basic idea behind this library.
@@ -87,7 +93,7 @@ Data binding is supported - extend [ViewModelBaseBindingFragment.java](library/s
``` java
@Override
public ViewModelBindingConfig getViewModelBindingConfig() {
- return new ViewModelBindingConfig(R.layout.fragment_sample_binding, getActivity());
+ return new ViewModelBindingConfig(R.layout.fragment_sample_binding, requireActivity());
}
```
@@ -112,5 +118,26 @@ Download
--------
```groovy
-compile 'eu.inloop:androidviewmodel:1.3.1'
+compile 'eu.inloop:androidviewmodel:1.4.0'
```
+
+## Android Studio Template
+For faster creating new screens, you can use [Android Studio Template](/template/AVM_Inloop)
+
+
+
+### Install template
+#### Manually:
+Copy the template folder to Android Studio templates folder (`/Applications/Android Studio.app/Contents/plugins/android/lib/templates/others` on Mac)
+#### Automatically:
+Run the following command to download and install the template automatically (Mac only)
+```
+curl -o androidviewmodel.zip -Lk https://github.com/inloop/AndroidViewModel/archive/master.zip && unzip androidviewmodel.zip && cp -af AndroidViewModel-master/template/AVM_Inloop/. "/Applications/Android Studio.app/Contents/plugins/android/lib/templates/other/AVM_Inloop" && rm -r AndroidViewModel-master && rm androidviewmodel.zip
+```
+Don't forget to restart the Android Studio.
+
+### Usage
+In the Android Studio right click inside the Projet window and select `File > New > AndroidViewModel Inloop > AVM Fragment`
+
+
+
diff --git a/build.gradle b/build.gradle
index 9b4bc30..51a9613 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,15 +1,17 @@
buildscript {
repositories {
jcenter()
+ google()
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.3.1'
+ classpath 'com.android.tools.build:gradle:3.3.1'
}
}
allprojects {
repositories {
jcenter()
+ google()
}
group = 'eu.inloop'
diff --git a/gradle.properties b/gradle.properties
index 1ae26a3..f9ed904 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -17,4 +17,6 @@
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
-VERSION_NAME=1.3.1
\ No newline at end of file
+android.enableJetifier=true
+android.useAndroidX=true
+VERSION_NAME=1.4.0
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 7379b41..ab096e7 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Mon Mar 13 13:06:15 CET 2017
+#Wed Feb 13 17:35:05 CET 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-3.4-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
diff --git a/library/build.gradle b/library/build.gradle
index 9fc4421..87a4ceb 100644
--- a/library/build.gradle
+++ b/library/build.gradle
@@ -2,30 +2,35 @@ apply plugin: 'com.android.library'
apply plugin: 'maven'
android {
- compileSdkVersion 25
- buildToolsVersion '25.0.2'
+ compileSdkVersion 28
defaultConfig {
minSdkVersion 15
- targetSdkVersion 25
+ targetSdkVersion 28
versionCode 1
versionName VERSION_NAME
consumerProguardFiles 'proguard-rules.pro'
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_7
- targetCompatibility JavaVersion.VERSION_1_7
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
}
buildTypes {
}
dataBinding {
- enabled = true;
+ enabled = true
}
}
dependencies {
- compile 'com.android.support:appcompat-v7:25.3.1'
+ implementation 'androidx.fragment:fragment:1.0.0'
+ implementation 'androidx.appcompat:appcompat:1.0.2'
+
+ androidTestImplementation 'junit:junit:4.12'
+ androidTestImplementation 'androidx.test:runner:1.1.2-alpha01'
+ androidTestImplementation 'androidx.test:rules:1.1.2-alpha01'
}
task androidJavadocs(type: Javadoc) {
diff --git a/library/src/androidTest/AndroidManifest.xml b/library/src/androidTest/AndroidManifest.xml
new file mode 100644
index 0000000..2e06fd1
--- /dev/null
+++ b/library/src/androidTest/AndroidManifest.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
diff --git a/library/src/androidTest/java/eu/inloop/viewmodel/ViewModelActivityTest.java b/library/src/androidTest/java/eu/inloop/viewmodel/ViewModelActivityTest.java
new file mode 100644
index 0000000..15eb73f
--- /dev/null
+++ b/library/src/androidTest/java/eu/inloop/viewmodel/ViewModelActivityTest.java
@@ -0,0 +1,157 @@
+package eu.inloop.viewmodel;
+
+
+import android.content.pm.ActivityInfo;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.MediumTest;
+import androidx.test.filters.SmallTest;
+import androidx.test.rule.ActivityTestRule;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Map;
+
+import eu.inloop.viewmodel.fixture.activity.VMTestActivity;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+
+@RunWith(AndroidJUnit4.class)
+public final class ViewModelActivityTest {
+
+ @Rule
+ public final ActivityTestRule mActivityTestRule =
+ new ActivityTestRule<>(VMTestActivity.class, false, false);
+
+ @SmallTest
+ @Test
+ public void viewModelActivity_onBindView_test() {
+ mActivityTestRule.launchActivity(VMTestActivity.makeIntent(InstrumentationRegistry.getContext(), true));
+
+ assertThat(mActivityTestRule.getActivityResult().getResultCode(), is(VMTestActivity.RESULT_CODE_OK));
+ }
+
+ @SmallTest
+ @Test
+ public void viewModelActivity_getViewModel_getView_test() {
+ mActivityTestRule.launchActivity(VMTestActivity.makeIntent(InstrumentationRegistry.getContext(), false));
+ mActivityTestRule.getActivity().getViewModel().loadData();
+
+ assertThat(mActivityTestRule.getActivityResult().getResultCode(), is(VMTestActivity.RESULT_CODE_OK));
+ }
+
+ @SmallTest
+ @Test
+ public void viewModelActivity_getViewModel_getViewOptional_test() {
+ mActivityTestRule.launchActivity(VMTestActivity.makeIntent(InstrumentationRegistry.getContext(), false));
+ mActivityTestRule.getActivity().getViewModel().loadDataOptional();
+
+ assertThat(mActivityTestRule.getActivityResult().getResultCode(), is(VMTestActivity.RESULT_CODE_OK));
+ }
+
+ @SmallTest
+ @Test
+ public void viewModelActivity_clearView_test() {
+ mActivityTestRule.launchActivity(VMTestActivity.makeIntent(InstrumentationRegistry.getContext(), false));
+ mActivityTestRule.getActivity().getViewModel().clearView();
+
+ assertThat(mActivityTestRule.getActivity().getViewModel().getView(), is(nullValue()));
+ }
+
+ @SmallTest
+ @Test
+ public void viewModelActivity_uniqueIdentifier_test() {
+ mActivityTestRule.launchActivity(VMTestActivity.makeIntent(InstrumentationRegistry.getContext(), false));
+ String uniqueIdentifier = mActivityTestRule.getActivity().getViewModel().getUniqueIdentifier();
+
+ assertThat(uniqueIdentifier, is(notNullValue()));
+ }
+
+ @SmallTest
+ @Test
+ public void viewModelActivity_fragment_getView_test() {
+ mActivityTestRule.launchActivity(VMTestActivity.makeIntent(InstrumentationRegistry.getContext(), false));
+
+ mActivityTestRule.getActivity().getTestFragment().getViewModel().loadData();
+
+ assertThat(mActivityTestRule.getActivityResult().getResultCode(), is(VMTestActivity.RESULT_CODE_OK));
+ }
+
+ @SmallTest
+ @Test
+ public void viewModelActivity_fragment_remove_test() {
+ mActivityTestRule.launchActivity(VMTestActivity.makeIntent(InstrumentationRegistry.getContext(), false));
+
+ String uniqueIdentifierActivity = mActivityTestRule.getActivity().getViewModel().getUniqueIdentifier();
+ String uniqueIdentifierFragment = mActivityTestRule.getActivity().getTestFragment().getViewModel().getUniqueIdentifier();
+
+ Map> viewModels =
+ mActivityTestRule.getActivity().getViewModelProvider().getViewModels();
+
+ assertThat(viewModels.containsKey(uniqueIdentifierActivity), is(true));
+ assertThat(viewModels.containsKey(uniqueIdentifierFragment), is(true));
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ mActivityTestRule.getActivity().removeTestFragment();
+ }
+ });
+
+ //Check If ViewModel is removed after removing fragment
+ viewModels = mActivityTestRule.getActivity().getViewModelProvider().getViewModels();
+
+ assertThat(viewModels.containsKey(uniqueIdentifierActivity), is(true));
+ assertThat(viewModels.containsKey(uniqueIdentifierFragment), is(false));
+ }
+
+ @SmallTest
+ @Test
+ public void viewModelActivity_fragment_model_state_test() {
+ mActivityTestRule.launchActivity(VMTestActivity.makeIntent(InstrumentationRegistry.getContext(), false));
+
+ final int stateValue = 1;
+ mActivityTestRule.getActivity().getTestFragment().getViewModel().setStateValue(stateValue);
+
+ rotateScreen(1);
+
+ int actualStateValue = mActivityTestRule.getActivity().getTestFragment().getViewModel().getStateValue();
+
+ assertThat(stateValue, is(actualStateValue));
+ }
+
+ @MediumTest
+ @Test
+ public void viewModelActivity_instance_count_test() {
+ mActivityTestRule.launchActivity(VMTestActivity.makeIntent(InstrumentationRegistry.getContext(), false));
+
+ String uniqueIdentifierActivity = mActivityTestRule.getActivity().getViewModel().getUniqueIdentifier();
+ String uniqueIdentifierFragment = mActivityTestRule.getActivity().getTestFragment().getViewModel().getUniqueIdentifier();
+
+ rotateScreen(5);
+
+ Map> viewModels =
+ mActivityTestRule.getActivity().getViewModelProvider().getViewModels();
+
+ assertThat(viewModels.size(), is(2)); //activity + fragment
+
+ assertThat(viewModels.containsKey(uniqueIdentifierActivity), is(true));
+ assertThat(viewModels.containsKey(uniqueIdentifierFragment), is(true));
+ }
+
+ private void rotateScreen(int numOfTimes) {
+ for (int i = 0; i < numOfTimes; i++) {
+ mActivityTestRule.getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ mActivityTestRule.getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ }
+ }
+
+}
diff --git a/library/src/androidTest/java/eu/inloop/viewmodel/fixture/activity/IVMTestActivityView.java b/library/src/androidTest/java/eu/inloop/viewmodel/fixture/activity/IVMTestActivityView.java
new file mode 100644
index 0000000..0d8b0d9
--- /dev/null
+++ b/library/src/androidTest/java/eu/inloop/viewmodel/fixture/activity/IVMTestActivityView.java
@@ -0,0 +1,9 @@
+package eu.inloop.viewmodel.fixture.activity;
+
+import eu.inloop.viewmodel.IView;
+
+public interface IVMTestActivityView extends IView {
+
+ void onLoadData(boolean loaded);
+
+}
diff --git a/library/src/androidTest/java/eu/inloop/viewmodel/fixture/activity/VMTestActivity.java b/library/src/androidTest/java/eu/inloop/viewmodel/fixture/activity/VMTestActivity.java
new file mode 100644
index 0000000..5e828f3
--- /dev/null
+++ b/library/src/androidTest/java/eu/inloop/viewmodel/fixture/activity/VMTestActivity.java
@@ -0,0 +1,72 @@
+package eu.inloop.viewmodel.fixture.activity;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import android.widget.LinearLayout;
+
+import eu.inloop.viewmodel.base.ViewModelBaseActivity;
+import eu.inloop.viewmodel.fixture.fragment.VMTestFragment;
+
+public class VMTestActivity extends ViewModelBaseActivity implements IVMTestActivityView {
+
+ public static final int RESULT_CODE_OK = 1;
+ public static final String EXTRA_CALL_ON_BIND = "EXTRA_CALL_ON_BIND";
+
+ @NonNull
+ public static Intent makeIntent(@NonNull Context context, boolean callOnBindModel) {
+ Intent intent = new Intent(context, VMTestActivity.class);
+ intent.putExtra(EXTRA_CALL_ON_BIND, callOnBindModel);
+
+ return intent;
+ }
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ LinearLayout view = new LinearLayout(this);
+ view.setId(android.R.id.content);
+ setContentView(view);
+
+ if (savedInstanceState == null) {
+ addTestFragment();
+ }
+
+ setModelView(this);
+ }
+
+ public void addTestFragment() {
+ getSupportFragmentManager()
+ .beginTransaction()
+ .add(android.R.id.content, new VMTestFragment())
+ .commitNow();
+ }
+
+ public void removeTestFragment() {
+ getSupportFragmentManager()
+ .beginTransaction()
+ .remove(getTestFragment())
+ .commitNow();
+ }
+
+ @NonNull
+ public VMTestFragment getTestFragment() {
+ for (Fragment fragment : getSupportFragmentManager().getFragments()) {
+ if (fragment instanceof VMTestFragment) {
+ return (VMTestFragment) fragment;
+ }
+ }
+ throw new AssertionError("Fragment not found");
+ }
+
+ @Override
+ public void onLoadData(boolean loaded) {
+ setResult(RESULT_CODE_OK);
+ finish();
+ }
+
+}
diff --git a/library/src/androidTest/java/eu/inloop/viewmodel/fixture/activity/VMTestActivityViewModel.java b/library/src/androidTest/java/eu/inloop/viewmodel/fixture/activity/VMTestActivityViewModel.java
new file mode 100644
index 0000000..129d230
--- /dev/null
+++ b/library/src/androidTest/java/eu/inloop/viewmodel/fixture/activity/VMTestActivityViewModel.java
@@ -0,0 +1,39 @@
+package eu.inloop.viewmodel.fixture.activity;
+
+import android.os.Bundle;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import eu.inloop.viewmodel.AbstractViewModel;
+
+public class VMTestActivityViewModel extends AbstractViewModel {
+
+ private boolean mCallOnBind;
+
+ @Override
+ public void onCreate(@Nullable Bundle arguments, @Nullable Bundle savedInstanceState) {
+ super.onCreate(arguments, savedInstanceState);
+ if (arguments == null) {
+ throw new AssertionError("Arguments must be set for this ViewModel");
+ }
+ mCallOnBind = arguments.getBoolean(VMTestActivity.EXTRA_CALL_ON_BIND);
+ }
+
+ @Override
+ public void onBindView(@NonNull IVMTestActivityView view) {
+ super.onBindView(view);
+
+ if (mCallOnBind) {
+ loadData();
+ }
+ }
+
+ public void loadData() {
+ getView().onLoadData(true);
+ }
+
+ public void loadDataOptional() {
+ getViewOptional().onLoadData(true);
+ }
+
+}
diff --git a/library/src/androidTest/java/eu/inloop/viewmodel/fixture/fragment/IVMTestFragmentView.java b/library/src/androidTest/java/eu/inloop/viewmodel/fixture/fragment/IVMTestFragmentView.java
new file mode 100644
index 0000000..f8844d4
--- /dev/null
+++ b/library/src/androidTest/java/eu/inloop/viewmodel/fixture/fragment/IVMTestFragmentView.java
@@ -0,0 +1,9 @@
+package eu.inloop.viewmodel.fixture.fragment;
+
+import eu.inloop.viewmodel.IView;
+
+public interface IVMTestFragmentView extends IView {
+
+ void onLoadData(boolean loaded);
+
+}
diff --git a/library/src/androidTest/java/eu/inloop/viewmodel/fixture/fragment/VMTestFragment.java b/library/src/androidTest/java/eu/inloop/viewmodel/fixture/fragment/VMTestFragment.java
new file mode 100644
index 0000000..ca603af
--- /dev/null
+++ b/library/src/androidTest/java/eu/inloop/viewmodel/fixture/fragment/VMTestFragment.java
@@ -0,0 +1,34 @@
+package eu.inloop.viewmodel.fixture.fragment;
+
+import android.os.Bundle;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+
+import eu.inloop.viewmodel.base.ViewModelBaseFragment;
+import eu.inloop.viewmodel.fixture.activity.VMTestActivity;
+
+public class VMTestFragment extends ViewModelBaseFragment
+ implements IVMTestFragmentView {
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ return new LinearLayout(getContext());
+ }
+
+ @Override
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ setModelView(this);
+ }
+
+ @Override
+ public void onLoadData(boolean loaded) {
+ requireActivity().setResult(VMTestActivity.RESULT_CODE_OK);
+ requireActivity().finish();
+ }
+}
diff --git a/library/src/androidTest/java/eu/inloop/viewmodel/fixture/fragment/VMTestFragmentViewModel.java b/library/src/androidTest/java/eu/inloop/viewmodel/fixture/fragment/VMTestFragmentViewModel.java
new file mode 100644
index 0000000..e8710d7
--- /dev/null
+++ b/library/src/androidTest/java/eu/inloop/viewmodel/fixture/fragment/VMTestFragmentViewModel.java
@@ -0,0 +1,42 @@
+package eu.inloop.viewmodel.fixture.fragment;
+
+import android.os.Bundle;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import eu.inloop.viewmodel.AbstractViewModel;
+
+public class VMTestFragmentViewModel extends AbstractViewModel {
+
+ private static final String STATE_INT = "STATE_INT";
+
+ private int mStateValue;
+
+ @Override
+ public void onCreate(@Nullable Bundle arguments, @Nullable Bundle savedInstanceState) {
+ super.onCreate(arguments, savedInstanceState);
+
+ if (savedInstanceState != null) {
+ mStateValue = savedInstanceState.getInt(STATE_INT);
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(@NonNull Bundle bundle) {
+ super.onSaveInstanceState(bundle);
+ bundle.putInt(STATE_INT, mStateValue);
+ }
+
+ public void setStateValue(int value) {
+ mStateValue = value;
+ }
+
+ public int getStateValue() {
+ return mStateValue;
+ }
+
+ public void loadData() {
+ getView().onLoadData(true);
+ }
+
+}
diff --git a/library/src/androidTest/java/sample/viewmodel/inloop/eu/viewmodelsample/ApplicationTest.java b/library/src/androidTest/java/sample/viewmodel/inloop/eu/viewmodelsample/ApplicationTest.java
deleted file mode 100644
index 3844758..0000000
--- a/library/src/androidTest/java/sample/viewmodel/inloop/eu/viewmodelsample/ApplicationTest.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package sample.viewmodel.inloop.eu.viewmodelsample;
-
-import android.app.Application;
-import android.test.ApplicationTestCase;
-
-/**
- * Testing Fundamentals
- */
-public class ApplicationTest extends ApplicationTestCase {
- public ApplicationTest() {
- super(Application.class);
- }
-}
\ No newline at end of file
diff --git a/library/src/main/java/eu/inloop/viewmodel/AbstractViewModel.java b/library/src/main/java/eu/inloop/viewmodel/AbstractViewModel.java
index aada88b..560b4c3 100644
--- a/library/src/main/java/eu/inloop/viewmodel/AbstractViewModel.java
+++ b/library/src/main/java/eu/inloop/viewmodel/AbstractViewModel.java
@@ -3,11 +3,11 @@
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
-import android.support.annotation.CallSuper;
-import android.support.annotation.CheckResult;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
+import androidx.annotation.CallSuper;
+import androidx.annotation.CheckResult;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
import android.util.Log;
import android.view.View;
diff --git a/library/src/main/java/eu/inloop/viewmodel/IView.java b/library/src/main/java/eu/inloop/viewmodel/IView.java
index dee387c..7bd2054 100644
--- a/library/src/main/java/eu/inloop/viewmodel/IView.java
+++ b/library/src/main/java/eu/inloop/viewmodel/IView.java
@@ -1,7 +1,7 @@
package eu.inloop.viewmodel;
import android.app.Activity;
-import android.support.annotation.Nullable;
+import androidx.annotation.Nullable;
import eu.inloop.viewmodel.base.ViewModelBaseActivity;
import eu.inloop.viewmodel.base.ViewModelBaseFragment;
diff --git a/library/src/main/java/eu/inloop/viewmodel/IViewModelProvider.java b/library/src/main/java/eu/inloop/viewmodel/IViewModelProvider.java
index 70e4555..76db555 100644
--- a/library/src/main/java/eu/inloop/viewmodel/IViewModelProvider.java
+++ b/library/src/main/java/eu/inloop/viewmodel/IViewModelProvider.java
@@ -1,6 +1,6 @@
package eu.inloop.viewmodel;
-import android.support.annotation.Nullable;
+import androidx.annotation.Nullable;
/**
* Your {@link android.app.Activity} must implement this interface if
diff --git a/library/src/main/java/eu/inloop/viewmodel/ProxyViewHelper.java b/library/src/main/java/eu/inloop/viewmodel/ProxyViewHelper.java
index ffa6b66..94d8ec4 100644
--- a/library/src/main/java/eu/inloop/viewmodel/ProxyViewHelper.java
+++ b/library/src/main/java/eu/inloop/viewmodel/ProxyViewHelper.java
@@ -1,11 +1,10 @@
package eu.inloop.viewmodel;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
@@ -34,6 +33,9 @@ public static Class> getGenericType(@NonNull Class> in, @NonNull Class> wh
if (genericSuperclass instanceof ParameterizedType) {
final Type[] typeArgs = ((ParameterizedType) genericSuperclass).getActualTypeArguments();
for (Type arg : typeArgs) {
+ if (arg instanceof ParameterizedType) {
+ arg = ((ParameterizedType) arg).getRawType();
+ }
if (arg instanceof Class>) {
final Class> argClass = (Class>) arg;
if (whichExtends.isAssignableFrom(argClass)) {
@@ -45,11 +47,6 @@ public static Class> getGenericType(@NonNull Class> in, @NonNull Class> wh
return null;
}
- private static final InvocationHandler sInvocationHandler = new InvocationHandler() {
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- return null;
- }
- };
+ private static final InvocationHandler sInvocationHandler = (proxy, method, args) -> null;
}
diff --git a/library/src/main/java/eu/inloop/viewmodel/ViewModelHelper.java b/library/src/main/java/eu/inloop/viewmodel/ViewModelHelper.java
index 48b9844..b00234d 100644
--- a/library/src/main/java/eu/inloop/viewmodel/ViewModelHelper.java
+++ b/library/src/main/java/eu/inloop/viewmodel/ViewModelHelper.java
@@ -2,12 +2,12 @@
import android.app.Activity;
import android.content.Intent;
-import android.databinding.DataBindingUtil;
-import android.databinding.ViewDataBinding;
+import androidx.databinding.DataBindingUtil;
+import androidx.databinding.ViewDataBinding;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
@@ -34,7 +34,7 @@ public class ViewModelHelper> {
/**
* Call from {@link android.app.Activity#onCreate(android.os.Bundle)} or
- * {@link android.support.v4.app.Fragment#onCreate(android.os.Bundle)}
+ * {@link androidx.core.app.Fragment#onCreate(android.os.Bundle)}
*
* @param activity parent activity
* @param savedInstanceState savedInstance state from {@link Activity#onCreate(Bundle)} or
@@ -86,7 +86,7 @@ public void onCreate(@NonNull Activity activity,
}
/**
- * Call from {@link android.support.v4.app.Fragment#onViewCreated(android.view.View, android.os.Bundle)}
+ * Call from {@link androidx.core.app.Fragment#onViewCreated(android.view.View, android.os.Bundle)}
* or {@link android.app.Activity#onCreate(android.os.Bundle)}
*
* @param view view
@@ -133,8 +133,8 @@ public void performBinding(@NonNull final IView bindingView) {
}
/**
- * Use in case this model is associated with an {@link android.support.v4.app.Fragment}
- * Call from {@link android.support.v4.app.Fragment#onDestroyView()}. Use in case model is associated
+ * Use in case this model is associated with an {@link androidx.core.app.Fragment}
+ * Call from {@link androidx.core.app.Fragment#onDestroyView()}. Use in case model is associated
* with Fragment
*
* @param fragment fragment
@@ -152,8 +152,8 @@ public void onDestroyView(@NonNull Fragment fragment) {
}
/**
- * Use in case this model is associated with an {@link android.support.v4.app.Fragment}
- * Call from {@link android.support.v4.app.Fragment#onDestroy()}
+ * Use in case this model is associated with an {@link androidx.core.app.Fragment}
+ * Call from {@link androidx.core.app.Fragment#onDestroy()}
*
* @param fragment fragment
*/
@@ -162,15 +162,15 @@ public void onDestroy(@NonNull final Fragment fragment) {
//no viewmodel for this fragment
return;
}
- if (fragment.getActivity().isFinishing()) {
- removeViewModel(fragment.getActivity());
+ if (fragment.requireActivity().isFinishing()) {
+ removeViewModel(fragment.requireActivity());
} else if (fragment.isRemoving() && !mOnSaveInstanceCalled) {
// The fragment can be still in backstack even if isRemoving() is true.
// We check mOnSaveInstanceCalled - if this was not called then the fragment is totally removed.
if (BuildConfig.DEBUG) {
Log.d("mode", "Removing viewmodel - fragment replaced"); //NON-NLS
}
- removeViewModel(fragment.getActivity());
+ removeViewModel(fragment.requireActivity());
}
mBinding = null;
}
@@ -194,7 +194,7 @@ public void onDestroy(@NonNull final Activity activity) {
}
/**
- * Call from {@link android.app.Activity#onStop()} or {@link android.support.v4.app.Fragment#onStop()}
+ * Call from {@link android.app.Activity#onStop()} or {@link androidx.core.app.Fragment#onStop()}
*/
public void onStop() {
if (mViewModel == null) {
@@ -205,7 +205,7 @@ public void onStop() {
}
/**
- * Call from {@link android.app.Activity#onStart()} ()} or {@link android.support.v4.app.Fragment#onStart()} ()}
+ * Call from {@link android.app.Activity#onStart()} ()} or {@link androidx.core.app.Fragment#onStart()} ()}
*/
public void onStart() {
if (mViewModel == null) {
@@ -234,7 +234,7 @@ public R getViewModel() {
/**
* Call from {@link android.app.Activity#onSaveInstanceState(android.os.Bundle)}
- * or {@link android.support.v4.app.Fragment#onSaveInstanceState(android.os.Bundle)}.
+ * or {@link androidx.core.app.Fragment#onSaveInstanceState(android.os.Bundle)}.
* This allows the model to save its state.
*
* @param bundle bundle
diff --git a/library/src/main/java/eu/inloop/viewmodel/ViewModelProvider.java b/library/src/main/java/eu/inloop/viewmodel/ViewModelProvider.java
index c541de4..ab07ecb 100644
--- a/library/src/main/java/eu/inloop/viewmodel/ViewModelProvider.java
+++ b/library/src/main/java/eu/inloop/viewmodel/ViewModelProvider.java
@@ -1,15 +1,18 @@
package eu.inloop.viewmodel;
import android.app.Activity;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v4.app.FragmentActivity;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.fragment.app.FragmentActivity;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.Map;
/**
* Create and keep this class inside your Activity. Store it
- * in {@link android.support.v4.app.FragmentActivity#onRetainCustomNonConfigurationInstance()
- * and restore in {@link android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle)} before
+ * in {@link androidx.core.app.FragmentActivity#onRetainCustomNonConfigurationInstance()
+ * and restore in {@link androidx.core.app.FragmentActivity#onCreate(android.os.Bundle)} before
* calling the super implemenentation.
*/
public class ViewModelProvider {
@@ -49,6 +52,12 @@ public synchronized void removeAllViewModels() {
mViewModelCache.clear();
}
+ @VisibleForTesting
+ @NonNull
+ Map> getViewModels() {
+ return Collections.unmodifiableMap(mViewModelCache);
+ }
+
@SuppressWarnings("unchecked")
@NonNull
public synchronized ViewModelWrapper getViewModel(@NonNull final String modelIdentifier,
diff --git a/library/src/main/java/eu/inloop/viewmodel/base/ViewModelBaseActivity.java b/library/src/main/java/eu/inloop/viewmodel/base/ViewModelBaseActivity.java
index 2a7dc47..f7b895a 100644
--- a/library/src/main/java/eu/inloop/viewmodel/base/ViewModelBaseActivity.java
+++ b/library/src/main/java/eu/inloop/viewmodel/base/ViewModelBaseActivity.java
@@ -1,9 +1,9 @@
package eu.inloop.viewmodel.base;
import android.os.Bundle;
-import android.support.annotation.CallSuper;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
+import androidx.annotation.CallSuper;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import eu.inloop.viewmodel.AbstractViewModel;
import eu.inloop.viewmodel.IView;
diff --git a/library/src/main/java/eu/inloop/viewmodel/base/ViewModelBaseEmptyActivity.java b/library/src/main/java/eu/inloop/viewmodel/base/ViewModelBaseEmptyActivity.java
index 35ebd20..f98db59 100644
--- a/library/src/main/java/eu/inloop/viewmodel/base/ViewModelBaseEmptyActivity.java
+++ b/library/src/main/java/eu/inloop/viewmodel/base/ViewModelBaseEmptyActivity.java
@@ -1,9 +1,9 @@
package eu.inloop.viewmodel.base;
import android.os.Bundle;
-import android.support.annotation.CallSuper;
-import android.support.annotation.Nullable;
-import android.support.v7.app.AppCompatActivity;
+import androidx.annotation.CallSuper;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
import eu.inloop.viewmodel.IViewModelProvider;
import eu.inloop.viewmodel.ViewModelProvider;
diff --git a/library/src/main/java/eu/inloop/viewmodel/base/ViewModelBaseFragment.java b/library/src/main/java/eu/inloop/viewmodel/base/ViewModelBaseFragment.java
index d198615..19d57b9 100644
--- a/library/src/main/java/eu/inloop/viewmodel/base/ViewModelBaseFragment.java
+++ b/library/src/main/java/eu/inloop/viewmodel/base/ViewModelBaseFragment.java
@@ -1,10 +1,10 @@
package eu.inloop.viewmodel.base;
import android.os.Bundle;
-import android.support.annotation.CallSuper;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
+import androidx.annotation.CallSuper;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
import android.view.View;
import eu.inloop.viewmodel.AbstractViewModel;
@@ -29,7 +29,7 @@ public void onCreate(@Nullable final Bundle savedInstanceState) {
//noinspection unchecked
viewModelClass = (Class extends AbstractViewModel>) ProxyViewHelper.getGenericType(getClass(), AbstractViewModel.class);
}
- getViewModelHelper().onCreate(getActivity(), savedInstanceState, viewModelClass, getArguments());
+ getViewModelHelper().onCreate(requireActivity(), savedInstanceState, viewModelClass, getArguments());
}
@CallSuper
@@ -94,7 +94,7 @@ public ViewModelHelper getViewModelHelper() {
@Override
public void removeViewModel() {
- mViewModelHelper.removeViewModel(getActivity());
+ mViewModelHelper.removeViewModel(requireActivity());
}
/**
diff --git a/library/src/main/java/eu/inloop/viewmodel/binding/ViewModelBaseBindingFragment.java b/library/src/main/java/eu/inloop/viewmodel/binding/ViewModelBaseBindingFragment.java
index 4e2c4fd..4fabe9e 100644
--- a/library/src/main/java/eu/inloop/viewmodel/binding/ViewModelBaseBindingFragment.java
+++ b/library/src/main/java/eu/inloop/viewmodel/binding/ViewModelBaseBindingFragment.java
@@ -1,13 +1,13 @@
package eu.inloop.viewmodel.binding;
-import android.databinding.ViewDataBinding;
+import androidx.databinding.ViewDataBinding;
import android.os.Bundle;
-import android.support.annotation.Nullable;
+import androidx.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
import eu.inloop.viewmodel.AbstractViewModel;
import eu.inloop.viewmodel.IView;
@@ -25,7 +25,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) {
@Nullable
@Override
- public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
getViewModelHelper().performBinding(this);
final ViewDataBinding binding = getViewModelHelper().getBinding();
if (binding != null) {
@@ -36,7 +36,7 @@ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
}
@SuppressWarnings("unused")
- @NonNull
+ @Nullable
public B getBinding() {
try {
return (B) getViewModelHelper().getBinding();
diff --git a/library/src/main/java/eu/inloop/viewmodel/binding/ViewModelBindingConfig.java b/library/src/main/java/eu/inloop/viewmodel/binding/ViewModelBindingConfig.java
index d008c47..4cb750c 100644
--- a/library/src/main/java/eu/inloop/viewmodel/binding/ViewModelBindingConfig.java
+++ b/library/src/main/java/eu/inloop/viewmodel/binding/ViewModelBindingConfig.java
@@ -1,8 +1,8 @@
package eu.inloop.viewmodel.binding;
import android.content.Context;
-import android.support.annotation.LayoutRes;
-import android.support.annotation.NonNull;
+import androidx.annotation.LayoutRes;
+import androidx.annotation.NonNull;
import eu.inloop.viewmodel.BR;
diff --git a/library/src/main/java/eu/inloop/viewmodel/support/ViewModelStatePagerAdapter.java b/library/src/main/java/eu/inloop/viewmodel/support/ViewModelStatePagerAdapter.java
index 4254e7a..c632fac 100644
--- a/library/src/main/java/eu/inloop/viewmodel/support/ViewModelStatePagerAdapter.java
+++ b/library/src/main/java/eu/inloop/viewmodel/support/ViewModelStatePagerAdapter.java
@@ -1,9 +1,9 @@
package eu.inloop.viewmodel.support;
-import android.support.annotation.NonNull;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentStatePagerAdapter;
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentStatePagerAdapter;
import android.util.Log;
import android.view.ViewGroup;
diff --git a/sample/build.gradle b/sample/build.gradle
index 75382a5..228c3a8 100644
--- a/sample/build.gradle
+++ b/sample/build.gradle
@@ -1,21 +1,20 @@
apply plugin: 'com.android.application'
android {
- compileSdkVersion 25
- buildToolsVersion '25.0.2'
+ compileSdkVersion 28
defaultConfig {
applicationId 'eu.inloop.viewmodel.sample'
minSdkVersion 15
- targetSdkVersion 25
+ targetSdkVersion 28
versionCode 1
versionName '1.0'
}
compileOptions {
encoding "UTF-8"
- sourceCompatibility JavaVersion.VERSION_1_7
- targetCompatibility JavaVersion.VERSION_1_7
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
}
buildTypes {
release {
@@ -25,14 +24,17 @@ android {
}
dataBinding {
- enabled = true;
+ enabled = true
}
}
dependencies {
- compile 'com.android.support:appcompat-v7:25.3.1'
- debugCompile 'com.squareup.leakcanary:leakcanary-android:1.4'
- releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4'
- compile 'com.jakewharton:butterknife:5.1.2'
- compile project(':library')
+ implementation 'androidx.fragment:fragment:1.0.0'
+ implementation 'androidx.appcompat:appcompat:1.0.2'
+
+ debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.5.1'
+ releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
+ implementation 'com.jakewharton:butterknife:10.0.0'
+ annotationProcessor 'com.jakewharton:butterknife-compiler:10.0.0'
+ implementation project(':library')
}
diff --git a/sample/src/main/java/eu/inloop/viewmodel/sample/activity/MainActivity.java b/sample/src/main/java/eu/inloop/viewmodel/sample/activity/MainActivity.java
index 60cf1b5..5d4ed8a 100644
--- a/sample/src/main/java/eu/inloop/viewmodel/sample/activity/MainActivity.java
+++ b/sample/src/main/java/eu/inloop/viewmodel/sample/activity/MainActivity.java
@@ -14,7 +14,7 @@ public class MainActivity extends ViewModelBaseEmptyActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
- ButterKnife.inject(this);
+ ButterKnife.bind(this);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().replace(R.id.root_content, new UserListFragment(), "user-list-fragment").commit();
diff --git a/sample/src/main/java/eu/inloop/viewmodel/sample/activity/SampleBindingActivity.java b/sample/src/main/java/eu/inloop/viewmodel/sample/activity/SampleBindingActivity.java
index 02226be..2967890 100644
--- a/sample/src/main/java/eu/inloop/viewmodel/sample/activity/SampleBindingActivity.java
+++ b/sample/src/main/java/eu/inloop/viewmodel/sample/activity/SampleBindingActivity.java
@@ -19,7 +19,7 @@ public static Intent newIntent(Context context) {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
- ButterKnife.inject(this);
+ ButterKnife.bind(this);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().replace(R.id.root_content, new SampleBindingFragment(), "sample-binding-fragment").commit();
diff --git a/sample/src/main/java/eu/inloop/viewmodel/sample/activity/ViewPagerActivity.java b/sample/src/main/java/eu/inloop/viewmodel/sample/activity/ViewPagerActivity.java
index 3027c8e..2e56405 100644
--- a/sample/src/main/java/eu/inloop/viewmodel/sample/activity/ViewPagerActivity.java
+++ b/sample/src/main/java/eu/inloop/viewmodel/sample/activity/ViewPagerActivity.java
@@ -1,10 +1,13 @@
package eu.inloop.viewmodel.sample.activity;
import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.view.ViewPager;
+
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.viewpager.widget.ViewPager;
+import butterknife.BindView;
+import butterknife.ButterKnife;
import eu.inloop.viewmodel.base.ViewModelBaseEmptyActivity;
import eu.inloop.viewmodel.sample.R;
import eu.inloop.viewmodel.sample.fragment.PagerFragment;
@@ -12,13 +15,15 @@
public class ViewPagerActivity extends ViewModelBaseEmptyActivity {
+ @BindView(R.id.pager)
+ ViewPager mViewPager;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pager);
-
- final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
- viewPager.setAdapter(new TestPagerAdapter(getSupportFragmentManager()));
+ ButterKnife.bind(this);
+ mViewPager.setAdapter(new TestPagerAdapter(getSupportFragmentManager()));
}
private final static class TestPagerAdapter extends ViewModelStatePagerAdapter {
diff --git a/sample/src/main/java/eu/inloop/viewmodel/sample/fragment/PagerFragment.java b/sample/src/main/java/eu/inloop/viewmodel/sample/fragment/PagerFragment.java
index 8eedea9..daf7d60 100644
--- a/sample/src/main/java/eu/inloop/viewmodel/sample/fragment/PagerFragment.java
+++ b/sample/src/main/java/eu/inloop/viewmodel/sample/fragment/PagerFragment.java
@@ -1,7 +1,8 @@
package eu.inloop.viewmodel.sample.fragment;
import android.os.Bundle;
-import android.support.annotation.Nullable;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -10,7 +11,6 @@
import com.squareup.leakcanary.RefWatcher;
import eu.inloop.viewmodel.base.ViewModelBaseFragment;
-import eu.inloop.viewmodel.binding.ViewModelBindingConfig;
import eu.inloop.viewmodel.sample.R;
import eu.inloop.viewmodel.sample.SampleApplication;
import eu.inloop.viewmodel.sample.viewmodel.PageModel;
@@ -28,12 +28,12 @@ public static PagerFragment newInstance(int position) {
@Nullable
@Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_pager, container, false);
}
@Override
- public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
((TextView)view.findViewById(R.id.text)).setText(Integer.toString(getArguments().getInt("position")));
setModelView(this);
@@ -44,7 +44,7 @@ public void onDestroy() {
super.onDestroy();
// watch for memory leaks
- RefWatcher refWatcher = SampleApplication.getRefWatcher(getActivity());
+ RefWatcher refWatcher = SampleApplication.getRefWatcher(requireActivity());
refWatcher.watch(this);
}
}
diff --git a/sample/src/main/java/eu/inloop/viewmodel/sample/fragment/SampleBindingFragment.java b/sample/src/main/java/eu/inloop/viewmodel/sample/fragment/SampleBindingFragment.java
index 6aad23b..934666f 100644
--- a/sample/src/main/java/eu/inloop/viewmodel/sample/fragment/SampleBindingFragment.java
+++ b/sample/src/main/java/eu/inloop/viewmodel/sample/fragment/SampleBindingFragment.java
@@ -1,10 +1,11 @@
package eu.inloop.viewmodel.sample.fragment;
import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import android.view.View;
+import androidx.fragment.app.Fragment;
import eu.inloop.viewmodel.binding.ViewModelBaseBindingFragment;
import eu.inloop.viewmodel.binding.ViewModelBindingConfig;
import eu.inloop.viewmodel.sample.R;
@@ -24,13 +25,13 @@ public SampleBindingFragment() {
}
@Override
- public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setModelView(this);
}
@Override
public ViewModelBindingConfig getViewModelBindingConfig() {
- return new ViewModelBindingConfig(R.layout.fragment_sample_binding, getActivity());
+ return new ViewModelBindingConfig(R.layout.fragment_sample_binding, requireActivity());
}
}
diff --git a/sample/src/main/java/eu/inloop/viewmodel/sample/fragment/SampleBundleFragment.java b/sample/src/main/java/eu/inloop/viewmodel/sample/fragment/SampleBundleFragment.java
index 055026a..031a285 100644
--- a/sample/src/main/java/eu/inloop/viewmodel/sample/fragment/SampleBundleFragment.java
+++ b/sample/src/main/java/eu/inloop/viewmodel/sample/fragment/SampleBundleFragment.java
@@ -1,7 +1,7 @@
package eu.inloop.viewmodel.sample.fragment;
import android.os.Bundle;
-import android.support.annotation.Nullable;
+import androidx.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -9,7 +9,6 @@
import butterknife.ButterKnife;
import eu.inloop.viewmodel.IView;
import eu.inloop.viewmodel.base.ViewModelBaseFragment;
-import eu.inloop.viewmodel.binding.ViewModelBindingConfig;
import eu.inloop.viewmodel.sample.R;
import eu.inloop.viewmodel.sample.viewmodel.SampleArgumentViewModel;
@@ -33,7 +32,7 @@ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
- ButterKnife.inject(this, view);
+ ButterKnife.bind(this, view);
setModelView(this);
}
}
diff --git a/sample/src/main/java/eu/inloop/viewmodel/sample/fragment/UserListFragment.java b/sample/src/main/java/eu/inloop/viewmodel/sample/fragment/UserListFragment.java
index 39a6055..d415492 100644
--- a/sample/src/main/java/eu/inloop/viewmodel/sample/fragment/UserListFragment.java
+++ b/sample/src/main/java/eu/inloop/viewmodel/sample/fragment/UserListFragment.java
@@ -2,7 +2,8 @@
import android.content.Intent;
import android.os.Bundle;
-import android.support.annotation.Nullable;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -17,10 +18,9 @@
import java.util.ArrayList;
import java.util.List;
+import butterknife.BindView;
import butterknife.ButterKnife;
-import butterknife.InjectView;
import eu.inloop.viewmodel.base.ViewModelBaseFragment;
-import eu.inloop.viewmodel.binding.ViewModelBindingConfig;
import eu.inloop.viewmodel.sample.R;
import eu.inloop.viewmodel.sample.SampleApplication;
import eu.inloop.viewmodel.sample.activity.SampleBindingActivity;
@@ -30,13 +30,13 @@
public class UserListFragment extends ViewModelBaseFragment implements IUserListView {
- @InjectView(android.R.id.progress)
+ @BindView(android.R.id.progress)
View mProgressView;
- @InjectView(R.id.progress_text)
+ @BindView(R.id.progress_text)
TextView mProgressText;
- @InjectView(android.R.id.list)
+ @BindView(android.R.id.list)
ListView mListview;
- @InjectView(R.id.open_binding_fragment)
+ @BindView(R.id.open_binding_fragment)
Button mOpenBindingFragment;
private ArrayAdapter mAdapter;
@@ -44,46 +44,46 @@ public class UserListFragment extends ViewModelBaseFragment(getActivity(), android.R.layout.simple_list_item_1, android.R.id.text1, new ArrayList());
+ mAdapter = new ArrayAdapter<>(requireActivity(), android.R.layout.simple_list_item_1, android.R.id.text1, new ArrayList());
}
@Override
- public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_userlist, container, false);
- ButterKnife.inject(this, view);
+ ButterKnife.bind(this, view);
final View headerView = inflater.inflate(R.layout.view_header_info, null, false);
headerView.findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- getFragmentManager().beginTransaction().replace(R.id.root_content, SampleBundleFragment.newInstance(1234), "empty-fragment").addToBackStack(null).commit();
+ requireFragmentManager().beginTransaction().replace(R.id.root_content, SampleBundleFragment.newInstance(1234), "empty-fragment").addToBackStack(null).commit();
}
});
headerView.findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- getActivity().finish();
- getActivity().startActivity(getActivity().getIntent());
+ requireActivity().finish();
+ requireActivity().startActivity(requireActivity().getIntent());
}
});
headerView.findViewById(R.id.button3).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- startActivity(new Intent(getContext(), ViewPagerActivity.class));
+ startActivity(new Intent(requireContext(), ViewPagerActivity.class));
}
});
mListview.addHeaderView(headerView, null, false);
mOpenBindingFragment.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- startActivity(SampleBindingActivity.newIntent(getActivity()));
+ startActivity(SampleBindingActivity.newIntent(requireActivity()));
}
});
return view;
}
@Override
- public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mListview.setAdapter(mAdapter);
mListview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@@ -120,7 +120,7 @@ public void onDestroy() {
super.onDestroy();
// watch for memory leaks
- RefWatcher refWatcher = SampleApplication.getRefWatcher(getActivity());
+ RefWatcher refWatcher = SampleApplication.getRefWatcher(requireActivity());
refWatcher.watch(this);
}
}
diff --git a/sample/src/main/java/eu/inloop/viewmodel/sample/viewmodel/PageModel.java b/sample/src/main/java/eu/inloop/viewmodel/sample/viewmodel/PageModel.java
index 69d4a9e..a238f1e 100644
--- a/sample/src/main/java/eu/inloop/viewmodel/sample/viewmodel/PageModel.java
+++ b/sample/src/main/java/eu/inloop/viewmodel/sample/viewmodel/PageModel.java
@@ -1,7 +1,7 @@
package eu.inloop.viewmodel.sample.viewmodel;
import android.os.Bundle;
-import android.support.annotation.Nullable;
+import androidx.annotation.Nullable;
import eu.inloop.viewmodel.AbstractViewModel;
import eu.inloop.viewmodel.sample.viewmodel.view.IPageView;
diff --git a/sample/src/main/java/eu/inloop/viewmodel/sample/viewmodel/SampleArgumentViewModel.java b/sample/src/main/java/eu/inloop/viewmodel/sample/viewmodel/SampleArgumentViewModel.java
index a8275a5..c31e0d3 100644
--- a/sample/src/main/java/eu/inloop/viewmodel/sample/viewmodel/SampleArgumentViewModel.java
+++ b/sample/src/main/java/eu/inloop/viewmodel/sample/viewmodel/SampleArgumentViewModel.java
@@ -1,7 +1,7 @@
package eu.inloop.viewmodel.sample.viewmodel;
import android.os.Bundle;
-import android.support.annotation.Nullable;
+import androidx.annotation.Nullable;
import android.util.Log;
import eu.inloop.viewmodel.AbstractViewModel;
diff --git a/sample/src/main/java/eu/inloop/viewmodel/sample/viewmodel/SampleBindingViewModel.java b/sample/src/main/java/eu/inloop/viewmodel/sample/viewmodel/SampleBindingViewModel.java
index 40a74e5..21f832f 100644
--- a/sample/src/main/java/eu/inloop/viewmodel/sample/viewmodel/SampleBindingViewModel.java
+++ b/sample/src/main/java/eu/inloop/viewmodel/sample/viewmodel/SampleBindingViewModel.java
@@ -1,8 +1,8 @@
package eu.inloop.viewmodel.sample.viewmodel;
-import android.databinding.ObservableField;
+import androidx.databinding.ObservableField;
import android.os.Bundle;
-import android.support.annotation.Nullable;
+import androidx.annotation.Nullable;
import eu.inloop.viewmodel.AbstractViewModel;
import eu.inloop.viewmodel.sample.viewmodel.view.ISampleBindingView;
diff --git a/sample/src/main/java/eu/inloop/viewmodel/sample/viewmodel/UserListViewModel.java b/sample/src/main/java/eu/inloop/viewmodel/sample/viewmodel/UserListViewModel.java
index 3c000bf..58e5a0c 100644
--- a/sample/src/main/java/eu/inloop/viewmodel/sample/viewmodel/UserListViewModel.java
+++ b/sample/src/main/java/eu/inloop/viewmodel/sample/viewmodel/UserListViewModel.java
@@ -1,9 +1,10 @@
package eu.inloop.viewmodel.sample.viewmodel;
+import android.annotation.SuppressLint;
import android.os.AsyncTask;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
@@ -45,6 +46,7 @@ public void onBindView(@NonNull IUserListView view) {
}
}
+ @SuppressLint("StaticFieldLeak")
private void loadUsers() {
mLoadingUsers = true;
mCurrentLoadingProgress = 0;
@@ -86,6 +88,7 @@ protected void onPostExecute(List s) {
}.execute();
}
+ @SuppressLint("StaticFieldLeak")
public void deleteUser(final int position) {
if (position > mLoadedUsers.size() - 1) {
return;
diff --git a/sample/src/main/res/layout/activity_pager.xml b/sample/src/main/res/layout/activity_pager.xml
index 0c61343..e6e6d08 100644
--- a/sample/src/main/res/layout/activity_pager.xml
+++ b/sample/src/main/res/layout/activity_pager.xml
@@ -3,7 +3,7 @@
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
-
diff --git a/template/AVM_Inloop/avm_inloop_template_preview.png b/template/AVM_Inloop/avm_inloop_template_preview.png
new file mode 100644
index 0000000..4216781
Binary files /dev/null and b/template/AVM_Inloop/avm_inloop_template_preview.png differ
diff --git a/template/AVM_Inloop/globals.xml.ftl b/template/AVM_Inloop/globals.xml.ftl
new file mode 100644
index 0000000..691656d
--- /dev/null
+++ b/template/AVM_Inloop/globals.xml.ftl
@@ -0,0 +1,5 @@
+
+
+
+ <#include "../../activities/common/common_globals.xml.ftl" />
+
\ No newline at end of file
diff --git a/template/AVM_Inloop/recipe.xml.ftl b/template/AVM_Inloop/recipe.xml.ftl
new file mode 100644
index 0000000..2747958
--- /dev/null
+++ b/template/AVM_Inloop/recipe.xml.ftl
@@ -0,0 +1,48 @@
+
+
+
+ <#if appCompat && !(hasDependency('eu.inloop:androidviewmodel'))>
+
+ #if>
+
+ <#if screenType == "Fragment">
+
+
+ #if>
+ <#if screenType == "BindingFragment">
+
+
+ #if>
+
+ <#if generateViewInterface>
+
+ #if>
+
+
+ <#if scrPackage != "">
+
+ <#else>
+
+ #if>
+
+ <#if vmPackage != "">
+
+ <#else>
+
+ #if>
+
+ <#if vPackage != "">
+
+ <#else>
+
+ #if>
+
+
+
+
\ No newline at end of file
diff --git a/template/AVM_Inloop/root/src/app_package/BindingFragment.java.ftl b/template/AVM_Inloop/root/src/app_package/BindingFragment.java.ftl
new file mode 100644
index 0000000..429d61e
--- /dev/null
+++ b/template/AVM_Inloop/root/src/app_package/BindingFragment.java.ftl
@@ -0,0 +1,45 @@
+package ${packageName}<#if scrPackage != "">.${scrPackage}#if>;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.view.View;
+<#if vPackage != "">
+ import ${packageName}<#if vPackage != "">.${vPackage?replace('/','.')}#if>.I${viewModelClass?replace('ViewModel', 'View')};
+<#else>
+ import eu.inloop.viewmodel.IView;
+#if>
+import eu.inloop.viewmodel.binding.ViewModelBaseBindingFragment;
+import eu.inloop.viewmodel.binding.ViewModelBindingConfig;
+import ${packageName}.databinding.${underscoreToCamelCase(layoutName)}Binding;
+import ${packageName}.R;
+import ${packageName}<#if vmPackage != "">.${vmPackage?replace('/','.')}#if>.${viewModelClass};
+
+<#if vPackage != "">
+ public class ${screenClass}
+ extends ViewModelBase${screenType}
+ implements I${viewModelClass?replace('ViewModel', 'View')} {
+<#else>
+ public class ${screenClass} extends ViewModelBase${screenType} {
+#if>
+
+
+ public static ${screenClass} newInstance() {
+ final Bundle bundle = new Bundle();
+ // set arguments
+ final ${screenClass} fragment = new ${screenClass}();
+ fragment.setArguments(bundle);
+ return fragment;
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ setModelView(this);
+ }
+
+ @Override
+ public ViewModelBindingConfig getViewModelBindingConfig() {
+ return new ViewModelBindingConfig(R.layout.${layoutName}, getActivity());
+ }
+
+}
\ No newline at end of file
diff --git a/template/AVM_Inloop/root/src/app_package/Fragment.java.ftl b/template/AVM_Inloop/root/src/app_package/Fragment.java.ftl
new file mode 100644
index 0000000..97ce736
--- /dev/null
+++ b/template/AVM_Inloop/root/src/app_package/Fragment.java.ftl
@@ -0,0 +1,45 @@
+package ${packageName}<#if scrPackage != "">.${scrPackage}#if>;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+<#if vPackage != "">
+ import ${packageName}<#if vPackage != "">.${vPackage?replace('/','.')}#if>.I${viewModelClass?replace('ViewModel', 'View')};
+<#else>
+ import eu.inloop.viewmodel.IView;
+#if>
+import eu.inloop.viewmodel.base.ViewModelBaseFragment;
+import ${packageName}.R;
+import ${packageName}<#if vmPackage != "">.${vmPackage?replace('/','.')}#if>.${viewModelClass};
+
+<#if vPackage != "">
+ public class ${screenClass}
+ extends ViewModelBase${screenType}
+ implements I${viewModelClass?replace('ViewModel', 'View')} {
+<#else>
+ public class ${screenClass} extends ViewModelBase${screenType} {
+#if>
+
+ public static ${screenClass} newInstance() {
+ final Bundle bundle = new Bundle();
+ // set arguments
+ final ${screenClass} fragment = new ${screenClass}();
+ fragment.setArguments(bundle);
+ return fragment;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.${layoutName}, container, false);
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ setModelView(this);
+ }
+
+}
\ No newline at end of file
diff --git a/template/AVM_Inloop/root/src/app_package/ViewInterface.java.ftl b/template/AVM_Inloop/root/src/app_package/ViewInterface.java.ftl
new file mode 100644
index 0000000..d79121b
--- /dev/null
+++ b/template/AVM_Inloop/root/src/app_package/ViewInterface.java.ftl
@@ -0,0 +1,8 @@
+
+package ${packageName}<#if vmPackage != "">.${vPackage?replace('/','.')}#if>;
+
+import eu.inloop.viewmodel.IView;
+
+public interface I${viewModelClass?replace('ViewModel', 'View')} extends IView {
+
+}
\ No newline at end of file
diff --git a/template/AVM_Inloop/root/src/app_package/ViewModel.java.ftl b/template/AVM_Inloop/root/src/app_package/ViewModel.java.ftl
new file mode 100644
index 0000000..1e57b44
--- /dev/null
+++ b/template/AVM_Inloop/root/src/app_package/ViewModel.java.ftl
@@ -0,0 +1,24 @@
+
+package ${packageName}<#if vmPackage != "">.${vmPackage}#if>;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import eu.inloop.viewmodel.AbstractViewModel;
+<#if vPackage != "">
+ import ${packageName}<#if vPackage != "">.${vPackage?replace('/','.')}#if>.I${viewModelClass?replace('ViewModel', 'View')};
+<#else>
+ import eu.inloop.viewmodel.IView;
+#if>
+
+<#if vPackage != "">
+ public class ${viewModelClass} extends AbstractViewModel {
+<#else>
+ public class ${viewModelClass} extends AbstractViewModel {
+#if>
+
+ @Override
+ public void onCreate(@Nullable Bundle arguments, @Nullable Bundle savedInstanceState) {
+ super.onCreate(arguments, savedInstanceState);
+
+ }
+}
\ No newline at end of file
diff --git a/template/AVM_Inloop/root/src/app_package/binding_layout.xml.ftl b/template/AVM_Inloop/root/src/app_package/binding_layout.xml.ftl
new file mode 100644
index 0000000..f90065f
--- /dev/null
+++ b/template/AVM_Inloop/root/src/app_package/binding_layout.xml.ftl
@@ -0,0 +1,19 @@
+
+.${scrPackage?replace('/','.')}#if>.${screenClass}">
+
+
+ ${vmPackage?replace('/','.')}.#if>${viewModelClass}"/>
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/template/AVM_Inloop/root/src/app_package/layout.xml.ftl b/template/AVM_Inloop/root/src/app_package/layout.xml.ftl
new file mode 100644
index 0000000..f0bf876
--- /dev/null
+++ b/template/AVM_Inloop/root/src/app_package/layout.xml.ftl
@@ -0,0 +1,9 @@
+.${scrPackage?replace('/','.')}#if>.${screenClass}"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+
\ No newline at end of file
diff --git a/template/AVM_Inloop/template.xml b/template/AVM_Inloop/template.xml
new file mode 100644
index 0000000..110cae4
--- /dev/null
+++ b/template/AVM_Inloop/template.xml
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ avm_inloop_template_preview.png
+
+
+
+
+
+
\ No newline at end of file
diff --git a/template/create-new-template-preview.png b/template/create-new-template-preview.png
new file mode 100644
index 0000000..1d57607
Binary files /dev/null and b/template/create-new-template-preview.png differ
diff --git a/template/template-preview.png b/template/template-preview.png
new file mode 100644
index 0000000..70f9526
Binary files /dev/null and b/template/template-preview.png differ