Drawing a tournament bracket in android? - android

I have an app that will take a list of players and set them up so that you can go through and create a bracket dynamically. The number of players will change and the names as well.
Instead of showing a whole bracket, my point will be to go in columns. I.e. instead of the left side of the arrow, it show the right side:
My questions is how do I best draw this?
My initial thought is to do multiple layouts where I hard code textviews with custom drawables and lines for each column of 16/8/4/2 with just one border, but then I have to constantly change the layout setup.
My second one would be to dynamically draw it on a canvas based on this answer here, but it didn't give a lot of ideas of implementations.
My Questions: If I choose method 1, will I be able to dynamically change the layout of my activity?
If I choose method 2, how could I go about this? I'm still pretty new to android.

As for question 1, yes you can absolutely change the layout dynamically. You can create several layout files and do one of two things: The first, is you can use your activity's setContentView(int) method to completely reset the activity's layout to a new view. The second would be to identify the parent view of the bracket portion, cast it to a ViewGroup and use addView(View) and removeView(View).
As for question 2, you could go about using a canvas, but it would be quite difficult to use only a canvas, but possibly a combination of a canvas and a set of text views could work. While this isn't directly answering your question, this tutorial is one I have used in the past, and gives you an excellent sense of how to work with the Canvas class in android.

Related

Putting a button on top of an imageView

So here is my problem. I've spent couple of days on this and didn't get anywhere. I've tried every layout possible, but it just doesn't seem to work.
Basically, I have a map of a floor and I want to make it so when you click on different parts of that floor, a new activity or a dialog box shows up. I want this to scale for all the devices. Why is this so difficult in Android? I would think that putting buttons on top of an image would be easy and made sure that it wouldn't move like in HTML.
I have been looking into Surface View, but wasn't sure if that's the best way to go? I can get the coordinates of the objects on the floor, would that help?
I want to implement this inside of an fragment. Thanks!
One possible solution could be to have a RelativeLayout as the base layout of your 'Floor Map' fragment, with the floor image set as its background.
Then you could add buttons or any other views to the Relativelayout at the coordinates of the objects.
If you already know how many features the floor will have, you could add the buttons statically, otherwise, loop through your array of features to add them dynamically.

iOS: Relative Positioning like Android's layouts

