Thursday, September 4, 2014

Implement callback function by implementing interface for custom view

Last post "Custom View, detect touch to toggle color" and also "warning: custom view overrides onTouchEvent but not performClick and #onTouchEvent should call #performClick when a click is detected", we have a self-running custom view to detect user touch and toggle color. But the MainActivity don't know what happen on it. To make MainActivity informed when color toggled, we can implement interface for our custom view.


MyView.java
package com.example.androidtouchview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class MyView extends View {
 
 public interface OnToggledListener {
  void OnToggled(MyView v, boolean touchOn);
 }

 boolean touchOn;
 boolean mDownTouch = false;
 private OnToggledListener toggledListener;

 public MyView(Context context) {
  super(context);
  init();
 }

 public MyView(Context context, AttributeSet attrs) {
  super(context, attrs);
  init();
 }

 public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  init();
 }

 private void init() {
  touchOn = false;
 }

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
    MeasureSpec.getSize(heightMeasureSpec));
 }

 @Override
 protected void onDraw(Canvas canvas) {
  if (touchOn) {
   canvas.drawColor(Color.RED);
  } else {
   canvas.drawColor(Color.GRAY);
  }
 }

 @Override
 public boolean onTouchEvent(MotionEvent event) {
  super.onTouchEvent(event);

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
             
             touchOn = !touchOn;
       invalidate();
       
       if(toggledListener != null){
        toggledListener.OnToggled(this, touchOn);
       }
             
                mDownTouch = true;
                return true;

            case MotionEvent.ACTION_UP:
                if (mDownTouch) {
                    mDownTouch = false;
                    performClick();
                    return true;
                }
        }
        return false;
 }

 @Override
 public boolean performClick() {
        super.performClick();
        return true;
 }
 
 public void setOnToggledListener(OnToggledListener listener){
  toggledListener = listener;
 }

}

MainActivity.java
package com.example.androidtouchview;

import com.example.androidtouchview.MyView.OnToggledListener;

import android.support.v7.app.ActionBarActivity;
import android.widget.Toast;
import android.os.Bundle;

public class MainActivity extends ActionBarActivity 
 implements OnToggledListener{
 
 MyView myView00, myView01;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  myView00 = (MyView)findViewById(R.id.myview00);
  myView01 = (MyView)findViewById(R.id.myview01);

  myView00.setOnToggledListener(this);
  myView01.setOnToggledListener(this);
 }

 @Override
 public void OnToggled(MyView v, boolean touchOn) {

  //get the id string
  String idString = getResources().getResourceName(v.getId());

  Toast.makeText(MainActivity.this, 
   "Toogled:\n" +
   idString + "\n" +
   touchOn, 
   Toast.LENGTH_SHORT).show();
 }

}

activity_main.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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context="com.example.androidtouchview.MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">
        
        <com.example.androidtouchview.MyView 
            android:id="@+id/myview00"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:layout_margin="10dp"/>
        <com.example.androidtouchview.MyView 
            android:id="@+id/myview01"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="2"
            android:layout_margin="10dp"/>
        
    </LinearLayout>
    
</LinearLayout>


No comments: