Skip to content
This repository was archived by the owner on Feb 26, 2023. It is now read-only.
This repository was archived by the owner on Feb 26, 2023. It is now read-only.

Layout with ListFragment #741

Description

@Lochnair

This is the code AA generates for my fragment. Now if you extend Fragment that's fine, but when you extend ListFragment it's not, because the ListFragment implementation of onCreateView doesn't return null, like the Fragment implementation does.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    contentView_ = super.onCreateView(inflater, container, savedInstanceState);
    if (contentView_ == null) {
        contentView_ = inflater.inflate(layout.simple_list, container, false);
    }
    return contentView_;
}

Currently I'm using this to make it work, though one could say it destroys the whole point of doing the layout the AA way.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return null;
}

If this was a design decision, why not add an optional boolean field to the annotation where you can tell AA to ignore super implementations.

Activity

  1. DayS commented on Sep 24, 2013

    @DayS
    Contributor

    This is related to #542

    We could imagine a field like forceLayoutInjection on the annotation, but I'm not sure it's the best solution. Any ideas ?

  2. Lochnair commented on Sep 24, 2013

    @Lochnair
    ContributorAuthor

    Referring to @naixx comment on #542 (comment).
    If I understand him right, it's the annotated class we care about, not whatever class it extends.

    So couldn't we add a check when generating the AA code, where we see if the annotated class has a onCreateView method or not. That way we could add the null check if it does, or let AA handle it if it doesn't.

  3. naixx commented on Sep 24, 2013

    @naixx
    Contributor

    Hello @MysteriooN!
    What check do you mean and what the generated code should look like?

  4. Lochnair commented on Sep 24, 2013

    @Lochnair
    ContributorAuthor

    I'm talking about the null check in the onCreateView method in a generated fragment class:

    contentView_ = super.onCreateView(inflater, container, savedInstanceState);
    if (contentView_ == null) {
        contentView_ = inflater.inflate(layout.simple_list, container, false);
    }
    return contentView_;

    So what I'm saying is if that the annotated class doesn't have a onCreateView method, the generated code should look like this:

    contentView_ = inflater.inflate(layout.simple_list, container, false);
    return contentView_;
  5. naixx commented on Sep 24, 2013

    @naixx
    Contributor

    What about subclassing in this solution? ListFragment is an example of this case, but there could be large hierarchy of abstract classes. So empty onCreateView can not be the point. So, if developer uses additional attribute forceLayoutInjection, he will see explicit and no hidden behavior.
    As for me, I don't know if it is good to provide such API or not instead of current workaround.

  6. Lochnair commented on Sep 24, 2013

    @Lochnair
    ContributorAuthor

    I said that assuming you meant only the annotated class, and not it's hierarchy in your comment. If you take the whole hierarchy into perspective, this won't work of course.

    Right now it seems to me like an additional attribute is the best solution, I'm guessing it's pretty easy to implement, and it leaves the behavior to the developer.

  7. DayS commented on Sep 25, 2013

    @DayS
    Contributor

    Let's go for the forceLayoutInjection attribute in @EFragment then.
    However, this will be implemented in AA 3.1

  8. naixx commented on Sep 25, 2013

    @naixx
    Contributor

    @DayS Only in @EFragment? I haven't checked, but what behavior will be in, for example, ListActivity?

  9. DayS commented on Sep 25, 2013

    @DayS
    Contributor

    There is no check on super.onCreate(...) result for @EActivity, so this problem doesn't exists on this annotation.

  10. voidrob commented on Oct 15, 2013

    @voidrob

    Thanks @MysteriooN for your workaround, it works!

  11. modified the milestones: Someday, 3.1 on May 11, 2014
  12. WonderCsabo commented on Oct 8, 2014

    @WonderCsabo
    Member

    We even can detect the supertype at compile time and generate the necessary injection code.
    But i am not sure, maybe the forceLayoutInjection injection attribute would be cleaner, since we can never know what supertype the client will use, which can eventually return other than null and our layout injection breaks.

  13. 7 remaining items

  14. Lochnair commented on Oct 9, 2014

    @Lochnair
    ContributorAuthor

    @nbelikov I agree with you, really. But the problem with the solution you're suggesting is what @WonderCsabo said before, if you extend anything other than ListFragment that overrides onCreateView and returns a non-null value, our injection will break.

    Edit: That's why I want the parameter, because it'll work in all cases.

  15. WonderCsabo commented on Oct 9, 2014

    @WonderCsabo
    Member
    contentView_ = super.onCreateView(inflater, container, savedInstanceState);
    forceLayoutInjection_ = true;
    if ((contentView_ == null)||(forceLayoutInjection_ == true)) {
           contentView_ = inflater.inflate(layout.fragment_main, container, false);
    }

    If forceLayoutInjection is true, the injection takes place regardless to the nullness of the returned View from the superclass. So to make this working in your case, you have to add this parameter to the @EFragment annotation on your ListFragment subclass.

  16. Lochnair commented on Oct 9, 2014

    @Lochnair
    ContributorAuthor

    @WonderCsabo Yep that's what @DayS and I agreed on a year ago, but unfortunately it wasn't implemented in the 3.1 release as planned.

  17. WonderCsabo commented on Oct 9, 2014

    @WonderCsabo
    Member

    BTW, @Lochnair, this would be more efficient (and maybe more correct):

    forceLayoutInjection_ = ...;
    if (!forceLayoutInjection) {
        contentView_ = super.onCreateView(inflater, container, savedInstanceState);
    }
    if ((contentView_ == null) || (forceLayoutInjection_ == true)) {
           contentView_ = inflater.inflate(layout.fragment_main, container, false);
    }
  18. Lochnair commented on Oct 9, 2014

    @Lochnair
    ContributorAuthor

    @WonderCsabo True, I'll edit it to do that.

  19. WonderCsabo commented on Oct 9, 2014

    @WonderCsabo
    Member

    Also i think we should handle this at generation time, and only generate the necessary calls, so in case of forcing we should just generate the inflation and return, etc.

  20. Lochnair commented on Oct 9, 2014

    @Lochnair
    ContributorAuthor

    Agreed, I'll see if I can get it to work.

  21. Lochnair commented on Oct 9, 2014

    @Lochnair
    ContributorAuthor

    Alright, now it generates either this

    contentView_ = inflater.inflate(layout.fragment_main, container, false);
    return contentView_;

    or this

    contentView_ = super.onCreateView(inflater, container, savedInstanceState);
    if (contentView_ == null) {
        contentView_ = inflater.inflate(layout.fragment_main, container, false);
    }
    return contentView_;

    See commit fd66f6a for the changes.

  22. WonderCsabo commented on Oct 9, 2014

    @WonderCsabo
    Member

    Why don't you create a PR?

  23. Lochnair commented on Oct 9, 2014

    @Lochnair
    ContributorAuthor

    Done #1186.

  24. removed this from the Someday milestone on Nov 12, 2014
  25. WonderCsabo commented on Nov 12, 2014

    @WonderCsabo
    Member

    Implemented.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions