Animation not working correctly - java

When the phone is shaked it is supposed to display an animation. The animation works the first time but the next shake it wont do it. Everything else is working correctly because every time I shake it it display the new text each time. Its just the animation wont do it again after the first. I do have the animation set for oneshot but that shouldnt effect the animation from triggering again?
Here is the activity I'm working with this on. Followed by its xml layout.
public class Ask extends Activity{
private SensorManager mSensorManager;
private ShakeEventListener mSensorListener;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ask);
mSensorListener = new ShakeEventListener();
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensorManager.registerListener(mSensorListener,
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_UI);
final ImageView v = (ImageView)findViewById(R.id.talk);
mSensorListener.setOnShakeListener(new ShakeEventListener.OnShakeListener() {
public void onShake() {
v.setBackgroundResource(R.anim.budtalk);
AnimationDrawable talking = (AnimationDrawable)v.getBackground();
talking.start();
}
});
}
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/page1"
>
<ImageView android:background="#drawable/page2ani1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="#+id/talk"></ImageView>
</RelativeLayout>

Does this work?
final Animation ani = AnimationUtils.loadAnimation(this,R.anim.budtalk);
//later
v.startAnimation(ani);
This is how I have applied animations repeatedly to TextView elements.
Failing that, because you have changed the ImageView , perhaps you might need a v.postInvalidate() afterwards?

Related

How to animate view to slide down and push down everything below it?

So I have looked into how to animate fade and drop down/slide up animations of Views using this thread, however it didn't quite work as expected. To begin with, here is the code I use for the animating:
public void toggleAdvancedVisibility(View text) { //text is a clickable textview thats acts as a toggle
int dur = 1000;
final View advView = findViewById(R.id.enc_advanced);
if(advView.getVisibility() == View.GONE && animationDone) {
advView.setVisibility(View.VISIBLE);
advView.setAlpha(0.0f);
//animate fade + drop down
advView.animate()
.setDuration(dur)
.translationY(advView.getHeight())
.alpha(1.0f)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
animationDone = true;
}
});
animationDone=false;
}
else if(advView.getVisibility() == View.VISIBLE && animationDone) {
//animate fade + slide up
advView.animate()
.setDuration(dur)
.translationY(0)
.alpha(0.0f)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
advView.setVisibility(View.GONE);
animationDone = true;
}
});
animationDone = false;
}
}
As I said, while there was animation, it didn't act anywhere near as expected.
Problem #1
The view is almost pushed out of visibility. I believe that this is due to the line .translationY(advView.getHeight()) as if I set the location of the view before the animation to advView.setTranslationY(-advView.getHeight()) and then animate .translationY(0) it goes to where it is supposed to.
The obvious problem with this is that while the view is animating, the view "collides" with the view above it before it is done. So how do I properly get this to slide down/up without running into the view above it?
Problem #2
The animation doesn't exactly "push" the view down, which is what I expected. What I mean by this is that the view being animated also has a view below it. I expected the view below it to be pushed down with the animated view. While I haven't tried it yet, I assume this can be simulated by setting the same animation to the view below it, but is there another way of doing it?
I am very new to this animation stuff and manipulating Views like this so any help is appreciated.
I made you a short example and I see it pushes down the rest of the view.
xml:
<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"
tools:context="com.example.teststuff.MainActivity"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/b1"
android:text="show"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tv1"
android:text="Hello World!"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!!!!"/>
and here is the .java:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv1 = (TextView) findViewById(R.id.tv1);
tv2 = (TextView) findViewById(R.id.tv2);
b1 = (Button) findViewById(R.id.b1);
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (tv1.isShown()){
tv1.startAnimation(slideInAnimation(view));
tv1.setVisibility(View.GONE);
}
else {
tv1.startAnimation(slideOutAnimation(view));
tv1.setVisibility(View.VISIBLE);
}
}
});
}
private TranslateAnimation slideOutAnimation(View view){
TranslateAnimation animate = new TranslateAnimation(0,0,-view.getHeight(),0);
animate.setDuration(500);
animate.setFillAfter(false);
return animate;
}
private TranslateAnimation slideInAnimation(View view){
TranslateAnimation animate = new TranslateAnimation(0,0,0,-view.getHeight());
animate.setDuration(500);
animate.setFillAfter(true);
return animate;
}
It works fine for me.

