SeekBar not displaying correctly on Android 2.x - android

I have SeekBars in an application which operate as expected and return values that I expect. However, on Android 2.x they display oddly.
I've looked for other similar things such as Android Drawable setLevel(); not filling SeekBar appropriately, but that is for a custom drawable. Otherwise I'm having trouble coming up with search terms for this issue to get anywhere.
In this case, all I'm doing is
SeekBar seekBar = (SeekBar)dialogLayout.findViewById(R.id.my_seek);
seekBar.setProgress(5);
seekBar.setMax(20);
If I move the slider, it properly fills the SeekBar the moment it's moved.
Any idea on what is going on?

After posting this, I realized the problem was the order of the method calls.
Incorrect
SeekBar seekBar = (SeekBar)dialogLayout.findViewById(R.id.my_seek);
seekBar.setProgress(5);
seekBar.setMax(20);
Correct
SeekBar seekBar = (SeekBar)dialogLayout.findViewById(R.id.my_seek);
seekBar.setMax(20);
seekBar.setProgress(5);
From what I gather if you first call setProgress(5) in my case, the system will set the drawable to display the progress as 5% since it is 5 / 100 and 100 is the default maximum.
Then if you call setMax(20), the value of 5 is still valid but the drawable is no longer valid and is not recalculated to display as 25% (5 / 20) of the bar.
Doing setMax(20) first will compel the drawable to be calculated correctly once you use setProgress(5).
In case it's of use to anyone, I tested this on Android 2.1, 2.2, 4.1 and 4.2.
Android 2.1 and 2.2 have this bug, the order matters
Android 4.1 and 4.2 do not have this bug, the order doesn't matter
Essentially to remain backwards compatible, always do setMax(int) first and then setProgress(int).

Related

Android TextView appears blurry when scaled

I recently found out that TextViews on Android are shown blurry / fuzzy when they are scaled in the 1.0-1.49 range.
I am not sure why this is happening, but it looks like a raster version of the unscaled version is used when the view is scaled on the XY axis in this range. However, the problem disappears if the view is scaled with a value above 1.5 (150%). Please check the attached screenshot collage in full resolution: https://i.imgur.com/A31ZC1N.png
The attached screenshots are from a real device, running Android 7.1.2 (API Level 25).
I have also tested this on an emulator running Android 9 (API Level 28), the results are identical. However, on my other device (OnePlus 6, Android 9), this issue is not present, everything scales nicely, without fuzziness.
A workaround for me was disabling HW acceleration on the current activity:
<activity android:hardwareAccelerated="false" />
Another workaround was setting a software layer on the parent of the view that is being scaled:
((View) mScaleValueTextView.getParent()).setLayerType(View.LAYER_TYPE_SOFTWARE, null);
Both of these will result in the TextView being scaled without the mentioned issue, but these methods have drawbacks, the first one that I noticed was that TextView's shadow caused by the elevation property was not drawn.
In order to demonstrate the default behavior, I created sample app where I added a TextView and a SeekBar that controls the scale, ranging from 100% to 200%.
The view is scaled by this method:
private void scaleView(View v, float scaleValue) {
v.setScaleX(scaleValue);
v.setScaleY(scaleValue);
}
You can get the entire sample app here.
Since the same code behaves differently across devices and the issue is occurring just between the mentioned scale range, I assume this is the result of a lower-level performance optimization that may or may not be implemented on some devices.
Is there any way to disable or work around this in a clean manner, without unwanted side effects?

Android RatingBar show black overlay on some devices

I have this ratingbar which is inside the applications and it is always displaying correctly.
But recently I realise that it is not working correctly on some devices (which include Nexus 5 with Lollipop version). The rating bar are covered by a black overlay as shown on the image below (only on some devices). When listview (with rating stars) is scrolled, the rating bar will be shown (and then black overlay shows again). it only affect the yellow stars but not the white ones.
I am not sure if anyone had ever met this problem before? I am thinking if it is the recent android update on Nexus 5 that causes this as the rating bar works well on other devices.
Accoring to me,
This may be using v21 of the support libraries or possibly unstable OS update as .xml file and code is not available.
These are the issue reported on google for rating bar please check link below,
RatingBar rendering broken on devices
The development team has fixed the issue that you have reported and it
will be available in a future build.
RatingBar w/ Custom Stars Drawable is rendered as 1 stretched star on pre-Lollipop phones
when using v21 of the support libraries, the RatingBar w/ custom stars
renders as expected. With v22, instead of 5 stars, you just get one,
but stretched to match the width that 5 stars should take
First of all, do not use RatingBar#setProgressDrawable because no
matter what platform, it is going to work like #setBackground()
(single stretched image for whole background). Secondly, setting
android:ratingBarStyle on theme level does not work. I ended up
creating custom style, with "android:progressDrawable" and applying it
for every view I needed.
RatingBar does not render in InfoWindow
setting the style to android:attr/ratingBarStyle does not work, and
ratingBarStyleSmall does work

TextButton padding changing with Android version

