Draw background height depending on a given value Android - android

I would like to have a background on my app that changes color depending on a given number. Let me elaborate some more. For example, I pass the number 40 out of 100, 2/5s of the screen should be x color, and the other 3/5s should be the other color. Here are two little diagrams:
40 / 100 40/60
+---+ +---+
| | 3/5 not filled in | | 1/3 not filled in
| | |...| 2/3 filled in
| | |...|
|...| 2/5 filled in +---+
|...|
+---+
So I was thinking I could go about making a dynamic background (giving a certain number) by drawing in the shapes. The problem is, I am not exactly sure how I would go about doing this. Where do I place the code to draw the shapes, and how exactly would I insert them into my XML file in the correct place (I already have a static color background that is up in my XML)?

Ok, you need to create an activity with two Linear Layouts. The width attribute will be set to match_parent and the height to 0dp. You will then be able to set the height with a layout weight of X %.
As an example, those layouts split the screen 25% 75% :
<LinearLayout
layout_weight="1"/>
<LinearLayout
layout_weight="3"/>
Give them an id to change values programmatically (weight and background color).
You can do it this way :
LinearLayout top = findViewById(R.id.top);
//Third Param stands for weight
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, 0, 1.0f);
top.setLayoutParams(param);
top.setBackgroundColor(Color.BLUE);

Related

Android: Can't make small fontsize on programmatic textviews

I'm using the following method which programatically creates a linearlayout and populates it with two textviews, adds text and then turns it into a drawable that I later use a layer above a shape. However, I've noticed that I can't create a small fontsize - it seems stuck at a minimum size which is relatively.. large, and anything that I specify below that value just seems to make it look increasingly blurry (but still the same size). What could be the reason for this?
This behavior occurs whether or not I used TypedValue.COMPLEX_UNIT_SP.
Edit: This size stays the same even if I specify something ridiculous like:
.setTextSize(TypedValue.COMPLEX_UNIT_SP, 60);
it doesn't get any bigger - it just gets "sharper".
Edit 2: If I specify the top textview as having a very large size, then the smaller I set the second textview, the smaller it becomes - as a ratio (for example, if I set the top at 100 and the bottom at 50 it looks exactly the same as the top at 10 and the bottom at 5). However, in no way can I reduce the size of the top textview.
Edit 3: If I remove one of the textviews, and leave only the other one as a single textview in the layout - I can't change the size at all. I can only make it more or less blurry depending how low I set the number but it will always appear the exact same size on screen.
private Drawable createTextLayer() {
LinearLayout newLinearLayout = new LinearLayout(getContext());
newLinearLayout.setOrientation(LinearLayout.VERTICAL);
newLinearLayout.setGravity(Gravity.CENTER);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
newLinearLayout.setBackgroundColor(getColor(R.color.somecolor));
newLinearLayout.setLayoutParams(layoutParams);
TextView headlinetv = new TextView(getContext());
TextView bodytv = new TextView(getContext());
headlinetv.setText(headlineText);
headlinetv.setTextSize(7);
headlinetv.setGravity(Gravity.CENTER);
bodytv.setText(bodyText);
bodytv.setTextSize(6);
bodytv.setGravity(Gravity.CENTER);
newLinearLayout.addView(headlinetv);
newLinearLayout.addView(bodytv);
newLinearLayout.setDrawingCacheEnabled(true);
newLinearLayout.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
newLinearLayout.layout(0, 0, newLinearLayout.getMeasuredWidth(), newLinearLayout.getMeasuredHeight());
newLinearLayout.buildDrawingCache(true);
Bitmap b = Bitmap.createBitmap(newLinearLayout.getDrawingCache());
newLinearLayout.setDrawingCacheEnabled(false);
return new BitmapDrawable(getResources(), b);
}
Change your code to:
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 7);
Change the font size of 7 to any font size as you wish.
This turned out to be quite tricky and took me several hours to solve, but I'm posting the answer for anyone else who ends up in a similar situation.
The cause:
The entire drawable layer was the uppermost layer above a shape, and was therefore stretched to the size of the shape no matter what. In order to stretch it to the size of the shape, the largest view was stretched (essentially, the longest textview) and therefore couldn't be enlarged or reduced in size.
The solution:
I defined two more textviews, gave them the longest string by 1 character, and made the textcolor transparent. I would have preferred to give them blank space as content but android refused to measure a textview containing whitespace, so it had to be actual text. I put one textview at the top and one at the bottom and thus the visible text appears perfectly centered and in the correct font size.
Edit:
There turns out to be a better way of doing this. Define the textview as the same size as the shape on which it sits as a layer and define padding around the textview (play around with it to find the minimal amount of padding needed). If you have several textviews, divide the size of the shape by the number of textviews and give each one a fraction.

Update sibling Views position during animation in a wrapped container (tried many methods. Still not achieving its intended effect)

