Плавающая кнопка не работает при маршрутизации на контроллер проводника во второй раз

Я использую проводник и нож.

У меня есть 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() не делает.

Вот пример двух контроллеров, первый из которых я хочу перенаправить обратно:

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 - Нажатие на все Fab-маршруты allDone в 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 ответа

Я подозреваю, что ваша проблема связана с тем, как вы вернетесь к WelcomeController. Ваш текущий код создает новый WelcomeController, когда onAllDoneClick() называется. В конце концов, у вас есть WelcomeController, покрытый RecordFingerPulseController, покрытый другим WelcomeController.

Вы уже настроили обратный переход в onFabNextClick() где вы добавили popChangeHandler,

Самый простой способ вернуться - позвонить getRouter().popCurrentController(); вместо добавления нового WelcomeController поверх RecordFingerPulseController. Это оставит вас только с WelcomeController.

Если вы посмотрите на реализацию маршрутизатора, вы обнаружите, что он имеет 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. И т.п.
Другие вопросы по тегам