Property animation of a moving button android - java

I need a button that will keep moving from left to right and whenever i click on it, it will do something. I came to know that I need to use Property Animation to do so. But I'm quite lost about it.
here is my main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<Button
android:id="#+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="39dp"
android:layout_marginTop="106dp"
android:text="Button" />
how do I edit my .java file to animate it from left to right using property animation?

Have a look on this Tutorial Android Animations.
The easiest way to animate a layout is, to do something like this :
your_layout.animate().translationX(your_layout.getWidth()).setDuration(500).setInterpolator(new AccelerateDecelerateInterpolator());

I would do it the following way:
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//new GetUrl().execute(20);
// Test XML Files
//testXMLFiles();
final Button speakButton = (Button)findViewById(R.id.play);
speakButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
// TODO: DO something!
}
});
final ObjectAnimator horizontalAnimator = ObjectAnimator.ofInt(new ButtonAnimatorHelper(speakButton), "marginLeft", 0, 600);
horizontalAnimator.setDuration(2000);
horizontalAnimator.setRepeatCount(ValueAnimator.INFINITE);
horizontalAnimator.setRepeatMode(ValueAnimator.REVERSE);
horizontalAnimator.setInterpolator(new LinearInterpolator());
horizontalAnimator.start();
}
/**
* Helper class for button animation
*/
private static class ButtonAnimatorHelper {
final Button mButton;
/**
* Default constructor
* #param speakButton
*/
public ButtonAnimatorHelper(final Button button) {
mButton = button;
}
public void setMarginLeft(final int margin) {
final ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mButton.getLayoutParams();
params.leftMargin = margin;
mButton.setLayoutParams(params);
}
}
}
For better understanding of property animation, I would suggest this session from Google I/O 2013 and of course, the tutorial here.

Related

Creating a progress bar for android

Hi I am new to threading in general and I am trying to set up a progress bar that increments itself every half-second up to 100 using the sleep method. I have been having trouble using a lot of the syntax I have found on line and when I launch this program it does not display a progress bar but instead displays a spinning loading icon. This is what I have:
public class main extends ActionBarActivity {
Handler mHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final Button startButton = (Button) findViewById(R.id.startbutton);
startButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showDialog(1);
startPb();
}
});
}
private void startPb(){
final ProgressBar pb = (ProgressBar) findViewById(R.id.progressBar);
pb.setIndeterminate(false);
pb.setProgress(0);
new Thread(new Runnable(){
public void run(){
for (int i = 0; i <= 100; i++)
try {
Thread.sleep(500);
pb.setProgress(i);
System.out.println(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
pb.post(new Runnable() {
public void run() {
pb.incrementProgressBy(1);
}
});
}
}).start();
}
I have a feeling I am not implementing the progress bar properly in the above code.
Layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".Counter"
android:id="#+id/counter"
tools:ignore="InvalidId">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="startButton"
android:id="#+id/startbutton"
android:layout_centerHorizontal="true" />
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/progressBar"
android:layout_below="#+id/startbutton"
android:layout_centerHorizontal="true" />
</RelativeLayout>
A spinning progress bar is an indeterminate progress bar. To use an actual progress bar you will want to call:
pb.setIndeterminate(false);
The progress bar style was also an issue. Here is a good reference explaining progress bar style types.
What's the meaning of android:progressBarStyle attribute in ProgressBar?

Android Studio: How to change the Background to jpg. images using OnclickListener

So far I know how to change the Background's color via html codes. Now I am Trying to change the background of the Layout of my main activity to different images using a button click. If possible using only one single button.
Thank you!
The following code is from this link Setting background image in java from Omi0301.
//assuming your Layout is named linearlayout1:
LinearLayout ll = (LinearLayout) findViewById(R.id.linearlayout1);
ll.setBackgroundResource(R.drawable.sample);
All you do is create a layout variable and set its background resource with the image that you would like it to be.
try to use "setImageResource" instead the "setBackgroundResourse"
Try below code
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/myLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="64dp"
android:layout_marginTop="71dp"
android:text="changeColor" />
</LinearLayout>
MainActivity.java
public class MainActivity extends Activity {
/** Called when the activity is first created. */
Button button;
LinearLayout mainLayout;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mainLayout=(LinearLayout)findViewById(R.id.myLayout);
button=(Button)findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
// TODO Auto-generated method stub
mainLayout.setBackgroundResource(R.drawable.newImage);
}
});
}
}

