Java 接口回调机制

前言

以前一直不明白什么是接口回调,随着在项目中大量使用这种机制,开始有点明白了到底是怎么一回事了,接下来写的仅是本人的一点见解,有什么问题直接提出即可,相互学习

举例

接口回调我感觉最经典也是平时我们在项目中常使用的按钮点击事件

mButton.setOnClickListener(this);

@Override
public void onClick(View v) {
    Toast.makeText(MainActivity.this,"OnClick",Toast.LENGTH_SHORT).show();
    }

下面就看看Android中是怎么实现的?
首先找到OnClickListenner这个接口,里面提供了一个onclick()回调方法

/** 
 * Interface definition for a callback to be invoked when a view is clicked. 
 */  
public interface OnClickListener {  
    /** 
     * Called when a view has been clicked. 
     * 
     * @param v The view that was clicked. 
     */  
    void onClick(View v);  
}  

接着看下setOnClickListenner()这个方法

public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource {  
    /** 
     * Listener used to dispatch click events. 
     * This field should be made private, so it is hidden from the SDK. 
     * {@hide} 
     */  
    protected OnClickListener mOnClickListener;  

    /** 
     * setOnClickListener()的参数是OnClickListener接口
     * Register a callback to be invoked when this view is clicked. If this view is not 
     * clickable, it becomes clickable. 
     * 
     * @param l The callback that will run 
     * 
     * @see #setClickable(boolean) 
     */  

    public void setOnClickListener(OnClickListener l) {  
        if (!isClickable()) {  
            setClickable(true);  
        }  
        mOnClickListener = l;  
    }  


    /** 
     * Call this view's OnClickListener, if it is defined. 
     * 
     * @return True there was an assigned OnClickListener that was called, false 
     *         otherwise is returned. 
     */  
    public boolean performClick() {  
        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);  

        if (mOnClickListener != null) {  
            playSoundEffect(SoundEffectConstants.CLICK);  

            //调用借口中的onClick方法 
            mOnClickListener.onClick(this);  
            return true;  
        }  

        return false;  
    }  
}  

具体应该是这样的:

MainActivity中的mButton调用了View类中的setOnClickListener()这个方法,之后View中的mOnClickListener调用onClick这个方法,这个时A中的方法,所以onClick就是个回调方法(不知道这么理解对不对)
相当于:A调用了B的方法,B开始执行,B执行完了,再调用A的方法

实际小例子

Java 接口回调机制_第1张图片

首先是MainActivity布局

"1.0" encoding="utf-8"?>
"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.hfs.android_27_03_listview_checkbox_focusable.MainActivity">

    "@+id/ll"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        

然后是MainActivity代码:


import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;


import java.util.ArrayList
import java.util.List;
import java.util.Map;

//CheckInterface是定义的接口
public class MainActivity extends AppCompatActivity implements CheckInterface{

    private ListView lv;
    private List list;
    private MyBaseAdapter adapter;

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

        initView();
    }

    private void initView() {
        lv = (ListView) findViewById(R.id.lv);

        list = getLoadData();

        adapter = new MyBaseAdapter(list);
        lv.setAdapter(adapter);

        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView parent, View view, int position, long id) {
                list.get(position).setStatus(!list.get(position).isStatus());
                Toast.makeText(MainActivity.this,list.get(position).getName(), Toast.LENGTH_LONG).show();
                adapter.notifyDataSetChanged();
            }

        });

        //这个是Adapter的方法,相当于setOnClickListenr()方法
        adapter.setOnCheckInterface(this);

    }

    private List getLoadData() {
        List list = new ArrayList<>();

        for (int i = 0; i < 10; i++) {
            MapBean mapBean = new MapBean("username" + i, false);
            list.add(mapBean);
        }
        return list;
    }

    public void btnClick(View view) {
        switch (view.getId()) {
            case R.id.btn_cancel:
                for (int i = 0; i < list.size(); i++) {
                    list.get(i).setStatus(false);
                }
                adapter.notifyDataSetChanged();
                break;
            case R.id.btn_selectall:
                for (int i = 0; i < list.size(); i++) {
                    list.get(i).setStatus(true);
                }
                adapter.notifyDataSetChanged();
                break;
            case R.id.btn_reverse:
                for (int i = 0; i < list.size(); i++) {
                    list.get(i).setStatus(!list.get(i).isStatus());
                }
                adapter.notifyDataSetChanged();
                break;
            case R.id.btn_delete:
                List templist = new ArrayList();
                for (int i = 0; i < list.size(); i++) {
                    if (list.get(i).isStatus()) {
                        templist.add(list.get(i));
                    }
                }
                list.removeAll(templist);
                adapter.notifyDataSetChanged();

                break;

        }
    }




/**
`*回调方法
`*/
    @Override
    public void onSelectClick(int position, boolean isCheck) {
        list.get(position).setStatus(isCheck);
        adapter.notifyDataSetChanged();
    }
}

adapter代码



import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;

import java.util.List;

/**
 * Created by HFS on 2016/4/15.
 */
public class MyBaseAdapter extends BaseAdapter {
    List list;

    private CheckInterface mCheckInterface;

    //对外提供的方法
    public void setOnCheckInterface(CheckInterface mCaiGouInterface) {
        this.mCheckInterface = mCaiGouInterface;
    }

    public MyBaseAdapter(List list) {
        this.list = list;
    }

    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;
        if (convertView == null) {
            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, null);
            viewHolder = new ViewHolder();
            viewHolder.item_tv = (TextView) convertView.findViewById(R.id.item_tv);
            viewHolder.item_cb = (CheckBox) convertView.findViewById(R.id.item_cb);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        final MapBean bean = list.get(position);

        viewHolder.item_tv.setText(bean.getName());
        viewHolder.item_cb.setChecked(bean.isStatus());

        viewHolder.item_cb.setTag(position);
        //对复选框做监听
        viewHolder.item_cb.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int position = (int) v.getTag();
                CheckBox checkOrderGoods = (CheckBox) v;
                boolean isChecked = checkOrderGoods.isChecked();
                        //调用回调方法
                mCheckInterface.onSelectClick(position, isChecked);
            }
        });


        return convertView;
    }

    class ViewHolder {
        TextView item_tv;
        CheckBox item_cb;
    }

```//自己定义的接口
    public interface CheckInterface {
        //定义的回调方法
        void onSelectClick(int position, boolean isCheck);

    }

}





"se-preview-section-delimiter">

JavaBean代码:
“`


JavaBean代码:
```java

/**
 * Created by HFS on 2016/4/15.
 */
public class MapBean {
    private String name;
    private boolean status;

    public MapBean(String name, boolean status) {
        this.name = name;
        this.status = status;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isStatus() {
        return status;
    }

    public void setStatus(boolean status) {
        this.status = status;
    }
}

好了,这只是一个简单的例子,多用用就会用了,多看看按钮那个点击事件就能明白接口回调到底是怎么回事了

你可能感兴趣的:(Java基础内容)