Due to forced inactivity, I thought of converting
@Peter Simpson's excellent sample application into a class-based app. (I read Luca’s effort too late, otherwise I would have integrated some of his excellent ideas.)
It’s basically the same code as Peter’s, but reorganised to take advantage of classes, nothing earth-chattering but new B4X members may find this useful for comparison.
I tried to encapsulate the app functionality in 3 files.
1. A Card class (B4XCardView) that deals with aspects related to a playing card.
2. A Deck class (B4XDeck) that deals with aspects related to a deck. It contains, of course, a collection of cards, an array in fact.
3. The main module which has been tremendously simplified.
What are the Differences?
First, I have removed the dependency on Star-Dust’s library. Here are a few lines of code (thanks to codota.com) that I have translated into B4A to do the flipping action. Here it is, for people who are only interested in this aspect. You could modify the method so that it accepts a view parameter, but for efficiency, as this Method is part of a class, it acts on a global class variable.
Private Sub FlipImageBA (RotationX As Float, RotationY As Float, Rotation As Float)
jo = mBaxView
Dim PivotX As Float = mBaxView.Width/2.0f
Dim PivotY As Float = mBaxView.Height/2.0f
jo.RunMethod("setPivotX", Array As Object( PivotX ))
jo.RunMethod("setPivotY", Array As Object( PivotY ))
jo.RunMethod("setRotationX", Array As Object( RotationX ))
jo.RunMethod("setRotationY", Array As Object( RotationY ))
jo.RunMethod("setRotation", Array As Object( Rotation ))
jo.RunMethod("setCameraDistance", Array As Object(1280.0f * Density))
End Sub
Or you can use this bit of Java Code instead, though I’m not sure there’s any advantage here:
#IF JAVA
import android.widget.ImageView;
import android.util.DisplayMetrics;
public void flipImage (ImageView imageView, float RotationX, float RotationY, float Rotation, float CameraDistance)
{
//BA.LogInfo("flipImage: In");
/*---------------------------------------------------------------------------------------
//Better to use parameter CameraDistance as B4A already provides the information required.
//However, here's a way to do it:
DisplayMetrics metrics = getResources().getDisplayMetrics();
float CameraDistance = 1280.0f * (metrics.density * 160f);
----------------------------------------------------------------------------------------
*/
float PivotX = imageView.getWidth()/2.0f; //width centre
float PivotY = imageView.getHeight()/2.0f; //height centre
imageView.setPivotX(PivotX);
imageView.setPivotX(PivotX);
imageView.setPivotY(PivotY);
imageView.setRotationX(RotationX);
imageView.setRotationY(RotationY);
imageView.setRotation(Rotation);
imageView.setCameraDistance(CameraDistance);
//BA.LogInfo("flipImage: Out");
}
#End If
Second, as each card implements its own rotation and keep track of its angles, cards can spin together without any side effect. I have altered the rotate function so that it accepts a parameter (number of rotations required). It’s therefore possible to have the 12 cards rotating at the same time, but it’s rather slow in Debug mode, but fast in release mode.
Sub DeckCard_Click
Dim TappedCard As B4XCardView = Sender
TappedCard.Rotate(5)
End Sub
Third, by having the classes do the heavy lifting, the main module code is very simple and easy to maintain. For instance, when you create a new deck, you simply invoke the Shuffle method (B4XDeck.Shuffle) to shuffle it.
Fourth, I did not make B4XCardView a CustomView , but it would be easy to do so.
Here are a couple of links:
Project:
Download Project
Animation: