Images are shown as '[OBJ]' in notification lines - java

I've been trying to add an image from drawable folder into a notification line. But the image doesn't appear and [OBJ] is shown instead.
I can add image in any other place on notifications. Also I can add emoji into a notification line like this issue Android notification - custom inboxstyle (add line ) .
But I can not add an image.
Is there any chance to overcome this issue?
public void someMethod() {
...
mInboxStyle.addLine(imageSpanned());
...
}
private Spanned imageSpanned () {
String imgString = "Something <img src=\"ic_arrow_forward_black_24dp\">";
return Html.fromHtml(imgString, mImageGetter, null);
}
Html.ImageGetter mImageGetter = new Html.ImageGetter() {
#Override
public Drawable getDrawable(String source) {
Drawable drawable;
Resources res = mContext.getResources();
int drawableId = res.getIdentifier(source, "drawable", mContext.getPackageName());
drawable = res.getDrawable(drawableId);
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
drawable.setBounds(0, 0, width, height);
return drawable;
}
};

You need to provide ic_arrow_forward_black_24dp icon resource in your drawables or mipmap.
SpannableStringBuilder builder = new SpannableStringBuilder();
builder.append("Something").append(" ");
builder.setSpan(
new ImageSpan(
getActivity(),
R.drawable.ic_arrow_forward_black_24dp),
builder.length() - 1,
builder.length(),
0
));
textView.setText(builder);

Related

Place Drawable on Imageview using PorterDuff.Mode.SRC_ATOP

I have an ImageView:
ImageView imageView = findViewById(R.id.imageView);
I would like to achieve something like this (Atop figure)
drawable1 is the original ImageView image, drawable2 is the one I want to place over it:
Drawable drawable1 = AppCompatResources.getDrawable(context, drawable1);
Drawable drawable2 = AppCompatResources.getDrawable(context, drawable2);
LD layerDrawable = new LD(new Drawable[]{
drawable1,
drawable2,
});
imageView.setImageDrawable(layerDrawable);
LD class:
public class LD extends LayerDrawable
{
private Paint p = new Paint();
public LD(Drawable[] layers) {
super(layers);
p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
}
#Override
public void draw(Canvas canvas) {
super.draw(canvas);
int count = canvas.saveLayer(null, null, Canvas.ALL_SAVE_FLAG);
for (int i = 0, numberOfLayers = getNumberOfLayers(); i < numberOfLayers; ++i) {
this.getDrawable(i).draw(canvas);
canvas.saveLayer(null, p, Canvas.ALL_SAVE_FLAG);
}
canvas.restoreToCount(count);
}
}
However this doesn't work, because the image I place over (drawable2) is placed over the whole imageView, not just over the non-transparent contents of the drawable1 image.
How do I achieve Atop figure (placing drawable2 only over the 'filled content' of drawable1)?
Edit:
p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
canvas.drawBitmap(bitmap1, 0, 0, null);
canvas.drawBitmap(bitmap2, 0, 0, p);

Updating an Image with Async

