In my app I need to know what is the size of main container of activity. I have written following code:
Button btnActionMenu = (Button) findViewById(R.id.actionbar_menu);
btnActionMenu.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
int width = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 40, getResources().getDisplayMetrics());
RelativeLayout rlContainer = (RelativeLayout) findViewById(R.id.inner_content);
Bitmap bitmap = Bitmap.createBitmap(rlContainer.getLayoutParams().width, rlContainer.getLayoutParams().height, Config.ARGB_8888);//
Canvas canvas = new Canvas(bitmap);
rlContainer.draw(canvas);
SlideoutHelper.setBitmap(bitmap, width);
startActivity(new Intent(Home.this, MenuActivity.class));
overridePendingTransition(0, 0);
}
});
rlContainer is the root container of activity. When I run and click on button, the application crashes and Logcat says "Application Null pointer exception" and points to line
Bitmap bitmap = Bitmap.createBitmap(rlContainer.getLayoutParams().width, rlContainer.getLayoutParams().height, Config.ARGB_8888);
any suggestion would be appreciated. Thanks
try this :
v.measure(
MeasureSpec.makeMeasureSpec(v.getLayoutParams().width,MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(v.getLayoutParams().height, MeasureSpec.EXACTLY));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
Bitmap bitmap = Bitmap.createBitmap(v.getWidth(), v.getHeight()
,Bitmap.Config.RGB_565);
have you tried getMeasuredHeight and getMeasuredWidth , or getHeight and getWidth (on the rlContainer variable ) ?
note that this works only after the view was prepared , and not inside the onCreate() method . however , it will work on this situation since it's inside a user-related action , which occurs after the views were shown to the user.
btw , about your code , "rlContainer.getLayoutParams().width" might return a negative value , in case it's wrap-content or match-parent .
Related
I need to copy an ImageView in my application and change it's size whenever the user wants. What I do is here:
public void testClick(View view)
{
ImageView im = new ImageView(this);
im.setImageDrawable(((ImageView) view).getDrawable());
Point size = getSize();//size of the window
al.addView(im, new AbsoluteLayout.LayoutParams(view.getWidth(), view.getHeight(), size.x / 2, size.y / 2));
im.setScaleType(ImageView.ScaleType.FIT_XY);
im.setOnTouchListener(touchListener);
}
public void changeSize()
{
...
view.setLayoutParams(new AbsoluteLayout.LayoutParams(width + deltaX, height + deltaY, params.x, params.y));
}
It doesn't work! means when I increase the size of the view, the image inside is not stretched.
But the weird thing happens when I change the line im.setImageDrawable(((ImageView) view).getDrawable()); with im.setImageResource(R.drawable.my_image);
It works!
any idea?
I do not want to use setImageResource because I need to copy the drawable of the clicked view, not a static one from resources.
Edit: When I use it in Galaxy Note 6.(I think it is Android 5) it works. but on my Android 4.1.2 device, it doesn't!
Edit2: I used
BitmapDrawable bd=(BitmapDrawable)((ImageView) view).getDrawable();
im.setImageBitmap(bd.getBitmap());
and it workd!
To fix your problem, use below code to change your ImageView size
mImageView.getLayoutParams().width = myWidth;
mImageView.getLayoutParams().height = myHeight;
And then call
mImageView.requestLayout();
to have the size change take effect.
I believe this should solve your problem.
I'm trying to use a custom view as the icon next to the up button. I searched for a solution online and read something about using a drawing cache and tried implementing it in my code but no icon is showing.
ActionBar bar = getSupportActionBar();
bar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.scheme_dark_blue)));
bar.setTitle(i.getStringExtra("schoolDay"));
CalendarIcon icon = (CalendarIcon) getLayoutInflater().inflate(R.layout.icon_calendar, null);
icon.setDrawingCacheEnabled(true);
day = Integer.parseInt(i.getStringExtra("date"));
icon.setData(day + "");
icon.buildDrawingCache();
bar.setIcon(new BitmapDrawable(getResources(), icon.getDrawingCache()));
bar.setDisplayHomeAsUpEnabled(true);
Thanks for any help :)
Your code is probably not working because the view does not have a size yet. I also suggest you don't use the drawing cache but instead draw the view on a canvas.
I have written a little example where the view is given a size when it doesn't have one yet. You may want to tune to code a bit to fit your needs.
Example:
public static Drawable createDrawableFromView(View v, int requestedWidth, int requestedHeight) {
// Because the view is never shown it does not have a size, but if shown don't resize it.
if (v.getMeasuredHeight() <= 0) {
// You may want to change these lines according to the behavior you need.
int specWidth = MeasureSpec.makeMeasureSpec(requestedWidth, MeasureSpec.AT_MOST);
int specHeight = MeasureSpec.makeMeasureSpec(requestedHeight, MeasureSpec.AT_MOST);
v.measure(specWidth, specHeight);
}
Bitmap b = Bitmap.createBitmap(v.getMeasuredWidth(), v.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
v.draw(c);
return new BitmapDrawable(v.getContext().getResources(), b);
}
Usage:
getActionBar().setTitle("View to icon test");
TextView view = new TextView(this);
view.setText("AI");
view.setGravity(Gravity.CENTER);
view.setTextColor(Color.RED);
getActionBar().setIcon(createDrawableFromView(view, 250, 250));
Result:
I have an Android related issue:
I am trying to centre a logo on the screen of my device, but it won't position correctly.
I am using the following function:
public void ImageCentered(int ID){
ImageView iv = (ImageView) findViewById(ID);
int x = 0;
int y = 0;
RelativeLayout.LayoutParams position = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
x = (screenWidth/2)-(iv.getWidth()/2);
y = (screenHeight/2)-(iv.getHeight()/2);
position.setMargins(x, y, 0, 0);
iv.setLayoutParams(position);
}
This could should work,but it won't. The image is set off slightly to the right and bottom like in this image:
https://www.dropbox.com/s/tf7r1u1xqcmb9t9/2014-08-16%2018.36.04.png
Now, the strange thing is, when I use the following code:
public void ImageCentered(int ID){
ImageView iv = (ImageView) findViewById(ID);
int x = 0;
int y = 0;
RelativeLayout.LayoutParams position = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
x = (screenWidth/2)-(iv.getWidth()/2);
y = (screenHeight/2)-(iv.getHeight()/2);
position.setMargins(x, y, 0, 0);
Message(IntToStr(x)+", "+IntToStr(y));
iv.setLayoutParams(position);
}
this is the result:
https://www.dropbox.com/s/mjw80zlzkav6dzs/2014-08-16%2018.41.16.png
Side note: The text in the Message() function does not matter, nor does its position within the ImageCentered() function.
I am not calling the function in my OnCreate(), as the width and height of the image would always return 0, so I looked something up and found this:
#Override
public void onWindowFocusChanged(boolean hasFocus){
ImageCentered(R.id.image);
}
This piece of code is in my MainActivity.java file, whereas the ImageCentered() function is in my UtilLib.java file.
So, I was wondering: What's going on here? Why does the code work when I pop in a Message() but not when I leave it out?
Sure, I can try hardcoding the data, but what about smaller/bigger screens?
I hope an Android guru can help me out here, as I've been struggling with this for quite some time now.
EDIT
Just noticed something interesting when pressing "OK" on my Message:
https://www.dropbox.com/s/a7lu6588hy1opw7/2014-08-16%2018.51.55.png
My guess is that my problem lies there, but after clicking the "OK" button once more, the data is "492, 207" again. scratches head
Assuming rom your code that the ImageView is inside a RelativeLayout, You could also do:
// get imageview layout params or create new ones
RelativeLayout.LayoutParams params = imageView.getLayoutParams();
params.addRule(RelativeLayout.CENTER_HORIZONTAL);
this way the image will be automatically centered without all those manual calculations!.
You can also specify it in the XML with
<ImageView .....
android:layout_centerHorizontal="true"/>
I've ultimately decided to just hardcode the x and y coordinates, and later on use some sort of scaling-conversion to position them properly, unless someone can provide me with a better method of fixing this.
UPDATE
So, after googling after a while (again), I have finally found the answer and created two functions:
public int GetImageHeight(int ID){
ImageView iv = (ImageView)findViewById(ID);
iv.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
iv.layout(0, 0, iv.getMeasuredWidth(), iv.getMeasuredHeight());
return iv.getMeasuredHeight();
}
public int GetImageWidth(int ID){
ImageView iv = (ImageView)findViewById(ID);
iv.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
iv.layout(0, 0, iv.getMeasuredWidth(), iv.getMeasuredHeight());
return iv.getMeasuredWidth();
}
All you have to do is pass the ID of the image you made in your xml file, like so:
GetImageHeight(R.id.logo)
I have an app that displays some data graphically. It creates two Views to draw graphics in and adds them to my layout. Each view shows the data differently way but each View implements onSizeChanged() the same:
protected void onSizeChanged(int curw, int curh, int oldw, int oldh) {
if (bitmap2 != null) {
bitmap2.recycle();
}
canvas2= new Canvas();
bitmap2 = Bitmap.createBitmap(curw, curh, Bitmap.Config.ARGB_8888);
canvas2.setBitmap(bitmap2);
}
The views are invoked thusly:
LinearLayout myLayout = (LinearLayout)findViewById(R.id.revlay);
GraphView1 graphView1 = new GraphView1(this, theEventArrayList);
myLayout.addView(graphView1);
GraphView2 graphView2 = new GraphView2(this, theEventArrayList);
myLayout.addView(graphView2);
Always the first onSizeChanged() that gets called gets a height of 652 and a width of 480; the second one gets a height of 0, which causes createBitmap() to fail. If I reversed the order of the above invocation then graphView1 would fail that way. I'd like each bitmap to have about half the area.
Thanks in advance for explaining what's going on!
its difficult to answer your question without knowing further implementation details about your graphviews and the layout parameters of the LinearLayout.
But assuming your LinearLayout has a horizontal orientation try this:
GraphView1 graphView1 = new GraphView1(this, theEventArrayList);
GraphView2 graphView2 = new GraphView2(this, theEventArrayList);
myLayout.addView(graphView2, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 0, 1));
myLayout.addView(graphView1, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 0, 1));
this will tell the LinearLayout to arrange your views so that they equally divide the horizontal space between themselves.
I'm building a widget which displays some text. By widget I mean the kind which lies on the desktop.
The problem is that I want to change text's font at runtime. There is several textview I would like, at runtime, to set the first as bold, the second blue and italic for example, etc.
I came up with this :
TextView tv = new TextView(context);
tv.setText(stringToDisplay);
tv.setTextColor(0xa00050ff); // example
tv.setTextSize(30); // example
Bitmap b = loadBitmapFromView(tv);
updateViews.setImageViewBitmap(R.id.id_of_the_imageview, b);
with
private static Bitmap loadBitmapFromView(View v)
{
Bitmap b = Bitmap.createBitmap(v.getLayoutParams().width, v.getLayoutParams().height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.layout(0, 0, v.getLayoutParams().width, v.getLayoutParams().height);
v.draw(c);
return b;
}
but it wont work (NullPointerException on first line of loadBitmap), until I replace
v.getLayoutParams().width, v.getLayoutParams().height by fixed sizes like 250, 50
Bitmap b = Bitmap.createBitmap(250, 50, Bitmap.Config.ARGB_8888);
// ...
v.layout(0, 0, 250, 50);
But that's not a good solution ...
so I tried this :
LayoutInflater li = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = li.inflate(R.layout.widget_text, null);
TextView tv = (TextView) row.findViewById(R.id.id_of_the_textview);
widget_text being a layout similar to the displayed one but with TextViews instead of ImageViews, in the hope to get some size information out of it ..
but it's not working and I get this exception :
01-02 17:35:06.001: ERROR/AndroidRuntime(11025): Caused by: java.lang.IllegalArgumentException: width and height must be > 0
on the call to Bitmap.createBitmap()
so, someone could point me in the right direction?
Through RemoteViews you can still hide and show elements, so why not duplicate the text views for all font styles you might encounter?
something like:
widget.setViewVisibility(R.id.textview_italic,View.GONE);
widget.setViewVisibility(R.id.textview_bold,View.VISIBLE);
using images to display text should always be the last resort.
You can set the size dynamically:
float mySize = 10f;
updateViews.setFloat(R.id.textview, "setTextSize", mySize);