I want to change the button background color for a short period of time after the button is pressed. The button should regain it's previous condition after that period.
Probably a handler is the correct decision for this problem, unfortunately i didn't found a working example for doing a similar thing.
If anyone can give me a short example of how doing a such thing i would appreciate it.
Do this :
public class LaunchActivity extends Activity implements OnTouchListener{
private Button yourButton;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
yourButton= (Button)findViewById(R.id.yourButton);
yourButton.setOnTouchListener(this);
}
#Override
public boolean onTouch(final View view, MotionEvent event) {
final int action = event.getAction();
if(view.getId()==R.id.yourButton){
if(action == MotionEvent.ACTION_DOWN)
yourButton.setBackgroundResource(R.drawable.ic_button_pressed);
if(action == MotionEvent.ACTION_UP){
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
yourButton.setBackgroundResource(R.drawable.ic_button_normal);
}
}, 2000);
}
}
}
}
Or with an onClick listener :
#Override
public void onClick(View v) {
yourButton.setBackgroundResource(R.drawable.first_icon);
// SLEEP 2 SECONDS HERE ...
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
yourButton.setBackgroundResource(R.drawable.second_icon);
}
}, 2000);
}
you can define an XML background for your button under res/drawable/button_background
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/button_background_pressed" android:state_pressed="true" />
<item android:drawable="#drawable/button_background_notpressed"/>
</selector>
and for use an ImageButton
<ImageButton
...
android:background="#drawable/button_background"
... />
Related
I'm building a simple counter, it has buttons to add or subtract from a total value, I want it to keep adding if I hold the button, incrementing +5 every second, but i'm having problems to make it work. I'm using onClickListener, but i can't find a way to make it work "together" with on touch listener.
pl.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
lf++;
lt.setText(Integer.toString(lf));
}
}
You will have to use handler to schedule a runnable that increments +5 every 1 second (+1 per 200 milliseconds to keep it smooth)
Handler handler = new Handler();
Runnable incrementTask = new Runnable(){
#Override
public void run(){
lf++;
handler.postDelayed(incrementTask, 200); //Execute after 200 milliseconds
}
};
Then you implement onTouchListener and post this runnable when ACTION_DOWN is dispatched and cancel it when ACTION_UP is dispatched.
boolean buttonPressed = false;
pl.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN){
//This check is imporant since ACTION_DOWN might be called
// multiple times when finger is moving
if(!buttonPressed){
buttonPressed = true;
handler.post(incrementTask);
}
} else if(event.getAction() == MotionEvent.ACTION_UP){
if(buttonPressed)
{
buttonPressed = false;
handler.cancel(incrementTask);
}
}
return false;
}
});
Please note that this logic won't work well with your current click listener. For better user experience, I would recommend that you start this timer/runnable only when your button is long pressed. I had a similar situation in a project so I wrote a utility class to help me detect when a button is being held and released after a long click. Normal clicks work fine as well. You can find my ClickAndHoldManager class on Github.
To use it, you simply pass your view in the constructor and set a listener:
ClickAndHoldManager manager = new ClickAndHoldManager(myButton);
manager.setClickCallback(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Regular Click
}
});
manager.setHoldCallback(new ClickAndHoldManager.HoldListener() {
#Override
public void holdStarted() {
// do handler.post() here
}
#Override
public void holdEnded() {
//do handler.cancel() here
}
});
I have an ImageButton in my application.
<ImageButton
android:id="#+id/imageButton1"
android:layout_width="80dp"
android:layout_height="80dp"
android:clickable="true"
android:src="#drawable/button" />
I bind it to an onClickListener:
View.OnClickListener imgButtonHandler = new View.OnClickListener() {
public void onClick(View v) {
// Here I update the image source to a different image.
}
};
Now what happens is: when I click the imagebutton, the imagebutton changes to a
different image. But I want it to change back automatically after 0.5 sec (during the
same time the user should not be able to click anything). How do I
implement that? I tried to sleep in the onClick function in the listener, but it's
not working...
New edit:
The proposed answer will solve my problem if I only have one imagebutton. I tried it out
and both work like charm!
Actually it is not working as expected. During that 500ms, the user still could click!
It is not solving the problem...
Posting a delayed runnable might do the job.
public void onClick(View v) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// change the background of the image button
(ImageButton)v.setBackgroundResource(R.drawable.someimage);
}
}, 500);
}
EDIT:
In fact, I've ran the following code on an actual device with two ImageButton and it works fine.
BTW, if you want the buttons to be un-clickable during the 500ms, just set it as imgBtn1.setClickable(false); and set it back to be clickable in the runnable as imgBtn1.setClickable(true);
public class TestFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.test_layout, container, false);
final ImageButton imgBtn1 = (ImageButton) view.findViewById(R.id.test_img_btn1);
final ImageButton imgBtn2 = (ImageButton) view.findViewById(R.id.test_img_btn2);
imgBtn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
imgBtn1.setBackgroundResource(R.drawable.device_type_apple);
imgBtn1.setClickable(false);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// change the background of the image button
imgBtn1.setBackgroundResource(R.drawable.device_type_windows);
imgBtn1.setClickable(true);
}
}, 500);
}
});
imgBtn2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
imgBtn2.setBackgroundResource(R.drawable.device_type_apple);
imgBtn2.setClickable(false);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// change the background of the image button
imgBtn2.setBackgroundResource(R.drawable.device_type_android);
imgBtn2.setClickable(true);
}
}, 500);
}
});
return view;
}
}
You can use handle with runnable to auto update image
Handler mHandler = new Handler();
Runnable mUpdateTimer = new Runnable() {
#Override
public void run() {
// code update image here
// auto update after 0.5s
mHandler.postDelayed(mUpdateTimer, 500);
}
};
And when image button clicked:
View.OnClickListener imgButtonHandler = new View.OnClickListener() {
public void onClick(View v) {
mHandler.postDelayed(mUpdateTimer, 500);
}
};
Handler.postDelayed
this method is not good way ,see http://developer.android.com/reference/android/os/Handler.html#postDelayed(java.lang.Runnable,long)
it say
Returns true if the Runnable was successfully placed in to the message queue. Returns false on failure, usually because the looper processing the message queue is exiting. Note that a result of true does not mean the Runnable will be processed -- if the looper is quit before the delivery time of the message occurs then the message will be dropped.
so this methed may never invoke,it may be make you image button status never come back ,so you must be care the return value or use other widget ViewFliper,it can set animation when image switch and you can set delpoy .
My app opens the input method picker (the menu where you choose a keyboard) with InputMethodManager.showInputMethodPicker(). My app doesn't actually create the picker (it's created by InputMethodManager) but I know it's a ContextMenu and its id is R.id.switchInputMethod.
The picker is part of a multi-step wizard so I need to know when the picker closes so my app can proceed to the next step. Right now I'm checking in a background thread if the default keyboard changed, but that doesn't help if the user selects the same keyboard or presses back.
So I need a way to tell when the picker closes (or some other clever way to know when to proceed).
Thanks in advance...
Here is a small trick. Please do test it and let us know if it works.
All you have to do is make your activity extend this InputMethodActivity. When you need the user to pick input method, call pickInput(), and onInputMethodPicked() will be called when the user is done.
package mobi.sherif.inputchangecheck;
import android.os.Bundle;
import android.os.Handler;
import android.content.Context;
import android.support.v4.app.FragmentActivity;
import android.view.inputmethod.InputMethodManager;
public abstract class InputMethodActivity extends FragmentActivity {
protected abstract void onInputMethodPicked();
#Override
protected void onCreate(Bundle savedInstanceState) {
mState = NONE;
super.onCreate(savedInstanceState);
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if(mState == PICKING) {
mState = CHOSEN;
}
else if(mState == CHOSEN) {
onInputMethodPicked();
}
}
private static final int NONE = 0;
private static final int PICKING = 1;
private static final int CHOSEN = 2;
private int mState;
protected final void pickInput() {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showInputMethodPicker();
mState = PICKING;
}
}
There is no such mechanism for check InputMethodPicker is open or not.
But you can check it via another way like as using hasWindowFocus() method for check has focus of your root layout.
Below is sample code:
Main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainlayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello" />
<Button
android:id="#+id/btnPicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Picker" />
<Button
android:id="#+id/btnCheck"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Stop" />
</LinearLayout>
DemoappActivity.class
public class DemoappActivity extends Activity {
/** Called when the activity is first created. */
Button btn1 , btn2;
InputMethodManager imeManager;
LinearLayout mLayoutRoot;
TimerTask timertask;
Timer timer;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mLayoutRoot = (LinearLayout)findViewById(R.id.mainlayout);
imeManager = (InputMethodManager) getApplicationContext().getSystemService(INPUT_METHOD_SERVICE);
btn1 = (Button)findViewById(R.id.btnPicker);
btn1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
showInputMethodPicker();
}
});
btn2 = (Button)findViewById(R.id.btnCheck);
btn2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
timer.cancel();
}
});
checkMyWindowHasFocus();
}
#Override
protected void onDestroy() {
timer.cancel();
super.onDestroy();
}
public void checkMyWindowHasFocus()
{
timertask = new TimerTask() {
#Override
public void run() {
System.out.println("has window focus..."+mLayoutRoot.hasWindowFocus());
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "Has focus "+mLayoutRoot.hasWindowFocus(), Toast.LENGTH_SHORT).show();
}
});
}
};
timer = new Timer();
timer.schedule(timertask, 500, 5000);
}
private void showInputMethodPicker() {
if (imeManager != null) {
imeManager.showInputMethodPicker();
} else {
Toast.makeText(this, "Error",Toast.LENGTH_LONG).show();
}
}
}
Simple you can know by using buildin function:
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
isMyInputMethodEnabled();// write what ever you want to do after default keyboard selected
}
public void isMyInputMethodEnabled() {
String imId = Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
if (imId.contains(getPackageName())) {
startActivity(new Intent(this, Main_uk.class));
finish();
}
}
this is my first Question, i hope i do it right.
I need to change the color of some buttons in a specific interval.
I decided to do it with the Colorfilter, because the setBackground method makes the Button look ugly.
The Problem is the following:
If i set the ColorFilter within a Runnable, it is not working.
But:
Setting the ColorFilter in the onCreate or click method is working.
And:
Setting the BackgroundColor with setBackgroundColor within the Runnable is working.
I forgot to mention, that it is all working fine if i run it on an emulator with android 4.1 but not with 2.3.3.
Any ideas? Here is the code
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
int counter = 0;
Button b = null;
final Handler handler = new Handler();
final Runnable doit = new Runnable() {
public void run() {
if ( counter % 2 == 0) {
b = (Button) findViewById(R.id.button1);
b.setBackgroundColor(0xffff0000); // working
//b.getBackground().setColorFilter(0xFFD2691E, PorterDuff.Mode.MULTIPLY); // doesnt work
}
else {
//b.getBackground().clearColorFilter();
b.setBackgroundColor(0xff00ff00);
}
counter++;
}
};
public void click(View view) {
// configure timer 1
Timer timer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
handler.post(doit);
}
};
timer.schedule(task, 1111, 1111);
}
}
I had the same problem with imageviews.
I found a solution, you have to call the invalidate()-methode:
ImageView img =(ImageView) findViewById(R.id.myimageview);
img.getDrawable().clearColorFilter();
img.invalidate();
I'm a little new to Android, but pretty fluent in VB.net. I have two questions regarding Splash Screens:
I am trying to create a Splash Screen that launches on Application start. I can do it with Frame-Animations but would like to use the TransitionDrawable class because of the effect it has (fadeIn) that I would like to use. I used the same code for the Frame-Animation, after changing the definitions, but can't get it to work. What am I doing wrong?
This logo I am loading consists of 16 images. How can I use the TransitionDrawable class to go from logo1 to logo2 to logo3... to logo16? I tried using a loop and the array of "imageIds" to create my own Frame Animation, but can't it to work for the Transition. Help would be greatly appreciated.
Here is my code:
public class SplashScreenActivity extends Activity {
TransitionDrawable animation;
ImageView transImage;
Integer[] imageIds = { R.drawable.logo1, R.drawable.logo2,
R.drawable.logo3, R.drawable.logo4, R.drawable.logo5,
R.drawable.logo6, R.drawable.logo7, R.drawable.logo8,
R.drawable.logo9, R.drawable.logo10, R.drawable.logo11,
R.drawable.logo12, R.drawable.logo13, R.drawable.logo14,
R.drawable.logo15, R.drawable.logo16 };
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
transImage = (ImageView) findViewById(R.id.splashImageView);
animation = (TransitionDrawable) getResources().getDrawable(R.anim.transition_list);
transImage.setBackgroundDrawable(animation);
transImage.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
finish();
startActivity(new Intent("com.V1.V1LogoSplash.V1LogoMainActivity"));
}
return false;
}; // END ONTOUCH
}); // END ONLISTSENER
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
// TODO Auto-generated method stub
super.onWindowFocusChanged(hasFocus);
animation.startTransition(3000);
finish();
}
}
you try this type code
public class SplashActivity extends Activity {
Thread mSplashThread;
private int SPLASH_DISPLAY_LENGTH = 3800;
ImageView image;
AnimationDrawable frameAnimation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// this.requestWindowFeature(Window.FEATURE_NO_TITLE);
// this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
// WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.splashactivity);
image = (ImageView) findViewById(R.id.splashImg);
image.setBackgroundResource(R.drawable.splash_animation);
frameAnimation = (AnimationDrawable) image.getBackground();
Thread splashTread = new Thread() {
public void run() {
try {
sleep(SPLASH_DISPLAY_LENGTH);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
Intent intent;
intent = new Intent(SplashActivity.this,
ProductListActivity.class);
startActivity(intent);
finish();
}
}
};
splashTread.start();
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
frameAnimation.start();
}
}
and other one
drawable in xml (your img put in xml)
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true" >
<item
android:drawable="#drawable/survey11"
android:duration="500"/>
<item
android:drawable="#drawable/survey6"
android:duration="300"/>
<item
android:drawable="#drawable/survey5"
android:duration="300"/>
<item
android:drawable="#drawable/survey3"
android:duration="300"/>
<item
android:drawable="#drawable/survey2"
android:duration="300"/>
<item
android:drawable="#drawable/survey1"
android:duration="800"/>
</animation-list>