Using a Custom Create Confirm Screen
Step 1: Extend BaseVoucherCreateConfirmFragment
The fragments first task is to confirm whether the user is happy with their Voucher. The second task is to display loading while the creation and possibly activation of the Voucher occurs. The create screen must extend the BaseVoucherLoadingFragment
which does much of the heavy lifting when interacting with the rest of the create flow.
public class SimpleCreateConfirmFragment extends BaseVoucherCreateConfirmFragment {
}
class SimpleCreateConfirmFragment : BaseVoucherCreateConfirmFragment() {
}
Option 1 : Creation
Calling transformVoucher
will asynchronously convert the PendingVoucher
into a Voucher
via the Voucher server. It can not be opened and is not considered funded until is has been activated which can happen on this screen or on the Summary Screen.
This can be achieved by calling the fragments method transformIntoVoucher()
and listening for its result.
The following kotlin code would convert the PendingVoucher
into a Voucher
and if successful continue the flow to the summary screen.
transformIntoVoucher()
.subscribe(new Subscriber<Voucher>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
// Error
}
@Override
public void onNext(Voucher voucher) {
forwardToSummary(voucher);
}
});
transformIntoVoucher()
.subscribe(
{ voucher ->
forwardToSummary(voucher)
},
{ throwable ->
// Error
})
Option 2 : Activate and Skip the Summary Screen
If you wish to activate here and skip the summary screen you can use fragment methods activateVoucher(Voucher voucher)
and forwardToComplete(Voucher voucher)
The following kotlin code would convert the PendingVoucher
into a Voucher
then activate it and if both are successful finish the flow.
transformIntoVoucher()
.flatMap(new Func1<Voucher, Observable<Voucher>>() {
@Override
public Observable<Voucher> call(Voucher voucher) {
return activateVoucher(voucher);
}
})
.subscribe(new Subscriber<Voucher>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
//Error
}
@Override
public void onNext(Voucher voucher) {
forwardToComplete(voucher);
}
});
transformIntoVoucher()
.flatMap { voucher -> activateVoucher(voucher) }
.subscribe(
{ voucher ->
forwardToComplete(voucher)
},
{ throwable ->
// Error
})
Protected Methods
The fragment has access to the following methods:
// Allows quick access of the create configuration and all it's settings.
CreateConfiguration getCreateConfig()
// The current pending voucher built in the last screen. This can still be modified until `transformIntoVoucher()` is called.
PendingVoucher getPendingVoucher()
// This will communicate with our server to create a Voucher object from a pendingVoucher
Observable<Voucher> transformIntoVoucher()
// This will activate a Voucher, which will make the voucher live.
Observable<Voucher> activateVoucher(Voucher voucher)
// This moves you forward in the create flow. This should be called if the activateVoucher() has not been call
void forwardToSummary(Voucher voucher)
// This finishes the create flow. This should be called if both transformIntoVoucher() and activateVoucher() is called
void forwardToComplete(Voucher voucher)
// Allows quick access of the create configuration and all it's settings.
fun getCreateConfig() : CreateConfiguration
// The current pending voucher built in the last screen. This can still be modified until `transformIntoVoucher()` is called.
fun getPendingVoucher() : PendingVoucher
// This will communicate with our server to create a Voucher object from a pendingVoucher
fun transformIntoVoucher() : Observable<Voucher>
// This will activate a Voucher, which will make the voucher live.
fun activateVoucher(voucher: Voucher) : Observable<Voucher>
// This moves you forward in the create flow. This should be called if the activateVoucher() has not been call
fun forwardToSummary(voucher: Voucher)
// This finishes the create flow. This should be called if both transformIntoVoucher() and activateVoucher() is called
fun forwardToComplete(voucher: Voucher)
Using the Navigator
If you want to preview the gift:
getNavigator().previewGift(getActivity(), getPendingVoucher());
navigator.previewGift(activity, pendingVoucher)
Simple Example
This example shows a button that when pressed with transform the voucher and proceed to the summary screen.
SimpleVoucherConfirmFragment.kt
class SimpleVoucherConfirmFragment extends BaseVoucherCreateConfirmFragment {
private TextView loadingText;
private VouchrButton sendButton;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_simple_voucher_confirm, container, false);
loadingText = view.findViewById(R.id.loadingText);
sendButton = view.findViewById(R.id.sendButton);
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
loadingText.setText("Ready to send?");
sendButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
loadingText.setText("Sending...");
transformIntoVoucher()
.subscribe(new Subscriber<Voucher>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) { // Error
loadingText.setText("Something went wrong... Retry?");
sendButton.setVisibility(View.VISIBLE);
}
@Override
public void onNext(Voucher voucher) { // Success
forwardToSummary(voucher);
}
});
}
});
}
}
class SimpleVoucherConfirmFragment : BaseVoucherCreateConfirmFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_simple_voucher_confirm, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
loadingText.text = "Ready to send?"
sendButton.setOnClickListener {
loadingText.text = "Sending..."
transformIntoVoucher()
.subscribe(
{ voucher -> // Success
forwardToSummary(voucher)
},
{ throwable -> // Error
loadingText.text = "Something went wrong... Retry?"
sendButton.visibility = View.VISIBLE
})
}
}
}
fragment_simple_voucher_confirm.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/loadingText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:text="Sending in progress..."
android:textAppearance="?TextAppearance.SecondaryHeader"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.surpriise.vouchrcommon.ui.components.VouchrButton
android:id="@+id/sendButton"
style="?VouchrButton.Dark.Positive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/send"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/loadingText" />
</android.support.constraint.ConstraintLayout>
Step 2: Set CreateFlowController
Setup the CreateFlowController
while building the CreateConfiguration
.
When you setup the CreateFlowController override the createConfirmScreen
function and pass in your own screen that we built in step 1.
CreateConfiguration createConfiguration = new CreateConfiguration.Builder(context)
.setCreateFlowController(new CreateFlowController.Default() {
@Override
public BaseVoucherCreateConfirmFragment createConfirmScreen(PendingVoucher pv, CreateConfiguration cc) {
return new SimpleVoucherLoadingFragment();
}
})
.build()
Engine.Builder engineBuilder = new Engine.Builder(VOUCHR_BASE_URL, SDK_ID);
engineBuilder.setCreateConfig(new CreateConfiguration.Builder(this).build())
engineBuilder.build().startup(this);
val createConfiguration = CreateConfiguration.Builder(context)
.setCreateFlowController(object : CreateFlowController.Default() {
override fun createConfirmScreen(pv: PendingVoucher, cc: CreateConfiguration): BaseVoucherCreateConfirmFragment {
return SimpleVoucherLoadingFragment()
}
})
.build()
val engineBuilder = Engine.Builder(VOUCHR_BASE_URL, SDK_ID)
engineBuilder.setCreateConfig(CreateConfiguration.Builder(this).build())
engineBuilder.build().startup(this)
More information on the CreateFlowController
can be found in the JavaDocs here
Step 3: Launching the create flow
To start the create flow use the following IntentBuilder.
VoucherCreationActivity.IntentBuilder.init().start(this);
VoucherCreationActivity.IntentBuilder.init().start(this)
And depending on your theme after progressing through the flow you should see something like this