I need some valuable advice from you guys...
I have a UI where I have to drag objects from one view to another.
I have a rough sketch of this UI below
I think I have to create a custom view for this. I have to drag a square and a ball from bag 1 and bag2 [both bags are scrollable, can contain 10 to 60 items each] and drop it to the closet one by one. and later I have to find the number of items in the closet. The items in the closet must be arranged in a well maintained fashion [may be ...like 6 in a row].
Where should I start?
How many custom views should I use?
Is there a simple and effective UI solution for this?
Happy coding..!
I would suggest a design with three different GridView objects laid out inside a ViewGroup that supports dragging objects from one GridView to another. The objects would be custom ImageView subclasses so you'd have a place in code to support a drag-and-drop protocol of some sort and because you'd likely want to associate some data that is specific to your application with the objects being dragged.
As for the drag-and-drop protocol, you could consider an adaptation of the Android Launcher drag-and-drop framework or the current drag-drop classes described on the Android developers' website. I don't have much to say about the current drag-drop classes. I have not tried them yet, but understanding them is on my to-do list. However, I have done an adaptation of the Launcher code, and I have written it up on my blog and posted demo apps and source code there. See Drag-Drop for an Android GridView.
With the framework that originated in the Android Launcher, you have a good set of classes and interfaces to work with. Some of the objects include: DragLayer, DragSource, DropTarget, DragController, DragView. The DragLayer is a custom ViewGroup within which all drag-drop operations occur. It delegates handling of all the touch events to a DragController, which is the object that does the actual moving of objects around on the screen. As it does so, it interacts with DropTarget objects to give the user visual feedback that something is being dragged and that a place to drop something is available. A DropTarget is an object where something can be dropped. A DragSource is the interface for objects that can be dragged within the DragLayer. The Launcher framework is a good one because it gives you a way to think about dragging and dropping and how you want to divide up the responsibilities defined by the framework.
The reason I suggest GridViews for your problem is it sounds like you are thinking that way already. The closet has "maybe 6 in a row" so that could be a GridView with one or more rows depending on how screen space you have. A GridView would also work for the container that holds the squares and circles. If that is a good fit, you could study the code in my drag-drop tutorial and see if that makes it easy for you to move objects from one GridView to another.
In my demo program, I ended up with a custom subclass of ImageView that I called an ImageCell. These are views that are on the grid. An ImageCell allows objects to be dragged from them and onto them. For awhile as I worked on the tutorial, I had a custom GridView class too but ended up with the standard GridView. It sounds like you'd want a custom GridView because it sounds like being in the closet is different than being in the other sections. Having it gives you a convenient place for the methods you have not thought of yet.
I hope some of these suggestions prove useful.
Depends on the Android version you are targeting. For 11 and above you can use the built in drag and drop functionality, otherwise you are pretty much on your own. I would normally advice you to implement some sort of a long press action that might even allow you to select multiple items and move them in batches, which would be a really simple thing to implement.
If you really need DnD you should check out this example, it should give you some idea on how to make your own implementation.
I think that bag1, bag2 and closet can be three instance of the same configurable custom view (let's name it CustomBagView).
CustomBagViews should be responsible for displaying items (using a gridview of imageview for example).
I think those will not need to handle drag & drop directly but they should support
removing and adding elements
provide a setOnItemTouched(Interface_class) callback setter.
Then you will need to code a Container custom view (let's name it BagContainerView) that will contain the three bags and handle the dragging & dropping from the bags.
You will provide a handleDrag callback to each bag using CustomBagView.setOnItemTouched, then track the finger motion in it.
When the dragging finishes, you must find where it ends, locate the right 'customBagView' and ask it to add the item to its list.
Related
I am new in the corporate world & from design perspective please correct me if I am doing something wrong here
I am fetching images from Flickr API.
GOAL: Show these images in two different type of view, grid view and listview. Which can be switch through the slide.
So I am using a View pager with two fragments and both of these fragments has separate listeners. So when the response came from Flickr both of these listeners are notified.
In my opinion, this saves two times calling of REST API, but I am looking for even more efficient design or flow through which
Using single listener
Rest API should be called once
Result should be store (Just in ArrayList) and share to both of views
May not choosing two separate fragments
Avoid creating Adapter object two times
Image should be stored in cache
Any tweak or suggestions will be helpful a lot, please comment if you don't understand any part or whole question.
For above problem, the tweaking you are thinking is almost right. Other than below:
What I believe you must create two different adapters to have more control over different views. For example, you might want to show with scale type crop center for an image in list view but scale type center inside for an image in grid view. There might be the different type of thing you may want to perform. So, it's a good practice to make two different adapters, to make the code more manageable.
Again the same goes for the fragment, see if actions in both the fragments are same or can be done with single variable passing. Then only go with a single fragment.
Rest of the things are perfect.
This is not a code problem, I interpret the guidelines as that being OK.
I've been researching a way of building an infinitely scrolling calendar-like view in Android, but I've reached an impasse.
Right now my dilemma is that most of the similar views available have their children placed relative each other in a recurring style. With this I mean:
item 4 comes after item 3, which comes after item 2, and there is constant padding/margin between all items.
What I need is a way to produce an infinitely long scrollable view that may, or may not, contain items. The items should be placed at variable positions within the view. The best way I can describe a similar looking view is a one-day calendar-like view that is infinitely scrollable.
So far my best two bets are using the new RecyclerView with a custom LayoutManager (this seems very complex and still not perfectly documented by Google though). I like this approach because, among other things, it is optimized for displaying large sets in a limited view.
My other solution would be to build a completely custom View. However, with that solution I loose the adapter unless I build a container view (which is probably more complex than building a layout manager).
How would you go about solving such a problem? Tips are appreciated, I don't need code examples, just ideas which path is the best to solve this problem.
Thanks.
Apologies if I've misunderstood the guidelines
Edit: How I resolved this problem
My first solution to use RecyclerView with a special Decorator seemed promising, but it remained a "hack" so we decided not to go for that solution since we were afraid of the complications that it would create down the line.
To solve the problem I went with a SurfaceView instead of an Adapter, this means having to rewrite all the adapter-functionality for my SurfaceView but it seemed to be the best way of solving this issue of very custom drawing and layout managing for my use-case.
It still would be nice to build a custom Viewgroup that can handle this kind of layout problems.
ListView and ListAdapter are based on a fixed list, so the current infinite-scrollers just keep adding more and more data to the end of the list.
But what you want is scroller similar to Google's Calendar app which has a bi-directional infinite scroller. The problem with using ListView and ListAdapter in this case is that if you add data to the front of the list, the index of any one item changes so that the list jumps.
If you really start thinking about this from the MVC perspective, you realize that ListAdapter does not provide a model that fits this need.
Instead of having absolute indexing (i.e. 1, 2, 3, 4, etc), what you really want is relative indexing, so instead of saying "Give me the item at index 42" you want to say "here's an item, give me the five items before it". Or you have something like a calendar date which is absolute; yet — unlike your device's memory — it has effectively no beginning or end, so what you really want here is a "window" into a section of that data.
A better data model for this would be a kind of double-ended queue that is partly a LRU cache. You place a limit on the number of items in the structure. Then as prior items are loaded (user is scrolling up) the items at back end are pushed off, and when subsequent items are added (user is scrolling down), items at the front are pushed off.
Also, you would have a threshold where if you got within a few items of of one edge of the structure, a "loadNext" or "loadPrevious" event would fire and invoke a callback that you set up to push more data onto the edge of the structure.
So once you've figured out that your model is completely different, you realize that even RecyclerView isn't going to help you here because it's tied to the absolute indexing model. You need some sort of custom ViewGroup subclass that recycles item views like a ListView, but can adapt to the double-ended queue. And when you search code repos for something like this, there's nothing out there.
Sounds like fun. I'll post a link when I get a project started. (Sadly, it won't be done in any timely manner to help you right now, sorry.)
Something that might help you a little sooner: look at Google's Calendar implementation and see how they did it: Google Calendar Git repo
What you may be searching for is a FragmentStatePagerAdapter , where you can implement a swiped view, meaning when the user (for example)swipes to the right, a completely new view is displayed.
Using a FragmentStatePagerAdapter , you can handle a huge amount of views without overflowing the memory, because this specific PagerAdapter only keeps the views' states and is explicitly meant to handle large sets of views.
Keeping your example of a calendar, you can implement swiped navigation between for example weeks and generate the week views on demand while only keeping for example the year and the week's number as identifiers.
There are plenty of online tutorials for Android, maybe you have a look at this one
I'm working on an app right now displaying a contact list. The app is for Android and iOS, developed in AS3. That contact list contains on a basic usage 1000 items and that could go to 10 000.
Now a displayList with that many items does not work of course.
So I tried using BitmapData (the same item is updated, moved, and "stamped" on the BitmapData) before rendering but again, that's too big for a bitmapData.
I am now thinking about calculating the position of the scroll in the contact list and render on the displayList only what's on screen but I'm not sure how to handle this.
What are the best practices for that kind of issue?
Thanks
I am now thinking about calculating the position of the scroll in the
contact list and render on the displayList only what's on screen but
I'm not sure how to handle this.
That's the correct way to do it, it's a form of object pooling and I think it's also known as layout virtualization. I don't know how to do it in classic AS, but I've been using the Starling framework (gpu rendered display list), and the components lib there (known as Feathers), has such a list, you may wish to check its implementation. Here's a demo (check the List), I've tested this with thousands of items and it works perfectly:
Feathers Component Explorer
But in short the idea is to create visual components equal to the maximum that can be seen at the same time. Then, whenever the list moves you must check which are the visible indexes. When they change, which happens when an item becomes invisible - for example going off the top, you move it to the bottom and reuse it with new data, corresponding to its index.
It's best to use some framework for that - search for UI tools. If you are using Starling - there is Feathers. Also you can use MadComponents which is pretty nice. For simple cases you can use MinimalComponents.
They all have built in lists. If you don't like them, you should build one by yourself.
The best practice is to show only the visible items, and have others removed from stage. So you have to calculate the current position of the list that is being scrolled, calculate the items that are visible, and then add them and display them. Everything else should be removed and hidden.
But again, I think some of those I mentioned should fit your needs.
Here's the basic UI i intend:
There is central circle:CENTER. As the view is rotated, new circles:NAME are generated on the circumference. The circle at the top is a newly generated circle, i.e. if an already generated circle passes the top it fetches a new name.
I don't know the Android API well enough yet, so can someone point me in the right direction? What classes should I look at? How can I create that sort of pathing? Do I generate circle programmatically or have the views already in the xml layout but invis?
Thanks.
EDIT: Currently I'm working on the custom views that will be each circle.
I think you could do it by extending AdapterView. I would start by looking at the source code for it and some of its decedents to see how they implemented them.
The functionality you are after I don't think is very far removed from a ListView or some of the other simple Adapter ready View widgets.
The main difference is going to be your onDraw() method, you'll need to override that to draw the circles for you. Whether you make the circles programmatically or define your own views in xml is going to depend on how you want to appear visually.
I don't have any sample code for the rotation effect you are after but surely it can be accomplished with a canvas and some geometry.
Once you've got the AdapterView built you'll also probably want to subclass an Adapter to hold your names and override its getView() method to populate the names into the circles for you.
If you have not ever implemented any of the ViewGroup widgets I suggest you start by exploring some of those. ListView, GridView, etc.. Learn how to use it with an adapter and some data to create the dynamic layout. Once you have a good understanding of how to use the ones that are already built then start trying to tackle the one you want to make.
I am comparing performances, specifically scrolling speeds of a ListView, of apps that I create, to native Android 4.0 apps - Gmail, Gtalk, etc.
One thing I have noticed is that the scrolling frame rate of a ListView on the native Android apps are very high - almost 60fps. In my apps, a ListView don't scroll nearly as fast.
Assuming I'm using ListView incorrectly (which I'm not - I've followed everything stated here: http://www.youtube.com/watch?v=wDBM6wVEO70), I decided to create a dummy ListView that just returns a dozen almost empty LinearLayout views as it's rows (yes I'm using convertView correctly). What's disturbing here is that my almost blank ListView has slower scrolling performance than any of the native apps - Gmail, Gtalk, Contacts, etc.
As a side note, a simple ScrollView has really good scrolling performance, but it is inadvisable to use a ScrollView for large lists.
Clearly, the native apps are doing something (or have access to something) that I don't understand. Unfortunately these native apps aren't open source. Does anyone have any insight as to how these native apps achieve such tremendous performance?
After look at the source code for the native email application, I have found that the list items in a list of messages are single Views, not ViewGroups like LinearLayout. That makes for a very flat View hierarchy which leads to a better frame rate while scrolling the list. I think I remember watching a video of a talk by Romain Guy (one of the lead Android UI engineers) that mentioned that the Gmail team did something similar to increase performance.
To achieve this yourself, you'd have to subclass View and draw everything in the View yourself in the onDraw() method.
Here is the source for a message list item in the current email application.
They do a cool trick where you inflate a view (but don't attach it), get the coordinates of where the items go based on the ViewGroup it is in, and cache the coordinates in a Map so when a view is recycled in a list you don't have to inflate that view again. I might try this in a future project of mine!
I hope this helps!
There are some techniques to make ListView faster: caching and using dissapeared list items as new list items to avoid long operation of creating them. You need to create your own class based on ListView to realize these techniques. Read more here.
I also followed on that video to build my list view. In my app, there are not much items (rows). But I think if we just do as the video said, we are on right way, at least on the theory?