So I have a database with a table where a User name corresponds to the name of an image. So In my AsyncHTTP I retrieve the Username and wish to map that Username to its correct image(all images are located in my drawable folder)
In my XML where this image will be rendered I just put an imageview and never assigned it an image(the Id for this imageView is myImage)
So how when I run my code the image is not rendered. I cant assign the image outside of async because of scope issues.
Context context = this;
AsyncHTTPPost asyncHttpPost2 = new AsyncHTTPPost(
"http://lamp.ms.wits.ac.za/~s1363679/avatars.php", params) {
#Override
protected void onPostExecute(String s) {
try {
JSONArray all = new JSONArray(s);
for (int i = 0; i < all.length(); i++) {
JSONObject item = all.getJSONObject(i);
fName = item.getString("avatarName");
System.out.println();
Toast.makeText(Profile.this, fName, Toast.LENGTH_LONG).show();
ImageView Image = (ImageView) findViewById(R.id.myImage);
System.out.println("");
theName = fName;
//String imagename="kaius";
Resources res = context.getResources();
int resID = res.getIdentifier(theName, "drawable", context.getPackageName());
Image.setImageResource(resID);
}
} catch (Exception e) {
Toast.makeText(Profile.this, e.toString(), Toast.LENGTH_LONG).show();
}
}
};
asyncHttpPost2.execute();
}
The imageName is retrieved correctly and stored in the variable "theName" but it doesnt seem to render onto the view.
At the same level of your drawable folder, there should also be some folders with these names:
-drawable-hdpi
-drawable-xhdpi
-drawable-xxhdpi
-drawable-xxxhdpi
Your images should be scaled according to different dpi´s and placed inside those folders to render correctly in all screens.
Another thing you could do instead, is:
// get drawable path
String imageUri = "drawable://" + R.drawable.image;
imageView.setImageBitmap(decodeSampledBitmapFromFile(imageUri , 1920, 1080));
And declare somewhere decodeSampledBitmapFromFile like this:
public static Bitmap decodeSampledBitmapFromFile(String imagePath,
int reqWidth, int reqHeight) {
// BitmapFactory.decodeFile(this.getFilesDir().getPath() + "/" + imagestoplay[currImage])
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
// BitmapFactory.decodeResource(res, resId, options);
BitmapFactory.decodeFile(imagePath, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(imagePath, options);
}
Don´t forget to change 1080 and 1920 to your required size in pixels.

Android: Create a mirror image of a view

I wrote a code that reflects the view of an ImageView in the splash activity. In order to implement this, I took three steps.
Create an ImageView in the layout_splash.xml file and also in the SplashActivity.java.
Call the setImageBitmap method with the reflected ImageView variable
Declare a method that reflects the view of the image.
And here is the code.
public class SplashActivity extends Activity {
private ImageView ivLogo;
private SharedPreferences appPreferences;
private Typeface typeface;
private TextView tvAppName;
private boolean isAppInstalled = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
String appName = getResources().getString(R.string.app_name);
appPreferences = PreferenceManager.getDefaultSharedPreferences(this);
isAppInstalled = appPreferences.getBoolean("isAppInstalled", false);
if(isAppInstalled == false) {
Intent shortcutIntent = new Intent(getApplicationContext(), SplashActivity.class);
shortcutIntent.setAction(Intent.ACTION_MAIN);
Intent intent = new Intent();
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, appName);
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(getApplicationContext(), R.mipmap.ic_launcher));
intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
getApplicationContext().sendBroadcast(intent);
SharedPreferences.Editor editor = appPreferences.edit();
editor.putBoolean("isAppInstalled", true);
editor.commit();
}
// Set the app name's font
typeface = Typeface.createFromAsset(getAssets(), "fonts/Catull.ttf");
tvAppName = (TextView) findViewById(R.id.tvAppName);
tvAppName.setTypeface(typeface);
Bitmap originalImage = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_gruppo);
ivLogo = new ImageView(this);
ivLogo.setImageBitmap(getReflection(originalImage));
Handler hd = new Handler();
hd.postDelayed(new Runnable() {
#Override
public void run() {
Intent intent = new Intent(getApplicationContext(), InitialActivity.class);
startActivity(intent);
// Implement the animation on activity change
overridePendingTransition(R.anim.push_down_in, R.anim.push_down_out);
finish();
}
}, 1200);
}
public Bitmap getReflection(Bitmap image) {
// The gap we want between the reflection and the original image
final int reflectionGap = 4;
// Get the bitmap from the mipmap folder
Bitmap originalImage = image;
int width = originalImage.getWidth();
int height = originalImage.getHeight();
// This will not scale but will flip on the Y axis
Matrix matrix = new Matrix();
matrix.preScale(1, -1);
// Create a Bitmap with the flip matrix applied to it.
// We only want the bottom half of the image
Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,
height / 2, width, height / 2, matrix, false);
// Create a new bitmap with same width but taller to fit reflection
Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
(height + height / 2), Bitmap.Config.ARGB_8888);
// Create a new Canvas with the bitmap that's big enough for
// the image plus gap plus reflection
Canvas canvas = new Canvas(bitmapWithReflection);
// Draw in the original image
canvas.drawBitmap(originalImage, 0, 0, null);
//Draw the reflection Image
canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
// Create a shader that is a linear gradient that covers the reflection
Paint paint = new Paint();
LinearGradient shader = new LinearGradient(0,
originalImage.getHeight(), 0, bitmapWithReflection.getHeight()
+ reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP);
// Set the paint to use this shader (linear gradient)
paint.setShader(shader);
// Set the Transfer mode to be porter duff and destination in
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
// Draw a rectangle using the paint with our linear gradient
canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
+ reflectionGap, paint);
return bitmapWithReflection;
}
}
But when running the application, I don't see the reflected image but just the plain one. Something wrong with the code?
Problems always occur from the very small things. In here the problem is that the ivLogo variable was not added into the content view. So the ivLogo must be added in the onCreate method like this,
ivLogo = (ImageView) findViewById(R.id.ivLogo);
instead of
ivLogo = new ImageView();

Darken/Dim/Blur Activity when navigation drawer is open