popup window over canvas Android

I am building an application which display a map (the map is the canvas background) and localise users by adding circle on the canvas(using draw circle). I would like to add a button over the canvas(for now a draw a button on the map and check with ontouch() if the user clicked on it) and when the button is touched I would like to have a window popup. It worked but the popup is behind the canvas(I could see a small piece of it(I removed it)).Is there a way to have my canvas BEHIND the button and the popup window? I saw people talking about putting the canvas in relative layout but I have no idea how to do that.
Here is the xml of my activity, really simple:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#drawable/umap2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:text="Button" />
</RelativeLayout>
And here is my activity java code(I removed a couple of things that doesnt have nothing to do with my problem)
package com.example.client;
import java.util.LinkedList;
//....
import java.util.Timer;
public class Campus extends Activity{
final Handler myHandler = new Handler();
MapView mapv;
final Activity self = this;
Float ratioX;
Float ratioY;
int width;
int height;
static boolean out=false;
Intent i;
//creating a linked list for each hall
static LinkedList<compMac> DMS = new LinkedList<compMac>();
static LinkedList<compMac> MCD = new LinkedList<compMac>();
//...
static LinkedList<compMac> SCI = new LinkedList<compMac>();
static LinkedList<compMac> STE = new LinkedList<compMac>();
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.campus);
setSize();
this.mapv = new MapView(this);//!! my view
setContentView(mapv);
i= new Intent(this, myService.class);
this.startService(i);
}
//*******************************View class!*******************************
public class MapView extends View {
/*
* Extract the connected users and location from the array. separate the
* array into an array for each building
* */
private Paint redPaint;
private float radius;
Canvas canvas;
public MapView(Context context) {
super(context) ;
redPaint = new Paint();
redPaint.setAntiAlias(true);
redPaint.setColor(Color.RED);
redPaint.setTextSize(10);
}
#Override
//drawing a point on every hall on the map where users are connected
public void onDraw (Canvas canvas) {
// draw your circle on the canvas
if(!out)
{
AlertDialog.Builder outOfCampus = new AlertDialog.Builder(self);
outOfCampus.setTitle("Sorry");
outOfCampus.setMessage("You are out of Campus");//(toDisplay);
outOfCampus.setCancelable(false);
outOfCampus.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
startActivity(new Intent("com.example.client.Sin"));
}});
AlertDialog alertdialog = outOfCampus.create();
outOfCampus.show();
}
this.canvas=canvas;
setBackgroundResource(R.drawable.umap2);
}
public void drawPoints(LinkedList<compMac> building)
{
if(!building.isEmpty())
{
while(!building.isEmpty())
{
compMac current = building.pop();
Float x= ratioX*(Float.parseFloat(current.getCoorX()));
Float y= ratioY*(Float.parseFloat(current.getCoorY()));
// Log.w("ratioX ",(((Double)(width/768)).toString()));
// Log.w("ratioY ",(float)(y.toString()));
canvas.drawCircle (x,y, 10, redPaint);
}
}
}
public boolean onTouchEvent (MotionEvent event) {
//...//
return true;
}
}
}
Someone have an idea how i can do that? Thanks
Calling setContentView two times would not work. Instead you should put your canvas view and the button in a single layout itself but with proper ordering. The last widget in the relative layout gets more priority, so if you want the button to come on top of the canvas your layout should be something like this.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#drawable/umap2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.example.client.MapView
android:id="#+id/mapView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:text="Button" />
</RelativeLayout>
And to access your MapView in java class
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.campus);
setSize();
this.mapv = findViewById(R.id.mapView); //!! my view
i= new Intent(this, myService.class);
this.startService(i);
}
And obviously alert dialog will be on top of the canvas. Hope it helps!
Edit: I think inflate error is due to incorrect class path. Since MapView is inner class of Campus, path should be like this
<com.example.client.Campus.MapView
android:id="#+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Also add this constructor to your MapView class
public MapView(Context context, AttributeSet attributeSet) {
super(context, attributeSet) ;
redPaint = new Paint();
redPaint.setAntiAlias(true);
redPaint.setColor(Color.RED);
redPaint.setTextSize(10);
}
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#drawable/umap2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<RelativeLayout
android:id="#+id/btn_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:background="#drawable/back_transparent_pressed" >
<Button
android:id="#+id/button1"
android:layout_centerInParent="true"
/>
</RelativeLayout>

