Android - Translating view bigger than screen size causes smearing - android

I am trying to make a game with several "screen". If the user goes to the edge of a screen, an animation should pop in that shifts out the current screen and shifts in the new screen.
I wanted to do this with a TranslateAnimation. First I calculate an bitmap which contains the first and the second screen and then i want to play this in the view 'transitionView' while i hide the view 'levelView', which originally contained the first screen. After the transition is finished, i want to hide 'transitionView' again and display the new screen in 'levelView'.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/viewGroup"
android:layout_width="match_parent"
android:layout_height="match_parent">
<view
class="at.test.game.ScreenTransitionTest2$LevelView"
android:id="#+id/levelView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<view
class="at.test.game.ScreenTransitionTest2$TransitionView"
android:id="#+id/transitionView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"/>
</RelativeLayout>
I first tried to to it with an ImageView, but it would always scale down the bitmap regardless of the settings i used. So I now created my own View, which just draws the image from (0, 0).
Since clipping occured, I disabled it in the onCreate method:
((RelativeLayout)findViewById(R.id.viewGroup)).setClipChildren(false);
The animation looks like this:
this.transitionView.setBitmap(calculateBitmap(screen1, screen2));
TranslateAnimation a = new TranslateAnimation(
Animation.ABSOLUTE, startx, Animation.ABSOLUTE, endx,
Animation.ABSOLUTE, starty, Animation.ABSOLUTE, endy);
a.setDuration(3000);
a.setFillAfter(true);
this.transitionView.setAnimation(a);
a.start();
My problem: Only 480x800 of the bitmap is rendered/moved correctly (the bitmap is about 1000x880 and its starting coordinates are like (-40, -40), endcoordinates (-520, -40)) outside this area (so on the bottom of the screen and to the right as the 2nd frame should move in) instead of displaying the rest of the bitmap nothing is drawn or just smeared (see screenshot)
Why does the bitmap not get correctly drawn in the animation? Did I miss some settings? I tried 'wrap_content' for the viewgroup, but that did not help either. Or is it just not possible to slide bigger bitmaps through the whole screen?
screenshot - nothing is drawn on bottom and smearing occurs on the right

Related

Android - How add a Large GLSurfaceView in a FrameLayout center?

I am using two GLSUrfaceView to render video of my own camera and video i receive from server. They are video call data. One small and one large in size. The large GLSurfaceView has two mode, one is Normal Screen mode which is done by filling screen width and calculating the screen height as (DISPLAY_WIDTH * ASPECT_RATIO_OF_IMAGE), and the second mode is full screen mode which is done by filling screen height and calculating the screen width as (DISPLAY_HEIGHT * ASPECT_RATIO_OF_IMAGE). I make the screen large on double tap and again normal in double tap again. But the problem is in large mode the image is cut in the right side only. I want my image to be cut in all side fitting the FrameLayout center at GLSurfaceView center. I am adding my Code part also. See the below image also which describe my need.
<RelativeLayout
android:id="#+id/video_call_views_container_outgoing"
android:layout_width="match_parent"
android:visibility="gone"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/largeGLSurfaceViewContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical"/>
<FrameLayout
android:id="#+id/smallGLSurfaceViewContainer"
android:layout_width="120dp"
android:layout_height="170dp"
android:orientation="vertical"
android:visibility="gone"/>
</RelativeLayout>
Here is my coding part :
GLSurfaceView frontCameraGLView = new GLSurfaceView (this);
GLSurfaceView opponentCameraGLView = new GLSurfaceView (this);
largeVideoRenderLayoutOutgoing.addView(opponentCameraGLView );
largeVideoRenderLayoutOutgoing.setOnClickListener(this);
opponentCameraGLView.setZOrderMediaOverlay(false);
smallVideoRenderLayoutOutgoing.addView(frontCameraGLView );
smallVideoRenderLayoutOutgoing.setOnClickListener(this);
largeVideoRenderLayoutOutgoing is the reference of FrameLayout having id largeGLSurfaceViewContainer , smallVideoRenderLayoutOutgoing also refer FrameLayout having id of smallGLSurfaceViewContainer. GLSurfaceView are added to FrameLayout's during onCreate of Activity. The problem is specified in the below image's
This image is image in the Upeer side is in Normal Mode. And the Below image is in Full Screen Mode. See the left side of these image. They are same but the right is cut in FullScreen mode i mean the last image. I wish that the image should be center fitted so that the image is cut in all side focusing my incoming video's center
If a GLSurfaceView's width is or height is larger than the device screen, it will behave like below:
1. For width larger than device width but height is same as device height: the GLSurfaceView will start drawing from top left corner which co-ordinate will be (0,0) and the extra image will be out of screen right side. So the image center will not be in layout's center. To solve this problem we need to shift image left as leftMargin which value will be half of (imageWidth-deviceWidth). The code's are like
ViewGroup.MarginLayoutParams marginLayoutParams = (ViewGroup.MarginLayoutParams) glSurfaceView.getLayoutParams();
int margin = (-1 * (int) ((glSurfaceView.getWidth() - displayWidth) / 2));
marginLayoutParams.setMargins(margin, 0, 0, 0);
setLayoutParams(marginLayoutParams);
Please do write a similar code if the heigh of the glsurfaceview is larger than device height. Add a margin on top so that the image is fitted in center of the device

