New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic item layout selector support. #179

Closed
weicheng113 opened this Issue Sep 26, 2014 · 13 comments

Comments

Projects
None yet
4 participants
@weicheng113
Member

weicheng113 commented Sep 26, 2014

Select item layout based on current item information. The following image taken from a news app for example.
dynamic item layout selection

@weicheng113 weicheng113 added the Feature label Sep 26, 2014

@guitcastro

This comment has been minimized.

guitcastro commented Nov 21, 2014

Any worked on this ? Do you have any workaround for now, or maybe can you point a direction for this implementation so I can do a pull request?

Regards,

@guitcastro

This comment has been minimized.

guitcastro commented Nov 21, 2014

So I have been studying your code and here what I coming out with:

You can bind a itemLayout with a factory function:
bind:itemLayout="@android:layout/myMethod

The function will have this signature:

int myMethod(MyModel model, ItemContext itemContext)

So the user can select the layout based on the model data or the position, furthermore you can create a method that return a View instead a int, but I will leave that for later.

How I'm planing to implement this:

DataSetAdapterBuilder should receive my factory method, create a new DataSetAdapter passing the factory method instead the itemLayoutId.

Then in the newView method we call the factory function to get the layout dynamic.

So what do you thing? Any suggestion ? Can I implement this and make a pull request ?

@weicheng113

This comment has been minimized.

Member

weicheng113 commented Nov 22, 2014

Hi Guilherme,

Great to see your interest on the framework. I will send you what i am
thinking and general consideration tonight.

Best regards,
Cheng Wei
2014-11-22 AM7:32于 "Guilherme Torres Castro" notifications@github.com写道:

So I have been studying your code and here what I coming out with:

You can bind a itemLayout with a factory function:
bind:itemLayout="@android:layout/myMethod

The function will have this signature:

int myMethod(MyModel model, ItemContext itemContext)

So the user can select the layout based on the model data or the position,
furthermore you can create a method that return a View instead a int, but I
will leave that for later.

How I'm planing to implement this:

DataSetAdapter should receive my factory method, create a new
DataSetAdapter passing the factory method instead the itemLayoutId.

Then in the newView method we call the factory function to get the layout
dynamic.

So what do you thing? Any suggestion ? Can I implement this and make a
pull request ?


Reply to this email directly or view it on GitHub
#179 (comment)
.

@weicheng113

This comment has been minimized.

Member

weicheng113 commented Nov 22, 2014

Hi Guiherme,

#179, #184 and #191 are related. I am thinking to provide a general solution for different kinds of adapters. The solution could be divided into several levels, a simple one for simple requirement(for example the current solution, layout xml plus @ItemPresentationModel annotation) and a more flexiable one for more complicated demand for example.

When we try to provide a solution, we want to provide a less invasive and clear one. If with addition of some annotations we can supply a clear solution, that would be good. If not, we think about through some interfaces or a set of classes for composition. We don't want to supply classes for subclassing where possbile.

You can have a go, if you would like to. I am working on #185, #139 and related, which will take me some time.

Best regards,
Cheng Wei

@guitcastro

This comment has been minimized.

guitcastro commented Nov 24, 2014

Cheng,

Can you elaborate a little more about a solution using annotations?
Would be annotated a method, to create the View or chose the layout dynamic instead a xml attribute ?

@ViewFactory
int getView (MyModel model, ItemContext itemContext)
@ViewFactory
View getView (MyModel model, ItemContext itemContext)

Or a class level annotation for the ItemPresentationModel or the PresentationModel that specifies a factoryClass that implements some interface?

@ViewFactory(MyViewFactory.class)
MyItemPresentationModel{}
MyViewFactory implements ResourceViewFactory{
    int getView (MyModel model, ItemContext itemContext)
}
AnotherViewFactory implements ViewFactory{
 View getView (MyModel model, ItemContext itemContext)
}

The only problem with this case, is that the ViewFactory may have some dependencies and we must provide a way to inject them. It's not my case and I don't know if it's something that worth worrying, I am just point out a downside of this solution.


Will be nice with you help to define the top level api of this feature, if will be a layout attribute, or using annotations as above or etc, so I can make something that work and later you can provide a more clean solution that fixes all the other issues that you cited in case my implementation does not covered them all, without changes for the users.

