介面回撥基礎理解
我們知道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個誇張了一點,但是基本的設計模式,我們還是要遵循的,所以介面回撥的好處,大家體會到了嗎?