Code Monkey home page Code Monkey logo

proteus's Introduction

: Android Layout Engine

Build Status Build Status Android Arsenal

Proteus is meant to be a drop-in replacement for Android’s LayoutInflater; but unlike the compiled XML layouts bundled in the APK, Proteus inflates layouts at runtime. With Proteus, you can control your Apps layout from the backend (no WebViews). Forget the boilerplate code to findViewById, cast it to a TextView, and then setText(). Proteus has runtime data bindings and formatters. Plugin in your own custom views and attributes and functions to flavour proteus to your requirements.

Getting Started

gradle (gradle 4.10.*)

// Add it in your root build.gradle at the end of repositories:
allprojects {
    repositories {
        google()
        jcenter()
        maven { url 'https://jitpack.io' }
    }
}
// Add in your app level dependency
dependencies {
    implementation 'com.github.flipkart-incubator.proteus:proteus-core:5.0.1'
    implementation 'com.github.flipkart-incubator.proteus:gson-adapter:5.0.1'
    implementation 'com.github.flipkart-incubator.proteus:cardview-v7:5.0.1'
    implementation 'com.github.flipkart-incubator.proteus:design:5.0.1'
    implementation 'com.github.flipkart-incubator.proteus:recyclerview-v7:5.0.1'
    implementation 'com.github.flipkart-incubator.proteus:support-v4:5.0.1'
}

How it works

Instead of writing layouts in XML, in proteus layouts are described in JSON, which can be used to inflate native Android UI at runtime. The JSON layouts can be hosted anywhere (on the device, on servers, etc.).

The Layout defines the the view heirarchy, just like XML.

The Data (optional) defines data bindings. These data bindings are similar to Android's Data Binding library.

Give the layout and data to ProteusLayoutInflater and get back a native view hierarchy.

Watch this video to see it in action.

Sample layout

{
  "type": "LinearLayout",
  "orientation": "vertical",
  "padding": "16dp",
  "children": [{
    "layout_width": "200dp",
    "gravity": "center",
    "type": "TextView",
    "text": "@{user.profile.name}"
  }, {
    "type": "HorizontalProgressBar",
    "layout_width": "200dp",
    "layout_marginTop": "8dp",
    "max": 6000,
    "progress": "@{user.profile.experience}"
  }]
}

Sample data

{
  "user": {
    "profile": {
      "name": "John Doe",
      "experience": 4192
    }
  }
}

Sample Java code

ProteusView view = proteusLayoutInflater.inflate(<layout>, <data>);
container.addView(view.getAsView());

Output

Setting up the Demo App

The demo app will let you play around with proteus as well as help you understand the internals better.

  • Install NodeJS here
  • open a terminal
  • cd into the project directory
  • run npm start
  • Start an AVD emulator
  • Install the Demo App

Ready to tinker

  • Tinker around with the layout and data
  • Hit the FAB to refresh the app.

Resources

Supported Modules

  • Native Android Widgets
  • CardView v7
  • Android Design Library
  • RecyclerView v7
  • Android Support v4

Contributing

How?

The easiest way to contribute is by forking the repo, making your changes and creating a pull request.

What?

  • Adding new Views and Attribute Proccessors.
  • Adding new Functions.
  • Adding JavaDoc and Wiki.
  • Completing TODOs
  • Writing unit tests.
  • Finding bugs and issues. (submit here)
  • Fixing bugs and issues.
  • Implement performance/benchmarking tools.

License

Apache v2.0

If you are using proteus check out the can, cannot and must

Contributors

You can check out the contributors here, but if you wish to contact us; just drop in a mail.

StackOverflow

Find us on StackOverflow at proteus.

Plugins

One click XML to JSON conversion plugin

Download this plugin (in beta) for Android Studio. Once enabled, you can select any android XML resource file and go to Tools > Proteus > Convert XML to JSON

proteus's People

Contributors

adityasharat avatar anirudhramanan avatar harpreetsinghflipkart avatar kushalsharma avatar nikhil-fk avatar raikvagandhi avatar thekirankumar avatar yasirmhd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

proteus's Issues

Not able to include proteus library in Android Studio 3.0

After following the steps given in ReadMe.

I am getting below error -

`Unable to resolve dependency for ':app@debug/compileClasspath': Could not resolve com.github.flipkart-incubator:proteus-core:5.0.0-rc11. Open File Show Details

screen shot 2017-11-15 at 2 40 01 pm
`

Data Driven Children logic needs refactoring

The data-driven children logic was buggy and convoluted. It needs to be refactored, to be consistent with the AttributeHandler principle. New usage of data-driven children is as follows:

{
  "children": {
    "data": "$path.to.data.set",
    "layout": {
        "type": "YourLayout"
    }
  }
}

So no more special attribute handling for children and no more special attributes called childType, childDataContext. The children attribute handler should be moved to ViewGroupParser and LayoutBuilder code has to be cleaned up.

Issue With gradle sync

Error:Module 'com.github.flipkart-incubator.proteus:design:5.0.0-rc8' depends on one or more Android Libraries but is a jar
`
compile 'com.github.flipkart-incubator.proteus:design:5.0.0-rc8'

`

