1. 程式人生 > >初學者使用介面回撥傳值

初學者使用介面回撥傳值

   對於剛接觸介面的我來講,真的是好難的一個東西啊,感覺不斷在追著資料跑,照著例子敲 有時還不知道敲的是什麼,上網上找部落格看 有個例子是打電話,那個讓我大概瞭解了介面,但是對於怎麼寫一個介面傳值仍一頭霧水.不過什麼東西敲多了就大概瞭解了. 

   我們用介面來傳值的一個很典型的例子就是RecyclerView的點選事件.所以我們來分析一下點選事件的書寫順序: 

    首先我們需要建立一個介面,如同建立一個類一樣,不過把class換為interface 介面名字其實可以隨便取(剛開始學時候以為名字改了不能用呢)  不過最好可以看出為RecyClerView的介面, 在接口裡寫一個沒有方法體的方法,類似這個 ,我希望傳的是點選的位置,也可以傳遞其他引數

public interface OnRecItemClickListener {
    public void onRecclick(int position);}

  建立完介面我們需要找到你想在什麼介面或什麼情況下觸發這個介面,比如這個RecyclerView 我希望在它的行佈局被點選時候觸發,那麼我需要找在哪裡有它的行佈局,是RecyclerView的介面卡在onBindViewHolder中我們看到他在對行佈局的檢視進行操作,那麼我們就在這裡觸發介面

  既然知道在那個介面有著介面的觸發條件,首先我們需要在這個介面建立一個介面物件

private OnRecyclerItemClick onRecyclerItemClick
;
 這個介面物件需要一個賦值方法,不然會空指標(在介面卡中用這個方法,假如在Fragment中想向Activity傳值需要Activity implement介面 在Fragment中用onAttach賦給介面物件值   如下  [只有依附在該activity上的fragment可以向activity傳值,若是兩者沒有關係,不要使用介面回撥 ])
public void setOnRecyclerItemClick(OnRecyclerItemClick onRecyclerItemClick) {
    this.onRecyclerItemClick = onRecyclerItemClick;
}
@Override
public void onAttach(Context context) {
    super.onAttach(context);
    this.context=context;
operateDatabase= (OperateDatabase) context;
}
在我們有了一個不為空的介面物件後,我們需要在行佈局被點選的事件中(系統的)來觸發我們自己寫的  如下 ,在onBindViewHolder 中
holder1.itemView.setOnClickListener(new View.OnClickListener() {
    @Override
public void onClick(View view) {
        onRecyclerItemClick.onItemClick(position);
}
});

如上,在holder中或的行佈局檢視itemview ,在itemView點選時 觸發行佈局點選並且傳值,不過這時候我們還沒有能接收物件的

不過接下來就很簡單了,我們只需要像使用其它介面時使用就行,不過因為是在adapter中觸發此事件,我們需要用adapter.setOnReclerItemClick(this),而不是像listview的點選是listview.setOnitemClickListener  這是我們就可以操作了,我們操作的就是傳過來的position.其他介面回撥的使用方法是一樣的

我們只需要找到我們想傳什麼,從什麼介面傳,傳到那個介面,以及在什麼情況下傳  介面回撥使用就不難.

  就比如我們在MainActivity的ViewPager中的Fragment向MainActivity傳值 (也不一定是傳值,有時我們在fragment做了某些操作,然後希望Activity做一些操作,我們也是用介面)

比如說我在fragment中有對資料庫進行操作的按鈕,但是操作過程我們希望在MainActivity中進行,首先我們的介面(與之前的類似):

public interface OperateDatabase {

    void insert();
    void deltete();
    void query();
    void update();
}

      資料庫的四種操作,在Fragment中我們還是先定義介面物件

private OperateDatabase operateDatabase;
     然後我們初始化它,程式碼如下(context是Activity,因為Activity  implement了這個介面,所以可以轉換)
@Override
public void onAttach(Context context) {
    super.onAttach(context);
    this.context=context;
operateDatabase= (OperateDatabase) context;
}
    接著我們開始找什麼時候觸發介面,讓Activity中的insert 方法執行,我們在點選按鈕時執行,所以我們寫按鈕的點選事件,並呼叫介面中方法
@Override
public void onClick(View view) {
    switch (view.getId())
    {
        case R.id.add_btn:
            operateDatabase.insert();
            break;
        case R.id.update_btn:
            operateDatabase.update();
            break;
        case R.id.delete_btn:
            operateDatabase.deltete();
            break;
        case R.id.query_btn:
            operateDatabase.query();
            break;
}
}
       而這個時候,我們在fragment中的操作就結束了,我們需要到Activity中進行操作

首先我們implement介面

public class MainActivity extends BaseActivity implements OperateDatabase{
這時就需要如同onClick時間一樣,實現方法(這個方法的名字是我們自己起的) 並且在方法中實現我們在Fragment點選按鈕後需要Activity做的事情

        在這裡我之前已經建立了資料庫和表,這裡就進行了對資料庫的操作

@Override
public void insert() {
    ContentValues values=new ContentValues();
values.put("name","value");
db.insert("student",null,values);
Log.e("66666", "insert: ");
}

@Override
public void deltete() {
    db.delete("student","name=?",new String[]{"values"});
Log.e("66666", "delete: ");
}

@Override
public void query() {
    Cursor cursor =db.query("student",null,null,null,null,null,null);
    if (cursor!=null) {
        while (cursor.moveToNext()) {
            String name=cursor.getString(cursor.getColumnIndex("name"));
}
    }
    Log.e("66666", "query: ");
}

@Override
public void update() {
    ContentValues values=new ContentValues();
values.put("name","update");
db.update("student",values,"name=?",new String[]{"value"});
Log.e("66666", "update: ");
}
這樣fragment向Activity傳值就實現了,需要傳值就在我們定義介面時寫進去,在傳值時傳過去就好.我的這個例子沒有傳值,以下是我隨便點打的log

E/66666: insert: 
E/66666: delete: 
E/66666: update: 
E/66666: query: 
E/66666: insert: 
E/66666: insert: 

不過因為我是個初學者,對於原理什麼的都不懂,所以上述所有肯定會有錯誤,so小心踩雷.