Android Custom View inside Linear Layout with other views

I have a custom view to display a simple piechart.
My intention is to take some values like size,background color etc thru Layout xml file.
I derive the radius of the circle, strokewidth etc as a factor of the height of the view(width is equal to width of the parent/screen) and all dimensions are based on this radius.
Here is my layout xml for the fragment
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/bluegrey200"
tools:context="ash.dbtest.GraphPieChartFragment">
<ash.dbtest.GraphPieChartView
android:layout_width="match_parent"
android:id="#+id/pieChart1"
custom:backgroundColor="#color/bluegrey800"
custom:labelColor="#color/white"
android:layout_height="800px"
/>
This appears perfectly fine now.
See the image:
The black rectangle is the area used in the overridden onDraw method. Note the blue diagonal line showing the bounds of the rectangle.
I know the height is mentioned in pixels and it must be in dp; but the values are now for debugging purpose.
I changed my layout xml file to below to add a banner above the Custom view in another linear layout.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/bluegrey200"
tools:context="ash.dbtest.GraphPieChartFragment">
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:text="TestBanner"
android:textSize="20sp"
android:layout_height="wrap_content" />
</LinearLayout>
<ash.dbtest.GraphPieChartView
android:layout_width="match_parent"
android:id="#+id/pieChart1"
custom:backgroundColor="#color/bluegrey800"
custom:labelColor="#color/white"
android:layout_height="800px"
/>
See the screenshot now, it goes weird.
See image here:
Now my customview moves to the bottom, but is getting truncated. The onDraw method is getting the right dimensions and the circle is getting drawn correctly. But somehow the View is getting truncated. In the screenshot below, note that the black rectangle is incomplete and the blue diagonal line is getting truncated.
What could be the issue ?
I am a beginner around android and hope that I have provided all required information. I did not post the code because its just basic draws on canvas.
Thank you very much for your time on this.
Code on the GraphPieCharView.onDraw
#Override
public void onDraw(Canvas canvas) {
Log.d("onDraw","onDraw");
Log.d("onDraw1",Float.toString(this.getLeft()));
Log.d("onDraw2",Float.toString(this.getTop()));
Log.d("onDraw3",Float.toString(this.getRight()));
Log.d("onDraw4",Float.toString(this.getBottom()));
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setStrokeWidth(20);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(BACKGROUND_COLOR);
canvas.drawRect(this.getLeft(),this.getTop(),this.getRight(),this.getBottom(),paint);
because your GraphPieChartView is below TextView
Figured it out.
I was drawing the rectangle using the below code
canvas.drawRect(this.getLeft(),this.getTop(),this.getRight(),this.getBottom(),paint);
Lets say the page is 1500px high and 1000px wide.
Here, when the customview is the only view on the page, below are the results of the getters.
left - 0
top - 0
right - 1000
bottom - 800
I drew the rectangle in these bounds, and all the calculation based on these bounds; it worked fine.
Now, when the custom view is the second view when listed vertically, with the top TextView taking say 50px,
left - 0
top - 50
right - 1000
bottom - 850
But these values are relative to the whole screen (1000*1500).
But inside my custom view, the canvas I have is 1000*800, starting from 0,0 and ending at 1000,800 diagonally.
But I was drawing on the canvas as if it starts from 0,50 and ending at 1000,850.
Adjusted the calculation inside the onDraw method to always start from 0,0 and it solved the issue.
Thanks for all the responses.

Letting an image expand into view using an animation

In my Android app, I have a TextView with a white background. When it is clicked, its background will change to a .png picture of some icon by calling setBackgroundResource(R.drawable.icon) on the TextView. This works as intended, but the change is rather abrupt. I would like to make the icon appear more gradually; when the TextView is clicked, a tiny version of the icon should appear in the center of the TextView and then immediately expand and fill out the entire TextView. I believe the best way to do this would be by using an animation, which of the available animation types in Android are best for this task?
In case it is not clear what I mean, I drew a sketch to illustrate. The second sequence shows how the code works right now, the first shows how I would like it to be.
So, I managed to get the effect you want with an ImageView, using ScaleAnimation. Here's what you have to do:
First, our XML ImageView:
<ImageView
android:id="#+id/scale_anim"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="#android:color/white" />
It has fixed dimensions and a white background.
The animation will start with one click with this, inside your onCreate() method:
ImageView starImageView = (ImageView) findViewById(R.id.scale_anim);
starImageView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ScaleAnimation starScaleAnimation =
new ScaleAnimation(0.3f, 1f, 0.3f, 1f,
ScaleAnimation.RELATIVE_TO_SELF, 0.5f,
ScaleAnimation.RELATIVE_TO_SELF, 0.5f);
starScaleAnimation.setDuration(500);
((ImageView) v).setImageResource(R.drawable.star);
ScaleAnimation scaleAnim = starScaleAnimation;
v.startAnimation(scaleAnim);
}
});
We are applying a scale animation on the ImageView that stars with 30% of the original size and scales to 100% of its size, from its center point. The duration of this animation is half a second. All these parameters can be changed.
Every time you click the ImageView, your drawable will be applied and the animation will start.
Try this way if it solve yours.
Create an ImageView (X) above your original ImageView (A) - same size and same place as (A)
Animate (X) with ObjectAnimator, listen for the onAnimationEnd call and set the (A)'s background. Then remove (X).
Hope this will help.

