Flip Coin Source Code Android Java

If you are searching for a Flip Coin Source Code Android example, this guide will walk you through building a realistic coin flip animation in Android using Java. This example includes sound effects, both sides of the coin visible during flipping, and a clean user interface built with ConstraintLayout.

Why Use This Flip Coin Source Code Android Example?

This project is perfect for beginners and intermediate developers who want to learn about animations, MediaPlayer usage, and responsive layouts. Whether you are creating a decision-making app, a fun game, or just experimenting with Android animations, this Flip Coin Source Code Android will save you time and effort.

Flip Coin Source Code Android – MainActivity.java


public class MainActivity extends AppCompatActivity {

    ImageView coinImage;
    Button btnShowSides, btnFlip;
    int side = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });
        // Set status bar color to black
        getWindow().setStatusBarColor(ContextCompat.getColor(this, R.color.black));

        coinImage = findViewById(R.id.coinImage);
        btnShowSides = findViewById(R.id.btnShowSides);
        btnFlip = findViewById(R.id.btnFlip);
        coinImage.setImageResource(R.drawable.head); //  Set initial image
        btnFlip.setEnabled(true);

        btnShowSides.setOnClickListener(view -> {
            showBothSidesInstant();

        });

        btnFlip.setOnClickListener(view -> flipCoinRealistically());
    }


    private void showBothSidesInstant() {
        if (side == 0) {
            coinImage.setImageResource(R.drawable.tail);
            side = 1;
        } else {
            coinImage.setImageResource(R.drawable.head);
            side = 0;
        }
    }

    private void flipCoinRealistically() {
        boolean isHeads = new Random().nextBoolean();

        // Optional: play coin flip sound
        MediaPlayer mp = MediaPlayer.create(this, R.raw.coin_sound);
        mp.start();
        mp.setOnCompletionListener(MediaPlayer::release);

        // Track which side is showing
        final boolean[] showingHeads = {true};

        // Listener to change image mid-flip
        ValueAnimator flipAnimator = ValueAnimator.ofFloat(0f, 1f);
        flipAnimator.setDuration(5000); // total time
        flipAnimator.setInterpolator(new LinearInterpolator());
        flipAnimator.addUpdateListener(animation -> {
            float progress = (float) animation.getAnimatedValue();
            float totalRotation = progress * 4320f; // 12 full flips (10 fast + 2 slow)
            coinImage.setRotationX(totalRotation);

            // At every 180°, swap image
            if ((int) (totalRotation / 180) % 2 == 0 && !showingHeads[0]) {
                coinImage.setImageResource(R.drawable.head);
                showingHeads[0] = true;
            } else if ((int) (totalRotation / 180) % 2 != 0 && showingHeads[0]) {
                coinImage.setImageResource(R.drawable.tail);
                showingHeads[0] = false;
            }
        });

        // When done, show final result
        flipAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                coinImage.setRotationX(0f);
                coinImage.setImageResource(isHeads ? R.drawable.head : R.drawable.tail);
            }
        });

        flipAnimator.start();
    }
    
}

Flip Coin Source Code Android – XML Layout (activity_main.xml)


<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#121212"
    android:padding="24dp">

    <ImageView
        android:id="@+id/coinImage"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_marginTop="80dp"
        android:contentDescription="Coin Image"
        android:scaleType="centerInside"
        android:src="@drawable/head"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btnShowSides"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="40dp"
        android:backgroundTint="#2196F3"
        android:text="Show Both Sides"
        android:textColor="#FFFFFF"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/coinImage" />

    <Button
        android:id="@+id/btnFlip"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:backgroundTint="#4CAF50"
        android:enabled="false"
        android:text="Flip Coin"
        android:textColor="#FFFFFF"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/btnShowSides" />

</androidx.constraintlayout.widget.ConstraintLayout>


How to Implement Flip Coin Source Code Android

  1. Copy the Java code into your MainActivity.java file.
  2. Replace the XML layout with the one provided above.
  3. Add head.png and tail.png images in your drawable folder.
  4. Add a coin_sound.mp3 in your res/raw folder.
  5. Run the app to enjoy realistic coin flipping.

Learn More About Android Development

For more details on animations and UI components, check out the Official Android Developer Documentation. You can also explore my Blog for more examples.

This Flip Coin Source Code Android project is easy to customize and can be integrated into decision-making apps, games, or entertainment tools.

Swipe and Tap Card Animation in Jetpack Compose

Creating an interactive card-based interface in Jetpack Compose is easier than ever. Today, we will explore how to implement a smooth Card Animation in Jetpack using swipe or tap gestures on cards with the CardSwipeOrTap composable. This approach is perfect for modern UI designs where users interact with content via gestures.

