B4A Library [B4X] [XUI] AS Swipe Card - a tinder like swipeable card view [Payware]

Hello Community,

This library is not free, because, it cost a lot of time and gray hair to create such views.
Thanks for your understanding. :)

This library is compatible and tested with B4A,B4I and B4J!
If you have bugs or a wish then tell me it in the comments.

Features
  • cross-platform compatible
  • enable or disable events
  • add and remove cards
  • scroll to cards
  • animations
  • swipe with fingers
  • and more...
sc_1.gif
sc_2.gif
Bildschirmaufnahme 2020-05-06 um 19.47.082.gif


On B4J and B4I you need a base panel, only this way the events can be triggered by your other control elements, see the example projects to learn more.

ASSwipeCard
Author: Alexander Stolte
Version: 2.00

  • ASSwipeCard
    • Events:
      • BaseResize (Width As Double, Height As Double)
      • IndexChanged (index As Int)
      • LazyLoadingAddContent (Parent As B4XView, Value As Object)
      • ReachEnd
      • SwipeStateChange (state As Int)
      • SwipeStateChanged (state As Int)
    • Functions:
      • AddCard (xpnl As B4XView, Tag As Object) As String
      • Base_Resize (Width As Double, Height As Double) As String
      • Class_Globals As String
      • Clear As String
        Clears all cards
      • Commit As String
      • DesignerCreateView (Base As Object, Lbl As Label, Props As Map) As String
        Base type must be Object
      • getBase As B4XView
      • GetCard (Index As Int) As B4XView
      • getCardBackground As B4XView
      • getCurrentIndex As Int
      • getLazyLoadingExtraSize As Int
      • getSize As Int
      • getTag (Index As Int) As Object
      • IniParent (parent As B4XView) As String
      • Initialize (Callback As Object, EventName As String) As String
      • IsInitialized As Boolean
        Tests whether the object has been initialized.
      • NextCard (swipe_state As Int)
      • PreviousCard (swipe_state As Int)
      • RemoveCard (Index As Int) As String
      • setCurrentIndex (index As Int) As String
      • setLazyLoadingExtraSize (ExtraSize As Int) As String
      • SwipeState_BOTTOM As Int
      • SwipeState_LEFT As Int
      • SwipeState_NEUTRAL As Int
      • SwipeState_RIGHT As Int
      • SwipeState_TOP As Int
      • SwipeStateRandom As Int
    • Properties:
      • Base As B4XView [read only]
      • CardBackground As B4XView [read only]
      • CurrentIndex As Int
      • LazyLoadingExtraSize As Int
      • Size As Int [read only]
  • SwipeCardItems
    • Fields:
      • IsInitialized As Boolean
        Tests whether the object has been initialized.
      • Tag As Object
      • xpnl_cardbase As B4XView
    • Functions:
      • Initialize
        Initializes the fields to their default value.
Changelog
  • 1.00
    • Release
  • 1.01
    • Add Designer Property: EnableLeftRightSwipe -Enabled or Disabled the swipe gesture for left and right swiping
    • Add Designer Property: EnableTopBottomSwipe -Enabled or Disabled the swipe gesture for top and bottom swiping
  • 1.02
    • Add Event "SwipeStateChange" - Triggers when the card is moved with the finger in one direction e.g. LEFT,RIGHT,TOP,BOTTOM or NEUTRAL
    • Event "SwipeStateChanged" - Triggers now only when the user has released the card
    • Add Clear - clears all cards
  • 1.03
    • get CurrentIndex is now readable
  • 1.04
    • Add Designer Properties - If true then the previous card is shown as next card if you swipe in the right direction
      • SwipeLeft2Previous
      • SwipeRight2Previous
      • SwipeTop2Previous
      • SwipeBottom2Previous
  • 1.05
    • BugFixes for the Features of V1.04
  • 1.06
    • BugFix
  • 1.07
    • BugFix
  • 1.08
    • Add Designer Property Rotation - activates or deactivates the rotation during the movement
      • Default: True
  • 1.09
    • BugFixes
  • 1.10
    • Designer BugFixes
  • 1.11
    • BugFixes
    • Base_Resize is now Public
  • 2.00
    • Add Designer Property LazyLoading - activates lazy loading
      • Default: False
    • Add Designer Property LazyLoadingExtraSize - How many pages to load in advance
      • Default: 5
    • Add Event LazyLoadingAddContent - Add here your layout or views
    • Add get and set LazyLoadingExtraSize
    • Add Commit - Triggers the LazyLoadingAddContent event
      • Call this after you have added the cards
