第二次路由到导体控制器时,浮动按钮不起作用

时间:2018-04-03 09:41:23

标签: android butterknife conductor

我正在使用指挥和刀。

我有一个 BaseController ,我在那里做BN样板:

    protected ButterKnifeController() { }
    protected ButterKnifeController(Bundle args) {
        super(args);
    }

    protected abstract View inflateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container);

    @NonNull
    @Override
    protected View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container) {
        View view = inflateView(inflater, container);
        unbinder = ButterKnife.bind(this, view);
        onViewBound(view);
        return view;
    }

    protected void onViewBound(@NonNull View view) { }

    @Override
    protected void onDestroyView(@NonNull View view) {
        super.onDestroyView(view);
        unbinder.unbind();
        unbinder = null;
    }
}

我有几个带FAB的控制器,虽然问题也与简单的按钮相同。

当我第一次路由到控制器时,onClick()按预期工作。但是当我第二次路由到控制器时,onClick()并没有。

以下是2个控制器的示例,第一个是我想要路由回的控制器:

WelcomeController - 当我第一次路线时,Fab工作正常

public class WelcomeController extends BaseController {
    @BindView(R.id.tv_step_title)
    TextView title;

    @BindView(R.id.tv_step_message)
    TextView message;


    @Override
    protected View inflateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container) {
        return inflater.inflate(R.layout.controller_base_title_text, container, false);
    }

    @Override
    protected void onViewBound(@NonNull View view) {
        super.onViewBound(view);
        title.setText(getResources().getText(R.string.wizard_welcome_step_title));
        message.setText(getResources().getText(R.string.wizard_welcome_step_message));
    }

    @Override
    protected void onAttach(@NonNull View view) {
        super.onAttach(view);
        requestVideoPermissions();
    }

    @OnClick(R.id.fab_next)
    public void onFabNextClick(){
        getRouter().pushController(RouterTransaction.with(new DiagnosePulseController())
                .pushChangeHandler(new FadeChangeHandler())
                .popChangeHandler(new FadeChangeHandler()));
    }
}

SecondController - 单击allDone Fab路由到WelcomeController但没有onClick()事件触发。

public class RecordFingertPulseController extends BaseController {

    private static final String TAG = RecordFingertPulseController.class.getSimpleName();
    public static final String WRIST_PPG_KEY = "wrist_ppg";
    public static final String WRIST_TS_KEY = "wrist_ts";

    private CameraController mCameraController;
    private static final PpgRecordedRxModel PPG_RX_MODEL = PpgRecordedRxModel.getInstance();
    private PulseModel mPulseModel = null;
    private final CameraController.Callback mRxCameraControllerCallback = new CameraController.Callback() {
        @Override
        public void onCameraAccessException() {
            Log.e(TAG, "CameraAccessException");
        }

        @Override
        public void onCameraOpenException(@Nullable OpenCameraException.Reason reason) {
            Log.e(TAG, new OpenCameraException(reason).getMessage());
        }

        @Override
        public void onException(Throwable throwable) {
            Log.e(TAG, throwable.getMessage());
        }
    };

    @BindView(R.id.fab_record_pulse)
    FloatingActionButton mFabRecordPulse;

    @BindView(R.id.fab_all_done)
    FloatingActionButton mFabAllDone;

    @BindView(R.id.tv_step_title)
    MyTextView tv_title;

    @BindView(R.id.tv_step_message)
    MyTextView tv_message;

    public RecordFingertPulseController(Bundle dataBundle) {
        super(dataBundle);
    }

