I'm trying my app format some images in the screen after the Activity loads. The problem is while inside onCreate(), onResume() methods my ImageView have width and height=0. How can I run some code after the views are resized?
I test onPostResume() but it dont work =(
Views in Android do not have fixed size/position like in Blackberry or iPhone; instead, they are layed out dynamically. Layout happens much later than onCreate/onResume, and theoretically can happen many times. Every view has methods onMeasure and onLayout which are responsible for that. Only after onLayout method returns you can tell the view's size and position. Before that the view's size is 0 and position is 0 (as you've noticed).
So it makes little sense trying to get ImageView's size in onCreate/onResume because onLayout hasn't yet been called at that point.
Instead, override onLayout like this and do your stuff there:
public class MyImageView extends ImageView {
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
// at this point size and position are known
int h = getHeight();
int w = getWidth();
doSomethingCool(h,w);
}
}
Related
I need to be able to add a view that has a larger size than their parent. What I am trying to do is to set the view's size to the length of a short bond paper (8.5 x 11 inches) on any screen using TypedValue then I have a zoom view that scales this view so that I can see the whole once I zoomed out therefore I'm not able to use ScrollView. The problem is that android's measure pass doesn't let me to do so. The things I have tried are:
Setting LayoutParams width and height to 8.5x11 inches would result to the view being clipped and when I check the width and height of this child view it only returns the width and height of its parent.
Setting parent.setClipChildren(false) parent.setClipToPadding(false)
Overriding onMeasure
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(width, height);
}
or this
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
}
then setting the width and height to layout params, however the parent view resizes larger than the child which I cannot have.
I just really need a child that has larger size than its parent so that when I add a view there it would look like it's scaled down. The UI looks like Microsoft Word with a page in the middle. Let me know if this is possible, if not then I think I should manually scale everything that's added to this 8.5x11 view.
I hope I made it clear. Thanks!
I want to apply a simple rotationX animation when a group expands/collapses on an ExpandableListView. The code below works in first two expands but after two/three/five times does not play the defined animation. The strange thing is that the first time that I expand /collapse it works perfect!
ExpandableListview exp = new ExpandableListview(context);
// set adapter code
LayoutTransition transition = new LayoutTransition();
Animator appearAnim = ObjectAnimator.ofFloat(null, "rotationX", 90f,0f).setDuration(transition.getDuration(LayoutTransition.APPEARING));
transition.setAnimator(LayoutTransition.APPEARING, appearAnim); // I also tried first argument equals DISSAPEARING, CHANGING, etc
exp.setLayoutTransition(transition);
Any idea?? Is this approach totally wrong???
I have to notice at this point that this is not a duplicate! I am looking for a solution that will be approached with LayoutTransition class / methods.
Here is some awesome sample which may help you to do animation on expands/collapses on an ExpandableListView, In the android-flip library that uses OpenGL for rendering animation ,if the minimum supported Android version for the app was 4.0 we can use standard Android SDK methods instead of OpenGL: View.setRotationX(), View.setScaleX(), etc. When hardware acceleration is enabled (and it is enabled by default if your target API level is >=14), these methods work quite efficiently using the device GPU.
You can use this FoldableLayout to implement folding animation for expands/collapses on an ExpandableListView.
Layout implementation in FoldableLayout:
The first element to design was a layout that can fold in half. Our
approach was rather bold: the main layout (FoldableItemLayout) simply
contains a specialized layout (BaseLayout). During the animation, the
BaseLayout writes its contents to cache which is a specially created
Bitmap object based on the size of the original layout. view plaincopy
to clipboardprint?
class FoldableItemLayout extends FrameLayout {
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
Bitmap cacheBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mBaseLayout.setCacheCanvas(new Canvas(cacheBitmap));
}
}
class BaseLayout extends FrameLayout {
private Canvas mCacheCanvas;
private void setCacheCanvas(Canvas cacheCanvas) {
mCacheCanvas = cacheCanvas;
}
#Override
public void draw(Canvas canvas) {
mCacheCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
super.draw(mCacheCanvas);
}
}
In addition, we needed to use two extra Views (PartView) – for the
upper and lower image halves – which would display the corresponding
data in cache that represents the upper and lower halves of the image
(Bitmap). Both Views encompass the entire area of the main layout, but
display only the required parts. To achieve this effect, we calculated
the Bitmap limits – and in the onDraw() method we made Canvas draw the
required part via the drawBitmap (Bitmap bitmap, Rect src, RectF dst,
Paint paint) method.
Then we managed to rotate these extra Views by setting the
setRotationX() method to the corresponding angle, achieving
independent rotation of the lower and upper parts of the images. To
pull this off, we add a new parameter for the FoldableItemLayout –
with the name FoldRotation.
Source: How to Make a Paper Folding Animation in Android?
I'm implementing a custom View and I want to be able of change it size on runtime.
Simplifying the problem: I need to display a Bitmap in this view, but since it is refreshed frequently I'd like to extend SurfaceView.
The problem is that I lose the ImageView's auto resize functionality.
So I want to declare a method setCustomBitmap(Bitmap bmp) and resize (at the moment or the next time the view is displayed) the view dimensions according with that bitmap width and height (keeping the aspect ratio).
What method should I use? I imagine that setWidth() and setHeight() is not the best idea
Since you're extending SurfaceView, you might be able to override the onMeasure() method. The MeasureSpec instances that you pass to the superclass (via super.onMeasure()) will determine the size of the SurfaceView. You can use the dimensions of your Bitmap to make each MeasureSpec.
For example:
protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec ) {
int parentViewWidth = MeasureSpec.getSize( widthMeasureSpec );
int parentViewHeight = MeasureSpec.getSize( heightMeasureSpec );
// ... take into account the parent's size as needed ...
super.onMeasure(
MeasureSpec.makeMeasureSpec( bitmap.width(), MeasureSpec.EXACTLY ),
MeasureSpec.makeMeasureSpec( bitmap.height(), MeasureSpec.EXACTLY ) );
}
I'm trying to make my first android game, just a pong clone really, I have a "PongView" class that extends SurfaceView and is my only view. It has objects of my "Ball" and "Paddle" classes. I just started moving code related to things, like detecting wall collisions, to the Ball and Paddle classes to tidy up my main view a bit and realised that i'd need to give these classes a way to know the views width and height. At the moment my work around is just to intialise a global variable inside the surfaceviews surfaceChanged method that stores the width and height of the view, like so:
//at the top of my class
private int viewWidth;
private int viewHeight;
..
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
//INITIALISE viewWidth and viewHeight here
//so that they can be passed as parameters
viewWidth = getWidth();
viewHeight = getHeight();
//some other irrelevant code here
}
Then I pass them as parameters:
ball.handleWallCollision(viewWidth, viewHeight);
However i'm not sure this is the way to go about it, as i will need to pass them in quite often i imagine. I thought it would be better if i had a copy of the current PongView in each class? But i'm not sure if thats true or how/when to go about getting it.
What would you recommend? Thanks
use object of surface view class that was used to setting view in activity.That object is live and will contain all changes regarding that surface view
SurfaceView sur=new SurfaceView(this); /// you created object
setContentView(sur);
//you do your work
//surface view is running
Now you want to exit from that activity.Then in onDestroy() used
CommonClass.ObjectVraible=sur;
this line will save current state of the surfaceview
I have a custom View in which i drawBitmap and then I scale the View to 1.5 scale factor.
After the scaling (zoom gesture) - I get the width and height of the view and it's the same just like the initial size. Thus, I have:
canvas.scale(1.5, 1.5, 0, 0);
measure(getWidth()*1.5, getHeight()*1.5);
and it calls onMeasure with the correct dimensions:
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(heightMeasureSpec, MeasureSpec.EXACTLY));
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
}
}
But after onMeasure is finished, if I get the width and height of the View, it's again the same as before...
And I need it to be the scaled size ...
I'm not sure, but I think you need to use a Matrix here, apply it to your image/canvas, and then use postscale() method to make it effective.
Hope that helps
To resize the View you need to have its parent lay out again. Make two calls on your View: First specify the new size view View.setLayoutParams(LayoutParams), then call View.requestLayout().
There is a method getMeasuredWidth/Height(), that should give you what the View's measured values are at drawing time.