Trying to set OnTouchListener to multiple ImageViews using ArrayLists

I'm trying for quite a long time to set OnTouchListener to multiple ImageViews using ArrayLists but my Application keeps on crushing down. This is my code:
MainActivity:
public class MainActivity extends AppCompatActivity {
private DragAndDrop dragAndDrop;
private InstantiateImages instantiateImages;
private ArrayList<ImageView> faces = new ArrayList<ImageView>();
private int i;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dragAndDrop = new DragAndDrop();
InstantiateImages instantiateImages = new InstantiateImages(this);
//Add elements to ArrayLists:
instantiateImages.Add();
//Get elements into ArrayLists:
faces = instantiateImages.getFaces();
for (i = 0; i< faces.size(); i++) {
faces.get(i).setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
//Follow the touch on the ImageView and move the
//ImageView accordingly:
dragAndDrop.action(v, event, faces.get(i));
return true;
}
});
}
}
}
InstantiateImages Class:
public class InstantiateImages {
this.activity = activity;
private ArrayList<ImageView> faces = new ArrayList<ImageView>();
//Faces declarations:
private ImageView FacesNoFace;
InstantiateEmojis() {
//Faces instantiations:
FacesNoFace = (ImageView)this.activity.findViewById(R.id.faces_no_face);
}
public void Add() {
//Add faces to ArrayList faces:
faces.add(FacesNoFace);
}
//Getters:
//Get Faces:
public ArrayList<ImageView> getFaces() {
return faces;
}
}
XML of layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="myproject.myproject.MainActivity"
tools:layout_editor_absoluteY="81dp"
tools:layout_editor_absoluteX="0dp"
tools:background="#ffffff">
<ImageView
android:id="#+id/faces_no_face"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:contentDescription=""
app:srcCompat="#drawable/faces_no_face"
tools:ignore="ContentDescription"
tools:layout_editor_absoluteX="16dp"
tools:layout_editor_absoluteY="16dp" />
</android.support.constraint.ConstraintLayout>
The DragAndDrop Class is a class that only has a method which follows the ImageView drag and drop (the inside/heart of the OnTouchListener) and before I tried to put the ImageView inside of the ArrayList "faces" which I created in the "InstantiateImages" Class I instentiate the OnTouchListener only on one ImageView (the one I added to the ArrayList now) and it worked totaly fine (I could drag and drop the ImageView arround the app screen). Now the Application is crushing after I Run it and it says: "MyProject keep stopping close app" or "MyProject Has stoped reopen app".
Any Help would be appreciated!!
I think you are overcomplicating parts of this. I think this will do what you're trying to do.
public class MainActivity extends AppCompatActivity {
private DragAndDrop dragAndDrop;
private final ArrayList<ImageView> faces = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dragAndDrop = new DragAndDrop();
faces.add((ImageView) findViewById(R.id.faces_no_face));
for (ImageView face : faces) {
face.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
//Follow the touch on the ImageView and move the
//ImageView accordingly:
dragAndDrop.action(v, event, (ImageView) v);
return false;
}
});
}
}
}
If you are planning on having a variable number of ImageViews that you want to listen to clicks on, you might want to look into RecyclerView and Lists.

Using onClickListener to show clicked image in larger size in another layout or activity?