    @Override
    protected View inflateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container) {
        return inflater.inflate(R.layout.controller_pulse_recording, container, false);
    }

    @NonNull
    @Override
    protected View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container) {
        return super.onCreateView(inflater, container);
    }

    @Override
    protected void onAttach(@NonNull View view) {
        super.onAttach(view);
        setupViews();
        //Analytics screws camera FPS
        FirebaseAnalytics.getInstance(getActivity()).setAnalyticsCollectionEnabled(false);
        startCamera();
        mCameraController.getConductorLifecycle().onAttach();
        subscribeToPpgRecorded();
    }

    private void subscribeToPpgRecorded() {
        PPG_RX_MODEL.getPpgObservable()
                .doOnNext(ppg -> Log.d(TAG, "PulseModel before filter :\t"
                        + ppg.getPulseName() + "\nPulseModel wrist ppg size"
                        + ppg.getWrisrPpgList().size()
                        + "\nPulseModel finger ppg size: " + ppg.getFingerPpgList().size()))
                .filter(ppg -> ppg.getWrisrPpgList().size() > 0
                        && ppg.getFingerPpgList().size() > 0)
                .doOnNext(ppg -> Log.d(TAG, "Got PulseModel() after filter with finger ppg size: "
                        + ppg.getFingerPpgList().size() + "\twrist ppg size: "
                        + ppg.getWrisrPpgList().size()))
                .subscribe(ppg -> finalizeWristRecording(ppg));
    }

    private void finalizeWristRecording(PulseModel ppg) {
//        mFabRecordPulse.setEnabled(true);
        mFabAllDone.setVisibility(View.VISIBLE);
        try {
            mPulseModel = ppg.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        Log.d(TAG, "Got the ppg with size: " + ppg.getWrisrPpgList().size());
    }

    private void startCamera() {
        CameraManager cameraManager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
        String cameraId = null;
        CameraCharacteristics characteristics = null;
        Size videoSize = null;
        try {
            cameraId = cameraManager.getCameraIdList()[0];
            characteristics = cameraManager.getCameraCharacteristics(cameraId);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
        StreamConfigurationMap map = characteristics
                .get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
        if (map == null) {
            throw new RuntimeException("Cannot get available preview/video sizes");
        }
        videoSize = MyUtils.chooseVideoSize(map.getOutputSizes(ImageReader.class));
        mCameraController = new CameraController(getActivity(), mRxCameraControllerCallback,
                cameraManager, cameraId, videoSize, CameraController.PpgSource.FINGER);
    }

    @Override
    protected void onDetach(@NonNull View view) {
        mCameraController.getConductorLifecycle().onDetach();
        mCameraController.getCameraClosedObservable().blockingLast();
        super.onDetach(view);
    }

    private void setupViews() {
        mFabAllDone.setVisibility(View.GONE);
        tv_title.setText(R.string.wizard_record_finger_pulse_step_title);
        tv_message.setText(R.string.wizard_record_finger_pulse_step_message);
        mFabAllDone.setImageResource(R.drawable.ic_done_all_white_24dp);

    }

    @OnClick(R.id.fab_record_pulse)
    public void onRecordPulseClick(){
        mFabRecordPulse.setEnabled(false);
        mCameraController.recordPulseClick();
    }

    @OnClick(R.id.fab_all_done)
    public void onAllDoneClick(){
        if(mPulseModel.getFingerPpgList().size() > 0 || mPulseModel.getWrisrPpgList().size() > 0){
            PulseFirebaseRepository.getRepoInstance().create(mPulseModel);
            requestVideoPermissions();      
mPulseModel.savePpg();
    getRouter().pushController(RouterTransaction.with(new WelcomeController())
                        .pushChangeHandler(new FadeChangeHandler())
                        .popChangeHandler(new FadeChangeHandler()));


        }else{
            if(null != getActivity()){
                new AlertDialog.Builder(getActivity())
                    .setMessage(R.string.empty_pulse_error)
                    .setPositiveButton(android.R.string.ok, null)
                    .show();
            }
        }
    }
}

我无法弄清楚原因。这感觉就像一个BN问题。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

我怀疑你的问题与你如何回到WelcomeController有关。当前代码在调用onAllDoneClick()时创建一个新的WelcomeController。最后,你有一个WelcomeRetroller,由RecordFingerPulseController覆盖,由另一个WelcomeController覆盖。

您已在onFabNextClick()添加popChangeHandler的位置设置了后转换。

返回的最简单方法是调用getRouter().popCurrentController();,而不是在RecordFingerPulseController之上添加新的WelcomeController。这将只给你一个WelcomeController。

答案 1 :(得分:1)

如果查看路由器实现,您会发现它有popToRoot(...)方法。这应该从后堆栈中删除所有内容。这是方法及其评论: -

/**
     * Pops all {@link Controller}s until only the root is left
     *
     * @return Whether or not any {@link Controller}s were popped in
     * order to get to the root transaction
     */
    @UiThread
    public boolean popToRoot() {
        ThreadUtils.ensureMainThread();

        return popToRoot(null);
    }

还有其他几种方法可以解决这个问题。

  1. 如果你不打算回到后面的堆栈,你可以更换控制器而不是推新控制器。
  2. 您可以添加使用标记以及popToTag(...)来将堆栈展开到您想要的控制器。
  3. 您可以使用getBackstack()将后台堆栈作为列表获取,然后使用该信息操作。