image

Recyclerview/Listview example

Unable to find any example of recyclerview implementation with Proteus. Could you please provide an example of how to write the adapter class with viewholder using Proteus? Any sort of hint would also help.
Thanks.

IOS Version

Is there any Plans for Something Similar for IOS.

Remove parent data from child scope

We should not insert parent data into a child scope. This will leak the parent data into the child scope, and also breaks the layout-data interface. Removing this will also improve performance by avoiding the copying loop per scope object.

Data

{
  "user": {
    "dt": "2017 04 22",
    "ll": "01, XZY, AB"
  }
}

Layout

{
  "type": "TextView",
  "layout_width": "wrap_content",
  "layout_height": "wrap_content",
  "textSize": "14sp",
  "data": {
    "date": "@{fn:date(@{user.dt},'E, d MMM')}"
  },
  "text": "@{fn:format('last login: %s from %s',@{date},@{user.ll})}"
}

Here in the layout user.ll is not added to the data scope of the layout and is only accessible from the outer scope. user.ll should be added to the data scope instead. As follows:

{
"type": "TextView",
"layout_width": "wrap_content",
"layout_height": "wrap_content",
"textSize": "14sp",
"data": {
"date": "@{fn:date(@{user.dt},'E, d MMM')}",
"loc": "@{user.ll}"
},
"text": "@{fn:format('last login: %s from %s',@{date},@{loc})}"
}

Bug in offset calculation in AttributeProcessor.prepare()

offset is currently being calculated from the size of the attributes map. If a module overrides a preregistered attribute the calculation goes for a toss; because the processors array length will be increased by 1 by the entry in the map will be just overridden.
The offset should be calculated using the processorsarray instead.

How to get text values from several EditTexts in a form?

Hi,

This might be a very silly question to ask but I am really unable to figure out a way on how to get the text from an EditText and pass the text to a button click event listener.

For example, I have the below layout json

{
  "type": "LinearLayout",
  "layout_height": "match_parent",
  "layout_width": "match_parent",
  "padding": "8dp",
  "orientation": "vertical",
  "children": [
    {
      "type": "EditText",
      "id": "etUsername",
      "layout_height": "wrap_content",
      "layout_width": "match_parent",
      "hint": "Username"
    },
    {
      "type": "EditText",
      "id": "etPassword",
      "layout_height": "wrap_content",
      "layout_width": "match_parent",
      "layout_marginTop": "4dp",
      "hint": "Password"
    },
    {
      "type": "Button",
      "id": "btnLogin",
      "layout_height": "wrap_content",
      "layout_width": "match_parent",
      "layout_marginTop": "4dp",
      "text": "Login",
      "onClick": {
        "action": "apiCall",
        "extras": {
          "endpoint": "www.someapi.com/api/v1/login",
          "method": "POST",
          "body": {
            "username": "",
            "password": ""
          }
        }
      }
    }
  ]
}

As you can see, I have a form containing username and password fields and a button. Now I am trying to set the text from etUsername and etPassword to username and password fields respectively in the onClick event object of the button whenever user clicks the button, but I am unable to figure out how to do that.

It would be a great help if anyone can help me in sorting this out as soon as possible.

Thanks,
Rajesh

Allow referring to variables within a data scope

{
 "type": "TextView",
 "data": {
    "var-1": "@{a.b.c}",
    "var-2": "@{fn:func(@{var-1})}"
  }
}

Here var-2 is a variable which is referring to var-1 which was declared before it. Basically standard block level variable scoping.

No Document?

There is no document or comment for any method. Its very hard to understand how it works..

Using Picasso or Glide for image caching

Amazing work here. Started exploring proteus and had a quick question.
From the demo I can see that Bitmaploader is used to download image from a network. I was wondering what needs to be done to use libraries like Picasso or Glide with the network images so caching is handled by them.

Add support for custom views which are not registered

Let the parser find out whether a view type exists in the registered handlers.
If not, it should use reflection to find out the view. If this is the case, the view should also specify parent parser.
If reflection also does not fetch the view, then we throw onUnknownViewType.

Bindings should allow assigning a new value to the data model.

The DataBinding class should have a method say:

public void assign(Value value, Value data, int dataIndex)

which can be used to assign a value at the binding path in the data . Example

data:

{
  "user": {
    "name": "John Doe"
  }
}

code:

DataBinding binding = DataBinding.valueOf("user.name");
Value name = new Primitive("Jane Doe");

binding.assign(name, data, 0); // where `data` is the above json

The data should now be:

{
  "user": {
    "name": "Jane Doe"
  }
}

Need Help

What Exactly Value class does in Event
override fun onEvent(view: ProteusView?, eventType: EventType?, value: Value?) { }

How can i able to get Json fields from Value class

And You examples Says You using Retrofit and Casting all layouts into Layout class , Is Layout class can you used for Casting any Layout

not working with existing ids?

i have tried to use proteus in my app.But its not working. i want change color and other attributes in the textview.But it is not working. will proteous support existing ids which is inflated by LayoutInflator

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.