I am using LDrawer in my project. I need to make the activity which is hosting the navigation drawer darken/dim/blur when the navigation drawer is opened.
I have gone through similar questions on Stackoverflow and I have not found a satisfiying answer.
Is there any simple trick to make the activity's layout darken/dim/blur when I open my NavigationDrawer
I have the RelativeLayout of my activity defined as
RelativeLayout myActivity = (RelativeLayout) findViewById(R.id.myActivity)
I have the toggle code for NavigationDrawer below
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
if (mDrawerLayout.isDrawerOpen(mDrawerList)) {
mDrawerLayout.closeDrawer(mDrawerList);
} else {
//I want to manipulate myActivity's Layout here
mDrawerLayout.openDrawer(mDrawerList);
}
}
return super.onOptionsItemSelected(item);
}
Is there any simple trick to make the activity's layout Darken/Dim/Blur when I open my NavigationDrawer ?
Yes, you can simply change the background image of your activity as Blur when you open the drawer.
Other way is change the alpha or your activity simply by setalpha() and pass the value how much change you want.
If you have list control on your activity and you want to make that blur then below code will work.
Display display = getActivity().getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int screenWidth = size.x;
int screenHeight = size.y;
Bitmap blurBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.invitation_blur_bg);
Rect rect = new Rect(0, 0, blurBitmap.getWidth(), blurBitmap.getHeight());
Implement the OnScrollListener on your activity or fragment where you want to apply this.
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
for (int i = 0; i < listview.getChildCount(); i++) {
View c = listview.getChildAt(i);
Rect r = new Rect();
c.getHitRect(r);
RelativeLayout llItemBg = ((RelativeLayout ) c.findViewById(R.id.root_layout of list item);
Drawable d = new BitmapDrawable(getResources(), cropImage(r,c));
itemBackground.setBackgroundDrawable(d);
}
}
private Bitmap cropImage(Rect r, View c2) {
Bitmap bmOverlay = Bitmap.createBitmap(screenWidth - 60,
c2.getHeight(), Bitmap.Config.ARGB_8888);
Rect rect1=new Rect(0, 0, bmOverlay.getWidth(), bmOverlay.getHeight());
Paint p = new Paint();
Canvas c = new Canvas(bmOverlay);
rect.right = r.right;
rect.top = rect.top;
rect.bottom = r.bottom / 2;
c.drawBitmap(blurBitmap, r, rect1, p);
return bmOverlay;
}

Customize Image referred From Html string

One of my project activities including long text written in string.xml ,i add some images from resource within textview ,as after each phrase there is image then next the text phrase then image and so on ,
i getting that images from string using this code :
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView htmlTextView = (TextView) findViewById(R.id.day_tv);
htmlTextView.setText(Html.fromHtml(getString(R.string.day), new ImageGetter(), null));
}
private class ImageGetter implements Html.ImageGetter {
public Drawable getDrawable(String source) {
int id = 0;
if (source.equals("image1.jpg")) {
id = R.drawable.a;
} else if (source.equals("image2.jpg")) {
id = R.drawable.b;
} else if (source.equals("image3.jpg")) {
id = R.drawable.c;
} else if (source.equals("image4.jpg")) {
id = R.drawable.d;
} else if (source.equals("image5.jpg")) {
id = R.drawable.e;
}
Drawable d = getResources().getDrawable(id);
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
return d;
}
};
}
and writing html img tag in string.xml as:
<img src="image1.jpg">
i want to be able to customize each image by changing its width and height or refer it to drawable style to add border around images for example .
i tried using the bellow code foe changing width and height :
<img src="image1.jpg" width="100" height="150">
but it doesn't work .
any advice to achieve that will be appreciated , thanks .
I finally end up to this solution which allow to change width and height for each image but still one point not achieved which is referring image to drawable shape as background ,
still work on it :
private class ImageGetter implements Html.ImageGetter {
public Drawable getDrawable(String source) {
int id,id1,id2,id3,id4 = 0;
if (source.equals("image1.jpg")) {
id = R.drawable.a;
Drawable d = getResources().getDrawable(id);
d.setBounds(0, 0, 80, 20);
return d;
}
else if (source.equals("image2.jpg")) {
id1 = R.drawable.b;
Drawable d1 = getResources().getDrawable(id1);
d1.setBounds(0, 0, 100, 40);
return d1;
}
else if (source.equals("image3.jpg")) {
id2 = R.drawable.c;
Drawable d2 = getResources().getDrawable(id2);
d2.setBounds(0, 0, 120, 60);
return d2;
}
else if (source.equals("image4.jpg")) {
id3 = R.drawable.d;
Drawable d3 = getResources().getDrawable(id3);
d3.setBounds(0, 0, 140, 80);
return d3;
}
else if (source.equals("image5.jpg")) {
id4 = R.drawable.e;
Drawable d4 = getResources().getDrawable(id4);
d4.setBounds(0, 0, 160, 100);
return d4;
}
return null;
};
}
}
The problem comes from Html.fromHtml(), which supports only a very limited set of tags and attributes. <img> is supported, but setting the width and height of the image is not. It's possible to achieve it with a TextView (by using SpannableString and ImageSpan), but it's more complicated and not very flexible.
Instead, you should use a WebView which handles HTML properly.
It's easy to load a string :
WebView webView = (WebView) findViewById(R.id.web_view);
webView.loadData(getResources(R.string.day), "text/html", null);
You can find more examples in the documentation.
Just for comparison, here is an example without using a WebView :
protected void onCreate(Bundle savedInstanceState) {
...
TextView textView = (TextView) findViewById(R.id.text_view);
SpannableString ss = new SpannableString("Hello :)");
// Draw the image with a size of 50x50
Drawable d = getResources().getDrawable(R.drawable.happy_face);
d.setBounds(0, 0, 50, 50);
// Replace the ":)" in the string by our drawable
ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
ss.setSpan(span, 6, 8, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(ss);
}
It will load much faster, but you can't use HTML.

Categories