So I have read a lot about MVC online and have learned about it in class, but I am still lost on one aspect - changing and showing Views. I know Views are GUI, they pass user input to the Controller, but I'm having a hard time wrapping my mind around how the following would work:
View A displayed
user clicks button on View A
Controller notified, tells Model
Model tells Controller to display View B
Controller displays View B?!?
The last 2 lines here is what I don't understand how to implement. If the View did not change to another View, I know to use the Observer/Observable interface to update the View. But in my case there is a Home Screen and a Game Screen and when the user clicks Play button on the Home Screen, I want the "view" and the GUI to change to the GameScreen. I want to use 2 distinct Views (I think).
I'm having trouble structuring my code to achieve this, and I don't know where to put the ActionEventListeners
Assuming you're just switching the view, this is the sequence.
View A displayed
User clicks button on View A
Button controller tells view to display View B
View displays View B
The model is not involved at all. Other controllers can change the model.
When coding a Java Swing application, here's what I do.
The view may read values from the model.
The view may not update the model.
The controller(s) will update the model.
The controller(s) may revalidate / repaint the view.
To see an example of the model / view / controller pattern in a realistic Swing application, take a look at my article, Retro Snake Game.
Related
I trying to refactor one of my activity class to implement mvp(using mvp mosby library) . I have a RecyclerView and in this view there is some items that some changes apply to them during the run time. for example I do some I/O operation and change one row.
I think it's better to keep my items in presenter class; what is the best practice for this? keep this in 1)presenter or 2)activity or 3)only keep view related item in adapter and all other item in presenter.
the activity now keep items directly and change item row in activity and then notify adapter. isn't better to move all this line in adapter and notify adapter in the adapter class? for example i want change icon of some row.where and which class is responsible for that? adapter? activity? now I want to implement it like this in adapter:
changeItemIcon(int position, int iconRes){
mImages.get(position).setICon(iconRes);
notifyItemChanged(position);
}
I invoke this method on activity and invoke activity method from presenter.
is it good? what is the best practice to do this?
UPDATE
also I find this question ( Best way to update data with a RecyclerView adapter ) that using adapter method for changing items. but what about modify? Need I keep reference to items in my activity?
for example i want change icon of some row.where and which class is responsible for that? adapter? activity?
I know it sounds a little bit strange, but changing an element is always the responsibility of your "business logic", even just for "icons".
The workflow should be as follows (unidirectional data flow):
View appeares, tells presenter to load a list of items
Presenter loads items form "business logic" and registers himself as an
observer / listener / callback (whatever you want to call it)
Presenter receives result and tells the view to display the list of
items (through RecyclerView and corresponding adapter).
so far is what you have implemented I guess, now it comes to the point where you want to change an item.
User clicks on an item in your RecyclerView which then should trigger to change the icon of this item. Therefore View should call: presenter.changeItem()
Presenter is just the man in the middle in this case and will invoke the "business logic layer" to tell that the item should be changed to new state (icon has changed).
"Business logic layer" will change the models state (change the items icon) and then will notify its observer / listeners that the model has been changed.
Since Presenter is still observing / listening to the business logic layer (see point 2.) the Presenter will be notified (see point 6.) with a new (updated) list of items containing the updated item which icon has been changed.
Similar to point 3. Presenter will tell the view to display the new (updated) list of items (through RecyclerView and corresponding adapter).
Do you see the unidirectional data flow? That is very important. Immutability FTW.
MVP has two different variants: Passive View and Supervising Controller. Depending on your taste, you can stick to one or mix both of them in your app.
If you choose Passive View, you need to hide Model from View and let Presenter format data then set to the View. In this case, you need to keep Model reference in Presenter. View should only hold view-data (adapter) for its displaying purpose.
If you stick to Supervising Controller, you can allow View to directly bind data from Model and ask Model to perform some simple logic. Presenter should only care complex logic, i.e some operations which need to involve Services. In this case, you can give Model (your items) to View (activity) and let it interact with Model in some simple manner.
PS: Please also check out our new MVP framework: Robo MVP at http://robo-creative.github.io/mvp.
I've never used mosby, but I've just read their docs (good reading btw) and here's my understanding:
A recycler view usually consists of the view (android term) and an adapter. Both are connected inside a fragment or activity. In terms of MVP/mosby this is all view layer. The presenter should only retrieve and pass the to-be-shown data from your service (model layer in mosby, "service layer" or "business logic" in other concepts), which in turn gets it from a DAO or repository (model layer).
The docs say that the presenter only handles the view state, not the actual contents. Your state is "showing list".
I have a app on Google App Engine and I'm using GWT, and when the user goes to www.myapp.com/#show I need to show a graph, and in that page there is a button to search and add nodes to that graph, when the search Button is clicked I need to show a popup with the search form (it has several functions and dialogs).
Can I create a view for that page and another view for the popup and use the same presenter for both?
or What is the best way to implement that based on the pattern MVP?
MVC(Model View Controller) style tells that you have this three packages for Entities, UI, Controller classes. This help you organize your code and break it to plugins.
As for your question it is better if you can implement a CustomPopUp class in the View(UI) package and make it abstact. So PopUp could have as parameters the message the context or everything it needs to show the approprate message.
And you can pass CustomPopUp as private delegator to your UI classes who need to show popup messages.
I want to develop an Android app, where start page of the app GUI, will contain 4 vertical layouts in the main layout. Now, in each layout, I want to add buttons/slider dynamically from the app (instead of adding buttons/slider dynamically in the source code). That means, initially all these 4 layouts will be blank and when user will select any button or slider in another layout, to add it in any of this 4 layouts, the button or slider will be added in that layout. User will be able to add max 10 views in any vertical layout and the views can be either button, slider or custom view.
My attempt:
First I tried to create 4 vertical layout under the main layout for startup page and I got succeed.
I also find after searching that its possible to add views dynamically in layouts in android.
dynamically adding a view to activity layout
But most examples, add views dynamically in android by running loops, instantiating the desired view class and then add it in the main layout. Although, in this way, views are added dynamically in the layout, it is done by modifying the source code.
Is it possible to write the source code in a way, so that it can be done directly from the app? So that when user will click on Add a slider in "layout 1", a slider will be added in layout 1 and then again, when the user will click on "Add a button" in layout 1, a button will be added at the end of the slider. User will be able to customize button or slider properties. Also, if the user change the value of the slider, the app will remember its value.
Now, next time, when the app will be opened, those views will be there in the layouts, they will not be deleted and the values will remain unchanged (for example, a ticked check box will remain ticked), so I think I also need some kind of storage or properties manager.
My question is, is it possible to do this in android (because I never seen such apps in android) and if possible, any idea, how can I implement it?
I am totally new to android, so my knowledge is limited but I completed the basic tutorials on android app development and I have plugin development experience in eclipse.
Thanks a lot in. I will highly appreciate your help.
Of course it is possible:
Every layout (like LinearLayout, RelativeLayout etc.) extends the ViewGroup-class, which offers the addView-method.
To add a new view (like a Slider) to one of your layouts, just instantiate it programmatically (via new) in your activity and assign the appropriate LayoutParams to it
To store the state of user added content, it is the easiest to use SharedPreferences - a simple key-value-store which holds data over the application's lifecycle
Yes. This is possible. To create the Views dynamically, you simply have to either extend the class of the View or just say new Button(Context, AttributeSet); (Not only for Button's every View has a constructor that takes an attribute set and a context).
Using Layout.addView() you can add any View to the Layout.
Using SharedPreferences you can indicate what View belongs in what Layout.
If you decide to extend the View's class, make sure not to do too much in it. I tried that once and it just gave me an OOM (OutOfMemory Error) because I had a ton a Views trying to do stuff at the same time.
I'm writing a glass app.
In one activity I want to scroll between few cards (which were popups in my android app).
1) I thought to use cardsScrollView.
problem: Is it possible to set customView to a card object?
2) I thought to use LiveCard
problems:
Is it possible to publish them inside my app and not in the timeline?
Is there an equivalent LiveCardsScrollView?
Any other idea how to implement this?
From Google's sample code at https://developers.google.com/glass/develop/gdk/ui/theme-widgets and API documentation at https://developers.google.com/glass/develop/gdk/reference/com/google/android/glass/widget/CardScrollView and https://developers.google.com/glass/develop/gdk/reference/com/google/android/glass/widget/CardScrollAdapter, it seems your 1) is possible, because:
1) The CardScrollAdapter's method public View getView(int position, View convertView, ViewGroup parent) returns a View (not a Card);
2) CardScrollView's get methods also return a View or Object, not Card specifically;
3) You can replace private List<Card> mCards; in the sample code (link #1 above) with private List<MyView> mViews;
But the documentation at those links also use Card as example, and the word cards seem to refer to static cards. So will have to test to find out for sure. However, there's a statement in link #1 that says "You can build a standard view hierarchy yourself or use the Card class.", suggesting it's possible to use a custom view.
I'll get back with you within 12 hours after I test with my Glass tonight.
As for your question 2, the answer is yes - you publish the scrollable content inside your app and not in the timeline. You can launch the activity (as in the sample code in Google's link #1) from a menu item selection, and the menu is attached to your livecard. Then inside that scrolling view, you can only swipe left and right to see other cards (or maybe custom views) in the scrolling view, but not the timeline. You have to swipe down to exit the activity (immersion) to go back to livecard, then you can swipe left and right and see the timeline. Note the scrolling view is not like static cards and will never show in the timeline. Also note that inside the scrolling view, you may use GestureDetector to capture other gestures (besides swipe left and right and down).
Just confirmed: custom views can be added to CardScrollView! I used a view that extends FrameLayout and inflates a layout xml file, and added three such views to CardScrollView. It works nicely!
Also tried to add a custom view that does the Canvas drawing, but haven't been able to see it shown in the scrolling view. Will try more later.
Just tested and found you can add any views to the CardScrollView - I'm able to add 4 custom views to a scrollview: one static Card, one view with Canvas drawing, one with OpenGL ES 1.0 drawing, and the final one with OpenGL ES 2.0 drawing. This is good to know to me! Thanks for your question.
I know how classic MVC looks like, but I was asked to write game using other type of MVC. I mean something like this : Draw which show my lecturer
BQ is LinkedBlockingQueue of Events. And I don't know how in this situation model can tell view and controller that his state has changed? My antoher problem with this MVCis fact that Controller shoud make deccision about consequenses of Clicked Button, but again, there is no connection from view to controller. Is it means that View should implement ActionListers inside of it?
It seems to me that the diagram shows the view generating events and placing them on a queue. The controller is reading from the queue and updating the model/notifying the view accordingly. To me this is still MVC.