Have Fun :)
@Alexander Stolte
 

Attachments

  • ASSwipeCard Example.zip
    12 KB · Views: 604
  • ASSwipeCard.zip
    4.8 KB · Views: 586
Last edited:

Alexander Stolte

Expert
Licensed User
Longtime User
Update
  • 1.04
    • Add Designer Properties - If true then the previous card is shown as next card if you swipe in the right direction
      • SwipeLeft2Previous
      • SwipeRight2Previous
      • SwipeTop2Previous
      • SwipeBottom2Previous
Now, only issue which I see is when I slide to right (so I go one card back), then first is shown next card for a split of a second, and then it's replaced with previous one.
Any idea how to handle that?
I added this as an internal function, just set the designer property to "true" in the direction you want to show the previous card.
 

Drago Bratko

Active Member
Licensed User
Longtime User
Great, thank you.
I appreciate your support, and I have initiate second donation.

There is one more issue ... in my case, I would like that if one came to first card and swipe one more to right, that it goes to last one. And also if one goes to last card, and swipe left, that it goes to first card. So it would be like a loop.

I have done it in this way which is fine:
B4X:
Sub ASSwipeCard1_SwipeStateChanged(state As Int)
    If state = ASSwipeCard1.SwipeState_NEUTRAL Then
        Log("SwipeStateChanged: Neutral")
    else If state = ASSwipeCard1.SwipeState_TOP Then
        Log("SwipeStateChanged: Top")
        ASSwipeCard1.CurrentIndex = nCurrentIndex
        ToastMessageShow("LIKE", False)
    else If state = ASSwipeCard1.SwipeState_BOTTOM Then
        Log("SwipeStateChanged: Bottom")
        ASSwipeCard1.CurrentIndex = nCurrentIndex
        ToastMessageShow("DISLIKE", False)
    else If state = ASSwipeCard1.SwipeState_LEFT Then
        nCurrentIndex = CurIndexCalc(1)
        ASSwipeCard1.CurrentIndex = nCurrentIndex
    else If state = ASSwipeCard1.SwipeState_RIGHT Then
        nCurrentIndex = CurIndexCalc(-1)
        ASSwipeCard1.CurrentIndex = nCurrentIndex
    End If
End Sub

Sub CurIndexCalc(nValue As Int) As Int
    Dim nNewIndex As Int
    nNewIndex = nCurrentIndex + (nValue)
    If nNewIndex < 0 Then
        nNewIndex = ASSwipeCard1.Size -1
    Else If nNewIndex = ASSwipeCard1.Size Then
        nNewIndex = 0
    End If
    Return nNewIndex
End Sub

But, error happened in that edged cases
B4X:
Error occurred on line: 440 (ASSwipeCard)
java.lang.ArrayIndexOutOfBoundsException: length=33; index=-1
    at java.util.ArrayList.get(ArrayList.java:439)
    at anywheresoftware.b4a.objects.collections.List.Get(List.java:117)
    at softwise.swipe.example.asswipecard$ResumableSub_TouchHandler.resume(asswipecard.java:1887)
    at softwise.swipe.example.asswipecard._touchhandler(asswipecard.java:1267)
    at softwise.swipe.example.asswipecard._xpnl_cardbase_touch2(asswipecard.java:1993)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:176)
    at anywheresoftware.b4a.agraham.reflection.Reflection$7.onTouch(Reflection.java:1118)
    at android.view.View.dispatchTouchEvent(View.java:15195)
    ....

Thanks for checking it. :)
 

Alexander Stolte

Expert
Licensed User
Longtime User

Drago Bratko

Active Member
Licensed User
Longtime User
you dont need this code, just check the following Designer Property: "Swipe Right 2 Previous"

