Implementing custom View and/or ViewGroup (Flow Layout) in Android - android

I'm trying to achieve something similar to this:
So, this is a container which can hold an arbitrary number of children. Each child is a simple text with border. Children may differ by their width. I assume this part can be implemented by extending the TextView widget (since it isn't clickable). Much more interesting thing here is the container for these bordered text views. It should support a regular addView(child) operation which automatically aligns the child according to the simple rule: if there is enough room within a current row - place child to the right of the last item in row. If there is no space - move child to the next row. So the basic logic seems quite similar to TextView or EditText: if text is too long, we display it in several lines. My idea is too extend RelativeLayout, but I still hope to find something easier.
The scheme I've described above (custom container + custom TextView) is not a mandatory, I'm just looking for ways to achieve this. Any thoughts guys?

Seems that pattern I was looking for is called FlowLayout (thanks to nitzanj). There are several of implementations of it:
FlowLayout by blazsolar
FlowLayout by ApmeM
If you decide to write your own version, here are helpful guides about writing custom views:
Official docs
Dive into Android (video)
Custom views (video, Google I/O 2013)

Related

Android layout: scrolling list with header

This is not a design question, I have the item designed. I am confused on how to pull it off.
I am tasked with designing a view for Android that has a view of a user's post and the comments under it. The post contains some extra information and widely different design from the comments, but all of them need to scroll in tandem, like a web page would (Oh, how I am spoiled by my years of web dev...).
My current solution is to nest a LinearLayout (at the top of the view to contain the user's post) and a RecyclerView (below the post to display the comments) inside a vertical ScrollView. The information is actually displayed, but the RecyclerView, of course, scrolls independently of the LinearLayout above it and ruins the functionality of the view.
I wish, if possible, to keep the RecyclerView in use
The best case scenario would be to have the LinearLayout with the post scroll a certain amount, and then the RecyclerView take over. However, I don't want to poison my codebase with 200+ ugly lines of code to achieve this, so if this is a laborious task to complete, I would rather look for alternatives.
The first thing to understand is: do you really need a RecyclerView, or even better, do you really need recycling?
If the answer is yes, the way to go is two different item types in the RecyclerView's Adapter (for more details, see here or here). This concept was already present in the ListView: the main difference is that RecyclerView enforce the use of the View Holder pattern. It is not so complex, and, more importantly, is the way the RecyclerView is supposed to solve that problem. Depending on your UI design, you may also want to have different view types for different types of comments (plain text, images, ...). Remember that, when the RecyclerView is included in a ScrollView, the recycling won't work, because all the items in it will be drawn at once to compute the height of the content of the parent ScrollView.
If the answer is no, then you could just create your views at runtime and add them to a parent LinearLayout in a ScrollView. It is really nothing more than a for loop.
A more fancy approach would be to use an ItemDecoration for the user's post, but I don't see any specific advantage in this case.

Embed elements of a RecyclerView inside CardViews

I have a RecyclerView that display the list of modifications per day for a document. Items are TextView with values like "Line 3 updated to ...", "Line 5 removed", etc. The ViewHolder handle 2 types of views :
Headers : which are the days. These are simple TextView too that are in bold, larger, etc.
Logs: that's what I was talking about : "Line 3 updated ...", etc.
What I would like is that each "day", with its corresponding logs are embedded inside a CardView. But a document can have huge number of modifications per day (>100). So programmatically creating a layout with a CardView as the root, calling 100 times addView() on it to add each logs and then passing this layout to the RecyclerView does not seems a good idea to me.
Is their any way to delimit between a "positionStart" and a "positionEnd" views that will be embedded inside a CardView? It seems to me that this isn't possible or by adding each TextView programmatically inside a CardView but it will then slow down the binding of the views and break the ViewHolder pattern. Am I right or is their a solution I didn't think about ?
You have 3 options to achieve this "grouped in a card" behavior.
(as mentioned) you create the layout yourself and put the whole thing into the recyclerview. This is probably the worst solution since it negates the idea of a recyclerview in the first place.
You just wrap each of your items in a CardView (and set the corner radius to 0dp).
On < 21 devices (I think) there will be some additional padding and every item will appear as its own card, but on higher API versions those cards will lie next to each other and just have some "seam" between them. The shadow on the corner is also a bit buggy, but this is probably the easiest and cheapest solution.
Alternatively you can also create a custom view that fixes the errors mentioned above (margins between and shadow) and use your own to wrap the views. (I believe this is what the Inbox app does if I recall correctly, which also features lists in cards.)
You use an ItemDecoration. For this approach you need a kind of stable setup of your dataset, but if its just the headers and logs, you can draw a shadow above the header, draw borders to the left and right of every item, and draw a shadow beneath the last log. This will also require some setup, and if you introduce further view types you will also have to modify this code (it's highly dependent on your data set)
The 1. method is probably the worst idea. It will work for small lists.
The 2. method can work, but you either will have to create your own custom view or live with a "bugged" version on lower api levels.
The 3. method is something I tried once for fun, and will work, but you will have some additional dependency between your data, your adapter, and your decoration. You can see an example of this decoration here on GitHub. It just draws a shadow around all of the items.

create a grid of dots

I would like to create a grid of dots very much like in this game: https://play.google.com/store/apps/details?id=com.nerdyoctopus.gamedots&hl=en
The aim is for each dot to be touchable, so I can recognise where that particular dot is and other information about it.
I don't really know where to start. Do I want to create a custom View for a dot with all the information I want, and then create multiple versions of it? And then do I arrange them in a grid with the setTranslation() method, or would it be better to use LayoutParams with offsets?
If I created my own "Dot" that extended "View", then I could add a lot of different information/methods to it - I could theoretically have a changeColor() method. Is this the best way?
A GridView is not what I am thinking of (as far as I know) as it is basically a different style of ListView.
There are lots of questions here! I have looked at a number of questions here on StackOverflow and elsewhere, but none show/ explain how I should start.
I would use a TableLayout for this. A GridView is the equivalent of a ListView in a 'grid' form, with scrolling, view recycling and whatnot, and that is not what you need. A GridLayout, as Dalmas suggested, would be a much better option if you want to build a static grid, but in my experience it is not easy to distribute the available space equally between columns, and if you are going to need to alter the grid distribution during the game, a TableLayout is much easier to use.
For the dots, yes, a custom view with a configurable color would be the best way to go around it.
You should use a GridLayout. It will do exactly what you need. It is available through the android support library v7 : http://developer.android.com/tools/support-library/features.html#v7-gridlayout
It allows you to arrange views using a grid of rectangular cells.
For the dots, I would go with a custom dot view as you suggest, with a simple method to set the color. Don't store any data in the views if possible, it will make things much easier and flexible.

Need suggestions for dynamically creating views in android

I am going to start one app where my activity page will contain "n" grouped views. Grouped view means "collections of views (i.e. One group can have TextView+Button+ImageView)". So the page will have "n" number of such grouped views.
I need suggestions like what would be the best practice to implement this. I could think of below ones:
1) Should a ScrollView be used (Then I will have to create groups in runtime and place one under another)?
2) Or a ListView be used (Then how can I accommodate the height of each row as grouped views height may differ from each other?)
Or is there any other way I can go along with?
Appreciate the suggestions and any sample examples if have. Advance Thanks.
Both options would work, it really depends on your use case.
Place a vertical LinearLayout inside of a ScrollView and add your grouped-views to the LinearLayout. I would recommend this if you have a relatively small number of such views (not necessarily a fixed number, but small enough that you wouldn't have to scroll many "pages" to see them all). Make sure the ScrollView has android:layout_height="match_parent" and the LinearLayout has android:layout_height="wrap_content".
If the number of grouped-views is not small, you could use a ListView and make an Adapter for it. This lets you take advantage of ListView's automatic view recycling when items get scrolled off screen.
For either case, make an XML file for just the grouped-views. In code, you would get a LayoutInflater object (usually by calling Activity.getLayoutInflater()) and call inflate(R.layout.your_grouped_views, null). If using the LinearLayout, you would add it in code with one of the LinearLayout.addView(..) methods; if using the ListView, your adapter would return the whole thing from getView(...).
create one xml layout containing the constant elements of your group view.
in you main xml layout which will be the contentView of your application, put a ScrollView and a single LinearLayout.
then in the program inflate as many views of your group view as you want.
For your answer i want to give you referance of this website, on this website you can learn create dynamic view in android...

Android - how to draw in a multiple view layout

i have to draw a ball inside a view (or anything else that is good for this task).
I have followed some tutorial about the matter, but every tutorial that i have found
uses only one view (that is shown on the screen without the use of a layout).
But in my Activity i use a layout, that is composed by many views, and i want to draw
only on one of them.
here a little mockup!
Anybody knows a way to do it?
Is the view the wrong container to do it?
Thanks is advance!
Bye
...
You should extend a view that inherits from ViewGroup. this kind of view lets you handle a view that contains other views. with that, you can control the drawing, measures and layout of each of it's children separately
Your mockup can be made with a LinearLayout, which will contain some TextView's and you own View (the one which is containing the ball).
I'm surprised by this question, because there are many examples over the net explaining how to build a layout containing multiple views.

Categories

Resources