I've got the following node in my XML layout:
<com.x.y.view.TagLayout android:id="#+id/TagLayout"
android:layout_width="fill_parent" android:layout_height="170dip" />
TagLayout is a class that extends ViewGroup, and basically holds a bunch of buttons with text (a custom object that act as tags, but that's neither here or there).
The problem is that when there are too many buttons, the view no longer scrolls. I can confirm that I am adding tags but I can't see anything.
If I wrap the above within a ScrollView, the layout never renders. I tried adding the attributes android:isScrollContainer and android:scrollbars, but that doesn't change anything. Is there something I'm missing here?
I should also add that TagLayout is overriding the onMeasure() event. I guess I need to implement a scrolling mechanism there...?
Well, I mostly got it. I had to actually wrap the node above with a LinearLayout, then wrap THAT around a ScrollView. The padding is a little off (the last item is cut from the view) but it's on the right track.
You can add scrolling to your custom ViewGroup without wrapping it in multiple other layouts and views (in fact, it's better not to wrap it if you don't have to...having flat layout hierarchies is much better for performance). Just do everything described in this question, and make sure you add setWillNotDraw(false); to your custom ViewGroup constructor as described in this answer.
Related
I have been working with Android for about 4 months. I need some guidance on how to implement something like this:
In that picture I've used three of the custom viewGroups (calling it ArcScrollView) stacked on top of on another which is what I am trying to achieve.
The questions that I have are:
Do I need to extend ViewGroup, frameLayout or what?
How can I make it scrollable?
I took a look at LinearLayout source code and it was extending frameLayout but again LinearLayout is not scrollable and need to be hosted by a scrollView.
I need to have complete control over scrolling because these arcScrollView are rectangles and I need onTouchIntercept of the viewGroup to return false (not consuming) at certain positions.
Is scrolling actually just changing the starting position of the first child view and putting them after one another or something magical that Android does?
I think I need to override the onDraw method also for drawing the partial circle. Does that effect anything that I need to worry about?
Should I override the ScrollView and LinearLayout instead? because I think there is a lot that have been implemented in them.
I am trying to draw a View in a ViewGroup without adding it to the child list.
I am doing this because I want to display something like a ProgressBar in the exact center of layouts like a LinearLayout so I don't want the layout to handle the measuring and layouting.
I also don't want to complicate the view hierarchy by adding extra layouts just to achieve this effect so my solution was to extend the LinearLayout, create a ProgressBar and handle measuring, layouting and drawing for that view myself.
My implementation seems to work ok from what I tested but I am wondering if there is anything I am not noticing or if there are any problems that can appear in the future.
From what I understand calling addView also sets the child view's parent and calls dispatchAttachedToWindow, these methods are package-private so I can't call them myself.
Is there any side effect that can arise from calling measure, layout and draw on a view that has no parent and that was not "attached" to a window? Is there a safer way to achieve the same effect?
Thanks.
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)
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.
I have a working example of a grid that allows items to be reordered using long touches to active a drag-n-drop. All is working well if the items are simple Views e.g. TextView or ImageView but if the items are LinearLayouts only the layout itself is displayed.
I've been using Tom Quinsn's grid (thanks Tom!!!) from this posting:
Android Gridview drag and drop example
I can get LinearLayouts to work if I derive my own LinearLayout class and override onLayout(), but this forces me to hardcode the positions of the child controls in the layout within this function.
Ideally I would like to be able to define the item layout within an XML file and inflate them before adding them to the Control that handles the grid. I'm guessing that for some reason the framework is not calling the layout function for the children contained within the DraggableGridView view as defined in Tom's code but I can't understand why that is.
I am developing my own Drag and Drop app with good help from this link. You may compare the code with the one from Tom Quesinsn. It also gets the different children of a GridView and add them as "drop targets" that accepts drops on them and copy the Image of the View you are dragging.
This is a known problem with the DraggableGridView that -- unfortunately -- I haven't gotten around to fixing. When I wrote DGV, I didn't entirely grasp how views were laid out. You might try having DGV measure each child before laying it out. Adding something like:
getChildAt(i).measure(MeasureSpec.makeMeasureSpec(childSize, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(childSize, MeasureSpec.EXACTLY));
before the layout on this line:
getChildAt(i).layout(xy.x, xy.y, xy.x + childSize, xy.y + childSize);