After rotating a linearlayout, the onclick events do not change position after the rotation

I have a vertical linearlayout with three clickable imageviews within the linearlayout. When i rotate the linearlayout by 90 degrees using simple animation the problem arises. The imageviews are rotated correctly but the onclick events for the imageviews are not rotated along with the linearlayout and remain in the original position as before the animation.
Below is my main java code
westplayer = (LinearLayout) findViewById(R.id.linearLayout_west);
// Create an animation instance
Animation an = new RotateAnimation(0.0f, 180.0f, 32, 180);
// Set the animation's parameters
an.setDuration(0); // duration in ms
an.setRepeatCount(0); // -1 = infinite repeated
an.setRepeatMode(Animation.REVERSE); // reverses each repeat
an.setFillAfter(true); // keep rotation after animation
// Apply animation to linearlayout
westplayer.setAnimation(an);
The code above handles the animation part. The code below follows the animation and is supoosed to update the layout positions but is not working for me.
// Update Layout
int top=westplayer.getTop();
int bottom=westplayer.getBottom();
int left=westplayer.getLeft();
int right=westplayer.getRight();
westplayer.layout(left, top , right, bottom );
The xml is as follows:
<LinearLayout
android:id="#+id/linearLayout_west"
android:layout_width="42dp"
android:layout_height="250dp"
android:layout_alignParentLeft="true"
android:layout_below="#+id/linearLayout_north"
android:duplicateParentState="false"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageViewW1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/spades_14"
/>
<ImageView
android:id="#+id/imageViewW2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/spades_14"
android:layout_marginTop="-15dp"
/>
<ImageView
android:id="#+id/imageViewW3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/spades_14"
android:layout_marginTop="-15dp"
/>
</LinearLayout>
I have got the update layout code from this and also found another solution that i have also tried this and still no positive results. I need this to work for API 10. Any help is much appreciated
Yes, you got the expected result.
Since Animation in android only try to apply a transformation matrix on the bitmap of view, it doesn't change the position and size of view.
So after your animation, although you setFillAfter(true) to let the view looks rotated, but in fact the view are still in the same place and doesn't move a little bit.
The problem you face, is because you use a Tween Animation. The View will rotate and only the visible part will move. But the positions of the ImageView will remain the same like defined in the layout. That's why the clickable area stays the same.
To redefine the position, according to the animation you will have to use a Property Animation, like a ObjectAnimator or a ValueAnimator. With this the propertys defined in xml will be updated. Now the clickable areas move along with the views.