Is there any way position views relative to each other like you can with Android layouts?
Example: You have two UILabels that are dynamically set to strings of variable length, one above the other, and you want the bottom label to appear directly below the last line of the top label, regardless of how many lines the top label ends up having.
Another example: Same situation as above, but one of the labels is sometimes hidden. You want the resulting label(s) to be centered vertically in the parent, regardless of whether it's one label or two labels.
Android's Linear Layout and Relative Layout make this very easy to do, but I can't figure out how to do this is iOS. Can it be done?
You will be able to do this using AutoLayout in iOS6. For an application that should run in iOS before 6.0, you have to do it by yourself, but this is not very complicated.
Actually I have implemented a class to do this (that's a long time ago, I hope it still works, but there is no reason not to). This OHStackView class is a subclass of UIView that automatically layout its subviews horizontally or vertically to stack or align them.
You can ask OHStackView to stack its subviews horizontally or vertically (one above the other, etc), or align their top/bottom/left/right borders or their centers, and even specify a padding between each subviews. Each time one of the subview changes its frame or size, OHStackView will automatically relayout all depending views to realign everything.
(E.g with your two UILabels, a simple call to sizeToFit on your labels to make them adjust their size to their content will relayout everything around automagically)
There is an example project provided so feel free to test it.
Note: IIRC, my subclass does not take the "hidden" property of the subviews into account. But you can easily add support to this behavior by adding a condition like if (v.hidden) continue; in the for loop of its layoutSubview implementation to only take non-hidden views into account in the layout algorithm.
HTH
I've been searching if it's possible for a long time. As far as i can tell, it's not possible for now. I don't remember where i read this,but it will be possible with ios6. Instead of using Android's Linear Layout,you can use sizeWithFont method to detect size of your UILabel,then you can set their frame to position them.First,you need to set their text of course to find their size according to their font family. Another thing you can use is sizeToFit method. Unfortunately,i don't know how to use it. You can give a shot,though. At that time,i found this.Maybe ,you can use it https://github.com/scalessec/CSLinearLayoutView

Which layout can provide free drag and drop insertion?

I'm using Eclipse graphical layout, and i want to Drag and Drop components to the layout and i want them to stay at the exact position that i dragged them.
Relative Layout is the closet thing but it changes the location of the components after couple insertion.
thanks.
Rami.
i want them to stay at the exact position that i dragged them.
No, you don't. Android devices come with screens in many different sized and resolutions, so fixed positioning of components is a recipe for making the application unusable to users with a different screen that you.
The point of layouts is that they can adjust to different screen sizes. Learn to use them properly.
You're looking for AbsoluteLayout, but it is deprecated.
RelativeLayout is the way to go, just pay some attention to the hints drawed on-screen when you place your elements.
You should be careful also to avoid circular references otherwise your items will be scattered randomly over the layout. (Example: Textview A on right of TextView B; TextView B on left of TextView A)
Be careful also when you change your element's id because the IDE does not update automatically all the references and thus your layout gets scattered again. When you update an ID you must update all its references in the XML file by hand.
Actually absolute layout is the answer what u want ,but that is deprecated.Relative layout does what you want.But it arrange its child based on parent position.If you drag a text view ,then other view will depend on this text view.If you have inserted 2 view,then third view will depend on the parent(2 views).But in between if u disturb any of the view ,it may affect other views.So do things systematically
In Java what we can typically use is GroupLayout. You may see what the equivalent is for android.

ListView row marker ala GMail

I am interested in creating a ListView where each row is marked the way it is done in GMail for 3.0+. This creates a nice separation of the left and right ListFragment.
Other examples include also Google Calendar on 2.3.4 for instance where a color marker is on the left of the ListView.
See the grey vertical divider between the two lists. How does one achive something like this? A bonus would be also the alternating width, but I guess that is only a smaller layout change.
I know I could probably do something like inserting an ImageView in there and then fill it with the color I would like but it seems to me that this is an ugly hack.
Another question would be also if there is a generalized way to combine the two ListView fragments somehow the way the GMail or Mail applications do it.
If you want speed, then the option I would go for is to use a custom View class (e.g. extend RelativeLayout) for the row container View and override the dispatchDraw(Canvas canvas) method.
The dispatchDraw method is called after the View has drawn its own contents and before it draws its children - the children are drawn when you call super.dispatchDraw.
Use this to do something like
private boolean mDrawMarker = false;
public void setShouldDrawMarker(boolean drawMarker) {
mDrawMarker = drawMarker;
}
public boolean getShouldDrawMarker() {
return mDrawMarker;
}
#Override
public void dispatchDraw(Canvas canvas) {
// draw the children of our view
super.dispatchDraw(canvas);
// draw our marker on top of the children if needed
if (mDrawMarker) {
// e.g. canvas.drawRect(...) or canvas.drawBitmap(...)
}
}
This way you avoid adding any extra views to the hierarchy which means you won't incur any penalty in the layout or measuring phases. Remember to re-use Paint and Rect objects if drawing a rectangle rather than creating a new one each time. Similarly if you use a bitmap you should share the same Bitmap instance across all instances of your View rather than loading a new one from your resources each time (this does not mean putting them in static fields)
For the indentation of the items, since in this case the lists don't seem to be overlapping you could (off the top of my head):
Set a left margin on the row container (not totally sure this will work)
Wrap the row container in a LinearLayout and set the left padding on this (if the above doesn't work)
Use a custom view class (if setting the left margin doesn't work)
Go with #commonsware suggestion and use two Views - one on the left with the grey background color and another to the right of that with the marker color - then just set the view on the left to visible/gone if you want indentation/no-indentation
As for the overlapping of the Views in the second example, I'll defer to #commonsware answer.
Please tell me if I have understood the problem correctly.... You would like to mark certain rows as selected, and selected rows appear to be indented visually (with a different colour and margin)?
Here are 2 techniques:
1 - Using a StateListDrawable for the row background:
If so I would create a list row layout file and set the "background" property to a StateListDrawable (can be XML). This will allow the row to switch visual states for selected and not selected.
The "drawable" attribute of the StateListDrawable would be a 9-patch PNG, one for the un-selected state that includes no margin, and one for the selected... the selected one would define a margin within the PNG itself, by specifying the content-area/bottom black line to not extend fully to the left hand side of the PNG, leaving a region which is your unscaled margin.
For the benefit of people finding this, Radley Marx just posted an excellent post on 9 patch: http://radleymarx.com/blog/simple-guide-to-9-patch/
With ListViews it's sometimes the case you want to turn off the "listSelector" (which is a separate entity either rendered above the list, or behind) and instead use the "duplicateParentState" attribute to allow the row itself to display the selection (no list selector needed). This can provide a bit more creative freedom, especially when you want to have variable-width margins on certain rows, or several types of row that all look different. Totally depends on the design though.
2 - Using a margin for each row:
If you decided you needed multiple types of colour indicator and so on, you may have to use a different approach, providing a margin attribute (which probably won't just work straight away)... This relates to how LayoutParams are used by the layout system. I'm trying to remember the exact details, but I think this is due to the different types of LayoutParam subclass, and the properties of a MarginLayoutParam (or subclass of that) e.g. marginLeft may be ignored by the layout code of the ListView. You should be using an instance of AbsListView.LayoutParams, which includes no options for margins. One way is to nest your row inside a container View (subclass) which does allow for margins in its LayoutParams*. I'm certain I didn't end up doing this extraneous-nesting but I'll have to dig into some code to remember the better solution.
You mention putting an ImageView and filling it with colour. There are a couple of alternatives you could look at... The most performant would probably be to define your own ListRow class and use onDraw() to actually draw the row contents yourself, canvas.draw_xyz() to paint the little colour tab, and draw text etc for the rest, rather than build the row in a composite layout. The second method using layouts would be to have a lighter-weight <View layout_height="match_parent" layout_width="4dip" background="#ffff0000" /> for example.
*A golden rule in Android layout: Complex UI hierarchy is death to performance, especially with things like ListView. It's often possible to avoid this by using other things: RelativeLayout, drawableTop(etc), 9-patch images, rather than adding more Views.
If I have misunderstood and the above is just too basic please could you provide some more detail, maybe a diagram indicating the exact part you need to reproduce.
How does one achive something like this?
Off the cuff, I'd use a View with the desired background color, visible when you want it, invisible when you don't.
A bonus would be also the alternating width, but I guess that is only a smaller layout change.
I do not know what you mean by "alternating width". I think there are two Views with the desired background color in a horizontal LinearLayout, with only one visible.
I know I could probably do something like inserting an ImageView in there and then fill it with the color I would like but it seems to me that this is an ugly hack.
Well, ImageView is a bit heavier than is needed. Otherwise, I fail to see why this is a hack. Think of them as icons that simply happen to be tall, thin, gray, and not always needed.
Another question would be also if there is a generalized way to combine the two ListView fragments somehow the way the GMail or Mail applications do it.
Use a RelativeLayout, so the right-hand fragment can float over the left-hand fragment.

Right way to do scrollable view of custom buttons?

I've just started playing with Android in the last few days and have begun to put together a simple application. I am struggling to work out whether I'm doing things the "right" way or just making life difficult for myself.
The app displays a series of connected nodes on the screen, similar to a mind-map. I want to be able to tap the nodes in order to edit them. When the map of nodes becomes larger than the screen, I need to be able to scroll on both X and Y axes as needed to see the whole map. Image of current implementation at http://ubergeek.org.uk/images/nodetest.png.
Currently I don't have scrolling working, however I assume that I can do that by making the root view a ScrollView and sticking an AbsoluteLayout inside that (though it's deprecated, I wish to place objects at specific X/Y coordinates).
The nodes themselves are currently each a pair of roundrects (one for the outline and one for the fill) and a drawText and are being drawn in the main activity's onDraw(). In order to make these clickable buttons I believe I need to create a custom view for the button in order to use its onClick() events. I can then create a view object for each of my nodes and add them to the AbsoluteLayout view.
Does this sound like a reasonable way to do it in Android, or is this a horrible abuse of the API? :)
Thanks!
Nope, that sounds about right. You just need to make sure that the view contained by the ScrollView has the right dimensions so the scrollbars will show up right, but I'm sure you got that covered.
It's certainly a bit non-standard, but I'm tempted to say that your approach will work right... I'd even go so far as to say that it's not a hack. Please keep us posted on how it works out, and if anything breaks!
(Btw, the SDK mentions that you should write your own layout instead of using AbsoluteLayout. Personally, I'd say use the AbsoluteLayout.)

Categories

Resources