Set transparent color in android webview - android

How to set transparent color in android webview?
<div style="background-color: black" >test</div>
How can I make black color to be transparent for the whole page (like chromakey)?

Had the same problem with the WebView, as it behaved randomly across different OS versions. Finnlay I fixed it with this code this after the loadDataWithBaseURL() call:
if (Build.VERSION.SDK_INT >= 11) {
webView.setBackgroundColor(0x01000000);
} else {
webView.setBackgroundColor(0x00000000);
}
I figure this will give the device something to draw, so various caching mechanisms will not kick in. But the result is practically the same as with total transparency, as it is undetectable by average human eye.
No performance penalties noticed as well.
Tested on several devices ranging from 2.2 to 4.2.
Cheers

try this
(YourWebview).setBackgroundColor(0x00000000);

I've found the solution. I've reimplemented OnDraw method of WebView
#Override
protected void onDraw(android.graphics.Canvas canvas) {
super.onDraw(canvas);
Paint p = new Paint();
p.setARGB(255, 0, 0, 0);
int removeColor = p.getColor();
p.setAlpha(1); // if Alpha is 0 it doesn't work. I don't know why
p.setXfermode(new AvoidXfermode(removeColor, 0, AvoidXfermode.Mode.TARGET));
canvas.drawPaint(p);
}

you can use this
webView.setBackgroundColor(0);

Related

Blur on Android

I am creating a blurred background for an Android app and having trouble with different versions.
While it seems I solved it for all cases, I don't actually have exact conditions on how to decide which case it is.
Right now, it seems this is correct:
/*
Here lies the question. Is this condition good enough? If android 10 or hw acceleration is off
*/
if (android.sdk_int >= 29 || hwAcceleration == false) {
// draw circle with blurred paint
Paint().asFrameworkPaint().apply {
maskFilter = BlurMaskFilter(radius, BlurMaskFilter.Blur.NORMAL)
}
} else {
// load drawable into bitmap and use deprecated RenderScript to blur it
RenderScript.create(this)
ScriptIntrinsicBlur.create(rs, Element.U8_4(rs))
...
}
According to this table, MaskFilter is not supported at all when hw accelerated, but that is not my experience with android emulators of version 10+. Is the table just not updated?

Trying to draw on canvas using canvas.clipPath

I am trying to draw circle on darken background, trying to achive smth like this -
This actually worked on my Samsung s4 and Samsung tab 3, but won't work on s2 and some emulator (all sorrounding viewgroup is darken, and inside oval too, seems like it does not see my circleSelectionPath). Help me please to find the way to make it work on every device
final Paint paint = new Paint();
paint.setColor(Color.parseColor("#77000000"));
Path circleSelectionPath = new Path();
mRectF.set(l, t, r, b);
circleSelectionPath.addOval(mRectF, Path.Direction.CW);
canvas.clipPath(circleSelectionPath, Region.Op.XOR);
canvas.drawRect(bitmapRect.left, bitmapRect.top, bitmapRect.right, bitmapRect.bottom, paint );
canvas.restore();
bitmapRect contains my viewgroup dimens (for example : 0,0, 500,500)
Got it. Android has a bug with canvas.clipRect, they have optimized it, but on some android apis it simple don't work after optimization ) I found an issue.
So fix - disable hrdware acceleration for this view
(Build.VERSION.SDK_INT <= 19 && mCropShape == CropImageView.CropShape.OVAL) {
//TURN off hardware acceleration
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}

how can I check if my device is capable to render Emoji images correctly?

I'm using Emoji unicode in a View. On most devices the images appear ok, but on one of my low-end device(android 2.3) they are rendered as little squares.
Can I check whether the device support emoji? So that I can publish my apk while won't show that ugly squares on some devices.
This is a late answer but I recently ran into a similar problem. I needed to filter through a List<String> and filter out emojis that couldn't be rendered on the device (i.e., if the device was old and didn't support rendering them).
What I ended up doing was using Paint to measure the text width.
Paint mPaint = new Paint();
private boolean emojiRenderable(String emoji) {
float width = mPaint.measureText(emoji);
if (width > 7) return true;
return false;
}
The width > 7 part is particularly hacky, I would expect the value to be 0.0 for non-renderable emoji, but across a few devices, I found that the value actually ranged around 3.0 to 6.0 for non-renderable, and 12.0 to 15.0 for renderable. Your results may vary so you might want to test that. I believe the font size also has an effect on the output of measureText() so keep that in mind.
Overall I am not sure if this is a great solution but it's the best that I've come up with so far.
please check the source code from Googles Mozc project.
The EmojiRenderableChecker class seems to work pretty well!
https://github.com/google/mozc/blob/master/src/android/src/com/google/android/inputmethod/japanese/emoji/EmojiRenderableChecker.java
it's like a compat version for Paint.hasGlypgh (added in Marshmallow).
https://developer.android.com/reference/android/graphics/Paint.html#hasGlyph(java.lang.String)
https://android.googlesource.com/platform/packages/inputmethods/LatinIME/+/master/java/src/com/android/inputmethod/keyboard/emoji/EmojiCategory.java#441
Inspired from the two methods found in the above file.
public static boolean canShowEmoji(String emoji) {
Paint paint = new Paint();
float tofuWidth = paint.measureText("\uFFFE");
float standardWidth = paint.measureText("\uD83D\uDC27");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return paint.hasGlyph(emoji);
} else {
float emojiWidth = paint.measureText(emoji);
return emojiWidth > tofuWidth && emojiWidth < standardWidth * 1.25;
// This assumes that a valid glyph for the cheese wedge must be greater than the width
// of the noncharacter.
}
}

