• Stars
    star
    815
  • Rank 55,957 (Top 2 %)
  • Language
    Java
  • License
    Apache License 2.0
  • Created about 10 years ago
  • Updated over 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Separating data and state handling from Fragments or Activities without lots of boilerplate-code.

AndroidViewModel

Important notice: Deprecated

This library served it's purpose for over 3 years. We believe that Google's Android Architecture Components are the preferred setup now for new projects. INLOOPX 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. An instance of a ViewModel class is assigned to your Fragment or Activity during the first creation and is kept during it's life cycle, even between display orientation changes. The ViewModel instance is removed after the Fragment or Activity is completely gone (finished, popped from backstack, replaced without keeping it in backstack).

You can execute asynchronous tasks in this ViewModel instance and this class is not destroyed during orientation change. All data handling and state logic should be placed inside this class. The Fragment or Activity is just a "dumb" view.

How to implement

  1. Create an interface for your View by extending IView. We will call it IUserListView for this example.

     public interface IUserListView extends IView {
          public void showUsers(List<User> users);
     }
  2. Create your ViewModel class by extending AbstractViewModel. For example:

    public class UserListViewModel extends AbstractViewModel<IUserListView> {
       ....
    }
  3. Each Fragment or Activity that you would like to associate with a ViewModel will need either to extend ViewModelActivityBase/ViewModelBaseFragment or copy the implementation from these classes to your base activity/fragment class (in case you can't inherit directly). For example:

    public class UserListFragment extends ViewModelBaseFragment<IUserListView, UserListViewModel> 
       implements IUserListView {
       
    }
  4. Also each Fragment or Activity has to call setModelView() after the View (Fragment/Activity) was created and initialized. This is usually on the end of onViewCreated (or onCreate in case of an Activity)

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
         ButterKnife.inject(this, view);
         setModelView(this);
    }

How to use

You can forward user interaction from the View into the ViewModel simply by calling:

getViewModel().onDeleteUserClicked(userId);

The same goes for the opposite direction, when your asynchronous operation in the ViewModel finished and you would like to forward data to the View to show a list for example:

getViewOptional().showUsers(userList);

The getViewOptional() method will never return null. It will return a dummy implementation in case the View is null at the moment (e.g. Fragment already destroyed, or between orientation change). You can also check if the View is not null in case you need to:

if (getView() != null) {
    getView().showUsers(userList);
}

Your Fragment argument Bundle and Activity intent Bundle is forwarded to the ViewModel's onCreate method, which you can override to read the initial arguments for the ViewModel.

public void onCreate(Bundle arguments, Bundle savedInstanceState) {
   long userId = arguments.getInt("user_id", -1);
}

Data binding support

Data binding is supported - extend ViewModelBaseBindingFragment.java instead of ViewModelBaseFragment and implement getViewModelBindingConfig() in your Fragment.

@Override
public ViewModelBindingConfig getViewModelBindingConfig() {
   return new ViewModelBindingConfig(R.layout.fragment_sample_binding, requireActivity());
}

That's it. You can then directly use ObservableField in your ViewModels. See example.

Special handling for FragmentStatePagerAdapter

The Android implementation of FragmentStatePagerAdapter is removing Fragments and storing their state. This is in contrast with FragmentPagerAdapter where the Fragments are just detached but not removed. We should be also removing ViewModels and storing their state to be consistent with this behaviour.

Use ViewModelStatePagerAdapter instead of the default FragmentStatePagerAdapter. This class is only overriding the destroyItem() method and making sure that ViewModel is removed. The state is stored/restored automatically. You can also use the standard FragmentStatePagerAdapter - in that case ViewModels will be kept in memory and removed only when you leave the screen (Activity finished or Fragment removed).

How does it work?

A unique global ID is generated for the first time your Fragment or Activity is shown. This ID is passed on during orientation changes. Opening another instance of the same Fragment or Activity will result in a different ID. The ID is unique screen identifier. A ViewModel class is created and bound to this ID. The corresponding ViewModel instance is attached to your Fragment or Activity after an orientation change or if you return to the fragment in the back stack. The ViewModel is discarded once the Fragment/Activity is not reachable anymore (activity is finished or fragment permanently removed).

Download