Android adding simple animations while setvisibility(view.Gone)

I have designed a simple layout.I have finished the design without animation, but now I want to add animations when textview click event and I don't know how to use it.
Did my xml design looks good or not?
Any suggestions would be appreciated.
My XML
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:longClickable="false"
android:orientation="vertical"
android:weightSum="16" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:background="#00DDA0"
android:layout_weight="3" >
</LinearLayout>
<TextView
android:id="#+id/Information1"
android:layout_width="match_parent"
android:layout_height="1dp"
android:text="Child Information"
android:background="#0390BE"
android:layout_weight="0.75"
android:textColor="#FFFFFF"
android:layout_gravity="center|fill_horizontal"/>
<LinearLayout
android:id="#+id/layout1"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="8.5"
android:background="#BBBBBB"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="TextView" />
</LinearLayout>
<TextView
android:id="#+id/Information2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:text="Parent Information"
android:background="#0390BE"
android:layout_weight="0.75"
android:textColor="#FFFFFF"
android:layout_gravity="center|fill_horizontal"/>
<LinearLayout
android:id="#+id/layout2"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:background="#BBBBBB"
android:layout_weight="8.5" >
<TextView
android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="TextView" />
</LinearLayout>
<TextView
android:id="#+id/Information3"
android:layout_width="match_parent"
android:layout_height="0dp"
android:text="Siblings"
android:background="#0390BE"
android:layout_weight="0.75"
android:textColor="#FFFFFF"
android:layout_gravity="center|fill_horizontal"/>
<LinearLayout
android:id="#+id/layout3"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:background="#BBBBBB"
android:layout_weight="8.5" >
<TextView
android:id="#+id/textView3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="TextView" />
</LinearLayout>
<TextView
android:id="#+id/Information4"
android:layout_width="match_parent"
android:layout_height="0dp"
android:text="Teacher Information"
android:background="#0390BE"
android:layout_weight="0.75"
android:textColor="#FFFFFF"
android:layout_gravity="center|fill_horizontal"/>
<LinearLayout
android:id="#+id/layout4"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:background="#BBBBBB"
android:layout_weight="8.5" >
<TextView
android:id="#+id/textView4"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="TextView" />
</LinearLayout>
<TextView
android:id="#+id/Information5"
android:layout_width="match_parent"
android:layout_height="0dp"
android:text="Grade Information"
android:background="#0390BE"
android:layout_weight="0.75"
android:textColor="#FFFFFF"
android:layout_gravity="center|fill_horizontal"/>
<LinearLayout
android:id="#+id/layout5"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:background="#BBBBBB"
android:layout_weight="8.5" >
<TextView
android:id="#+id/textView5"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="TextView" />
</LinearLayout>
<TextView
android:id="#+id/Information6"
android:layout_width="match_parent"
android:layout_height="0dp"
android:text="Health Information"
android:background="#0390BE"
android:layout_weight="0.75"
android:textColor="#FFFFFF"
android:layout_gravity="center|fill_horizontal"/>
<LinearLayout
android:id="#+id/layout6"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:background="#BBBBBB"
android:layout_weight="8.5" >
<TextView
android:id="#+id/textView5"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="TextView"
android:layout_weight="8.5" />
</LinearLayout>
</LinearLayout>
My java
public class Certify_Info extends Activity {
private static TextView tv2,tv3,tv5,tv6,tv4,tv1;
private static LinearLayout l1,l2,l3,l4,l5,l6;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_certify__info);
tv1=(TextView) findViewById(R.id.Information1);
tv2=(TextView) findViewById(R.id.Information2);
tv3=(TextView) findViewById(R.id.Information3);
tv4=(TextView) findViewById(R.id.Information4);
tv5=(TextView) findViewById(R.id.Information5);
tv6=(TextView) findViewById(R.id.Information6);
l1=(LinearLayout) findViewById(R.id.layout1);
l2=(LinearLayout) findViewById(R.id.layout2);
l3=(LinearLayout) findViewById(R.id.layout3);
l4=(LinearLayout) findViewById(R.id.layout4);
l5=(LinearLayout) findViewById(R.id.layout5);
l6=(LinearLayout) findViewById(R.id.layout6);
l2.setVisibility(View.GONE);
l3.setVisibility(View.GONE);
l4.setVisibility(View.GONE);
l5.setVisibility(View.GONE);
l6.setVisibility(View.GONE);
tv1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
l2.setVisibility(View.GONE);
l3.setVisibility(View.GONE);
l4.setVisibility(View.GONE);
l5.setVisibility(View.GONE);
l6.setVisibility(View.GONE);
l1.setVisibility(View.VISIBLE);
}
});
tv2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
l1.setVisibility(View.GONE);
l3.setVisibility(View.GONE);
l4.setVisibility(View.GONE);
l5.setVisibility(View.GONE);
l6.setVisibility(View.GONE);
l2.setVisibility(View.VISIBLE);
}
});
tv3.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
l1.setVisibility(View.GONE);
l2.setVisibility(View.GONE);
l4.setVisibility(View.GONE);
l5.setVisibility(View.GONE);
l6.setVisibility(View.GONE);
l3.setVisibility(View.VISIBLE);
}
});
tv4.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
l1.setVisibility(View.GONE);
l2.setVisibility(View.GONE);
l3.setVisibility(View.GONE);
l4.setVisibility(View.GONE);
l5.setVisibility(View.GONE);
l6.setVisibility(View.GONE);
l4.setVisibility(View.VISIBLE);
}
});
tv5.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
l1.setVisibility(View.GONE);
l2.setVisibility(View.GONE);
l3.setVisibility(View.GONE);
l4.setVisibility(View.GONE);
l6.setVisibility(View.GONE);
l5.setVisibility(View.VISIBLE);
}
});
tv6.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
l1.setVisibility(View.GONE);
l2.setVisibility(View.GONE);
l3.setVisibility(View.GONE);
l4.setVisibility(View.GONE);
l5.setVisibility(View.GONE);
l6.setVisibility(View.VISIBLE);
}
});
}
}
You can do two things to add animations, first you can let android animate layout changes for you. That way every time you change something in the layout like changing view visibility or view positions android will automatically create fade/transition animations. To use that set
android:animateLayoutChanges="true"
on the root node in your layout.
Your second option would be to manually add animations. For this I suggest you use the new animation API introduced in Android 3.0 (Honeycomb). I can give you a few examples:
This fades out a View:
view.animate().alpha(0.0f);
This fades it back in:
view.animate().alpha(1.0f);
This moves a View down by its height:
view.animate().translationY(view.getHeight());
This returns the View to its starting position after it has been moved somewhere else:
view.animate().translationY(0);
You can also use setDuration() to set the duration of the animation. For example this fades out a View over a period of 2 seconds:
view.animate().alpha(0.0f).setDuration(2000);
And you can combine as many animations as you like, for example this fades out a View and moves it down at the same time over a period of 0.3 seconds:
view.animate()
.translationY(view.getHeight())
.alpha(0.0f)
.setDuration(300);
And you can also assign a listener to the animation and react to all kinds of events. Like when the animation starts, when it ends or repeats etc. By using the abstract class AnimatorListenerAdapter you don't have to implement all callbacks of AnimatorListener at once but only those you need. This makes the code more readable. For example the following code fades out a View moves it down by its height over a period of 0.3 seconds (300 milliseconds) and when the animation is done its visibility is set to View.GONE.
view.animate()
.translationY(view.getHeight())
.alpha(0.0f)
.setDuration(300)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
view.setVisibility(View.GONE);
}
});
The easiest way to animate Visibility changes is use Transition API which available in support (androidx) package. Just call TransitionManager.beginDelayedTransition method then change visibility of the view. There are several default transitions like Fade, Slide.
import androidx.transition.TransitionManager;
import androidx.transition.Transition;
import androidx.transition.Fade;
private void toggle() {
Transition transition = new Fade();
transition.setDuration(600);
transition.addTarget(R.id.image);
TransitionManager.beginDelayedTransition(parent, transition);
image.setVisibility(show ? View.VISIBLE : View.GONE);
}
Where parent is parent ViewGroup of animated view. Result:
Here is result with Slide transition:
import androidx.transition.Slide;
Transition transition = new Slide(Gravity.BOTTOM);
It is easy to write custom transition if you need something different. Here is example with CircularRevealTransition which I wrote in another answer. It shows and hide view with CircularReveal animation.
Transition transition = new CircularRevealTransition();
android:animateLayoutChanges="true" option does same thing, it just uses AutoTransition as transition.
Try adding this line to the xml parent layout
android:animateLayoutChanges="true"
Your layout will look like this
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:longClickable="false"
android:orientation="vertical"
android:weightSum="16">
.......other code here
</LinearLayout>
Please check this link. Which will allow animations like L2R, R2L, T2B, B2T animations.
This code shows animation from left to right
TranslateAnimation animate = new TranslateAnimation(0,view.getWidth(),0,0);
animate.setDuration(500);
animate.setFillAfter(true);
view.startAnimation(animate);
view.setVisibility(View.GONE);
if you want to do it from R2L then use
TranslateAnimation animate = new TranslateAnimation(0,-view.getWidth(),0,0);
for top to bottom as
TranslateAnimation animate = new TranslateAnimation(0,0,0,view.getHeight());
and vice a versa..
Base on #ashakirov answer, here is my extension to show/hide view with fade animation
fun View.fadeVisibility(visibility: Int, duration: Long = 400) {
val transition: Transition = Fade()
transition.duration = duration
transition.addTarget(this)
TransitionManager.beginDelayedTransition(this.parent as ViewGroup, transition)
this.visibility = visibility
}
Example using
view.fadeVisibility(View.VISIBLE)
view.fadeVisibility(View.GONE, 2000)
I was able to show/hide a menu this way:
MenuView.java (extends FrameLayout)
private final int ANIMATION_DURATION = 500;
public void showMenu()
{
setVisibility(View.VISIBLE);
animate()
.alpha(1f)
.setDuration(ANIMATION_DURATION)
.setListener(null);
}
private void hideMenu()
{
animate()
.alpha(0f)
.setDuration(ANIMATION_DURATION)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
setVisibility(View.GONE);
}
});
}
Source
Based on the answer of #Xaver Kapeller I figured out a way to create scroll animation when new views appear on the screen (and also animation to hide them).
It goes from this state:
Button
Last Button
to
Button
Button 1
Button 2
Button 3
Button 4
Last Button
and viceversa.
So, when the user clicks on the first button, the elements "Button 1", "Button 2", "Button 3" and "Button 4" will appear using fade animation and the element "Last Button" will move down till end. The height of the layout will change as well, allowing using scroll view properly.
This is the code to show elements with animation:
private void showElements() {
// Precondition
if (areElementsVisible()) {
Log.w(TAG, "The view is already visible. Nothing to do here");
return;
}
// Animate the hidden linear layout as visible and set
// the alpha as 0.0. Otherwise the animation won't be shown
mHiddenLinearLayout.setVisibility(View.VISIBLE);
mHiddenLinearLayout.setAlpha(0.0f);
mHiddenLinearLayout
.animate()
.setDuration(ANIMATION_TRANSITION_TIME)
.alpha(1.0f)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
updateShowElementsButton();
mHiddenLinearLayout.animate().setListener(null);
}
})
;
mLastButton
.animate()
.setDuration(ANIMATION_TRANSITION_TIME)
.translationY(mHiddenLinearLayoutHeight);
// Update the high of all the elements relativeLayout
LayoutParams layoutParams = mAllElementsRelativeLayout.getLayoutParams();
// TODO: Add vertical margins
layoutParams.height = mLastButton.getHeight() + mHiddenLinearLayoutHeight;
}
and this is the code to hide elements of the animation:
private void hideElements() {
// Precondition
if (!areElementsVisible()) {
Log.w(TAG, "The view is already non-visible. Nothing to do here");
return;
}
// Animate the hidden linear layout as visible and set
mHiddenLinearLayout
.animate()
.setDuration(ANIMATION_TRANSITION_TIME)
.alpha(0.0f)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
Log.v(TAG, "Animation ended. Set the view as gone");
super.onAnimationEnd(animation);
mHiddenLinearLayout.setVisibility(View.GONE);
// Hack: Remove the listener. So it won't be executed when
// any other animation on this view is executed
mHiddenLinearLayout.animate().setListener(null);
updateShowElementsButton();
}
})
;
mLastButton
.animate()
.setDuration(ANIMATION_TRANSITION_TIME)
.translationY(0);
// Update the high of all the elements relativeLayout
LayoutParams layoutParams = mAllElementsRelativeLayout.getLayoutParams();
// TODO: Add vertical margins
layoutParams.height = mLastButton.getHeight();
}
Note there is a simple hack on the method to hide the animation. On the animation listener mHiddenLinearLayout, I had to remove the listener itself by using:
mHiddenLinearLayout.animate().setListener(null);
This is because once an animation listener is attached to an view, the next time when any animation is executed in this view, the listener will be executed as well. This might be a bug in the animation listener.
The source code of the project is on GitHub:
https://github.com/jiahaoliuliu/ViewsAnimated
Happy coding!
Update: For any listener attached to the views, it should be removed after the animation ends. This is done by using
view.animate().setListener(null);
My solution extension
fun View.slideVisibility(visibility: Boolean, durationTime: Long = 300) {
val transition = Slide(Gravity.BOTTOM)
transition.apply {
duration = durationTime
addTarget(this#slideVisibility)
}
TransitionManager.beginDelayedTransition(this.parent as ViewGroup, transition)
this.isVisible = visibility
}
Use:
textView.slideVisibility(true)
Find the below code to make visible the view in Circuler reveal, if you send true, it'll get Invisible/Gone. If you send false, it'll get visible. anyView is the view you're going to visible/hide, it could be any view (Layouts, Buttons etc)
private fun toggle(flag: Boolean, anyView: View) {
if (flag) {
val cx = anyView.width / 2
val cy = anyView.height / 2
val initialRadius = Math.hypot(cx.toDouble(), cy.toDouble()).toFloat()
val anim = ViewAnimationUtils.createCircularReveal(anyView, cx, cy, initialRadius, 0f)
anim.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation)
anyView.visibility = View.INVISIBLE
}
})
anim.start()
} else {
val cx = anyView.width / 2
val cy = anyView.height / 2
val finalRadius = Math.hypot(cx.toDouble(), cy.toDouble()).toFloat()
val anim = ViewAnimationUtils.createCircularReveal(anyView, cx, cy, 0f, finalRadius)
anyView.visibility = View.VISIBLE
anim.start()
}
}

