Implementing Attendee Detail BottomSheet UI in Open Event Orga App

In Open Event Orga App (Github Repo), we allow the option to check the attendee details before checking him/her in or out. Originally, a dialog was shown showing the attendee details, which did not contain much information about the attendee, ticket or the order. The disadvantage of such design was also that it was tied to only one view. We couldn’t show the check in dialog elsewhere in the app, like during QR scanning. So we had to switch back to the attendee view for showing the check in dialog. We decided to create a usable detached component in the form of a bottom sheet containing all required information. This blog will outline the procedure we employed to design the bottom sheet UI. The attendee check in dialog looked like this: So, first we decide what we need to show on the check in bottom sheet: Attendee Name Attendee Email Attendee Check In Status Order Status ( Completed, Pending, etc ) TIcket Type ( Free, Paid, Donation ) Ticket Price Order Date Invoice Number Order ‘Paid Via’ As we are using Android Data Binding in our layout, we’ll start by including the variables required in the layout. Besides the obvious attendee variable, we need presenter instance to handle the check in and check out of the attendee and DateUtils class to parse the order date. Additionally, to handle the visibility of views, we need to include the View class too <data> <import type="org.fossasia.openevent.app.utils.DateUtils" /> <import type="android.view.View" /> <variable name="presenter" type="org.fossasia.openevent.app.event.checkin.contract.IAttendeeCheckInPresenter" /> <variable name="checkinAttendee" type="org.fossasia.openevent.app.data.models.Attendee" /> </data>   Then, we make the root layout to be CoordinatorLayout and add a NestedScrollView inside it, which contains a vertical linear layout in it. This vertical linear layout will contain our fields. Note: For brevity, I’ll skip most of the layout attributes from the blog and only show the ones that correspond to the text Firstly, we show the attendee name: <TextView style="@style/TextAppearance.AppCompat.Headline" android:text='@{attendee.firstName + " " + attendee.lastName }' tools:text="Name" />   The perks of using data binding can be seen here, as we are using string concatenation in layout itself. Furthermore, data binding also handles null checks for us if we add a question mark at the end of the variable name ( attendee.firstName? ). But our server ensures that both these fields are not null, so we skip that part. Next up, we display the attendee email <TextView android:text="@{ checkinAttendee.email }" tools:text="xyz@example.com" />   And then the check in status of the attendee <TextView android:text="@{ checkinAttendee.checkedIn ? @string/checked_in : @string/checked_out }" android:textColor="@{ checkinAttendee.checkedIn ? @color/light_green_500 : @color/red_500 }" tools:text="CHECKED IN" />   Notice that we dynamically change the color and text based on the check in status of the attendee Now we begin showing the fields with icons to their left. You can use Compound Drawable to achieve this effect, but we use vector drawables which are incompatible with compound drawables on older versions of Android, so we use a horizontal LinearLayout instead. The first field is the order status denoting…

Continue ReadingImplementing Attendee Detail BottomSheet UI in Open Event Orga App

Smart Data Loading in Open Event Android Orga App

In any API centric native application like the Open Event organizer app (Github Repo), there is a need to access data through network, cache it for later use in a database, and retrieve data selectively from both sources, network and disk. Most of Android Applications use SQLite (including countless wrapper libraries on top of it) or Realm to manage their database, and Retrofit has become a de facto standard for consuming a REST API. But there is no standard way to manage the bridge between these two for smart data loading. Most applications directly make calls to DB or API service to selectively load their data and display it on the UI, but this breaks fluidity and cohesion between these two data sources. After all, both of these sources manage the same kind of data. Suppose you wanted to load your data from a single source without having to worry from where it is coming, it’d require a smart model or repository which checks which kind of data you want to load, check if it is available in the DB, load it from there if it is. And if it not, call the API service to load the data and also save it in the DB there itself. These smart models are self contained, meaning they handle the loading logic and also handle edge cases and errors and take actions for themselves about storing and retrieving the data. This makes presentation or UI layer free of data aspects of the application and also remove unnecessary handling code unrelated to UI. From the starting of Open Event Android Orga Application planning, we proposed to create an efficient MVP based design with clear separation of concerns. With use of RxJava, we have created a single source repository pattern, which automatically handles connection, reload and database and network management. This blog post will discuss the implementation of the AbstractObservableBuilder class which manages from which source to load the data intelligently Feature Set So, first, let’s discuss what features should our AbstractObservableBuilder class should have: Should take two inputs - disk source and network source Should handle force reload from server Should handle network connection logic Should load from disk observable if data is present Should load from network observable if data is not present is disk observable This constitutes the most basic data operations done on any API based Android application. Now, let’s talk about the implementation Implementation Since our class will be of generic type, we will used variable T to denote it. Firstly, we have 4 declarations globally private IUtilModel utilModel; private boolean reload; private Observable<T> diskObservable; private Observable<T> networkObservable;   UtilModel tells us if the device is connected to internet or not reload tells if the request should bypass database and fetch from network source only diskObservable is the database source of the item to be fetched networkObservable is the network source of the same item Next is a very simple implementation of the builder pattern methods which will be…

Continue ReadingSmart Data Loading in Open Event Android Orga App