I'm supporting an android 2.2+ app. I'm using the code image.setOnClickListener(new View.On Click Listener()
and a dialog to show a larger image in another layout.
Current project has an error. When I debug the project, I see a NullPointerException on image.setOnClickListener(new View.OnClickListener() saying the image is null.
Main Activity
#SuppressLint("ClickableViewAccessibility")
public class MainActivity extends ListActivity {
Context c;
Intent intent;
ImageView image, image1;
#SuppressLint("SdCardPath")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
image = (ImageView) image.findViewById(R.id.image_my);
// *** mean here
image_my.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TO DO Auto-generated method stub
show(v);
}
});
}
public void show(View v) {
final Dialog dialog = new Dialog(MainActivity.this);
dialog.setContentView(R.layout.show);
image1 = (ImageView) image1.findViewById(R.id.image_my1);
dialog.show();
}
}
Layout 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:orientation="vertical">
<ImageView
android:id="#+id/image_my1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="left|center_vertical"
android:src="#drawable/image_def" />
</LinearLayout>
I'm not sure where you got this code from, but you are repeatedly using variables before you have assigned them:
image = (ImageView) image.findViewById(R.id.image_my);
Here you are calling findViewById on your image instance, but image will be null here. You probably want:
image = (ImageView) this.findViewById(R.id.image_my);
Similarly, in your show() method:
image1 = (ImageView) image1.findViewById(R.id.image_my1);
should be
image1 = (ImageView) this.findViewById(R.id.image_my1);
You might want to try using more descriptive names for your variables too - it makes it a bit easier to spot problems like this.

How to transfer data between Views in a Layout

I haven't beeen able to find the answer to the following question:
How do I get data from View A to View B, with View A and View B in the same LinearLayout? Is this even possible? Do I need to start working with threads?
I haven't been able to get the correct search phrase I guess, I'm probably not the first person that wants to do this, but I can't find it :(
Below is what I use now to create the views. In the TargetTrainer (which extends View) I'm letting the user give some input, and I'd like to be able to give feedback to the user in the TextView. How would I for instance show the coordinates of the onTouchEvent of TargetTrainer in the TextView?
Below is a clipped/simplified version of my program.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
LinearLayout linear;
linear = new LinearLayout(this);
linear.setOrientation(LinearLayout.VERTICAL);
TextView text = new TextView(this);
text.setText("Test");
linear.addView(text);
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
TargetTrainer t = new TargetTrainer(this, width, height);
linear.addView(t);
setContentView(linear);
}
As I can see from the snippet, you already pass Context in the constructor new TargetTrainer(this, width, height). Assuming that the code you provided is from activity called BaseActivity create reference to BaseActivity in the TargetTrainer constructor and call the update method from TargetTrainer.
public TargetTrainer extends View {
....
BaseActivity mBaseActivity = null;
public MyView(Context context, int width, int height) {
....
mBaseActivity = (BaseACtivity)context;
....
}
....
private void update(String text)
{
mBaseActivity.updateTextView(text);
}
}
In BaseActivity create updateTextView:
public void updateTextView(String updateText){
text.setText(updateText);
}
You should set the id of that TextView, listen to the touch events in your TargetTrainer, and when one occures, you use
final TextView tv = (TextView)TargetTrainer.this.findViewById(R.id.myTextView);
tv.setText(touchEvent.toString());
That's it.
Update
It would be much cleaner, if you'd build your main layout from an xml source.
You need to create a new layout xml inside the /res/layout that looks like the one you're creating inside your onCreate method:
res/layout/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/myTextView" android:text="Test"
android:layout_width="fill_parent" android:layout_height="wrap_content" />
<!-- change the your.package part to match the package declaration
of your TargetTrainer class -->
<your.package.TargetTrainer android:id="#+id/myTargetTrainer"
android:layout_width="fill_parent" android:layout_height="fill_parent" />
</LinearLayout>
This way a new entry will be placed inside your R class' static layout class with the name main.
You can reference it by R.layout.main.
Note, that in this xml you have id attributes defined for both
your TextView: myTextView, and
your TargetTrainer:
'myTargetTrainer'.
The #+id inside the xml tag means that you are creating a new id with the name after the '/' sign.
This also will create new members inside your R class' static id class with the names you've provided: myTextView and myTargetTrainer that are accessible from now on from anywhere in your code.
If you've built this xml, your onCreate method will look like this:
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// attach the OnTouchListener to your TargetTrainer view:
(TargetTrainer)findViewById(R.id.myTargetTrainer).setOnTouchListener(this);
}
You also have to extend your main activity class to implement the View.OnTouchListener interface, and add the necessary method at the end of your class:
#Override
public boolean onTouch(View view, MotionEvent event)
{
//note, that here the view parameter is the view the touch event has been dispatched to
final TextView tv = (TextView)findViewById(R.id.myTextView);
tv.setText(event.toString());
return true; //or false, if you are dealing further with this event in parent classes
}