Android Application closing for no reason

Hi guys i started learning android development about 2 days ago.. So was trying out with a basic application to increment and decrement.
Everything is okay but when i'm testing the application even on the emulator, i get a message "Unfortunately, application "
I tried debugging the code and found that Even after declaring a statement findViewById(), my variables are pointing to null. And i think that's the reason for this error.. heres my code, in MainActivity.java. Please help me out!
public class MainActivity extends ActionBarActivity {
/* Your original code */
/*
TextView sum;
Button increment;
Button decrement;
*/
int total;
/* My interpretation */
protected static TextView sum;
protected static Button increment;
protected static Button decrement;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.findViewById();
total = 0;
increment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
total++;
sum.setText("Sum is "+total);
}
});
decrement.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
total--;
sum.setText("Sum is "+total);
}
});
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
}
/* Your original code (moved to fragment) */
/*
private void findViewById() {
sum = (TextView) findViewById(R.id.tv); // sum points to null
increment = (Button) findViewById(R.id.inc); //increment points to null
decrement = (Button) findViewById(R.id.dec); // decrement points to null
}
*/
EDIT ::
placeholder fragment ::
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
/* added */
Context ctx = null;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView;
rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
/* added */
init();
}
/* added */
private void init()
{
final View v = getView();
ctx = getActivity().getApplicationContext();
MainActivity.sum = (TextView) v.findViewById(R.id.tv); // sum points to null
MainActivity.increment = (Button) v.findViewById(R.id.inc); //increment points to null
MainActivity.decrement = (Button) v.findViewById(R.id.dec); // decrement points to null
}
}
here is the layout ::
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.vishal.Simplecalc.MainActivity$PlaceholderFragment">
<TextView
android:id="#+id/tv"
android:text="#string/sumView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:layout_gravity="center"
tools:context=".MainActivity"
/>
<Button
android:id="#+id/inc"
android:text="#string/inc"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:textSize="30sp"
android:layout_gravity="center"
android:textStyle="bold"
tools:context=".MainActivity"
/>
<Button
android:id="#+id/dec"
android:text="#string/dec"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:textSize="30sp"
android:layout_gravity="center"
android:textStyle="bold"
tools:context=".MainActivity"
/>
</LinearLayout>
Just guessing here (you haven't added the name for your xml layout).
I'm guessing you're probably confusing your layouts and just posted fragment_main.xml which actually has the content your code is believing to be held in activity_main, which causes your code to return nulls when you're assigning the findViewById()
I think the problem is that PlaceholderFragment is setting a new layout, and that doesn't allow the text to be changed.
Sometimes it can be because of emulators, create new emulator or try it with your real device .

Categories

Resources