Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Sindre Tellevik
    @graknol
    finally!
    Basically bansa
    Benedict
    @BenedictP
    my mvvm architecture with anvil is online: https://github.com/BenedictP/NotesMVVM
    over the weekend I'm going to translate the readme (and fix the "uml" picture ;) )
    Stephen Fox
    @stevemasta34
    I've got a question about using Anvil's RenderableAdapter
    I want to make a TodoMVC with Anvil, because I love the mindset of functional + composable components for Views (over Fragments 😒), but I need some examples
    Or docs
    Never mind 😅
    Lalit Maganti
    @tilal6991
    @zserge would you be open to exposing the internals of Anvil?
    i.e. Mount, Attr, Node etc?
    My idea is to separate the creation of the DOM from the rendering part
    Make it a two part system
    I've been exploring JS approaches to DOM rendering and most of them seem to have this feature
    DavidMihola
    @DavidMihola
    @BenedictP What happened to your MVVM example? The ones I know of all use Android's Data Binding so I'd love to see an alternative using Anvil!
    Yannick
    @ElectricCookie

    Hey there. I'm trying to render a textInputLayout, but my app keeps crashing during the second render-cycle with the following exception: java.lang.IllegalArgumentException: We already have an EditText, can only have one

    The view looks like this:

    DesignDSL.textInputLayout(() -> {
        DSL.layoutGravity(DSL.TOP);
        DesignDSL.hint(getContext().getString(R.string.connect_hint_port));
        DesignDSL.textInputEditText(() -> {
            DSL.inputType(InputType.TYPE_CLASS_NUMBER);
            DSL.enabled(state.connect().state() != State.CONNECT_STATE.CONNECTING);
            DSL.text(String.valueOf(state.connect().port())); 
            DSL.onTextChanged((s) -> {
                 App.getInstance().getStore().dispatch(new Action("CONNECT_SET_PORT",s.toString()));
            });
           });
    });

    I also tried using a standard DSL.editText() but still not working.. Thanks!

    Earl St Sauver
    @estsauver
    Hey there! I have what should be a quick question. Anvil comes in a bunch of build flavors, is there any reason to not just use the earliest possible build flavor (SDK-15)? Am I missing out on something by choosing the older SDK?
    Serge Zaitsev
    @zserge
    @estsauver Different SDK variants contain just different DSL.java classes generated from different android.jar. I normally use sdk-19 these days, but you may choose either of them.
    Have a look here to see which DSL methods are available in SDK19 only (or in SDK21 only) - https://github.com/zserge/anvil/blob/master/DSL.md
    Mitch Ryan Jusay
    @mitchryanjusay
    Hi guys, I'm pretty new to anvil and i've encountered @ElectricCookie 's problem with the TextInputLayout, actually, aside from the error when re-rendered it's not showing its hint and also not animating.
    Also any update on this @zserge zserge/anvil#83
    Jacob Henry
    @jachenry
    @zserge I'm looking to suggest Anvil on a project I help develop but zserge/anvil#81 is a blocker. Could you give me some tips on how to fix? It'll be nice to play around with the code.
    Guilherme Araújo
    @guilhermearaujo
    Hi! How can I set a button's style using Anvil? There is no style() method
    Serge Zaitsev
    @zserge
    @/all Hello, smiths! I'm working on Anvil 0.5.0. The major change so far is getting rid of the virtual nodes and using real views instead (yes, there was no performance gain from using virtual nodes!). This helps to fix issues with XML layouts and nasty widgets from the support libraries.
    Also I'm making a change where attributes are identified by string literals (not lambda singletons) and dispatched with a switch/case statement and not hundreds of lambas. This reduces method count at least in half and allows to use the same attribute name in multiple handlers (e.g. gravity() in core DSL and gravity() in the support DSL, also users can do their own "middleware" to handle their own custom view attributes). This opens a way to proper components.
    There is a lot to be done (getting rid of reflection in view factories to speed up view construction, adding keys to views to identify similar views somehow), but it seems to be usable enough to test it. I've ensured that anvil-examples work fine and some of my project also run correctly with Anvil 0.5.0. I think it should be pretty much backwards compatible with Anvil 0.4.0.
    So feel free to clone the "anvil-forge" branch, run ./gradlew publishToMavenLocal and give it a try!
    Serge Zaitsev
    @zserge
    Just merged forge branch into master. If anyone had issues with Anvil 0.4.0 - there is a good chance that new master branch changes fix them (or show them in a different light).
    robinchew
    @robinchew
    Hi everyone, I'm new to Android development, but familiar with web frontend development using Mithril. When I read up on fragments since it is the blessed way of doing Android dev, I was scared into searching for alternatives. I searched for 'android virtual dom' and I was pleased to find someone @zserge being inspired by mithril, resulting with Anvil.
    One of the killer features of mithril over react, is that I can easily fallback to my dirty ways of jquery dom manipulation post render.
    Mithril really doesn't get in the way, and works well with others. So I wonder if Anvil has this level of flexibility? Can I get fragments (if I understood how to work it) to work together with Anvil?
    Oh by the way is this where the Anvil community largely hang?
    Serge Zaitsev
    @zserge
    Hi Robin! Thanks for your interest in Anvil (and Mithril, too - I think it's a very underrated framework)
    You're right, Anvil often plays well with normal Android development approach - you can use it with fragments, you can use View instances and call their methods directly if you want. Also, you can use XMLs if you prefer that to Anvil's DSL (or if you're refactoring existing code).
    As for the Anvil's community - there's not much of a community that I'm aware of. There are some very nice and helpful people who hanged out here and helped me to do a big refactoring last year, but as long as everything is working - people just use it, eventually filing issues on github. So if you have a question - feel free to ask it here, if you found a bug - submit it on github.
    robinchew
    @robinchew
    So I can mess with the element after the virtualdom has rendered it? For example in mithril:
    m('div', { oncreate: function(vdom){
        vdom.element.innerHTML = 'I am Replacing Div Content!';
    }}, 'Div Content')
    Excuse my excessive edits
    robinchew
    @robinchew
    Cool with the community, let the code speak for itself.
    Serge Zaitsev
    @zserge
    Exactly. To avoid confusion I have to mention that Anvil has evolved from "virtual DOM" concept to the "incremental DOM", because virtual DOM turned out to be too heavy for Android's GC.
    However the general logic is still the same - during the rendering cycle current "declarative" layout is compared to the real layout and the real layout is lazily patched according to the changes.
    You should be able to get an instance of a View like this:
    public void view() {
      linearLayout(() -> {
        button(() -> { // Inside any view block...
          init(() -> { // you may declare "init" function and pass lambda into it
            Button b = Anvil.currentView(); // Type of a view is deduced automatically in most cases
            mButton = (Button) Anvil.currentView(); // Or you may cast it explicitly
            // You are not forced to do this within "init" block, but otherwise your code will be called on every rendering cycle
          })
        });
      });
    }
    // later on you may use mButton as a normal view:
    mButton.performClick();
    As an alternative, you may use View IDs:
    button(() -> {
      id(MY_BUTTON);
    });
    // later just find view by ID, IIRC Android caches views and their IDs:
    findViewByID(MY_BUTTON).performClick();
    robinchew
    @robinchew
    Thanks for the code example.
    robinchew
    @robinchew
    I notice that mithril nests the elements via the arguments, but anvil nests via lambdas. m() will return nested plain objects, does linearLayout() return anything?
    Serge Zaitsev
    @zserge

    No, in Anvil there are two forms of DSL:
    One is for Java 8 and Kotlin, where you pass lambdas. Here functions return void.
    Another is for Java 6 and it uses a trick which makes it look similar to Mithril:

    o (linearLayout(),
       size(FILL, FILL),
       o (button(),
          size(FILL, WRAP),
          onClick(someHandler)),
       o (button(),
          size(FILL, WRAP),
          text(someText),
          onClick(someOtherHandler)));

    o in this case looks like a bullet point in the list, so the whole layout (if nicely indented) looks like a tree of view items.
    In this case to tell views from attributes in the function parameters some functions return some special types to make the compiler check for the types. But again, they don't return actual views. The only way to get a view instance is to use Anvil.currentView(). Good news is that you can use it anywhere in you code (e.g. in other methods), as long as your code is called from within the view() function.

    robinchew
    @robinchew
    Does the o DSL pass lambdas behind the scenes anyway?
    Is it just your personal design choice to pass lambdas, or was it something that forces a need to be lambdas?
    robinchew
    @robinchew
    @zserge I'm writing some anvil now, and I need to do constraints, and I'm not sure what's the Anvil way of dealing with constraints. Nothing much on Google on it.
    robinchew
    @robinchew

    This is what I attempted:

    class HelloView(c: Context, constraint: ConstraintLayout) : RenderableView(c) {
        val constraint: ConstraintLayout
        init {
            this.constraint = constraint
        }
        override fun view() {
            textView {
                text(R.string.login_title)
                val title: TextView = Anvil.currentView()
                this.constraint.addView(title)
            }
        }
    }
    
    class LoginActivity : AppCompatActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            val constraint = ConstraintLayout(this)
    
            setContentView(HelloView(this, constraint))
        }
    }

    However that will error saying, java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() which I understand.

    It's kotlin by the way
    Also my example didn't append constraint to anything
    robinchew
    @robinchew
    I need to get constraints to work programmatically first, which is already quite painful
    robinchew
    @robinchew
    Without using Anvil, I can't even do a simple top margin constraint on a TextView. If I have to resort to XML for constraints then it defeats the purpose of Anvil I think. But I would like to know your opinion on constraints.
    robinchew
    @robinchew
    Anyway I got something simple working:
    class ContactView(c: Context) : RenderableView(c) {
        override fun view() {
            textView {
                text("Contact Title")
            }
        }
    }
    
    class LoginActivity : AppCompatActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            val constraintLayout = ConstraintLayout(this)
            constraintLayout.id = 1
            setContentView(constraintLayout)
    
            val contactUs = ContactView(this)
            val clpcontactUs = ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.WRAP_CONTENT, ConstraintLayout.LayoutParams.WRAP_CONTENT)
    
            constraintLayout.addView(contactUs)
    
            val constraintSet = ConstraintSet()
            constraintSet.clone(constraintLayout)
            constraintSet.constrainWidth(contactUs.id, ConstraintSet.WRAP_CONTENT)
            constraintSet.centerHorizontally(contactUs.id, constraintLayout.id)
            constraintSet.connect(contactUs.id, ConstraintSet.TOP, constraintLayout.id, ConstraintSet.TOP, 68)
            constraintSet.applyTo(constraintLayout)
    And there's a bug if you use ConstraintSet.LEFT, it doesn't work, but apparently does in XML. https://issuetracker.google.com/issues/62154545
    robinchew
    @robinchew
    Sooo what's the state of the Anvil project?
    robinchew
    @robinchew