天天看點

Otto 應用入門

Otto 應用入門

本篇部落格通過分析Otto官方提供的例子來分析otto的使用

分析界面功能

Otto 應用入門

功能很簡單,通過點選Move Location按鈕,在下面的fragment中添加一個位置資訊,即經緯度。當然,這裡是采用随機數的方法随機生成的。再然後就是Clear History按鈕,點選這個按鈕,清除剛剛生成的位置資訊。

界面代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
              android:padding="@dimen/holo_gap">
    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="@dimen/holo_gap"
            android:orientation="horizontal">
        <Button android:id="@+id/clear_location"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:layout_marginRight="@dimen/holo_gap"
                android:text="@string/clear_location"
                />
        <Button android:id="@+id/move_location"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="@string/move_location"
                />
    </LinearLayout>
    <fragment class="com.squareup.otto.sample.LocationMapFragment"
              android:id="@+id/map"
              android:layout_width="match_parent"
              android:layout_height="0dp"
              android:layout_weight="1"
              android:layout_marginBottom="@dimen/holo_gap"/>
    <fragment class="com.squareup.otto.sample.LocationHistoryFragment"
              android:id="@+id/history"
              android:layout_width="match_parent"
              android:layout_height="0dp"
              android:layout_weight="1"
            />
</LinearLayout>
           

當然要實作這個功能很簡單,比如用廣播,或者fragment提供一個公有方法供外界調用,修改界面。此處,使用Otto架構來實作。

由于兩個按鈕差不多,此處我隻分析Move Location按鈕。

Otto使用

1.提供一個java類來傳遞資料

這裡要實作的功能其實就是如何以Otto的方式将資料從Activity中傳遞到Fragment,既然要傳遞資料,自然要提供一個類來封裝

//代碼路徑com.squareup.otto.sample.LocationChangedEvent 
public class LocationChangedEvent {

    public final float lat;
    public final float lon;
    //省略了帶這兩個參數的構造函數,以及toString方法
    ...
}
           

2.注冊

Otto的使用需要注冊

@Override
protected void onResume() {
    super.onResume();
    // Register ourselves so that we can provide the initial value.
    BusProvider.getInstance().register(this);
}

@Override
protected void onPause() {
    super.onPause();
    // Always unregister when an object no longer should be on the bus.
    BusProvider.getInstance().unregister(this);
}
           

注冊非常簡單,核心方法如下

BusProvider.getInstance().register(this);

BusProvider.getInstance().unregister(this);
           

注意,無論是發送的Activity還是接受的Fragment都需要注冊。此處的BusProvider是一個Bus的工廠,提供Bus的單例。

3.傳遞資料

有了資料下一步要做的就是傳遞資料,當然可以使用廣播的方式,Otto這裡做的更加簡便

findViewById(R.id.move_location).setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        //經緯度通過随機數生成
        lastLatitude += (RANDOM.nextFloat() * OFFSET * ) - OFFSET;
        lastLongitude += (RANDOM.nextFloat() * OFFSET * ) - OFFSET;
        //核心代碼      
        BusProvider.getInstance().post(produceLocationEvent());
    }
});

@Produce
public LocationChangedEvent produceLocationEvent() {
    // Provide an initial value for location based on the last known
    // position.
    return new LocationChangedEvent(lastLatitude, lastLongitude);
}
           

總結一下

1. 提供一個

public

方法(注意,必須是public方法,否則會報錯),方法的傳回值傳回我們需要傳遞的資料即可

2. 在方法上面加上

@Produce

注解

3. 在需要釋出資料的地方post一下即可

4.接收資料(LocationHistoryFragment)

1)同樣的接收方也需要注冊與反注冊

2)訂閱事件

private final List<String> locationEvents = new ArrayList<String>();
private ArrayAdapter<String> adapter;

@Subscribe
public void onLocationChanged(LocationChangedEvent event) {
    locationEvents.add(, event.toString());
    if (adapter != null) {
        adapter.notifyDataSetChanged();
    }
}

@Subscribe
public void onLocationCleared(LocationClearEvent event) {
    locationEvents.clear();
    if (adapter != null) {
        adapter.notifyDataSetChanged();
    }
}
//省略界面初始化相關代碼
...
           

從代碼可知,有兩個方法訂閱了事件,但是傳入的參數不同。從上文可知我們傳遞的參數是LocationChangedEvent,是以此處會将事件傳遞給onLocationChanged方法。

這樣當我們點選按鈕時候,就會通過post方法将我們需要傳遞的資料傳遞給訂閱了該對象的方法。

至此,此Example的流程就簡單的分析完了。

看首個界面,發現我們并沒有點選Move Location按鈕,但是界面上依然出現了一行資料。這是因為當我們regist時候,會向所有訂閱此事件的方法傳遞一個資料。訂閱通過@Subscribe以及傳入的參數來判斷。

總結一下,Otto的使用:

1)在訂閱與生産事件的類中注冊

2)在生産者類中添加@Produce方法

3)在訂閱類中添加@Subscribe方法

4)通過post方法進行事件傳遞