Say we have the below vertical LinearLayout (WRAP_CONTENT on both layout width and height) with two childs Button with varying height.
{ LinearLayout
* empty space *
| |
| Button 1 |
|__________|
|Button 2| }
Why animating Button 1 "y" using ObjectAnimator, producing this:
{ LinearLayout
| |
| Button 1 |
|__________|
* empty space *
|Button 2| }
hence leaving a space there instead of moving Button2 below Button1 as well?
As for the code (nothing fancy): ObjectAnimator.ofFloat(button1, "y", delta).start();
I tried using ValueAnimator (with setY in OnAnimationUpdate() and then upon seeing the same thing,
Setting LinearLayout to invalidate during OnAnimationUpdate() also did the same thing.
tried with TranslateAnimation with fillEnabled and fillAfter being true. Both still producing this behavior.
What am I missing here? I have used LayoutAnimation but so far, I only used to animate them if a child is added or removed. Not if their bounds change.
Can anyone clue me in to the right method/terms here (or the correct way to achieve this effect)?
Note that I also actually wanted Button1 to be clipped by the parent container, if I animate beyond the parent bounds (though I not sure if it makes any difference for Button2). English isn't my first language so pardon the grammar or terms. Thanks.

LinearLayout in HorizontalScrollView is not expanding

I have this custom HorizontalScrollView that dynamically builds the following layout
<HorizontalScrollView width=match_parent>
<LinearLayout width=match_parent horizontal>
// here TextViews are dinamycally added
</LinearLayout>
</HorizontalScrollView>
so whenever I need to update the TextViews, what is actually done is removeAllViews() in the LinearLayout and they are re-created and re-added.
The TextViews have a padding of a some DP and setLines(1);. When adding them to the LinearLayout, they're being added with LinearLayout.LayoutParams(0, WRAP_CONTENT, 1f) (zero width, but weight=1).
The objective here is that if the TextViews are smaller than the screen width they will expand to fit the screen and if they're bigger than the screen width they will be padding + text lenght + padding and scroll horizontally in the screen.
It almost works except in some edge cases. Examples:
Works: I have 5 TextViews with a couple of short/medium words on each. All layouts nicely and you can scroll through them
Works: I have 2 TextViews with a couple of short/medium words on each. The TextViews expands to fill the screen and the text is centered on them.
Fail: I have 3 TextViews with the following texts: 1 lorem | 43 consectetur | 20 dolor the layout will simply match the screen width and the word "consectetur" will disappear (trying to go to the next line). Similar fails for different size words or numbers.
I tried requestLayout, invalidate, setVisibility(GONE);setVisibility(VISIBLE) updateViewLayout, setFillViewport(true); and trick out the layout weight of the TextViews based on the text lenght. All with no luck.
Does anyone knows how I could make this work without having to re-write the onMeasure of the LinearLayout (which I checked it's a total of 381 lines for the Horizontal version)

Android: Position by percentage?

I have a UI Design from my designer, and it exists of a background map with several buttons on it, positioned non-linear all over the map. Currently I position them in a RelativeLayout that is as large as the map, and use margin-left and margin-top etc in dip.
This works ok, but I also need to account for users with very small screens, that cause the map to scale down. My relative layout scales with it, but the margin values ofcourse not.
So I am wondering, how should I do this? I would prefer to layout these buttons using percentages like
left="30%"
top="50%"
Is there anything in Android that makes such a thing possible? Otherwise I have to come up with a custom layout class for that.
Visual Representation: (Ofcourse they don't actually are on 6 lines, and partially overlap in x or y position). It's actually a real (abstract) map of a building with location markers that you can press as buttons.
-------------------------
| x x |
| x |
| |
| x |
| x |
| x x|
-------------------------
Here is a complicated way that does not require a custom ViewGroup. Suppose you want a button at left 30%, top 40%
FrameLayout
View with background, match parent
LinearLayout orientation=horizontal, match parent
View layout_width=0dp, layout_weight=30, height=match_parent
LinearLayout orientation=vertical, width=0dp, weight=70, hieght=match
View layout_height=0dp, layout_weight=40, width=match_parent
FrameLayout layout_height=0dp, layout_weight=60
Button
I use Dimension resource files put in the relevant layout- buckets so I can change margins/paddings/sizes depending on device size.
(http://developer.android.com/guide/topics/resources/more-resources.html#Dimension)
(Storing dimensions in xml file in Android)

How to make smart tablelayout

I came up with this very annoying layout issue.
Basically the UI component I'm looking for is not that complex, but the behavior needs to be exact.
In all cases I have 2 or 3 texts I need to layout horizontally.
In best case scenario all of these 3 fit in one line, so layout is not a problem.
| text 1 < empty space> | text 2 | < empty space> text 3 |
But when I hit an issue that text1 needs more than 1 lines, I should set that column 0 stretchable for TableLayout at the same time text2 might also need more than 1 lines so that column also needs to be stretchable and I would need the result to be like this:
| text1 many lines taking 40% | text2 takes 20% | text 3 many lines takes 40% |
And when this issue comes I haven't found a way to set TableLayout shrink and stretch columns. And also problem is that TableRow can contain 2 or 3 children.
I did few hour testing playing with LinearLayout and onGlobalLayout I calculated how much which is taking and adjusted weights of those views, but that's very complex and not working always, width on view3 sometimes just returned zero when view1 was very long.
I'm looking for some tips where to start here, should I do layouts in xml and inflate them instead programmically making them etc.
Okay I found out the solution, column 0 shrinkable, column 1 stretchable and tablerow span 2 for tablerow child number 2 if only 2 childs.

Categories

Resources