0

我正在使用导体和黄油刀。

我有一个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();
            }
        }
    }
}

我根本不知道为什么。感觉就像是国阵的问题。任何帮助将不胜感激。

4

2 回答 2

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(),然后使用该信息操作事物。
  4. 等等。
于 2018-05-16T22:19:47.597 回答
1

我怀疑您的问题与您返回 WelcomeController 的方式有关。您当前的代码在调用时会创建一个新的 WelcomeController onAllDoneClick()。最后,您有一个被 RecordFingerPulseController 覆盖的 WelcomeController,被另一个 WelcomeController 覆盖。

您已经在onFabNextClick()添加popChangeHandler.

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

于 2018-05-01T12:54:18.533 回答