I would like to create a loop somewhere in my Android code that changes the color of a drawable rectangle between two colors continuously at some rate. I would like to start and stop its blinking using two buttons. I have done a lot of research, but just can't seem to figure out how to do it. I am new to android and do not have experience with run() methods. But I am guessing I have to make some kind of rectangle class with a run() method that will animate it into changing colors.
I am also fairly new to android, but I will give it a shot.
Since you say you want it to blink, you should be able to switch the actual image between, lets say, blue and red, with a simple 'for' loop. When the button is pressed, you could change the status of a boolean from false to true. Then, when the 'for' statement is not true anymore, it jumps to the next set of code, which stops it. Here is what I would do.
Your XML for the two buttons:
<Button
android:id="#+id/start"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Start"
android:Clickable="true"
android:onClick="start"
/>
<Button
android:id="#+id/stop" <!-- Gives the button an ID to use in java code -->
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Stop" <!-- sets the text on the button -->
android:Clickable="true" <!-- makes the button clickable -->
android:onClick="stop" <!-- The method it calls when it is clicked, removes the necessity of an OnClickListener -->
/>
Now, you would have 2 ImageViews: blue_rectangle and red_rectangle, both in the same place in the layout. Here is the XML for the two ImageViews
<ImageView
android:id="#+id/blue_rectangle"
android:layout_width="100dp"
android:layout_height="75dp"
android:layout_marginLeft="50dp"
android:layout_marginTop="5dp"
android:src="#drawable/blue_rectangle" />
<ImageView
android:id="#+id/red_rectangle"
android:layout_width="100dp"
android:layout_height="75dp"
android:layout_marginLeft="50dp"
android:layout_marginTop="5dp"
android:src="#drawable/red_rectangle" />
This next part is the tricky part.
Here is the Java.
package your.package.name.thingy.here;
//everything it tells you to import goes here
public class BlinkingActivity extends Activity{
ImageView blueRectangle;
ImageView redRectangle;
Button start;
Button stop;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.yourLayout);
blueRectangle = (ImageView) findViewById(R.id.blue_rectangle);
redRectangle = (ImageView) findViewById(R.id.red_rectangle);
start = (Button) findViewById(R.id.start);
stop = (Button) findViewById(R.id.stop);
Boolean isBlinking = new Boolean(false);
blinkRectangle(whateverVariableThisNeeds);
}
public static void blinkRectangle(View view){
blueRectangle.setVisibility(View.INVISIBLE);
redRectangle.setVisibility(View.INVISIBLE);
for(initialization; isBlinking; update){
blueRectangle.setVisibility(View.VISIBLE);
blueRectangle.postDelayed(new Runnable() {
#Override
public void run() {
blueRectangle.setVisibility(View.INVISIBLE);
}
}, 2000); //the 2000 is the number of milliseconds for how long blue is visible
redRectangle.setVisibility(View.VISIBLE);
redRectangle.postDelayed(new Runnable() {
#Override
public void run(){
redRectangle.setVisibility(View.INVISIBLE);
}
}, 2000);
blueRectangle.setVisibility(View.VISIBLE); //This prevents a bug where if the user hits the stop button at just the right time, both rectangles will be invisible.
}
public static void start(View view){ //no need to call this anywhere, the XML onClick does it for you
isBlinking = true; //I think this is how you set a boolean, if not, correct me.
}
public static void stop(View view){//same here
isBlinking = false; //again, correct me if I'm wrong.
}
}
Here is what the code basically does.
It has a boolean which is defaulted to false. While it is false, the rectangle does not blink. While it is true, the for statement in blinkRectangle() runs. That for loop makes the blue on visible, waits 2 seconds, makes it invisible, makes the red one visible, waits two seconds, and repeats. The start() and stop() methods switch the boolean to true and false, respectively. I think this type of for loop re-checks the boolean when it gets back to the top. I have never worked with it before. That's what I could gather from the website I looked at.
Well, I think that about does it. If you don't understand what any of the code does, or it doesn't work, or I have the question wrong, or I am just downright wrong, or ANYTHING, just comment on this answer. I hope this works!
Good Luck!
P.S. Here are the websites I used for reference
http://www.tutorialspoint.com/java/java_loop_control.htm
http://www.java-examples.com/java-boolean-example
Wow...I just realized this question is 2 years old. Still, I hope this helps you!
Related
I want to turn off touches on the screen just for 1 or 2 seconds and then turn on. How to do this with a background service as an infinite loop? For instance, if you touch once you cannot touch again in 2 seconds in anywhere on the screen and then keep doing same thing for every touches (not include back, menu or home buttons).
Note: I am using Service for background progress.
You might could do it this way. Disable all views (you can iterate over all children of your root layout) and enable them after two seconds.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final RelativeLayout root = (RelativeLayout) findViewById(R.id.activity_main);
final Button btnDisable = (Button) findViewById(R.id.btnDisable);
final Handler handler = new Handler();
btnDisable.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
root.setEnabled(false);
btnDisable.setEnabled(false);
handler.postDelayed(new Runnable() {
#Override
public void run() {
//enable your views after 2 seconds
root.setEnabled(true);
btnDisable.setEnabled(true);
}
}, 2000);
}
});
}
Here is the xml inside of a RelativeLayout with the id activity_main
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<Button
android:text="disable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/btnDisable"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
if you want to disable touch only in your app consider bounding service and communicate with your Activity and override MotionEvent related methods, e.g.
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
// your code goes here if needed
return true; //disabled touching in whole activity
}
if you want to disable touching in whole system then this is obvoiusly impossible, because is highly unsecure for user...
In my activity is a TextView with the content "Ecl pse", where the "i" is missing. After I click on a button I want the letter "i" to appear in the right Position. But the "i" should be so animated, that it firstly appears a little bit bigger and then gets smaller until it is as big as the the other letters after I clicked on the button. But momentarily with my code the whole word "Ecl pse" is influenced by the ValueAnimation. It's not only that the "i" is bigger and gets smaller after I clicked on the button, but also the position of the whole word "Ecl pse" changes: "Ecl pse" goes down and then comes back in the origin position. How can i fix that? Again, I want only the letter "i" to appear a little bit bigger and then getting smaller until it is as big as the other letters of the word "Ecl pse" after I clicked on the button...
XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/tvhallo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="87dp"
android:text="Ecl pse"
android:textSize="70sp" />
<Button
android:id="#+id/BtnKlick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="Klick" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/tvhallo"
android:layout_alignBottom="#+id/tvhallo"
android:layout_alignLeft="#+id/BtnKlick"
android:layout_toLeftOf="#+id/BtnKlick"
android:text="i"
android:textSize="70sp" />
</RelativeLayout>
CODE:
public Button btn;
public TextView tw;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.pagetwo);
btn = (Button) findViewById(R.id.BtnKlick);
tw = (TextView) findViewById(R.id.tvhallo);
btn.setOnClickListener(this);}
#SuppressLint("NewApi")
public void onClick(View v) {
// TODO Auto-generated method stub
ValueAnimator animator = new ValueAnimator();
animator.setDuration(2000);
animator.setObjectValues("Ecl pse", "Eclipse");
animator.setEvaluator(new TypeEvaluator<CharSequence>()
{
#Override
public CharSequence evaluate(float fraction, CharSequence startValue, CharSequence endValue)
{
float relativeSize = 4 - 3 * fraction;
Spannable span = new SpannableString("Eclipse");
span.setSpan(new RelativeSizeSpan(relativeSize), 3, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return span;
}
});
animator.addUpdateListener(new AnimatorUpdateListener()
{
#Override
public void onAnimationUpdate(ValueAnimator animation)
{
tw.setText((CharSequence)animation.getAnimatedValue());
}
});
animator.start();}}
I really doubt a TextView is the right instrument for what you're trying to achieve. It is both overkill and inadequate for the job. It can display all matters of text with various formatting and is for a good reason described as "a complete text editor". It's main purpose is to provide a way to display text, and possibly quite a lot of it (that part was the overkill). Inserting and (potentially) scaling the 'i' will cause the rest of the letters to move, as that is what the class is for. It's intended to layout text, not layout it statically in a way that causes changes to the content to move as little as possible (this is the inadequate part)
But what you actually want is not to display text, but an animation. I would recommend you create the text you want in any imaging program with various states: one without the 'i', a few with it too large and scaling down, and a final image with the correct proportions. Now use these images do display the animation triggered by pressing the button. I believe the correct class for this task would be AnimationDrawable, though I haven't used it myself. There are certainly numerous ways on how to get the exact behavior you want, but I hope this'll get you started!
I am using ViewFlipper to flip two images. one image is a small heart and another is a big heart and they are flipping continuously so that it looks like heart is throbbing.
everything works well except one thing
when the Activity containing ViewFlipper is on the front and the ViewFlipper is flipping once i called the startFlippling , and after a while if my device's light gets dim and then turned off and if i press the home/power button immediately the ViewFlipper stops flipping. in this case no onResume or onPause gets called.
moreover when the device's light gets turned off and after a while if i press power button and entered my password to unlock the screen , then the ViewFlipper is working fine.
here is my layout code , i have set the autoStart to false because based on some event
i am calling startFlipping of ViewFlipper
<ViewFlipper
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autoStart="false"
android:flipInterval="700"
android:id="#+id/heartThrob"
android:layout_centerHorizontal="true"
android:layout_centerInParent="true"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/small"
android:id="#+id/heartOne"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/big"
android:id="#+id/heartTwo"
/>
</ViewFlipper>
Rite now i have set the ViewFlipper property android:keepScreenOn to true so that the screen remain ON , but i am still waiting for some better answer
I had the same issue if I use viewFlipper's startFlipping with setFlipInterval methods. So I've solved this by using a handler to animate viewFlipper.
By the way, this problem occurs on Galaxy Nexus 4.0.1 but not on Galaxy Nexus 4.2.2.
I hope this part of my code helps you.
private Handler handler = new Handler();
private Runnable autoSwipeRunnable = new Runnable() {
#Override
public void run() {
moveLeft();
}
};
private void moveLeft() {
if (mViewFlipper != null && mViewFlipper.getChildCount() > 1) {
mViewFlipper.setInAnimation(animLeftIn);
mViewFlipper.setOutAnimation(animLeftOut);
mViewFlipper.showNext();
startAutoCycle();
}
}
private void startAutoCycle() {
if (mViewFlipper.getChildCount() > 1) {
if (autoCycleInterval <= 0) {
autoCycleInterval = 5000;
}
handler.removeCallbacks(autoSwipeRunnable);
handler.postDelayed(autoSwipeRunnable, autoCycleInterval);
}
}
This question has been asked several times, but everyone gives the reason for why this occurs (i.e. calculation occurs before the layout is laid). But I need the solution for this. I tried getBottom();, getTop();, getLocationOnScreen(int[] location);. But all returns the value Zero (0). I even tried giving these in onStart();, to give time for layout to be laid, but no luck.
Here is my code:
TextView tv;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv = (TextView) findViewById(R.id.textView1);
Log.d("getBottom :", Integer.toString(tv.getBottom()));
Log.d("gettop :", Integer.toString(tv.getTop()));
int[] location = new int[2];
tv.getLocationOnScreen(location);
Log.d("getlocationonscreen values :", Integer.toString(location[0])+" "+Integer.toString(location[1]));
}
#Override
protected void onStart() {
Log.d("getBottom in onStart :", Integer.toString(tv.getBottom()));
Log.d("gettop in onStart :", Integer.toString(tv.getTop()));
int[] location = new int[2];
tv.getLocationOnScreen(location);
Log.d("getlocationonscreen in onStart :", Integer.toString(location[0])+" "+Integer.toString(location[1]));
super.onStart();
}
Layout XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="156dp"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
Again, I apologize for repeating the question. Thanks in advance.
You put the 'measuring' in the onWindowFocusChanged()-method.
As the documentation states:
This is the best indicator of whether this activity is visible to the user.
You could also put it in the onResume() which is the last step before the application is completely on screen and active, however:
Keep in mind that onResume is not the best indicator that your activity is visible to the user; a system window such as the keyguard may be in front. Use onWindowFocusChanged(boolean) to know for certain that your activity is visible to the user (for example, to resume a game).
If the window/view has not yet been displayed there is no guarantee that it has its measurements, thus the previous method would be better.
Cant figure this out (am a noob) but I have a default activity that starts with just one image button, clicking that image button opens the second activity that contains a bunch of image buttons but only one has an onclick, this is the exact code:
<ImageButton android:src="#drawable/level1"
android:layout_width="wrap_content" android:id="#+id/imageButton1"
android:layout_height="wrap_content"
android:onClick="button_clicked1">
</ImageButton>
in the java file this is my code:
public void button_clicked1(View v) {
//text1.setText("clicked");
//ib2.setImageResource(R.drawable.level5);
}
The screwy part, if that above function is empty nothing happens but no matter what I put in the above function... for example even a simple settext like the above commented one, and it force closes on me :((
the full java file if you are interested: http://pastebin.com/W4sJUKXH
and the manifest file (as the problem might be there, like I said, am a noobie) http://pastebin.com/yEuG1su7
** Where i think the error is:
In the manifest file I only have declared the second activity, nothing else...
Set id for the ImageViews, this is how you handle many Buttons with one method
public void button_clicked1(View v) {
switch(v.getId())
{
case R.id.myfirstimage:
//do something
break;
case R.id.mysecondimage:
// do something
break;
// add more cases
default:
// do something if none of the cases is your image view or do nothing
}
}
Set setContentView( ) before you do anything with the UI components. (Thats why you get some Exception)
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.start_levels_screen);
text1 = (TextView) findViewById(R.id.textView1);
ib2 = (ImageButton) findViewById(R.id.imageButton2);
}