I have an activity and an extended View class,that both use the same xml layout. In the extended view I do some drawings on screen with touch, and want to pass the coordinate x of the touch to the Activity, whenever the user taps the screen.
So far I have used a getter method and call it from inside the activity but it ,only, passes the initializing value of X of the constructor and not the actual X coordinate the user has touched.
I am pretty sure I am missing something. Can you give me some directions?
EDIT : As suggested, instead of the getter practice, I tried using a public interface, still with X not changing. Here is my code:
My custom class:
public class ImageView1 extends View {
Context context;
ArrayList<ViewWasTouchedListener> listeners = new
ArrayList<ViewWasTouchedListener>();
ImageView1 img = (ImageView1) findViewById (R.id.imageView1);
public float x=0;
public float y=0;
public ImageView1(Context context) {
super(context);
this.context=context;
setFocusable(true);
}
public ImageView1(Context context, AttributeSet attrs) {
super(context, attrs);
this.context=context;
setFocusable(true);
}
@Override
public boolean onTouchEvent(MotionEvent event){
switch (event.getAction()){
case (MotionEvent.ACTION_DOWN): {
x = event.getX();
y = event.getY();
for (ViewWasTouchedListener listener:listeners){
Log.d("Touchpoint", String.valueOf(x) +"," + String.valueOf(y));
listener.onViewTouched(x);
}
}
return true;
}
@Override
public void onDraw(Canvas canvas){
super.onDraw(canvas);
....
}
public void setWasTouchedListener(ViewWasTouchedListener listener){
listeners.add(listener);
}
}
My Main Activity:
public class TargetPractise extends Activity implements ViewWasTouchedListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.target_form);
ImageView1 value = new ImageView1(TargetPractise.this);
value.setWasTouchedListener(TargetPractise.this);
}
public void onViewTouched(float x){
Log.d("x",String.valueOf(x));
}
}
My interface:
public interface ViewWasTouchedListener {
void onViewTouched(float x);
}
My xml layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<android.archer.test.ImageView1
android:id="@+id/imageView1"
android:layout_width="300dip"
android:layout_height="300dip"
android:layout_gravity="center_horizontal"
android:background="@drawable/target" >
</android.archer.test.ImageView1>
Define an interface and use a callback to let the activity know that x has changed. I like this approach because it works for any class interested in knowing when x has changed, not just your activity. Imagine you add a new type of view class but it also needs to know when your custom view has been touched (I do this with a graph and horizontal and vertical scales which can be dragged – the scales tell anyone who’s interested that they have changed).
In your custom view
In your touch event
In your Activity:
All from memory so please excuse typos and you should improve the view class by adding removeViewWasTouchedListener and checking that you do not add the same listener twice in setViewWasTouchedListener.
You probably want y as well so just add it to the Interface definition.