Main Activity Setup

We start by setting up the MainActivity that uses a Scaffold layout inside the RecyclerViewTheme. This ensures that our UI fills the entire screen while providing padding to our card interactions.

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            RecyclerViewTheme {
                Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
                    CardSwipeOrTap(modifier = Modifier.padding(innerPadding))
                }
            }
        }
    }
}

Building the Card Swipe or Tap Composable

The CardSwipeOrTap composable manages the card stack. It uses a Box to overlay cards on top of each other and applies a slight rotation and vertical offset for a realistic stacked effect.

Each card is individually rendered using the CardItem composable. We use a simple CoroutineScope to delay actions and allow for smooth animations between swipe or tap events.

@Composable
fun CardSwipeOrTap(modifier: Modifier = Modifier) {
    val scope = rememberCoroutineScope()
    var cards by remember { mutableStateOf(listOf(0, 1, 2)) }
    var isAnimating by remember { mutableStateOf(false) }

    val cardColors = listOf(
        Color(0xFFFF9800), // Orange
        Color(0xFFF44336), // Red
        Color(0xFF00E676)  // Light Green
    )

    Box(
        modifier = modifier.fillMaxSize().padding(32.dp),
        contentAlignment = Alignment.Center
    ) {
        cards.reversed().forEachIndexed { index, cardIndex ->
            CardItem(
                index = cardIndex,
                color = cardColors[cardIndex % cardColors.size],
                rotation = if (index == 0) 0f else if (index == 1) -10f else 10f,
                offsetY = (index * 20).dp,
                isTop = index == cards.size - 1,
                isAnimating = isAnimating,
                onSwiped = {
                    if (!isAnimating) {
                        isAnimating = true
                        scope.launch {
                            kotlinx.coroutines.delay(300)
                            val updated = cards.toMutableList()
                            val removed = updated.removeAt(0)
                            updated.add(removed)
                            cards = updated
                            isAnimating = false
                        }
                    }
                }
            )
        }
    }
}

Animating Card Movement with CardItem

The CardItem composable handles the animation when a user swipes or taps a card. It uses animateDpAsState and animateFloatAsState to animate the card’s offset and opacity, giving the appearance of a disappearing card when an interaction occurs.

@Composable
fun CardItem(
    index: Int,
    color: Color,
    rotation: Float,
    offsetY: Dp,
    isTop: Boolean,
    isAnimating: Boolean,
    onSwiped: () -> Unit
) {
    val animatedOffsetX by animateDpAsState(
        targetValue = if (isAnimating && isTop) 500.dp else 0.dp,
        animationSpec = if (isAnimating && isTop) tween(durationMillis = 500, easing = FastOutLinearInEasing) else snap(),
        label = "OffsetXAnimation"
    )

    val animatedAlpha by animateFloatAsState(
        targetValue = if (isAnimating && isTop) 0f else 1f,
        animationSpec = if (isAnimating && isTop) tween(durationMillis = 3000) else snap(),
        label = "AlphaAnimation"
    )

    Card(
        modifier = Modifier
            .fillMaxWidth(0.7f)
            .aspectRatio(1f)
            .offset(x = animatedOffsetX, y = offsetY)
            .graphicsLayer {
                rotationZ = rotation
                alpha = animatedAlpha
            }
            .pointerInput(isTop) {
                if (isTop && !isAnimating) {
                    detectDragGestures(
                        onDragEnd = { onSwiped() },
                        onDrag = { change, _ -> change.consume() }
                    )
                }
            }
            .pointerInput(isTop) {
                if (isTop && !isAnimating) {
                    detectTapGestures(
                        onTap = { onSwiped() }
                    )
                }
            },
        elevation = CardDefaults.cardElevation(defaultElevation = 8.dp),
        shape = RoundedCornerShape(20.dp),
        colors = CardDefaults.cardColors(
            containerColor = color,
            contentColor = Color.White
        )
    ) {
        Box(
            modifier = Modifier.fillMaxSize(),
            contentAlignment = Alignment.Center
        ) {
            Text(
                text = "Card #$index",
                style = MaterialTheme.typography.titleLarge,
                color = Color.White
            )
        }
    }
}


Final Thoughts for Card Animation in Jetpack

With just a few lines of Kotlin code, you can create a stunning card swipe and tap animation in Jetpack Compose. This approach is not only visually appealing but also highly interactive, offering a smooth user experience without the complexity of a traditional RecyclerView setup. Try it out in your next Android app project!

You can also read the official Jetpack Compose animation documentation.