Animate ImageView width without scaling

I'm trying to animate an ImageView so it's slowly shown from left to right.
When I asked this before I was having trouble to explain what I wanted, so this time I created the desired effect using HTML / JS:
http://jsfiddle.net/E2uDE/
What would be the best way to get this effect in Android?
I tried changing the scaleType and then applying a ScaleAnimation directly to that ImageView:
Layout:
<ImageView
android:id="#+id/graphImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:scaleType="centerCrop"
android:background="#android:color/transparent"
android:contentDescription="#string/stroom_grafiek"
/>
Java:
scale = new ScaleAnimation((float)0,
(float)1, (float)1, (float)1,
Animation.RELATIVE_TO_SELF, (float)0,
Animation.RELATIVE_TO_SELF, (float)1);
scale.setDuration(1000);
graphImage.startAnimation(scale);
But this stil scales the image.
I also tried wrapping the ImageView in a FrameLayout, hoping I could just animate the FrameLayout:
<FrameLayout
android:layout_width="70dp"
android:layout_height="fill_parent"
android:clipChildren="true"">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|left|clip_horizontal" />
</FrameLayout>
This will still try to scale my ImageView to fit inside the FrameLayout.
There are several ways to do this - one way is to simply change the clip on the canvas (i.e. the area where the view is allowed to draw) of the ImageView drawing your image. Slowly increasing the right-hand edge of the draw bounds will result in same effect as in your example link.
I have written some example code which illustrates this technique. If you download/build/run the project, clicking on the image will run the reveal animation.
Have a look at the onDraw method of the CoveredImageView class, which has the following basic structure:
#Override
protected void onDraw(Canvas canvas) {
...
canvas.getClipBounds(mRect);
mRect.right = ...;
canvas.clipRect(mRect);
...
super.onDraw(canvas);
...
invalidate();
}
The clip is adjusted and then invalidate() is called, causing onDraw() to be called again.
I have also written some code to interpolate the right clip value from the elapsed time, which does not depend on any particular version of Android. However, as a note, from Android 3.0 there is a new animation framework and a ValueAnimator class which could help perform such tasks.
You could overlap your imageview with another one, for example one with a plain white drawable. Then you can animate the overlapping imageview without worrying about scale until it has a width of 0 and remove it. For that to work you have to place your imageView in a RelativeLayout ofc.

Categories

Resources