This is Part 2 in a series highlighting CollectionView
, a super powered list control with recycled rows providing you best of class on each platform suited to fit all sorts of needs.
Continuing onward with Swipeable cells for Android, we can again take advantage of layoutStyle
to register behaviors to our control.
CollectionView supports a layoutStyle
property allowing you to register custom platform behavior against the control, for example:
<CollectionView layoutStyle="swipe" />
This can be any string
value used to identify a custom registered layout style:
CollectionView.registerLayoutStyle('swipe', {
createLayout: () => {
// return a customized platform layout
return layout;
},
});
The layouts possible on Android can be anything in the RecyclerView.LayoutManager family. It provides an abstract base class for variety of layouts like GridLayoutManager, LinearLayoutManager and StaggeredGridLayoutManager.
Numerous tutorials can be found covering this; here's just a few:
One of the neatest things about NativeScript is the documentation and tutorials for a lot of the things you may want to do are already available in variety of platform sources because after all, NativeScript gives you the platform in JavaScript!
We can create one right from within our TypeScript codebase:
// Convenient Java/Kotlin package usage with NativeScript
import GridLayoutManager = androidx.recyclerview.widget.GridLayoutManager;
// Construct a GridLayoutManager
new GridLayoutManager(Utils.android.getApplicationContext(), 1);
Using the tutorials mentioned above as our guide we will implement 1 trailing swipe action by configuring the callbacks as illustrated. This is what we want our createLayout
to look like:
CollectionView.registerLayoutStyle("swipe", {
createLayout(view: CollectionView) {
const recyclerView = <RecyclerView>view.nativeView;
// Create a swipe to delete handler
const swipeToDeleteCallback = SwipeToDeleteCallback.initWithOwner(
new WeakRef(view)
);
// Register the handler with our RecyclerView
const itemTouchHelper = new ItemTouchHelper(swipeToDeleteCallback);
itemTouchHelper.attachToRecyclerView(recyclerView);
// Upon a full swipe, add a nice animation when the row removes itself
recyclerView.addItemDecoration(
new SwipeToDeleteAnimation()
);
return new GridLayoutManager(Utils.android.getApplicationContext(), 1);
}
})
It's pretty neat to take Kotlin/Java code into a TypeScript file for usage with NativeScript. We can do so using the example blog posts to end up with this, in part:
import ItemTouchHelper = androidx.recyclerview.widget.ItemTouchHelper;
import RecyclerView = androidx.recyclerview.widget.RecyclerView;
import Canvas = android.graphics.Canvas;
@NativeClass()
class SwipeToDeleteCallback extends ItemTouchHelper.SimpleCallback {
// Common way to statically init a class with a WeakRef to the owner
static initWithOwner(owner: WeakRef<CollectionView>) {
const swipe = new SwipeToDeleteCallback(
ItemTouchHelper.UP |
ItemTouchHelper.DOWN |
ItemTouchHelper.START |
ItemTouchHelper.END,
ItemTouchHelper.LEFT
);
swipe.owner = owner;
return swipe;
}
onChildDraw(
c: Canvas,
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
dX: number,
dY: number,
actionState: number,
isCurrentlyActive: boolean
) {
// configure swipeable regions as needed using standard drawable methods
}
}
The full example illustrates how much is possible giving you full control over every nuanced aspect of what you'd like your target platform to do.
If we were to run this on Android (ns debug android
) with CollectionView markup, styled with TailwindCSS, to match what we had with Part 1 as follows:
<CollectionView [items]="items" layoutStyle="swipe">
<ng-template let-item="item">
<GridLayout rows="auto,auto,auto" class="pl-4 pr-2 py-4 v-center">
<Label
[text]="item.name"
class="text-[17px] text-black font-bold align-middle"
></Label>
<Label
row="1"
[text]="item.subject"
class="text-base text-black leading-none align-middle"
></Label>
<Label
row="2"
[text]="item.body"
class="text-base leading-none text-gray-500"
maxLines="2"
></Label>
<GridLayout rowSpan="3" columns="auto,auto" class="align-top h-right">
<Label
[text]="item.date | date : 'shortDate'"
class="text-sm align-middle text-gray-500"
></Label>
</GridLayout>
</GridLayout>
</ng-template>
</CollectionView>
We would see this:
At this point, you could take things further with additional swipe regions based on project needs.
We will look at "View Modes" next providing us the ability to switch between multi column layouts or single spanned row setups.
Founded in 2016 by open source collaborators, nStudio is recognized for establishing a healthy open source governance model to serve the global communities interest around NativeScript. If you are in need of professional assistance on your project, nStudio offers services spanning multiple disciplines and can be reached at [email protected].