Android drawCircle compatibility problems

I've got custom widget - blinking circle in custom frequency. In my onDraw method i paint a circle.
#Override
protected void onDraw(Canvas c) {
super.onDraw(c);
if (data[mBitIndex] == '1'){
c.drawCircle(c.getWidth() / 2, c.getHeight() / 2, c.getWidth() / 2, mPaint);
}
}
This works perfect on android 4.2.1, but if i try this on android 2.3, no circle shown. I've done some experiments to determine the problem
#Override
protected void onDraw(Canvas c) {
super.onDraw(c);
if (data[mBitIndex] == '1'){
c.drawColor(mPaint.getColor());
}
}
This works as i expected on both versions of android. But, it's a square, not circle, which i want.
How is it even possible to draw square, but not circle? I've searching on the internet, but noone has this problem before or it's only my problem. I don't get this, can anyone explain me where could be mistake?
On Honeycomb (API 13) or earlier, the hardware acceleration is buggy and cannot draw your circle.
Disable hardware acceleration for your view:
setLayerType(View.LAYER_TYPE_SOFTWARE,null);
This worked for me.
Or set targetSDKVersion to 14 or higher (which might cause other issues).

Canvas not displaying all drawn parts in Custom View?

I'm working on a custom view for an android application, similar to the Analog Gauge sample code available from Mind the Robot.
Running the code from listed site, I get see this on my screen:
(Motorola Droid, 2.2.3), (Emulator, 4.0.3)
(Xoom, 4.0.3)(Other phone, 4.0.3)
The hand is missing!
The drawing calls are being made (I can see them in logcat), but the canvas elements the calls draw are invisible.
It's not API level dependent, though; if I import it the right way into a project, it will hand will show up when I run it on the Xoom.
But, when I move the files to a different project folder (same source code, same layouts) it goes back to missing the dial.
What's going on? How could the same code be producing such different outcomes on different devices?
So, the key clue in my mystery seemed to be that it worked on the emulator, but not on the hardware devices.
Hardware Rendering
I did peruse the hardware rendering page on the Android Developer's website, but apparently not closely enough.
http://developer.android.com/guide/topics/graphics/hardware-accel.html
While it does mention that the API's are available beginning version 11, it does not say that Hardware Rendering is turned on for all applications by default, starting with API Level 14 (ICS).
What does this mean for us?
Almost everything is faster; except for the few things that don't work.
I managed to violate two of these, without realizing it:
Canvas.DrawTextOnPath()
Paint.setShadowLayer()
It's not mentioned in the API reference (or anywhere else I can find, and certainly not checked by Lint), but using any of the listed operations can do weird things.
In my case, Canvas.DrawTextOnPath() seemed to work just fine.
But when Android notice that the paint that I used on the hand had shadow layer set, it silently ignored it.
How do I know if my View is hardware accelerated?
From the documentation link above:
There are two different ways to check whether the application is hardware accelerated:
View.isHardwareAccelerated() returns true if the View is attached to a hardware accelerated window.
Canvas.isHardwareAccelerated() returns true if the Canvas is hardware accelerated
If you must do this check in your drawing code, use Canvas.isHardwareAccelerated() instead >of View.isHardwareAccelerated() when possible. When a view is attached to a hardware >accelerated window, it can still be drawn using a non-hardware accelerated Canvas. This >happens, for instance, when drawing a view into a bitmap for caching purposes.
In my case, the opposite appears to have occurred.
The custom view logs that it is not Hardware-accelerated; however, the canvas reports that it is hardware-accelerated.
Work Arounds and Fixings
The simplest fix is forcing the custom view to do software rendering. Per the documentation this can be accomplished by:
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
Alternatively, you could remove the offending operations, and keep hardware rendering turned on.
Learn from my misfortune. Good luck, all.
I put it into init() and worked fine after that.
private void init() {
setLayerType(myView.LAYER_TYPE_SOFTWARE, null);
....
}
With myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); suggestion I can see hand. But I have still a problem: I see scale with only 0 written! As in the picture and two strage zeros out of the schema: (GALAXY NEXUS 4.2.1)
My drawScale() method is as in the example:
private void drawScale(Canvas canvas) {
canvas.drawOval(scaleRect, scalePaint);
canvas.save(Canvas.MATRIX_SAVE_FLAG);
for (int i = 0; i < totalNicks; ++i) {
float y1 = scaleRect.top;
float y2 = y1 - 0.020f;
canvas.drawLine(0.5f, y1, 0.5f, y2, scalePaint);
if ((i % 5) == 0) {
int value = nickToDegree(i);
if ((value >= minDegrees) && (value <= maxDegrees)) {
String valueString = Integer.toString(value);
canvas.drawText(valueString, 0.5f, y2 - 0.015f, scalePaint);
}
}
canvas.rotate(degreesPerNick, 0.5f, 0.5f);
}
canvas.restore();
}
in my case i made this:
AnalogView bar = (AnalogView) findViewById(R.id.AnalogBar);
bar.setLayerType(bar.LAYER_TYPE_SOFTWARE, null);
if (value_list.size()>0) bar.SetData(Double.parseDouble(value_list.get(value_list.size()-1)));
where SetData in AnalogView is
public void SetData(double data) {
setHandTarget((float)data);
invalidate();
}
On Galaxy S4 Android 4.4.2
TYPE_TEMPERATURE is deprecated
use
TYPE_AMBIENT_TEMPERATURE
For anyone having problems with text drawing on scale in the initialisation do this:
scalePaint.setLinearText(true);

Categories

Resources