I have been developing an app over the past few months getting ready for publication. Everything was looking just perfect. I was doing a few things with text in buttons - using my own 9-patch button backgrounds, changing the default font, repositioning textbuttons with setX() and setY() etc. I had some big buttons and smaller ones. Some were a tight fit amongst other objects on the screen, but it all worked, the buttons looked perfect on a variety of tablets and phones.
Then I remembered one last thing on my todo list which wast to change the android:minSdkVersion in my manifest from 8 up to 11. I needed to do this because the setX and setY methods are only available on android 3.0 and higher. But as soon as I did this, the text within my buttons was all screwed up. For a start it was white instead of black - easily fixed. But also the padding round the text was completely different. Buttons were now overlapping each other and looking unbalanced in a variety of ways.
So my question now is this: Is there any way to say "this software must only run on Android 3.0 (api 11) and above" AND "let all the text button characteristics be set to whatever that were with api level 8".
I have no idea why such things would happen - but it's better to just support the older platforms if you can help it. For example, if the only thing keeping you from using API 8+ is the setX() and setY() methods, you can use ViewHelper in the NineOldAndroids project to do this and support the lower API. For example:
ViewHelper.setX(myView, myXValue);
ViewHelper.setY(myView, myYValue);

Using ActionBarSherlock; experiencing View.getLocationOnScreen() inconsistency between 2.2 and ICS/JB

I have a RelativeLayout whose size takes up all screen area that is available to the containing Activity. That is, it fills all screen area except for the notification bar.
I am using ActionBarSherlock. The ActionBar is set to overlay mode using getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY). Therefore, the height of my RelativeLayout spans from immediately below the notification bar right down to the bottom of the screen, and any child Views it holds could potentially be placed behind the ActionBar. The ActionBar is therefore definitely operating in overlay mode. I confirm this is the case on devices running 2.2, 4.0.x(ICS) and 4.1(JB).
Because my application implements a drag-and-drop mechanism within this RelativeLayout, I need to know the layout's position on the screen so that I can correct the absolute screen Y touch values returned by getRawY(). To achieve this, after the layout phase has been done, I have been calling mRelativeLayout.getLocationOnScreen() inside of onWindowFocusChanged().
On my 4.0 and 4.1 devices, the call to getLocationOnScreen() produced a Y value that matched the height, in pixels, of the very top notification bar. In order to determine the height of the notification bar and ActionBar combined, I would add the Y value returned by getLocationOnScreen() to the result of ActionBarSherlock's getHeight() method.
The problem is that when testing on a 2.2 device, getLocationOnScreen() is returning a Y value that is already the notification bar height plus the ABS height. This is the case even though the ABS is set to overlay mode.
There are a few questions on SO regarding implausable results from getLocationOnScreen(); the one here has an answer which gives me the idea to just abandon getLocationOnScreen() and instead calculate the RelativeLayout's top Y offset by subtracting the layout's height from the total screen height:
DisplayMetrics dm = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(dm);
int mRelativeLayoutYOffs = dm.heightPixels - mRelativeLayout.getMeasuredHeight();
What I find bizarre about the result of this though is that it seems to give me the same inconsistency as I get from getLocationOnScreen(). What happens on 2.2 is that the call to .getMeasuredHeight() on the RelativeLayout actually seems to be giving a height value that has the ActionBar height subtracted from the actual height of the RelativeLayout, even though the ABS is set to overlay and that I have visually confirmed it is definitely in overlay mode.
The best strategy I can think of doing at the moment is to just treat the result of getLocationOnScreen() differently depending on the operating system version. If it's 2.2, then I know it includes the ABS height. If 4.0 onwards, it doesn't. Anything between 2.2 and 4.0, I'm not yet sure. Perhaps people can help fill those details in. Perhaps the difference is introduced in OS versions that support the ActionBar natively? If it is predictable and well defined what the behaviour is, then hopefully this would be a safe strategy.
Failing that, are there any suggestions for other means of determining the RelativeLayout's top and left screen positions in order to correct the absolute screen touch values?
The problem was because I should not have been using getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY). Intead, my custom style (which inherits from a parent ActionBarSherlock theme) needed to contain:
<item name="android:windowActionBarOverlay">true</item>
<item name="windowActionBarOverlay">true</item>
Furthermore, I was wrong in saying that on 2.2 the ABS was working in overlay mode - in fact, it wasn't. Now that I'm using the above style items, it is now working in overlay mode in 2.2.
.getLocationOnScreen() is now correctly returning a Y value that only represents the notification bar height on my 2.2, 4.0 and 4.1 devices.

Auto Scale TextView Text to Fit within Bounds in 4.0

The solution Chase gave for this problem was working fine in 2.2 - 3.2 but when I tested it on 4.0 it failed.
Here is the original post:
Auto Scale TextView Text to Fit within Bounds
On 4.0 I get a strange line spacing problem which brings me to something he/she wrote in his/her code:
// Some devices try to auto adjust line spacing, so force default line spacing
// and invalidate the layout as a side effect
textPaint.setTextSize(targetTextSize);
setLineSpacing(mSpacingAdd, mSpacingMult);
I guess this is failing now and I'm not sure why (anyone?). Also not sure why he/she wrote it in the first place as isn't this OS dependent and not a device dependent problem?
ICS has TextView resizing issue where in some conditions it will resize up but not down. This black magic works for me. After you set the text of your TextView, also perform this
textView.append("\uFEFF");

Categories

Resources