SwitchDisplayable a la Android

i'm still porting a J2ME app to Android and now my problem is with the GUI.
For what i've seen, Android's Activities are great, but my J2ME is filled with the classic:
public void switchDisplayable(Alert alert, Displayable nextDisplayable) {
Display display = getDisplay();
if (alert == null)
display.setCurrent(nextDisplayable);
else
display.setCurrent(alert, nextDisplayable);
}
I just can't make every Displayable to an Activity, so i thought about replacing them with View. I tried that but it just doesn't works, the app doesn't changes the screen.
Update:
Thanks for answering, but placed al vews inside FrameLayout and still nothing. This is the core of my test code, so you can check it out:
public class TestActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView t = (TextView)findViewById(R.id.text); // Shows "Hi"
showDialog(); // it just shows a dialog asking if the user wants to change screen
}
showDialog() {
// in OnClick()... i do the following, and here is where it fails, i tried so far:
TestView testv= new MarcoLoco(MFActivity.this);
setContentView(testv);
testv.invalidate();
testv.requestFocus();
testv.showMeSomething();
}
public class TestView extends View{
private Context context;
TextView tv;
public TestView(Context context) {
super(context);
this.context=context;
}
public void showMeSomething() {
tv = (TextView)findViewById(R.id.tessto); // it should show "Bye"
}
}
After the OnClick the "Hi" dissapears from the screen but nothing appears, no "Bye".
Why, oh, why!?
I don't have any expirience with Java ME, but this might help you
Put your Views inside a FrameLayout, then you can use
mViewA.setVisibility(View.VISIBLE);
mViewB.setVisibility(View.GONE);
mViewA.requestFocus();
to switch between diffrent views
EDIT:
Here is a short example program that toggles between 2 textviews:
public class test extends Activity {
boolean showTV1 = true;
OnClickListener ocl = new OnClickListener() {
#Override
public void onClick(View v) {
showTV1= !showTV1;
if (showTV1){
tv1.setVisibility(View.VISIBLE);
tv2.setVisibility(View.GONE);
tv1.requestFocus();
} else {
tv2.setVisibility(View.VISIBLE);
tv1.setVisibility(View.GONE);
tv2.requestFocus();
}
}
};
private TextView tv1, tv2;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv1 = (TextView) findViewById(R.id.TextView01);
tv2 = (TextView) findViewById(R.id.TextView02);
tv1.setOnClickListener(ocl);
tv2.setOnClickListener(ocl);
}
}
and main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/frameLayout01" android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView android:id="#+id/TextView01" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:background="#0f0"
android:text="Hi" />
<TextView android:id="#+id/TextView02" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:background="#f00"
android:text="Bye" android:visibility="gone"/>
</FrameLayout>
I am not sure I fully understand your questions, but try looking at ViewAnimator and ViewFlipper - perhaps these can help
PS. just out of curiosity... have you tried any of automatic converters?
Why are you porting from J2ME to Android on your own, instead of using a conversion tool ?
Quicker, no need to learn and excel with Android, no need to debug and maintain 2 code bases... Give it a try at www.UpOnTek.com. Thanks.

Categories