@weicheng113

This comment has been minimized.

Member

weicheng113 commented Nov 24, 2014

Hi Guiherme,

I don't have a concrete idea for the top level API of the feature yet. I will have to experiment to find out most suitable way. Would you like to fork the framework and implement the feature for your requirement first? And when i finish the task at hand, i will concentrate on this feature. This feature may be too complicated as the first experiment with the framework at the first time.

Best regards,
Cheng

@cnevinc

This comment has been minimized.

cnevinc commented Jul 3, 2015

+1 for this feature :P

@weicheng113

This comment has been minimized.

Member

weicheng113 commented Aug 27, 2015

a reference - https://github.com/evant/binding-collection-adapter.
Start looking into this. Need a elegant implementation where possible.

@weicheng113

This comment has been minimized.

Member

weicheng113 commented Aug 28, 2015

This is a very good effort made by @derron - #230.
The usage from user point of view can be simplified and summarized as follows - derron/RoboBinding-album-sample@bd40ab0:

@PresentationModel
public class MyPresentationModel implements HasPresentationModelChangeSupport {
    ...
    @ItemPresentationModel(value = MyItemPresentationModel.class,
        factoryMethod="newMyItemPresentationModel", 
        viewFactory = MyItemViewFactory.class)
    public List<Item> getItems() {
        return items;
    }

    public MyItemPresentationModel<Item> newItemPresentationModel(Item item) {
        if (shouldChoose(item)) {
            return new MyItemPresentationModel1();
        } else {
            return new MyItemPresentationMode2();
        }
    }

    public static class MyItemViewFactory implements ItemViewFactory {
        ...
        @Override
        public int getItemViewTypeCount() {
            return numOfDifferentLayouts;
        }

        @Override
        public int getItemViewType(int position, Object item) {
            return determineViewType(position, item);
        }

        @Override
        public int getItemLayoutId(int position, Object item) {
            return chooseItemLayout(position, item);
        }
    }
}
@weicheng113

This comment has been minimized.

Member

weicheng113 commented Aug 28, 2015

Based on @derron effort, it seems we can further simplify the usage a bit. We can specify item layouts in owner layout xml. It seems we can avoid to implement getViewTypeCount() and getItemViewType(...).

<Spinner
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:prompt="@string/item_layouts"
    bind:itemLayout="@layout/multi_item_layout1, @layout/multi_item_layout2"
    bind:dropdownLayout="@layout/multi_dropdown_item_layout1, @layout/multi_dropdown_item_layout2"
    bind:source="{items}"/>
@PresentationModel
public class MyPresentationModel implements HasPresentationModelChangeSupport {
    ...
   @ItemPresentationModel(value = MyItemPresentationModel.class,
        factoryMethod= "newMyItemPresentationModel", 
        layoutSelector = "selectItemLayoutId")
    public List<Item> getItems() {
        return items;
    }

    public MyItemPresentationModel<Item> newItemPresentationModel(int itemLayoutId) {
        if (shouldChoose(itemLayoutId)) {
            return new MyItemPresentationModel1();
        } else {
            return new MyItemPresentationMode2();
        }
    }

    /*itemLayoutChoices are the itemLayoutIds from xml*/
    public selectItemLayout(int[] itemLayoutChoices, Item item, int position) {
        return chooseOne(itemLayoutChoices);
    }
}
@weicheng113

This comment has been minimized.

Member

weicheng113 commented Aug 28, 2015

If you have any other ideas, please do post them. We are currently evaluate this feature and going to implement it.

@derron

This comment has been minimized.

derron commented Aug 28, 2015

@weicheng113, your idea is very nice, much simpler than my implementation, look forward for your implementation.

weicheng113 added a commit that referenced this issue Sep 26, 2015

weicheng113 added a commit that referenced this issue Sep 26, 2015

weicheng113 added a commit that referenced this issue Sep 26, 2015

All unit tests passed. #179 implemented. An example was added to Gallery
project - res/layout/activity_adapter_view.xml

@weicheng113 weicheng113 added this to the v0.8.11 milestone Oct 11, 2015

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