compile 'eu.inloop:androidviewmodel:1.4.0'

Android Studio Template

For faster creating new screens, you can use Android Studio Template

Android Studio Template Window

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

Android Studio New Template

More Repositories

1

svg2android

SVG to Android VectorDrawable XML resource file
JavaScript
1,706
star
2

shadow4android

Android 9-patch shadow generator
JavaScript
943
star
3

sqlite-viewer

View SQLite file online
JavaScript
861
star
4

interpolator

Realtime interpolation equation editor
JavaScript
391
star
5

apk-method-count

Output per-package method counts in Android APK
TypeScript
295
star
6

easygcm

Android Library for easy GCM integration in few lines of code.
Java
261
star
7

UpdatableFragmentStatePagerAdapter

FragmentStatePagerAdapter but with working notifyDataSetChanged() support
Java
136
star
8

image-picker

An easy to use, highly configurable image picker for your chat application.
Swift
101
star
9

easyrelease

Gradle plugin for Android projects that helps with signing release APKs
Groovy
58
star
10

SimpleRecyclerAdapter

A simple and reusable RecyclerView adapter
Java
41
star
11

LocalMessageManager

Simpler to use and faster alternative to LocalBroadcastManager
Java
40
star
12

ScreenInfo

Android screen info tool for developers
Java
20
star
13

qlplayground

QuickLook generator for the Xcode Playgrounds
CSS
20
star
14

Styles

Styling iOS apps made easy
Swift
18
star
15

cra-docker

Docker image for running Create React App distributions
Dockerfile
11
star
16

INLBreadcrumbs

iOS library for UINavigationController breadcrumb navigation
Objective-C
7
star
17

CodableStore

Persistance providers for swift Codables
Swift
6
star
18

PinIndicatorView

A simple UI component that mimics the lock screen pin indicator
Swift
6
star
19

styles-zeplin-extension

Zeplin extension for Styles
TypeScript
5
star
20

UIViewController-DisplayChild

UIViewController containment made easy
Swift
4
star
21

UIViewController-DisplayInDrawer

Present any view controller easily in a drawer (iOS Maps style)
Swift
4
star
22

goclitools

Collection of tools for creating cli apps.
Go
3
star
23

slack-ooo

JavaScript
3
star
24

Knight

MVP library with Dependency Injection for Android
Java
3
star
25

ParallaxAnimation

iOS UICollectionView layout parallax effect example
Swift
3
star
26

devopscli

CLI tools for devops to automate everyday tasks
Go
3
star
27

INLThemes

An iOS library for supporting multiple UI themes
Objective-C
3
star
28

qc

Cisco AnyConnect Secure Mobility Server helper for the lazy ones
Swift
3
star
29

INLConfig

An iOS library for loading your configuration from a plist that supports automatic code generation for supporting code and remote updates
Swift
3
star
30

eureka-article

Source code for the Medium post about Eureka
Swift
2
star
31

SVGMap

SVGMap
Swift
2
star
32

bitbucket-pr-badges

Pull Request status badges for Bitbucket (browser extension).
JavaScript
2
star
33

PluggableApplicationDelegate

Service oriented application delegate. Carthage ready.
Swift
2
star
34

enhanced-volley

Java
2
star
35

inkwire

Wireframe kit and UX pattern library for Sketch. iOS in progress, Android to come.
2
star
36

cleaner-swift-templates

Inloop Clean Swift Xcode templates
Makefile
2
star
37

easylog

A simple wrapper for android.util.Log which adds useful features such as: calling method name added to each log, log message parameters, tag automatically added, option to disable all logs...
Java
2
star
38

go-transport-queue

Queue for transporting large batch of messages with specific interval and batch size.
Go
1
star
39

INLAsyncOperation

The wrapper for the AsynchronousOperation
Shell
1
star
40

YoutubeLeakSample

Java
1
star
41

nsq-transport

NSQ consumer for transporting messages to various targets
Go
1
star
42

tslint-config

1
star
43

HideableItemsTabbarController

Hide UITabBar items with ease.
Swift
1
star
44

csv2languagefiles

Translates CSV containing language translations to both iOS and Android file formats.
Python
1
star
45

sql-exporter

Command line utility to export data from SQL database
Go
1
star