I have a LinearLayout View in my activity.
When I press back button I want LinearLayout's children to slide out.
I have the following code which doesn't do anything:
private void SlideOut()
{
LayoutAnimationController controller = AnimationUtils.loadLayoutAnimation(this, R.anim.layout_animation_row_slide_out);
Animation animation=controller.getAnimation();
animation.setFillAfter(true);
LinearLayout menuLayout =((LinearLayout)findViewById(R.id.menuLayout));
menuLayout.setLayoutAnimation(controller);
menuLayout.startLayoutAnimation();
}
#Override
public void onBackPressed(){
//super.onBackPressed();
SlideOut();
}
I have commented out super.OnBackPressed() to see if the animation starts, and it don't start.
Somebody with similar problems ?
check if SlideOut() is called in onBackPressed - i'm guessing your back press is being handled elsewhere - possibly by the virtual keyboard
try this.it may help you:
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if(keyCode==KeyEvent.KEYCODE_BACK){
SlideOut();
return true;
}else{
return false;
}
//return super.onKeyDown(keyCode, event);
}
can u just change the code here here :
private void SlideOut()
{
Animation controller = AnimationUtils.loadLayoutAnimation(this, R.anim.layout_animation_row_slide_out);
// Animation animation=controller.getAnimation();
animation.setFillAfter(true);
LinearLayout menuLayout =((LinearLayout)findViewById(R.id.menuLayout));
menuLayout.startAnimation(controller);
}
I think you might be exiting the activity before animation is finished. Try implementing Animation Listener
Related
I am displaying a FrameLayout with some components inside a Fragment. In onCreateView(..) I am animating the content of the FrameLayout and everything works fine. Now I want to animate the content before closing the Fragment.
In my current solution I am overriding onBackPressed() in the parent Activity and then I'm calling the method onBackPressed() inside my Fragment and animating the content there. The problem with this solution is, that I want to inflate the Fragment from various activities and then this is not really a nice solution... Does anybody know a better approach?
Thanks for your help!
Note:
I also tried to override onCreateView() and onPause() but the animation is not shown if I start it in those methods
and the following method does not fulfill my requirements either as it animates the whole fragment and I want to animate the content
getActivity().getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations(R.anim.slide_in_up, R.anim.slide_out_up, R.anim.slide_out_down, R.anim.slide_in_down)
Maybe you can try to handle onBackPressed in your fragment like below:
yourRootLayout.setFocusableInTouchMode(true);
yourRootLayout.requestFocus();
yourRootLayout.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK){
animateMyViews();
return true;
}
return false;
}
});
I wanted to perform sliding exit animation before dismissing the view/fragment.
These are the steps I performed:
I created a runnable task which can dismiss the current screen.
Passed that runnable to animating view.
Used view.postOnAnimationDelayed(runnable, 400) so that it can animate and execute the runnable after 400 milliseconds.
Also I made sure that my animation duration is >= 400 so that the transition is smooth.
Below is a little bit altered version of code for idea.
I used view.postOnAnimationDelayed(runnable, 400) to
Dialog dialog = new Dialog(getActivity(), getTheme()) {
#Override
public void onBackPressed() {
ParentFragment.this.onBackPressed();
Runnable runnable = new Runnable() {
#Override
public void run() {
//Referencing this class in runnable
getInstance().dismiss();
}
};
//webView is the child view loaded on this fragment
if(webView != null && webView.webViewClient != null) {
webView.webViewClient.animateClose(webView, runnable);
} else {
super.dismiss();
}
};
function animateOnClose in webViewClient looked like this:
public void animateClose(final WebView view, Runnable runnable) {
Animation anim = AnimationUtils.loadAnimation(getMainActivityContext(),
animationResource);
view.startAnimation(anim);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
view.postOnAnimationDelayed(runnable, 400);
// you can also try view.postOnAnimation(runnable);
} else {
runnable.run();
}
}
I think what you need is to notify the Fragment that you are about to destroy it.
A crude pseudocode might look like
myFragment.aboutToClose();
While in your Fragment's aboutToClose() method.
public void aboutToClose()
{
// Perform all the animations you want.
// Don't forget to add onAnimationEnd() call back.
onAnimationEnd()
{
// Notify Activity that Animations have completed.
callback.animationsCompleted();
}
}
Finally in your calling Activity.
public void animationsCompleted()
{
// Destroy fragment.
getActivity().getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations(R.anim.slide_in_up, R.anim.slide_out_up, R.anim.slide_out_down, R.anim.slide_in_down);
}
How to make an app which will not listen to touch events and back/home pressing but will listen only to the power button.
I've tried this but it wasn't successful.
#Override
public boolean onKeyDown(int keyCode, android.view.KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_POWER) {
return true;
}else if ((keyCode == KeyEvent.KEYCODE_HOME)|| (keyCode == KeyEvent.KEYCODE_BACK )){
return false;
}
return false;
}
You could wrap you class with a custom View of yours and override its OnClickListener and OnTouchListener methods. Override them with blank methods.
Also, keep your code to set how your app should work when the Power Button is clicked.
For instance, if you wrap your layout with a RelativeLayout or a general View, you could use something like
relativeLayout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
return false;
}
});
relativeLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
return false;
}
});
To block user touch event try this solution. And if you want to disable back and home try to override this method of Activity:
#Override
public void onAttachedToWindow() {
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
super.onAttachedToWindow();
}
three weeks ago, i want also to catch the home button, but i faied. i do some research, i find the android system don't support to modify it.you can visit this
Overriding the Home button - how do I get rid of the choice?, about homebutton.
as for the touchEvent, i advice you can try this method ,override onTouchEvent (if you dont add onTouchListener, make it retrun fasle and do nothing, at the same time ,the activity also dont handle the onTounEvent or OnClick(whole layout).
I want my fragment to not receive any clicks on the views while the fragment transition animation is not yet finished. It is just a simple fade. But things get wonky when I immediately press any view while the next fragment is fading in.
Any thoughts how to achieve this?
This is actually used in my own app. The idea is very simple, it just works, but needs quite a lot of additional coding.
The idea is very simple, use a boolean variable to maintain whether the screen should be locked, let's call it screenLocked. I do not actually block the click, but let the click do nothing.
For those actions which takes time, set screenLocked to true before start working, and set it back to false when the task is finished. Also you have to add checking on screenLocked before any action is done.
Another difficulty of the this method is that you need to have clear end point of your tasks. Using Fragment transition as an example, if the backstack is poped, there has no actual callback notifying you, for this case. To handle this, I would set another flag releaseOnResume before starting Fragment transition, and in onResume, I would use this flag to check if I should set screenLocked back to false.
Other solutions I have tried but not used:
Before I settled with the method I just mentioned, I have tried setEnabled, setClickable, or any UI based blocking, e.g. add a FrameLayout on top and capture all touch events.
These methods are not bad, especially given that they are easy to implement.
The only problem is that, onClick events can be queued due to double tapping, when you are handling the first onClick event, actually there could be another one queued up, even if you do any UI changes immediately to block any further clicks, you can't stop the next onClick event to come because it is queued already.
Hope this helps.
I use a countdown timer.
I manage this through the ontouch listener.
I create a method that manages the creation of the timer. I call it in the ontouch event. I use two methods (this is optional, but good for extensibility) to handle button enabling and disabling. I then use these methods with the timer to enable and disable the button.
See my code snippet.
In oncreate:
#Override protected void onCreate(Bundle savedInstanceState) {
/.../
button.setOnTouchListener(new View.OnTouchListener() {
#Override public boolean onTouch(View v, MotionEvent event) {
disableButton(button);
countDwn1();
/... time to do whatever you need..
// custom methods...
fragment = new MyFragAddFragment();
replaceFragment(fragment);
return false;
}
});
Methods:
public void countDwn1() {
CountDownTimer countDownTimer = new CountDownTimer(2000, 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
enableButton(button);
}
}.start();
}
public void disableButton(Button button) {
button.setEnabled(false);
}
public void enableButton(Button button) {
button.setEnabled(true);
}
You can extend this method to include passing the button as a parameter into the timer, for extensibility.
In the end I used something like this. I created a parent class for all my fragments and overriden the OnCreateAnimation method which is called on every animation.
#Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
//Check if the superclass already created the animation
Animation anim = super.onCreateAnimation(transit, enter, nextAnim);
//If not, and an animation is defined, load it now
if (anim == null && nextAnim != 0) {
anim = AnimationUtils.loadAnimation(getActivity(), nextAnim);
}
//If there is an animation for this fragment, add a listener.
if (anim != null) {
anim.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
isAnimationFinished = false;
}
#Override
public void onAnimationEnd(Animation animation) {
isAnimationFinished = true;
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
}
return anim;
}
The isAnimationFinished variable is a public variable that can be used by the calling activity and the child classes
I followed this tutorial http://www.andengine.org/forums/tutorials/multiple-screen-andengine-game-v2-t4755.html to create a simple application with multiple scene and only one activity.
I'd like to know how can i can return to the previous scene when i use the back button and finish the activity when i'm in the first scene.
I tried so in the MultiScreen Class:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
this.mEngine.getScene().back();
}
return super.onKeyDown(keyCode, event);
}
replacing the core.getEngine().setScene(scene); in the SceneManager with this.mEngine.getScene().setChildScene(scene);
scene work differently from how I understood, I resolve with:
#Override
public void onBackPressed()
{
Scene scene = this.mEngine.getScene();
if(scene.hasChildScene()){
scene.back();
}
else{
this.finish();
}
}
You can override the back key in one of two ways, either by overriding the onBackPressed() method, or the dispatchKeyEvent() method
Overriding onBackPressed:
#Override
public void onBackPressed()
{
// your code here
}
Overriding dispatchKeyEvent:
#Override
public boolean dispatchKeyEvent(KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_BACK)
{
// your code here
}
return (yourbooleanhere);
}
I had a dilemma like you in that sense. I explain. I have an activity like works with a ViewFlipper. I need to go to the different "layout" that I wrote on ViewFlipper tag and, when a I was in a particular "layout" that is not the main "layout" of the activity, I need to come back to the main pressing the back button, but, it doesn't work what I want.
To resolve this dilema, I override OnBackPressed function like:
#Override
public void onBackPressed() {
if (condition) {
// go to the main
} else {
super.onBackPressed();
}
}
where condition, as name says, how do you know that you are in the main "layout"? For example, in my ViewFlipper, the main "layout" are ordered by numbers, that begin on 0, so my main "layout" is 0 and how I know that I am in the 0 "layout", viewflipper.getDisplayedChild(). If it returns 0, I stay in the main "layout" or not, otherwise.
So simple but, I know, not so elegant. It's an idea, I think that can help you.
How to terminate an Activity in Adroid on touch. Here i shows a view which is described in details.xml. I need to dismiss the activity on touch. I tried the following code. But its not working. Any ideas?
public class Details extends Activity {
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.details);
}
public boolean onTouchEvent(MotionEvent event){
this.finish();
return true;
}
}
You should use
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
finish();
return super.dispatchTouchEvent(ev);
}
Your onTouchEvent() will only be called if no other views under the finger in the view hierarchy have consumed the event. This is uncommon, since many views do interact with touch events.
It is wrong to do stuff in onTouchEvent() without look at what the actual event is.
Generally you should implement a view that reacts to touches and does the appropriate thing.
I know its an old question but my solution is this if anyone need it:
I had the same problem so I solved it with giving my parent layout i.e(consraintLayout) an id then calling finish() in setOnClickListener() method and it worked.
View v = findViewById(R.id.validateLayout);
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
validateLayout is parent constraint layout of my activity.
any review is welcomed.
Also i want to know if suggestion of Addev is better then this code.
You didn't install a listener in onCreate(). Like:
findViewById(R.id.some_view).setOnTouchListener(this);