Imagine a number 10, then after user clicks a button it changes to 100. But how to make an efficient transition
10 -> 100,
that will display values like
12, 15, 18, ..., 97, 100 over 1 second.
I've seen something like that in "Cookie clicker" but couldn't find anything about that kind of transition in the source code.
I had an idea of a loop (for number1 < number2, do number1++), it will work fine for small numbers, but if 10 changes to 1 billion, then the loop will probably freeze the whole app.
Second idea is to get added value (100-10=90) and divide by 30 or 60 frames, and add this value with each frame. But what will happen if frame is dropped? - Probably value will not be added. What if user makes double click or the system adds values automatically?
Hope it gives an idea of what kind of number transition I need.
Maybe I overlooked and there is a simple approach? Any help is appreciated.
Hope this little demo using a ValueAnimator will inspire you to find an appropriate solution.
You can specify the duration of the animation (see code) and even adjust the frame-rate by saying mAnimator.setFrameDelay(frameDelay);.
By using animator.isRunning() or animator.isStarted() you can prevent double-click malfunction or other unwanted behaviour while the current animation is runnning.
The Main Activity:
/** ValueAnimator demo */
public class MainActivity extends Activity {
ValueAnimator mAnimator;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView tv = (TextView) findViewById(R.id.textview);
mAnimator = ValueAnimator.ofInt(1, 100).setDuration(1000);
mAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
mAnimator.addUpdateListener(new AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(final ValueAnimator animator) {
final Integer value = (Integer) animator.getAnimatedValue();
tv.setText(String.format("%04d", value));
}
});
mAnimator.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animator) {
super.onAnimationEnd(animator);
final int endValue = Integer.parseInt((String) tv.getText());
mAnimator.setIntValues(endValue, endValue + 100);
}
});
}
/** Button callback */
public void onClick(final View view) {
if (!mAnimator.isStarted() && !mAnimator.isRunning()) {
mAnimator.start();
}
}
}
Simple demo 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:orientation="vertical" >
<TextView
android:id="#+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25sp"
android:typeface="monospace"
android:text="0001" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Gimme +100"
android:onClick="onClick">
</Button>
Here's another demo (hope this answers your 2. question), which implements different behaviour dependent on single click or double-click on the button. Just experiment with it, you now have the basic building blocks to construct own behavour ...
/** ValueAnimator demo */
public class MainActivity extends Activity {
ValueAnimator mAnimator;
TextView mTv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTv = (TextView) findViewById(R.id.textview);
mAnimator = ValueAnimator.ofInt(1, 100).setDuration(1000);
mAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
mAnimator.addUpdateListener(new AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(final ValueAnimator animator) {
final Integer value = (Integer) animator.getAnimatedValue();
mTv.setText(String.format("%04d", value));
}
});
final Button button = (Button) findViewById(R.id.button);
final GestureDetector gestureDetector = new GestureDetector(this,
new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onDoubleTap(MotionEvent e) {
performAnimation(100);
return true;
}
#Override
public boolean onSingleTapConfirmed(MotionEvent e) {
performAnimation(0);
return true;
}
});
button.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
});
}
/** starts animation */
private void performAnimation(final int offset) {
if (!mAnimator.isStarted() && !mAnimator.isRunning()) {
final int endValue = Integer.parseInt((String) mTv.getText());
mAnimator.setIntValues(endValue + offset, endValue + 100 + offset);
mAnimator.start();
}
}
}
Don't forget to replace your layout file, since the click-attribute of the button has been removed:
<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:orientation="vertical" >
<TextView
android:id="#+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25sp"
android:typeface="monospace"
android:text="0001" />
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Gimme +100" >
</Button>
</LinearLayout>
I guess you can do it by using different threads. Only main thread works with UI so you can divide the interval into small intervals and make a transitions in different threads.After send them to main thread and print. Hope it will help.
Related
In my app, I have a button to show a drop-down menu, inside of that menu we have some options, one of this is "flip A coin",
the purpose of this option is to flip a coin easy animation, that animation appears inside a textView, and show a head-side or a tail-side of a coin instead of the text in the textView.
I have two problems:
The animation doesn't work how I want, it should appear in 1 second a coin instead of the text inside the textView, it stays there and after 2 seconds he disappears, but after the disappearance, the coin image come back inside the textView, it shouldn't reappear.
This is not a real question for a problem but more an optional question like "you know how to do that?". I 'don't know how to create a flip animation with a coin multiple rotations.
XML drop down menu:
<item
android:id="#+id/flipacoin"
android:title="#string/flipACoin" />
<item
android:id="#+id/rolladice"
android:title="#string/rollADice" />
<item
android:id="#+id/imagebackground"
android:title="#string/changeImage" />
JAVA code that calls the animation function:
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()){
case R.id.flipacoin:
flipACoin();
return true;
case R.id.rolladice:
Toast.makeText(this,"TODO roll a dice",Toast.LENGTH_SHORT).show();
return true;
case R.id.imagebackground:
Toast.makeText(this,"TODO image background",Toast.LENGTH_SHORT).show();
return true;
default:
return false;
}
}
JAVA animation function:
public void flipACoin(){
coin.setText(null); //this is for remove the text inside the textView
coin.setBackground(RANDOM.nextFloat() > 0.5f ? getResources().getDrawable(R.drawable.tails) : getResources().getDrawable(R.drawable.heads));
Animation fadeIn = new AlphaAnimation(0, 1);
fadeIn.setInterpolator(new DecelerateInterpolator());
fadeIn.setDuration(1000);
Animation fadeOut = new AlphaAnimation(1, 0);
fadeOut.setInterpolator(new AccelerateInterpolator());
fadeOut.setStartOffset(2000);
fadeOut.setDuration(1000);
AnimationSet animation = new AnimationSet(false);
animation.addAnimation(fadeIn);
animation.addAnimation(fadeOut);
coin.setAnimation(animation);
}
When You set background at the beginning it just stays after animation. To set back text and background to null You can add Animation listener. Below is sample application which does it:
public class MainActivity extends AppCompatActivity
{
TextView coin;
Random RANDOM;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RANDOM = new Random();
coin = findViewById(R.id.coin);
(findViewById(R.id.click)).setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
flipACoin();
}
});
}
public void flipACoin()
{
coin.setText(null);
coin.setBackground(ResourcesCompat.getDrawable(getResources(),
RANDOM.nextFloat() > 0.5f ? R.drawable.ic_launcher_background : R.drawable.ic_launcher_foreground,
null
));
Animation fadeIn = new AlphaAnimation(0, 1);
fadeIn.setInterpolator(new DecelerateInterpolator());
fadeIn.setDuration(1000);
Animation fadeOut = new AlphaAnimation(1, 0);
fadeOut.setInterpolator(new AccelerateInterpolator());
fadeOut.setStartOffset(2000);
fadeOut.setDuration(1000);
AnimationSet animation = new AnimationSet(false);
animation.addAnimation(fadeIn);
animation.addAnimation(fadeOut);
// listener, it will execute function when animation starts/ends/repeats
animation.setAnimationListener(new Animation.AnimationListener()
{
#Override
public void onAnimationStart(Animation animation)
{
Log.d("MyTag", "onAnimationStart:");
}
#Override
public void onAnimationEnd(Animation animation) // when animation ends, set text and background to null
{
Log.d("MyTag", "onAnimationEnd:");
coin.setBackground(null);
coin.setText("Default");
}
#Override
public void onAnimationRepeat(Animation animation)
{
Log.d("MyTag", "onAnimationRepeat:");
}
});
coin.setAnimation(animation);
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<Button
android:id="#+id/click"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="click"
/>
<TextView
android:id="#+id/coin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Default"
/>
</androidx.appcompat.widget.LinearLayoutCompat>
friends. I started to learn Android app developinng with Android Studio and Java. Now i am trying to make one progressbar. When app is started we have two EditText fields where first is 100 by default(how will be the max value for progressbar ) and one EditText field for increment by(this is step) for progressbar. When we click Start it must show up via dialog.
I write the code, there is no more errors, but app is closing when i hit the Start Button. The progressbar is not working
This is the code:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:id="#+id/txt_max"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Max Value" />
<EditText
android:id="#+id/maximum"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="100.0" />
<TextView
android:id="#+id/txt_increment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Increment by"/>
<EditText
android:id="#+id/increment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="5.0" />
<Button
android:id="#+id/butt_Start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start" />
</LinearLayout>
This is the MainActivity.java:
public class MainActivity extends AppCompatActivity {
int increment;
ProgressDialog dialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button startButton = (Button) findViewById(R.id.butt_Start);
startButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
EditText et = (EditText) findViewById(increment);
increment = Integer.parseInt(et.getText().toString());
dialog = new ProgressDialog(MainActivity.this);
dialog.setCancelable(true);
dialog.setMessage("Loading...");
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setProgress(0);
EditText max = (EditText) findViewById(R.id.maximum);
int maximum = Integer.parseInt(max.getText().toString());
dialog.setMax(maximum);
dialog.show();
Thread background = new Thread(new Runnable()
{
public void run()
{
try
{
while (dialog.getProgress() <= dialog.getMax())
{
Thread.sleep(500);
progressHandler.sendMessage(progressHandler.obtainMessage());
}
} catch (java.lang.InterruptedException e)
{
}
}
});
background.start();
}
Handler progressHandler = new Handler() {
public void handleMessage(Message msg) {
dialog.incrementProgressBy(increment);
}
};
});
}
}
There are some error with that code.. I will comment each by reporting your snippet:
public class MainActivity extends AppCompatActivity {
int increment;
ProgressDialog dialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button startButton = (Button) findViewById(R.id.butt_Start);
startButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
EditText et = (EditText) findViewById(increment);
Here is the first error: not really a wrong thing, but it's better to istantiate the EditText in your onCreate (outside the onClick), because this way you will re-create the EditText every time you click the button.
The error is double: you are using findViewById(increment) where, in your code, increment is an int variable whose value is actually 0. You have to use (as you did for the button)
findViewById(R.id.increment);
Going on:
increment = Integer.parseInt(et.getText().toString());
dialog = new ProgressDialog(MainActivity.this);
dialog.setCancelable(true);
dialog.setMessage("Loading...");
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setProgress(0);
EditText max = (EditText) findViewById(R.id.maximum);
int maximum = Integer.parseInt(max.getText().toString());
Here the error is xml side: since you are assuming that max.getText().toString() is an Integer, add inputType to your xml with number value.
dialog.setMax(maximum);
dialog.show();
Thread background = new Thread(new Runnable()
{
public void run()
{
try
{
while (dialog.getProgress() <= dialog.getMax())
{
Thread.sleep(500);
progressHandler.sendMessage(progressHandler.obtainMessage());
}
} catch (java.lang.InterruptedException e)
{
}
}
});
background.start();
}
Handler progressHandler = new Handler() {
public void handleMessage(Message msg) {
dialog.incrementProgressBy(increment);
}
};
});
}
}
Another thing is that is better to avoid naming a variable with same name of your id, expecially because id should be representative of the control you are pointing at (for example call it "EditTextMaxValueMainActivity", this is a limit example but it is representative).
If I can suggest you, TheNewBoston channel/site is the best for tutorials, it has a couple of playlist with android basics to advanced and it is simple and really explicative. Good luck!
for other errors, we will need the logtrace
The Answer for me is here:
This line:
EditText et = (EditText) findViewById(increment);
Must be changed to:
EditText et = (EditText) findViewById**(R.id.increment)**;
And i go to design view of activity_main.xml and changed the inputType of increment EditText and maximum EditText to number.
And removed the decimal format from the numbers.
<EditText
android:id="#+id/increment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="5" />
And here i had number with decimal, now i removed them.
<EditText
android:id="#+id/maximum"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="100" />
I need to create Collapse / Expand forms in Android. I am thinking about using either RelativeLayout or TableLayout for this purpose. But, what XML element make these forms expand and hide in android?
If you are not sure what I am not talking about, take an application like Sales Force for an example. There you have these expandable menus in all the forms. How can I do this?
Following is an example (taken from Sales Force)
When you expand these, it looks like below
You could do the following. create a layout that has the following:
1. A Heading or a textview with the label contacts
2. Below it a layout that has forms related to it
3. Add another textview below #2 and name it address
4. Add a lyout below #3 .
The layout 2 and 4 will have visibility gone in the first case
When the user taps on layout 1, or the first textview, make layout 2 visible and vice versa. Do the same with the second textview.
Hope that helps.!
I have had a similar problem, i want parts of my form to be hidden in sektions and created a class for this issue.
public class section extends LinearLayout{
public LinearLayout container;
public Button toggler;
public section(Context context, String section_name, String section_state) {
super(context);
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.flxsection, this);
container = (LinearLayout) this.findViewById(R.id.container);
container.setVisibility(section_state.equals("0") ? View.GONE:View.VISIBLE);
toggler = ((Button)this.findViewById(R.id.section_toggle));
toggler.setTag(section_state);
toggler.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
String tag = (String) v.getTag();
v.setTag(tag.equals("0") ? "1":"0");
if(tag.equals("0")){expand(container,false);}else{collapse(container,false);}
setImage(tag.equals("0"));
}
});
toggler.setText(" " + section_name);
setImage(section_state.equals("1"));
setTextSize();
}
public void setTextSize(){
toggler.setTextSize(GV.Style.TextSize);
}
public void setImage(boolean open){
int a = open ? R.drawable.minus_48_white: R.drawable.plus_48_white;
Drawable img = main.res.getDrawable(a);
final float scale = main.res.getDisplayMetrics().density;
int size = (int) (12 * scale + 0.5f);
img.setBounds(0,0,size,size);
toggler.setCompoundDrawables(img,null,null,null);
}
}
the 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="wrap_content"
android:background="#android:color/transparent"
android:focusable="false"
android:layout_marginLeft="4dip"
android:layout_marginRight="4dip"
android:orientation="vertical" >
<Button
android:id="#+id/section_toggle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dip"
android:layout_marginTop="4dip"
android:background="#drawable/section"
android:drawableLeft="#drawable/plus_48"
android:focusable="false"
android:gravity="left|center_vertical"
android:padding="6dip"
android:textAppearance="?android:attr/textAppearanceLargeInverse"
android:textSize="22dip" />
<LinearLayout
android:id="#+id/container"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:focusable="false"
android:background="#android:color/transparent"
android:orientation="vertical" >
</LinearLayout>
Expand and collapse:
public static void expand(final View v,boolean quick) {
v.requestLayout();
v.measure(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
final int targtetHeight = v.getMeasuredHeight();
v.getLayoutParams().height = 0;
v.getLayoutParams().width = LayoutParams.FILL_PARENT;
v.setVisibility(View.VISIBLE);
if(quick){
v.getLayoutParams().height = LayoutParams.WRAP_CONTENT;
v.requestLayout();
}else{
android.view.animation.Animation a = new android.view.animation.Animation()
{
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
v.getLayoutParams().height = interpolatedTime == 1
? LayoutParams.WRAP_CONTENT
: (int)(targtetHeight * interpolatedTime);
v.requestLayout();
}
#Override
public boolean willChangeBounds() {
return true;
}
};
// 1dp/ms
int duration = (int)(targtetHeight / v.getContext().getResources().getDisplayMetrics().density);
if(duration> 500)duration=500;
a.setDuration(duration);
//(int)(targtetHeight / v.getContext().getResources().getDisplayMetrics().density)
v.startAnimation(a);
}
}
public static void collapse(final View v,boolean quick) {
v.requestLayout();
final int initialHeight = v.getMeasuredHeight();
if(quick){
v.setVisibility(View.GONE);
v.requestLayout();
}else{
android.view.animation.Animation a = new android.view.animation.Animation()
{
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
if(interpolatedTime == 1){
v.setVisibility(View.GONE);
}else{
v.getLayoutParams().height = initialHeight - (int)(initialHeight * interpolatedTime);
v.requestLayout();
}
}
#Override
public boolean willChangeBounds() {
return true;
}
};
// 1dp/ms
int duration = (int)( initialHeight/ v.getContext().getResources().getDisplayMetrics().density);
if(duration> 500)duration=500;
a.setDuration(duration);
v.startAnimation(a);
}
}
If if create a form and need a section, i create a instance of this class and add the controls.
You might need to turn the hardware acceleration on in order to get the best performance
edit:
Usage is like:
section s = new section(context, section_name, section_state);
s.container.addView([your view 1]);
s.container.addView([your view 2]);
s.container.addView([your view 3]);
//...
form.addView(s);
I create simple Android app (https://www.linux.com/learn/docs/683628-android-programming-for-beginners-part-1) with latest Android Studio. Code:
public class test_act extends Activity {
private static final int MILLIS_PER_SECOND = 1000;
private static final int SECONDS_TO_COUNTDOWN = 30;
private android.widget.TextView countdownDisplay;
private android.os.CountDownTimer timer;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.full_act);
countdownDisplay = (android.widget.TextView) findViewById(R.id.time_display_box);
android.widget.Button startButton = (android.widget.Button) findViewById(R.id.startbutton);
startButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
try {
showTimer(SECONDS_TO_COUNTDOWN * MILLIS_PER_SECOND);
} catch (NumberFormatException e) {
// method ignores invalid (non-integer) input and waits
// for something it can use
}
}
});
}
private void showTimer(int countdownMillis) {
if(timer != null) { timer.cancel(); }
timer = new android.os.CountDownTimer(countdownMillis, MILLIS_PER_SECOND) {
#Override
public void onTick(long millisUntilFinished) {
countdownDisplay.setText("counting down: " +
millisUntilFinished / MILLIS_PER_SECOND);
}
#Override
public void onFinish() {
countdownDisplay.setText("KABOOM!");
}
}.start();
}
}
My 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" >
<TextView
android:id="#+id/time_display_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="60dp"
android:text="#string/_00_30"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<Button
android:id="#+id/startbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/time_display_box"
android:layout_centerHorizontal="true"
android:layout_marginTop="41dp"
android:text="#string/start" />
</RelativeLayout>
In emulator it's good working. But on my Galaxy S2 with CyanogenMod10.1(Android 4.2.2) app wrong updating TextView. Screenshot:
How I can resolve this problem?
upd: after screen rotate TextView is updating once.
You might want to try invalidating your layout every time it is updated. I am guessing with how often the text is being updated the phone is not having enough time to redraw the layout. This would also explain why it works when you rotate your phone, because then the layout is forced to update.
countdownDisplay.invalidate();
Let me know if that does not work.
It commonly happens when you put UI updates inside try blocks, try to avoid it or wrap with runOnUiThread.
EDIT:
Another reason - you update it to fast - you code does 1000 updates per second i dont think it can handle it.
I'm making an app that just displays a clock, but I want is so that everytime a user touches the screen it changes the color of the text (from a list of preselected colors in a colors.xml file) but I haven't got a clue where to start. Can someone point me in the right direction?
Here's the main activity:
public class MainActivity extends Activity {
private static final Random RANDOM = new Random();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_main);
Handler handler = new RandomMoveHandler((TextView) findViewById(R.id.digitalClock1));
handler.sendEmptyMessage(0);
}
// Make the handler subclass static because of this: http://stackoverflow.com/a/11408340/111777
private static class RandomMoveHandler extends Handler {
private final WeakReference<TextView> textViewWeakReference;
private RandomMoveHandler(TextView textView) {
this.textViewWeakReference = new WeakReference<TextView>(textView);
}
#Override
public void handleMessage(Message msg) {
TextView textView = textViewWeakReference.get();
if (textView == null) {
Log.i(TAG, "WeakReference is gone so giving up.");
return;
}
int x = RANDOM.nextInt(350 - 100);
int y = RANDOM.nextInt(800 - 100);
Log.i(TAG, String.format("Moving text view to (%d, %d)", x, y));
textView.setX(x);
textView.setY(y);
//change the text position here
this.sendEmptyMessageDelayed(0, 30000);
}
}
private static final String TAG = MainActivity.class.getSimpleName();
}
and here's the layout xml:
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context=".MainActivity"
android:background="#color/black" >
<DigitalClock
android:id="#+id/digitalClock1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="DigitalClock"
android:textColor="#color/ics_blue"
android:textSize="28sp" />
I haven't making deal with DigitalClock but I think, at first, you should reference DigitalClock variable, not TextView. And second, to intercept touch event you need to override onTouckEvent method of your activity, it will callback everytime user touches the screen.
You should follow these steps
Use a TimerTask to.continusly show the time
Implement a touchlistener on that clock view
like this
view.setOnTouchListener
Make an array Colors like this
int[] colr={Color.BLACK,Color.BLUE};
and use random index in your touch event andset it as your color of the view