public void launchEditTemplateDialog() {
        final boolean isSignature = getKey().equals(getContext().getString(R.string.pref_signature));

        final View v = LayoutInflater.from(getContext()).inflate(R.layout.template_preference_dialog, null);
        final TextInputLayout titleLayout = v.findViewById(R.id.titleLayout);
        editTitle = v.findViewById(R.id.title);
        editText = v.findViewById(R.id.edit);

        boolean focusOnText = true;
        if (isSignature) {
            editText.setText(Settings.getSignature());
        } else {
            titleLayout.setVisibility(View.VISIBLE);
            final Settings.PrefLogTemplate template = Settings.getLogTemplate(this.getKey());
            if (template != null) { // can be null if template contains no value
                editTitle.setText(template.getTitle());
                editText.setText(template.getText());
            }
            focusOnText = StringUtils.isNotEmpty(editTitle.getText());
        }
        Dialogs.moveCursorToEnd(editText);
        Keyboard.show(getContext(), focusOnText ? editText : editTitle);

        final AlertDialog dialog = Dialogs.newBuilder(getContext())
                .setView(v)
                .setPositiveButton(android.R.string.ok, null)
                .setNeutralButton(R.string.init_signature_template_button, null)
                .show();

        // override onClick listener to prevent closing dialog on pressing the "default" button
        dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(v2 -> {
            final String newTitle = editTitle.getText().toString();
            final String newText = editText.getText().toString();
            // check that for log templates both title and text are filled
            if (!isSignature && StringUtils.isEmpty(newTitle) && !StringUtils.isEmpty(newText)) {
                editTitle.setError(getContext().getString(R.string.init_log_template_missing_error));
            } else if (!isSignature && !StringUtils.isEmpty(newTitle) && StringUtils.isEmpty(newText)) {
                editText.setError(getContext().getString(R.string.init_log_template_missing_error));
            } else if (StringUtils.isEmpty(newTitle) && StringUtils.isEmpty(newText)) {
                // don't save empty templates
                dialog.dismiss();
            } else {
                if (isSignature) {
                    persistString(newText);
                } else {
                    Settings.putLogTemplate(new Settings.PrefLogTemplate(getKey(), newTitle, newText));
                }
                callChangeListener(newText);
                dialog.dismiss();
            }
        });
        dialog.getButton(DialogInterface.BUTTON_NEUTRAL).setOnClickListener(v2 -> {
            final AlertDialog.Builder templateBuilder = Dialogs.newBuilder(TemplateTextPreference.this.getContext());
            templateBuilder.setTitle(R.string.init_signature_template_button);
            final List<LogTemplate> templates = LogTemplateProvider.getTemplatesWithoutSignature();
            final String[] items = new String[templates.size()];
            for (int i = 0; i < templates.size(); i++) {
                items[i] = getContext().getString(templates.get(i).getResourceId());
            }
            templateBuilder.setItems(items, (selectionDialog, position) -> {
                selectionDialog.dismiss();
                final String insertText = "[" + templates.get(position).getTemplateString() + "]";
                ActivityMixin.insertAtPosition(editText, insertText, true);
            });
            templateBuilder.create().show();
        });
    }
default value, if none is given in the preference XML.
main/src/main/java/cgeo/geocaching/settings/TemplateTextPreference.java