Android回调

回调就是A和B有合作关系,A的某一个环节需要B自己告诉A要怎么做,这就是回调,回调一定有接口。

只要写过自定义控件的,就一定写回调。这个是自然的,本文的意义是为了简单描述对回调的一个理解。

其实做回调很好,比如我们做了一个自定义的进度条,按钮,或者开关等等,我们都需要做回调接口,有什么好处呢?可以让使用我们控件的人自己去选择一些事情,而不是我们写接口的吧东西给写死了,我们可以提供一些方法,让别人自己选择颜色,大小,数值等等。

例子

我们假设做了一个自定义的开关按键,然后按下之后就可以改变一下另外一个控件的文字。(只为演示,不做开关,免得代码偏长)

点击之后调用者要执行一些逻辑,至于具体执行什么逻辑,一点都不关我们事,这是使用我们控件的人自己想干嘛就去干吗。


一个简单自定义控件

/**
 * 一个自定义开关按钮(假设),附带set点击的接口
 * 第一步,定义接口,接口里面有个 设置点击的监听
 * 第二步,在当前类中定义一个接口的变量,以便接受其他类实现接口后传过来的接口
 * 第三步,当当前类中写一个 public的设置接口的方法,参数是我们写的接口
 * 第四步,在我们的需要的地方执行其他类要求我们做的事情
 */
public class DiyToggle extends View {

    private Bitmap mBackground;

    // 第二步,在当前类中定义一个接口的变量,以便接受其他类实现接口后传过来的接口
    private OnToggleClickListener onToggleClickListener;

    public DiyToggle(Context context) {
        super(context);
    }

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

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


    public void setBackground(int resId) {
        mBackground = BitmapFactory.decodeResource(getResources(), resId);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int measuredWidth = mBackground.getWidth();
        int measuredHeight = mBackground.getHeight();
        setMeasuredDimension(measuredWidth, measuredHeight);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        // 画背景
        if (mBackground != null) {
            canvas.drawBitmap(mBackground, 0, 0, null);
        }

    }

    // 第三步,当当前类中写一个 public的设置接口的方法,参数是我们写的接口
    // 这样其他类一旦调用了setToggleClickListener,就必须实现我们写的接口
    public void setToggleClickListener(OnToggleClickListener onToggleClickListener){
        if(onToggleClickListener != null){
            this.onToggleClickListener = onToggleClickListener;
        }
    }


    // 第一步,定义接口,接口里面有个 设置点击的监听
    interface OnToggleClickListener{
        void onDoClick();
    }


    // 第四步,在我们的需要的地方执行其他类要求我们做的事情
    // 这里我们复写了系统自带的onTouchEvent的up方法,也就是当点击后松开手指时执行
    // 我们在松开手指后,就调用我们自己接口的  onDoClick方法,具体做什么,我们不知道,也不用知道
    // 其他人说,我们做就好。
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        if(action==MotionEvent.ACTION_UP){
            onToggleClickListener.onDoClick();
        }
        return true;
    }
}

布局文件

<?xml version="1.0" encoding="utf-8"?>
<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"

    tools:context="com.amqr.callbackdemo.MainActivity">

    <com.amqr.callbackdemo.DiyToggle
        android:id="@+id/mTog"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >
        </com.amqr.callbackdemo.DiyToggle>

    <TextView
        android:id="@+id/mTvCenter"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello"
        android:textSize="30dp"
        android:layout_centerInParent="true"
        />

</RelativeLayout>

MainActivity

public class MainActivity extends Activity {

    private DiyToggle mTog;
    private TextView mTvCenter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTog = (DiyToggle) findViewById(R.id.mTog);
        mTvCenter = (TextView) findViewById(R.id.mTvCenter);

        mTog.setBackground(R.mipmap.tog);

        // 调用了DiyToggle的 setToggleClickListener 方法,就得实现 接口
        mTog.setToggleClickListener(new DiyToggle.OnToggleClickListener() {
            @Override
            public void onDoClick() {
                Log.d("Tog","...=================");
                mTvCenter.setText("世界");
            }
        });
    }
}

猜你喜欢

转载自blog.csdn.net/grandgrandpa/article/details/82759661
今日推荐