I create a view like below image in my monodroid application with code. While every thing is right when I test the app in android 4.1 but when I test it on the android 4.3 and 4.4.2 I faced with below screen. I do not test it on the android 4.2
In the textviews any numbers are not showing. It looks that I typed space. Also about some letters.
What is wrong?! What has been changed in the android 4.3 + ?
There is still space for the letters, so perhaps it's an issue with the styling.
Change the style to default, do the letters show up?
Try adding a shadow to the textviews and see if the shadow exists (maybe the letters are somehow transparent, or the same color as the background?)
by referring to #ArieDov comment I post this answer:
Below method that I used caused the problem:
public static void AddShadowEffect (TextView textview)
{
try {
if(RltXmlSettings.Instance.getVal ("shadow_enabled")=="1")
{
float[] direction = new float[] {0.3f, -1.0f, 0.0f};
MaskFilter filter = new EmbossMaskFilter (direction, 0.8f, 15f, 5f);
textview.Paint.SetMaskFilter (filter);
textview.Invalidate ();
}
} catch (Exception ex) {
RltLog.HandleException (ex);
}
}
the purpose of this method was adding the shadows you see in the question image. and I fixed the problem by changing the style of textviews just like what #Matt said. I used below code for my textviews:
txtlName.SetTypeface (null, TypefaceStyle.Bold);
and this fixed my problem.
Related
By code, I can make a button that inserts these 3 emojis into the text: ⚽️😈🐺
On many phones when the user clicks the button, though, the problem is that ⚽️😈🐺 displays as [X][X][X]. Or even worse, it displays only three empty spaces.
I would like to disable and hide my own built-in emoji-keypad on Android devices that do not display emojis correctly. Does anyone knows or have a tip on how to detect in code if a device has emoji support?
I have read that emoji is supported from android 4.1, but that is not my experience....
I just implemented a solution for this problem myself. The nice thing with Android is that it is open source so that when you come around problems like these, there's a good chance you can find an approach to help you.
In the Android Open Source Project, you can find a method where they use Paint.hasGlyph to detect whether a font exists for a given emoji. However, as this method is not available before API 23, they also do test renders and compare the result against the width of 'tofu' (the [x] character you mention in your post.)
There are some other failings with this approach, but it should be enough to get you started.
Google source:
https://android.googlesource.com/platform/packages/inputmethods/LatinIME/+/master/java/src/com/android/inputmethod/keyboard/emoji/EmojiCategory.java#441
https://android.googlesource.com/platform/packages/inputmethods/LatinIME/+/master/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
Based on Jason Gore answer:
For example create boolean canShowFlagEmoji:
private static boolean canShowFlagEmoji() {
Paint paint = new Paint();
String switzerland = "\uD83C\uDDE8\uD83C\uDDED"; // Here enter Surrogates of Emoji
try {
return paint.hasGlyph(switzerland);
} catch (NoSuchMethodError e) {
// Compare display width of single-codepoint emoji to width of flag emoji to determine
// whether flag is rendered as single glyph or two adjacent regional indicator symbols.
float flagWidth = paint.measureText(switzerland);
float standardWidth = paint.measureText("\uD83D\uDC27"); // U+1F427 Penguin
return flagWidth < standardWidth * 1.25;
// This assumes that a valid glyph for the flag emoji must be less than 1.25 times
// the width of the penguin.
}
}
And then in code whenever when you need to check if emoji is available:
if (canShowFlagEmoji()){
// Code when FlagEmoji is available
} else {
// And when not
}
Surrogates of emoji you can get here, when you click on detail.
An alternative option might be to include the Android "Emoji Compatibility" library, which would detect and add any required Emoji characters to apps running on Android 4.4 (API 19) and later: https://developer.android.com/topic/libraries/support-library/preview/emoji-compat.html
final Paint paint = new Paint();
final boolean isEmojiRendered;
if (VERSION.SDK_INT >= VERSION_CODES.M) {
isEmojiRendered = paint.hasGlyph(emoji);
}
else{
isEmojiRendered = paint.measureText(emoji) > 7;
}
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.
The second part was answerd by RogueBaneling here how can I check if my device is capable to render Emoji images correctly?
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);
I'm trying to create an Android app that adds a random quote to images.
The general process is this:
Start from a custom given image that shows when starting the app.
From this image all the user can do is tap on it and generate a new random "quote" that get overlaid on the image.
The user can save the newly created image with the quote he chose and set it as wallpaper.
I have got to the point where I can display the image in an ImageView.
My list of quotes is stored in my strings.xml file.
I do something like this in an app. Use Canvas.
I edited down a piece of my code, which actually adds a couple of other images on the background and stuff too.
Meat of code:
private static Bitmap getPoster(...) {
Bitmap background = BitmapFactory.decodeResource(res, background_id)
.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(background);
Typeface font = Typeface.createFromAsset(res.getAssets(), FONT_PATH);
font = Typeface.create(font, Typeface.BOLD);
Paint paint = new Paint();
paint.setTypeface(font);
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
paint.setStyle(Style.FILL);
paint.setShadowLayer(2.0f, 1.0f, 1.0f, Color.BLACK);
float fontSize = getFontSize(background.getWidth(), THE_QUOTE, paint); //You'll have to define a way to find a size that fits, or just use a constant size.
paint.setTextSize(fontSize);
canvas.drawText(THE_QUOTE, (background.getWidth() - paint.measureText(THE_QUOTE)) / 2,
background.getHeight() - FILLER_HEIGHT, paint); //You might want to do something different. In my case every image has a filler in the bottom which is 50px.
return background;
}
Put your own version of that in a class and feed it the image id and anything else. It returns a bitmap for you to do whatever you want with (display it in an imageview, let the user save it and set as wallpape).
I know i did this for the PC with imagemagick a few years ago(save image with text on)
Seems like imagemagick have been ported to android, so I would start digging into thier documentation.
https://github.com/lilac/Android-ImageMagick
Ok! Francesco my friend, I've an idea although not a working code ('cuz I'm not really good at it). So, here it is:
Implement an onClickListener() on your ImageView like below:
ImageView iv = (ImageView)findViewById(R.id.imageview1);
iv.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
/** When I say do your stuff here, I mean read the user input and set your wallpaper here. I'm sorry that I don't really know how to save/set the wallpaper */
}
});
When it comes to reading user input/generating random quotes, you can do this:
You said you already have the quotes saved in the strings.xml file. Using the ids of those strings, I think you can implement a switch case scenario where it uses java imports - java.util.Scanner and java.util.Random. Ultimately, using these in your ImageView onClickListener could/should result in the desired output.
I know my answer is too vague, but I've a faint hope that it has given you a minute lead as to what you can implement. I seriously hope there are better answers than this. If not, then I hope this helps you some, and I also hope that I'm not leading you in the wrong direction since this is just a mere speculation. Sorry, but this is all I've got.
I think I might be about to ask a dummy question, but I'm still new with Android programming, and I couldn't (despite all my efforts) find my answer on Google.
The thing is, I'm trying to develop a little game, with 2D Graphics. I want my "gaming board" to be at a specific position on my screen, so that I can display in-game informations above and below the box. But since there is beginning to be a lot of Android phones out there, I was thinking about getting "dynamic" values so that I can adapt my font size to every device.
My game is not in full screen (but it could be, it's no big deal), but in a window with no title bar.
I'm using an extension of the default SurfaceView class, implementing SurfaceHolder.Callback. I tried writing the following method :
public void getViewSize()
{
VIEW_WIDTH = this.getWidth();
VIEW_HEIGHT = this.getHeight();
}
but the values returned are zeroes.
Anyone got an idea (even if it means changing display strategy) ?
Thanks a lot.
You can do this:
public void onDraw(Canvas canvas) {
VIEW_WIDTH = canvas.getWidth();
VIEW_HEIGHT = canvas.getHeight();
}
I'm animating a an ImageView from the left to the right of the screen using a translate animation. The ImageView is place inside a RelativeLayout over the top of my main layout using FrameLayout.
When I run the animation on the emulator everything works pretty well but when I use run it on my G1 it leaves visual artifacts behind and effects the rendering of the text component behind it.
Is this a performance issue and I'm being too ambitious or is it a bug I can overcome?
If it is a performance issue is there anything I can do to improve things?
I was also experiencing the same issue on 2.3.
Invalidating the container of the moving view ( the layout in which the moving view resides ) in Animation.applyTransformation fixed it for me.
See:
Android - Artifacts using Animation
I now this may be a little old, but I just found this:
http://groups.google.com/group/android-developers/browse_thread/thread/5481450f8b71a26c/e750730b9953d9a8?lnk=gst&q=animation+leaves+trails#e750730b9953d9a8
Not sure what android version your using, but it may be a bug in the android libraries!
Looks like that's what the problem is for me! :)
... Dontcha just love it when its not your fault! :D
Here's a workaround I found that solved this for me: "An easy workaround would be to pad your image with a small (1 pixel should do it) transparent region on the right/bottom - this would have no effect on how it would look, but it would force an invalidation of a region slightly larger than the actual image and thus compensate for the bug."
http://code.google.com/p/android/issues/detail?id=22151
Without actually seeing the problem is sounds like you're not clearing the display buffer before writing the next frame. It doesn't sound like a performance issue to me.
Do you have control over whether the device does double buffering or not?
Given that it works on the emulator this could point to either a problem with the emulator or a bug in your code that isn't showing up on the emulator (which I suppose is technically a problem with the emulator!) rather than a performance issue.
I would suggest using a SurfaceView for animation. It is double-buffered, so it should eliminate flickering if you use it properly. If you want an example, the LunarLander demo included in the sdk shows this really well. Also, if you have a more specific question with code, ask away.
As for general Android performance, it is very possible to have reasonably high frame rates, so you aren't expecting too much.
This is happening to me as well. I'm using an emulator using 1.6 with the Google APIs, and I just confirmed that it happens on a Nexus One running FRF83. Here's the relevant code:
Animation a = new TranslateAnimation(0.0f, 0.0f, 100.0f, 0.0f);
a.setDuration(2000);
this.myView.startAnimation(a);
Here's the relevant code for instantiating the view:
View v = new View(this.getApplication());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, 80);
v.setLayoutParams(params);
v.setBackgroundColor(0xFFFF0000);
//
LinearLayout layout = (LinearLayout)this.findViewById(R.id.theLayout);
layout.addView(v);
//
v.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
// TODO Auto-generated method stub
doAnimation();
}
});
//
myView = v;
So basically, the double buffering etc, is being handled by the OS, and I have no control over it at all.
I had a similar problem on Android 2.3, so the bug may still in exist.
I was using an ImageView with a PNG which had some transparent parts. This imageview was leaving trails when animated with TranslateAnimation. Using a fake background drawable for the imageview elimanated the trail (I used a drawable as background).
I figured this out on Jelly bean i was experiencing this in a gallery view while performing some animation. It looks more like a drawing issue not cpu ....
make your activity implement the interface AnimatorListener ..... override the below method and pick which one you want to redraw your view in
#Override
public void onAnimationEnd(Animator animation) {
// TODO Auto-generated method stub
mView.requestLayout();
Toast.makeText(this, "animation ended", 0).show();
}
#Override
public void onAnimationRepeat(Animator animation) {
// TODO Auto-generated method stub
mView.requestLayout();
}
#Override
public void onAnimationStart(Animator animation) {
// TODO Auto-generated method stub
mView.requestLayout();
}