Heh, you are right. Swipe works perfectly in both directions. :)

Now, only when I came to last card and try to go to next one that it goes to first one (like in circle).
And also, when I came to first card and try to go to previous one that it goes to last one (like in circle).

How do you suggest to implement it?
 

Alexander Stolte

Expert
Licensed User
Longtime User
Update
  • 1.05
    • BugFixes for the Features of V1.04
Now, only when I came to last card and try to go to next one that it goes to first one (like in circle).
And also, when I came to first card and try to go to previous one that it goes to last one (like in circle).
try it now.
 

Drago Bratko

Active Member
Licensed User
Longtime User
Update
  • 1.05
    • BugFixes for the Features of V1.04

try it now.

Thank you.
Now I got this error :

B4X:
Error description: Undeclared variable 'swipecarditems' is used before it was assigned any value.
Error occurred on line: 334 (ASSwipeCard)
SwipeCardIemsList.Get(i).As(SwipeCardItems).xpnl_cardbase.Visible = False
 

Drago Bratko

Active Member
Licensed User
Longtime User
I don't have this error.
Do you have the latest version of the IDE?

☺️ You were right ... I didn't have latest IDE ... that solved issue with compiling.


But edge cases are still behaving same as before. (when I came to last card and try to go to next one and when I came to first card and try to go to previous one ... in both cases screen with no card is shown and no movements are possible any more).
 

Alexander Stolte

Expert
Licensed User
Longtime User
But edge cases are still behaving same as before. (when I came to last card and try to go to next one and when I came to first card and try to go to previous one ... in both cases screen with no card is shown and no movements are possible any more).
After all, that's the way it's meant to be. When this happens, you must decide what happens, you can then automatically display the 1st card or do something else.
No other card comes before the 1st card and the same after the last card. You have to decide what happens, the events work.
 

Drago Bratko

Active Member
Licensed User
Longtime User
After all, that's the way it's meant to be. When this happens, you must decide what happens, you can then automatically display the 1st card or do something else.
No other card comes before the 1st card and the same after the last card. You have to decide what happens, the events work.
OK, got it. I have implemented it in that way. Thank you.

Funny problem (still one) is that without problem I can reference to first card, but not to last card. Any idea why?

B4X:
    If state = ASSwipeCard1.SwipeState_LEFT Then
        If ASSwipeCard1.CurrentIndex = ASSwipeCard1.Size Then
            ASSwipeCard1.CurrentIndex = 0 ' that works
        End If
    else If state = ASSwipeCard1.SwipeState_RIGHT Then
        If ASSwipeCard1.CurrentIndex = -1 Then
            ASSwipeCard1.CurrentIndex = ASSwipeCard1.Size -2 ' that works
            'ASSwipeCard1.CurrentIndex = ASSwipeCard1.Size -1 ' that is not working
        End If
    End If
 

Drago Bratko

Active Member
Licensed User
Longtime User
looks like you reach the last card. I dont see a issue.

There are 25 cards in the deck.
I have swipe left 3 cards and then swipe one card right (back) ... and it went to that state.

If I swipe slowly (cca 1 sec per swipe) it's fine. But if I swipe faster like on the video, I can replicate it all the time.
Maybe it's related with that ...
 

wl

Well-Known Member
Licensed User
Longtime User
Nice library, looking into it....
One question though, while swiping the views/cards, visually the card that is swiped away moves but also partly rotates/pivots while moving.

Is it possible to have a simple move operation (to the left/top/right/bottom) without any rotation/pivot in the movement ?

Thanks
 

wl

Well-Known Member
Licensed User
Longtime User
Thanks :)

you dont need this code, just check the following Designer Property: "Swipe Right 2 Previous"

Trying to navigate back and forth between the cards depending on the swipe direction, but even with the mentionned properties it is not running correctly.

Property "SwipeRight 2 Previous" is set to true. I have no code interfering with the currentindex (yet)
I can swipe right to left to get the next card.
If I swipe left to right I get an empty card (even though I am on my second, third, ... card), and then I can't get any other card anymore

Any chance of having an example ?

ps: running in b4i

Thanks
 
Last edited:
Top