1. 程式人生 > >介面回撥基礎理解

介面回撥基礎理解

介面回撥聽起來好像很厲害的樣子,但其實只要能夠搞清楚程式碼的執行過程,多看幾遍,並且認真思考,再加上勤奮的練習,熟練掌握簡單的介面回撥並不是難題,接下來,我會用一個簡單的例子,來帶大家一起分析程式碼的執行過程,以及這樣寫的好處,以及這樣寫的思路。

我們知道recyclerView是沒有自帶點選事件的,所以這裡我們就拿給recyclerView新增點選事件為例。

ok 我們做好了一個簡單的recycerView,但是此時點選他的條目是無效的,接下來我們為他新增自己定義的條目點選事件。

在介面卡中加入:

 //自定義公開介面,定義抽象方法
    public interface onItemClickListener{
        void onItemClick(int position,View itemView);
    }
    //建立介面型別變數(接受傳值並設定事件)
    private onItemClickListener mOnItemClickListener;
    //暴露設定介面的方法
    public void setOnItemClickListener(onItemClickListener mOnItemClickListener){
        this.mOnItemClickListener = mOnItemClickListener;
    }

在介面卡的onBindViewHolder方法中開始監聽事件:
 @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
        final MyViewHolder viewHolder = (MyViewHolder) holder;
        viewHolder.textView.setText(datas.get(position));
        if (position % 2 == 0){
            viewHolder.textView.setTextColor(Color.BLUE);
        }else {
            viewHolder.textView.setTextColor(Color.RED);
        }
        if (mOnItemClickListener != null){
            viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    int pos = holder.getLayoutPosition();
                    mOnItemClickListener.onItemClick(pos,holder.itemView);
                }
            });
        }
    }

最後一步就是在MainActivity中,實現onItemClickListener介面,設定監聽,並實現抽象方法:
public class MainActivity extends AppCompatActivity implements MyAdapter.onItemClickListener
adapter.setOnItemClickListener(this);


  @Override
    public void onItemClick(int position, View itemView) {
        Toast.makeText(MainActivity.this, "條目位置 :" + ( position + 1 ), Toast.LENGTH_SHORT).show();
    }

OK,點選事件新增成功


很簡單,很快,但是這個自己新增的點選事件,其中程式碼的執行過程大家清楚麼?

按照程式碼的執行順序,我們新增的程式碼第一句執行的就是:

adapter.setOnItemClickListener(this);
這是呼叫了介面卡設定監聽的方法,this代表當前類,我們這裡指的就是MainActivity,而這個方法定義的引數要求是一個我們自己定義的介面,所以我們要通過
MainActivity去實現OnItemClickListener介面,那麼此時我們的MainActivity就也可以稱作是OnItemClickListener型別。
將MainActivity傳入後,就是將我們傳入的值賦值給了自己定義的介面型別變數
//暴露設定介面的方法
    public void setOnItemClickListener(onItemClickListener mOnItemClickListener){
        this.mOnItemClickListener = mOnItemClickListener;
    }
然後我們再來看一看這個自己定義的變數去做了什麼:
if (mOnItemClickListener != null){
            viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    int pos = holder.getLayoutPosition();
                    mOnItemClickListener.onItemClick(pos,holder.itemView);
                }
            });
        }

這是新增在onBindViewHolder中的,在呼叫了setOnItemClickListener方法後,mOnItemClickListener就不為空,然後當viewholder的條目點選之後,我們的mOnItemClickListener就呼叫了自己的onItemClick方法。

開始思考:我們這裡的mOnItemClickListener不為空,那麼他的值是哪裡來的呢?是誰呢? 沒有錯,就是我們的MainActivity,那麼這裡呼叫了onItemClick方法,實際上呼叫的就是MainActivity中實現的抽象方法onItemClick

 @Override
    public void onItemClick(int position, View itemView) {
        Toast.makeText(MainActivity.this, "條目位置 :" + ( position + 1 ), Toast.LENGTH_SHORT).show();
    }

至此,我們得以解惑,只要在MainActivity中,實現一個介面,就實現了RecyclerView的點選事件,也瞭解了這個程式碼的執行過程,不過有人可能會疑惑,點選事件我直接寫在介面卡中不好嗎,這樣MainActivity中的程式碼不是會更少,更簡潔嗎?


好,根據質疑,我將程式碼做了如上修改,確實,點選事件依然好用,但是介面回撥就沒有作用嗎?那還要他幹嘛。好了,我要提出需求了。

如果我們的需求是點選了一條目之後,修改MainActivity中一個控制元件(例如Button)的背景顏色,想一想,此時怎麼操作?

可能還真有頭鐵的愣頭青會說:可以在MainActivity中通過介面卡的構造方法,把控制元件(例如Button)物件傳到Adapter裡面,很好,很有思想。但是我這裡首先不說你違背了通俗的程式設計習慣(我沒怎麼見過把一個控制元件物件傳來傳去的),如果我要有100個控制元件要改變呢?

顯然 100個誇張了一點,但是基本的設計模式,我們還是要遵循的,所以介面回撥的好處,大家體會到了嗎?