侦听事件以触发另一个类中的方法(Rx)

时间:2016-01-08 08:31:37

标签: android rx-java rx-android

对RxJava / RxAndroid来说很新,但我认为由于Rx经常用于事件处理,或许这是一个很好的尝试。

我有一个自定义视图,它在自定义视图类中使用Runnable来处理长按点击:

    final Handler handler = new Handler();
    Runnable longPressed = new Runnable() {
        public void run() {
            //Call method in this views Activity here.
        }
    };

我希望在触发此事件并调用run()时调用Activity中的方法。可以使用Rx调用Activity中的方法是一个干净的解决方案吗?如何使用RxJava / RxAndroid完成?

2 个答案:

答案 0 :(得分:3)

您可以简单地为此创建一个列表器界面。

public interface ViewUpdateListner{
void update();
}

然后打电话给:

 final Handler handler = new Handler();
    Runnable longPressed = new Runnable() {
        public void run() {
            updateListner.update();
        }
    };

在活动中设置Listner,就像按下按钮一样。

view.setOnViewUpdateListner(this);

现在,如果你想为此使用Rx,那么只需在自定义视图类中包装你的列表器即可。像

 public static Observable<ViewUpdateEvent> viewUpdateEvents(View view) {
    return Observable.create(new ViewUpdateEventOnSubscribe(view));
  }

    final class ViewUpdateEventOnSubscribe implements Observable.OnSubscribe<ViewUpdateEvent> {
  final View view;

  ViewUpdateEventOnSubscribe (View view) {
    this.view = view;
  }

  @Override public void call(final Subscriber<? super ViewUpdateEvent> subscriber) {
   ViewUpdateListnerlistner listner= new ViewUpdateListner() {
                @Override
                public void update() {
                    if (!subscriber.isUnsubscribed()) {
                        subscriber.onNext(new ViewUpdateEvent());
                    }
                }
            };
  view.setOnViewUpdateListner(listner);
  }
}

然后你可以在你的活动中使用它,如:

viewUpdateEvents(view)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<ViewUpdateEvent>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(ViewUpdateEvent update) {

        };)

答案 1 :(得分:2)

您好我也是Rx的新手,我们可以使用RxJava实现简单的事件总线。

因此,对于问题,我们会在触发长按时发布事件,并在活动上订阅事件。因此,如果已发出事件,将通知活动执行某些操作。

以下是我的尝试:

public class RxBus {

  private final Subject<Object, Object> mRxBus = new SerializedSubject<>(PublishSubject.create());

  private static RxBus mInstance;

  public static RxBus getInstance() {
    if (mInstance == null) {
        mInstance = new RxBus();
    }
    return mInstance;
  }

  private RxBus() {

  }
  public void send(Object o) {
    mRxBus.onNext(o);
  }

  public Observable<Object> toObserverable() {
    return mRxBus;
  }

  public boolean hasObservers() {
    return mRxBus.hasObservers();
  }
}

在片段类上:

public class MainFragment extends Fragment {
private static final String TAG = MainFragment.class.toString();
private RxBus mRxBus;
private Handler mHandler = new Handler();
private Runnable mRunnable = new Runnable() {
    @Override
    public void run() {
        if (mRxBus.hasObservers()) {
            mRxBus.send(new LongPressEvent());
        }
    }
};
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_main, container, false);
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    Button longPressButton = (Button) view.findViewById(R.id.longpress_button_main);
    longPressButton.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    mHandler.postDelayed(mRunnable, 3000);
                    break;
                case MotionEvent.ACTION_CANCEL:
                    mHandler.removeCallbacks(mRunnable);
                    break;
                case MotionEvent.ACTION_UP:
                    mHandler.removeCallbacks(mRunnable);
                    break;
            }
            return false;
        }
    });
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    mRxBus = RxBus.getInstance();
}

public static class LongPressEvent {

}
}

最后在活动:

public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.toString();
private static final String FRAGMENT_TAG = "fragment_tag";
private RxBus mRxBusInstance = RxBus.getInstance();

private CompositeSubscription mCompositeSubscription;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initView();
    eventSubscription();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    mCompositeSubscription.unsubscribe();
}

private void eventSubscription() {
    mCompositeSubscription = new CompositeSubscription();
    getRxBusInstance();

    Observable<Object> longPressEvent = mRxBusInstance.toObserverable();
    mCompositeSubscription.add(longPressEvent.subscribe(new Action1<Object>() {
        @Override
        public void call(Object o) {
            if (o instanceof MainFragment.LongPressEvent) {
                //do something here
            }
        }
    }));
}
}

希望这有帮助!!以及来自博客

的更多信息的参考资料

http://nerds.weddingpartyapp.com/tech/2014/12/24/implementing-an-event-bus-with-rxjava-rxbus/