tutorials – RaHaprogramming

Android – Working with XML Animations

Adding animations to your app interface will give high quality feel to your android applications. Animations can be performed through either XML or android code. In this tutorial i explained how to do animations using XML notations. I will explain how to do the same using android java code in future tutorials. Here i covered basic android animations like fade in, fade out, scale, rotate, slide up, slide down etc.

In the source code project provided in this tutorial, I wrote separate activity and XML for each animation. Download and play with the code to get familiar with the animations. Following are list of animations covered in this article.

android animations using xml

Basic steps to perform animation

Following are the basic steps to perform an animation on any UI element. Creating animation is very simple, all it needs is creating necessary files and write small pieces of code.

Step 1: Create xml that defines the animation

Create an xml file which defines type of animation to perform. This file should be located under anim folder under res directory (res ⇒ anim ⇒ animation.xml). If you don’t have anim folder in your res directory create one. Following is example of simple fade in animation.

android animation anim folder

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"android:fillAfter="true" > 

<alpha android:duration="1000"android:fromAlpha="0.0"android:interpolator="@android:anim/accelerate_interpolator"android:toAlpha="1.0" />

 </set>

Step 2: Load the animation

Next in your activity create an object of Animation class. And load the xml animation using AnimationUtils by calling loadAnimation function.

public class FadeInActivity extends Activity{

    TextView txtMessage;

    // Animation

    Animation animFadein;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_fadein);

        txtMessage = (TextView) findViewById(R.id.txtMessage);

        // load the animation

        animFadein = AnimationUtils.loadAnimation(getApplicationContext(),

                R.anim.fade_in);       

    }

}

Step 3: Set the animation listeners (Optional)

If you want to listen to animation events like start, end and repeat, your activity should implements AnimationListener. This step is optional. If you implement AnimationListener you will have to override following methods.

onAnimationStart – This will be triggered once the animation started
onAnimationEnd – This will be triggered once the animation is over
onAnimationRepeat – This will be triggered if the animation repeats

public class FadeInActivity extends Activity implements AnimationListener {

// set animation listener

animFadein.setAnimationListener(this);

// animation listeners

    @Override

    public void onAnimationEnd(Animation animation) {

        // Take any action after completing the animation

        // check for fade in animation

        if (animation == animFadein) {

            Toast.makeText(getApplicationContext(), “Animation Stopped”,

                    Toast.LENGTH_SHORT).show();

        }

    }

    @Override

    public void onAnimationRepeat(Animation animation) {

        // Animation is repeating

    }

    @Override

    public void onAnimationStart(Animation animation) {

        // Animation started

    }

Step 4: Finally start the animation

You can start animation whenever you want by calling startAnimation on any UI element by passing the type of animation. In this example i am calling fade in animation on TextView.

// start the animationtxtMessage.startAnimation(animFadein);

Complete Code

Following is complete code for FadeInActivity

public class FadeInActivity extends Activity implements AnimationListener {

    TextView txtMessage;

    Button btnStart;

    // Animation

    Animation animFadein;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        // TODO Auto-generated method stub

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_fadein);

        txtMessage = (TextView) findViewById(R.id.txtMessage);

        btnStart = (Button) findViewById(R.id.btnStart);

        // load the animation

        animFadein = AnimationUtils.loadAnimation(getApplicationContext(),

                R.anim.fade_in);

        // set animation listener

        animFadein.setAnimationListener(this);

        // button click event

        btnStart.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                txtMessage.setVisibility(View.VISIBLE);

                // start the animation

                txtMessage.startAnimation(animFadein);

            }

        });

    }

    @Override

    public void onAnimationEnd(Animation animation) {

        // Take any action after completing the animation

        // check for fade in animation

        if (animation == animFadein) {

            Toast.makeText(getApplicationContext(), “Animation Stopped”,

                    Toast.LENGTH_SHORT).show();

        }

    }

    @Override

    public void onAnimationRepeat(Animation animation) {

        // TODO Auto-generated method stub

    }

    @Override

    public void onAnimationStart(Animation animation) {

        // TODO Auto-generated method stub

    }

}

Important XML animation attributes

When working with animations it is better to have through knowledge about some of the important XML attributes which create major differentiation in animation behavior. Following are the important attributes you must known about.

android:duration – Duration of the animation in which the animation should complete

android:startOffset – It is the waiting time before an animation starts. This property is mainly used to perform multiple animations in a sequential manner

android:interpolator – It is the rate of change in animation

android:fillAfter – This defines whether to apply the animation transformation after the animation completes or not. If it sets to false the element changes to its previous state after the animation. This attribute should be use with <set> node

android:repeatMode – This is useful when you want your animation to be repeat

android:repeatCount – This defines number of repetitions on animation. If you set this value to infinite then animation will repeat infinite times

Some useful animations

Following i am giving xml code to perform lot of useful animations. Try to assign different values to xml attributes to see change in animations.

1. Fade In
2. Fade Out
3. Cross Fading
4. Blink
5. Zoom In
6. Zoom Out
7. Rotate
8. Move
9. Slide Up
10. Slide Down
11. Bounce
12. Sequential Animation
13. Together Animation

Fade In

For fade in animation you can use <alpha> tag which defines alpha value. Fade in animation is nothing but increasing alpha value from 0 to 1.

fade_in.xml

<?xml version=”1.0″ encoding=”utf-8″?>

<set xmlns:android=”http://schemas.android.com/apk/res/android

    android:fillAfter=”true” >

    <alpha android:duration=”1000″  android:fromAlpha=”0.0″

        android:interpolator=”@android:anim/accelerate_interpolator”

        android:toAlpha=”1.0″ />

</set>

Fade Out

Fade out is exactly opposite to fade in, where we need to decrease the alpha value from 1 to 0

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"android:fillAfter="true" > <alphaandroid:duration="1000"android:fromAlpha="1.0"android:interpolator="@android:anim/accelerate_interpolator"android:toAlpha="0.0" /> 

</set>

Cross Fading

Cross fading is performing fade in animation while other element is fading out. For this you don’t have to create separate animation file, you can just use fade_in.xml and fade_out.xml files.

In the following code i loaded fade in and fade out, then performed them on two different UI elements.

TextView txtView1, txtView2;

Animation animFadeIn, animFadeOut;

// load animations

animFadeIn = AnimationUtils.loadAnimation(getApplicationContext(),

                R.anim.fade_in);

animFadeOut = AnimationUtils.loadAnimation(getApplicationContext(),

                R.anim.fade_out);

// set animation listeners

animFadeIn.setAnimationListener(this);

animFadeOut.setAnimationListener(this);

// Make fade in elements Visible first

txtMessage2.setVisibility(View.VISIBLE);

// start fade in animation

txtMessage2.startAnimation(animFadeIn);

// start fade out animation

txtMessage1.startAnimation(animFadeOut);

Blink animation is animating fade out or fade in animation in repetitive fashion. For this you will have to set android:repeatMode=”reverse” and android:repeatCount attributes.

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"><alpha android:fromAlpha="0.0"android:toAlpha="1.0"android:interpolator="@android:anim/accelerate_interpolator"android:duration="600"android:repeatMode="reverse"android:repeatCount="infinite"/></set>

Zoom In

For zoom use <scale> tag. Use pivotX=”50%” and pivotY=”50%” to perform zoom from the center of the element. Also you need to use fromXScalefromYScale attributes which defines scaling of the object. Keep these value lesser than toXScaletoYScale

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"android:fillAfter="true" > <scalexmlns:android="http://schemas.android.com/apk/res/android"android:duration="1000"android:fromXScale="1"android:fromYScale="1"android:pivotX="50%"android:pivotY="50%"android:toXScale="3"android:toYScale="3" ></scale>
 </set>

Zoom Out

Zoom out animation is same as zoom in but toXScaletoYScale values are lesser than fromXScalefromYScale

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"android:fillAfter="true" > <scalexmlns:android="http://schemas.android.com/apk/res/android"android:duration="1000"android:fromXScale="1.0"android:fromYScale="1.0"android:pivotX="50%"android:pivotY="50%"android:toXScale="0.5"android:toYScale="0.5" ></scale> 
</set>

Rotate

Rotate animation uses <rotate> tag. For rotate animation required tags are android:fromDegrees and android:toDegrees which defines rotation angles.

Clock wise – use positive toDegrees value
Anti clock wise – use negative toDegrees value

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"><rotate android:fromDegrees="0"android:toDegrees="360"android:pivotX="50%"android:pivotY="50%"android:duration="600"android:repeatMode="restart"android:repeatCount="infinite"android:interpolator="@android:anim/cycle_interpolator"/> </set>

Move

In order to change position of object use <translate> tag. It uses fromXDeltafromYDelta for X-direction and toXDeltatoYDelta attributes for Y-direction.

<?xml version="1.0" encoding="utf-8"?><setxmlns:android="http://schemas.android.com/apk/res/android"android:interpolator="@android:anim/linear_interpolator"android:fillAfter="true"> <translateandroid:fromXDelta="0%p"android:toXDelta="75%p"android:duration="800" /></set>

Slide Up

Sliding animation uses <scale> tag only. Slide up can be achieved by setting android:fromYScale=”1.0″ and android:toYScale=”0.0″

<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"android:fillAfter="true" > <scaleandroid:duration="500"android:fromXScale="1.0"android:fromYScale="1.0"android:interpolator="@android:anim/linear_interpolator"android:toXScale="1.0"android:toYScale="0.0" /> </set>

Slide Down

Slide down is exactly opposite to slide down animation. Just interchange android:fromYScale and android:toYScale values.

<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"android:fillAfter="true"> <scaleandroid:duration="500"android:fromXScale="1.0"android:fromYScale="0.0"android:interpolator="@android:anim/linear_interpolator"android:toXScale="1.0"android:toYScale="1.0" /> </set>

Bounce

Bounce is just an animation effect where animation ends in bouncing fashion. For this set android:interpolator value to @android:anim/bounce_interpolator. This bounce can be used with any kind animation. Following slide down example uses bounce effect.

<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"android:fillAfter="true"android:interpolator="@android:anim/bounce_interpolator"> <scaleandroid:duration="500"android:fromXScale="1.0"android:fromYScale="0.0"android:toXScale="1.0"android:toYScale="1.0" /> </set>

Sequential Animation

If you want to perform multiple animation in a sequential manner you have to use android:startOffset to give start delay time. The easy way to calculate this value is to add the duration and startOffset values of previous animation. Following is a sequential animation where set of move animations performs in sequential manner.

<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"android:fillAfter="true"android:interpolator="@android:anim/linear_interpolator" > <!-- Use startOffset to give delay between animations -->  <!-- Move --><translateandroid:duration="800"android:fillAfter="true"android:fromXDelta="0%p"android:startOffset="300"android:toXDelta="75%p" /><translateandroid:duration="800"android:fillAfter="true"android:fromYDelta="0%p"android:startOffset="1100"android:toYDelta="70%p" /><translateandroid:duration="800"android:fillAfter="true"android:fromXDelta="0%p"android:startOffset="1900"android:toXDelta="-75%p" /><translateandroid:duration="800"android:fillAfter="true"android:fromYDelta="0%p"android:startOffset="2700"android:toYDelta="-70%p" /> <!-- Rotate 360 degrees --><rotateandroid:duration="1000"android:fromDegrees="0"android:interpolator="@android:anim/cycle_interpolator"android:pivotX="50%"android:pivotY="50%"android:startOffset="3800"android:repeatCount="infinite"android:repeatMode="restart"android:toDegrees="360" /> </set>

Together Animation

Performing all animation together is just writing all animations one by one without using android:startOffset

<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"android:fillAfter="true"android:interpolator="@android:anim/linear_interpolator" > <scalexmlns:android="http://schemas.android.com/apk/res/android"android:duration="4000"android:fromXScale="1"android:fromYScale="1"android:pivotX="50%"android:pivotY="50%"android:toXScale="4"android:toYScale="4" ></scale> <!-- Rotate 180 degrees --><rotateandroid:duration="500"android:fromDegrees="0"android:pivotX="50%"android:pivotY="50%"android:repeatCount="infinite"android:repeatMode="restart"android:toDegrees="360" /> </set>

I hope you like this tutorial, feel free to ask any kind of questions in the comment section.

TEXTUREVIEW: VIDEO CROPPING – FULL SCREEN VIDEO BACKGROUND IN ANDROID APPLICATIONS

Video Cropping

In this part of Android SurfaceView story we are going to create application which will do the following:

  • display video from assets folder using TextureView.
  • display a full screen background video without distorting the video size

This tutorial is derived from the creation of our latest app, TrackBack – available on the play store soon. Some XML names and items have been changed slightly to suite this tutorial. We used royalty free video and a basic video editor to adjust the video size and combine clips.

Final Results:

Step 1 – Preparing

Create Android project and target Android version 4.0. Make sure you have following lines in your AndroidManifest.xml file.

<uses-sdk
    android:minSdkVersion="14"
    android:targetSdkVersion="14"/>

Step 2 – XML

Copy a video file to your assets folder at res/raw. If raw doesn’t exist, make it.

In your values folder create dimen.xml file and add following lines.

<!-- common settings -->
<dimen name="padding_left_right">23dp</dimen>
<dimen name="margin_left_right">23dp</dimen>
<dimen name="margin_left_right_large">50dp</dimen>
<dimen name="margin_top_bottom">30dp</dimen>
<dimen name="margin_top_bottom_lg">90dp</dimen>
<dimen name="margin_btn_lg">50dp</dimen>
<dimen name="text_btn_lg">21dp</dimen>
<dimen name="margin_top_bottom_alt">45dp</dimen>
<dimen name="heading_lg">35sp</dimen>
<dimen name="heading_md">21sp</dimen>

In your values folder create string.xml file and add following lines – adjusting appropriately.

<!-- app required strings -->
<string name="app_name">TrackBack</string>
<!-- Strings related to login -->
<string name="welcome_login">Do you have an account? Sign in</string>
<string name="welcome_msg">Keep track of everyone and everything you love... in real time!</string>

In your layout folder create activity_video_crop.xml file or any appropriate name for this in your app.. and add following lines:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/welcome_constraint"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Activity_Welcome">

    <FrameLayout
        android:id="@+id/welcome_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <TextureView
        android:id="@+id/videoview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_gravity="center"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"

        >
    </TextureView>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorPrimarySeeThrough"
        >
    <ImageView
        android:layout_width="55dp"
        android:layout_height="55dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginTop="@dimen/margin_top_bottom_lg"
        android:id="@+id/welcome_logo"
        android:src="@drawable/logo_white"
        />
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/margin_left_right"
            android:id="@+id/welcome_text"
          app:layout_constraintTop_toBottomOf="@+id/welcome_logo"
            android:text="@string/app_name"
            android:textSize="@dimen/heading_lg"
            android:textColor="@color/white"
            android:textStyle="bold"
            android:textAlignment="center"
            />
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="90dp"
            android:layout_marginRight="@dimen/margin_left_right"
            android:layout_marginLeft="@dimen/margin_left_right"
            android:id="@+id/welcome_note_2"
          app:layout_constraintBottom_toBottomOf="@+id/btn_start"
            android:text="@string/welcome_msg"
            android:textSize="@dimen/heading_md"
            android:textColor="@color/white"
            android:backgroundTint="@color/white"
            android:textAlignment="center"
            />
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
           android:background="@drawable/rounded_top_bottom_blue"
            android:text=" Continue "
            android:textSize="@dimen/text_btn_lg"
            android:textAlignment="center"
            android:gravity="center"
            android:foregroundGravity="center"
            android:textColor="@color/slight_white"
     app:layout_constraintBottom_toBottomOf="@id/welcome_sign_in"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
       android:layout_marginBottom="@dimen/margin_top_bottom_alt"
            android:layout_marginLeft="@dimen/margin_btn_lg"
            android:layout_marginRight="@dimen/margin_btn_lg"
            android:id="@+id/btn_start"
            />
        <TextView
            android:id="@+id/welcome_sign_in"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            android:textSize="20dp"
            android:textColor="@color/slight_white"
            android:text="@string/welcome_login"
        android:layout_marginBottom="@dimen/margin_top_bottom_lg"
            />
    </androidx.constraintlayout.widget.ConstraintLayout>
    </FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

Note: All that’s required here is the FrameLayout and the TextureView. I prefer using ConstraintLayout as the root to easily position items.

Step 3 – Basic code

Create a new activity class and call it ActivityCrop or something appropriate. Don’t forget to declare it inside AndroidManifest.xml file.

Imports:

package com.rahaprogramming.trackback;

import android.content.Context;
import android.graphics.Matrix;
import android.graphics.SurfaceTexture;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Surface;
import android.view.TextureView;
import android.widget.FrameLayout;
import androidx.appcompat.app.AppCompatActivity;
public class Activity_Welcome extends AppCompatActivity implements
        TextureView.SurfaceTextureListener, MediaPlayer.OnCompletionListener {
    //declare class variables
    Context context = this;
    Uri video_uri;
    
    // MediaPlayer instance
    private MediaPlayer mMediaPlayer;
    //views
    private TextureView mTextureView;
    FrameLayout frameLayout;
    Surface surface;
    // Original video size - we created this video and knew the size.
    // for unknown size - use meta data
    private float mVideoWidth = 1080;
    private float mVideoHeight = 1440;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_welcome);
        //Toolbar toolbar = findViewById(R.id.toolbar);
        //setSupportActionBar(toolbar);
        video_uri = Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.trackback);

        //set views
        mTextureView = findViewById(R.id.videoview);
        mTextureView.setClickable(false);
        frameLayout = findViewById(R.id.welcome_frame);

        //init MediaPlayer
        mMediaPlayer = new MediaPlayer();

        //set implemented listeners
        mMediaPlayer.setOnCompletionListener(this);
        mTextureView.setSurfaceTextureListener(this);
    }
    //plays the video
    private void playVideo() {
        //its a big file - use separate thread
        new Thread(new Runnable() {
            public void run() {
                try {
                    mMediaPlayer.setDataSource(context,video_uri);
                    mMediaPlayer.setLooping(true);
                    mMediaPlayer.prepareAsync();
                    // Play video when the media source is ready for playback.
                    mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                        @Override
                        public void onPrepared(MediaPlayer mediaPlayer) {
                            mediaPlayer.start();
                        }
                    });
                } catch (Exception e) { // I can split the exceptions to get which error i need.
                    Utils.log("Error: "+e.toString());
                    e.printStackTrace();
                }
            }
        }).start();
    }
    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
        //set surface
        surface = new Surface(surfaceTexture);
        mMediaPlayer.setSurface(surface);
        //update viewable area
        updateTextureViewSize(width, height);
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) {
        //set surface
        surface = new Surface(surfaceTexture);
        mMediaPlayer.setSurface(surface);
        //update viewable area
        updateTextureViewSize(width, height);
    }

    //uses the view width to determine best crop to fit the screen
    //@param int viewWidth width of viewport
    //@param int viewHeight height of viewport
    private void updateTextureViewSize(int viewWidth, int viewHeight) {
        float scaleX = 1.0f;
        float scaleY = 1.0f;

        Utils.log(viewWidth+" "+viewHeight+" "+mVideoHeight+" "+mVideoWidth);
        if (mVideoWidth > viewWidth && mVideoHeight > viewHeight) {
            scaleX = mVideoWidth / viewWidth;
            scaleY = mVideoHeight / viewHeight;
        } else if (mVideoWidth < viewWidth && mVideoHeight < viewHeight) {
            scaleY = viewWidth / mVideoWidth;
            scaleX = viewHeight / mVideoHeight;
        } else if (viewWidth > mVideoWidth) {
            scaleY = (viewWidth / mVideoWidth) / (viewHeight / mVideoHeight);
        } else if (viewHeight > mVideoHeight) {
            scaleX = (viewHeight / mVideoHeight) / (viewWidth / mVideoWidth);
        }

        // Calculate pivot points, in our case crop from center
        int pivotPointX = viewWidth / 2;
        int pivotPointY = viewHeight / 2;

        Matrix matrix = new Matrix();
        matrix.setScale(scaleX, scaleY, pivotPointX, pivotPointY);
        //transform the video viewing size
        mTextureView.setTransform(matrix);
        //set the width and height of playing view
        mTextureView.setLayoutParams(new FrameLayout.LayoutParams(viewWidth, viewHeight));
        //finally, play the video
        playVideo();
    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {

    }

    // callback when the video is over
    public void onCompletion(MediaPlayer mp) {
        //if this happens.. never will.. just restart the video
        mp.stop();
        mp.release();
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mMediaPlayer != null) {
            // Make sure we stop video and release resources when activity is destroyed.
            mMediaPlayer.stop();
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
    }
}

Step 5 – Video cropping

The resizing is done by the updateTextureViewSize method. First we need to calculate scaleX and scaleY factor and set it to Matrix object using method setScale(..). Next pass this matrix to TextureView by setTransform(..) method and you are done.

//uses the view width to determine best crop to fit the screen
    //@param int viewWidth width of viewport
    //@param int viewHeight height of viewport
    private void updateTextureViewSize(int viewWidth, int viewHeight) {
        float scaleX = 1.0f;
        float scaleY = 1.0f;

        Utils.log(viewWidth+" "+viewHeight+" "+mVideoHeight+" "+mVideoWidth);
        if (mVideoWidth > viewWidth && mVideoHeight > viewHeight) {
            scaleX = mVideoWidth / viewWidth;
            scaleY = mVideoHeight / viewHeight;
        } else if (mVideoWidth < viewWidth && mVideoHeight < viewHeight) {
            scaleY = viewWidth / mVideoWidth;
            scaleX = viewHeight / mVideoHeight;
        } else if (viewWidth > mVideoWidth) {
            scaleY = (viewWidth / mVideoWidth) / (viewHeight / mVideoHeight);
        } else if (viewHeight > mVideoHeight) {
            scaleX = (viewHeight / mVideoHeight) / (viewWidth / mVideoWidth);
        }

        // Calculate pivot points, in our case crop from center
        int pivotPointX = viewWidth / 2;
        int pivotPointY = viewHeight / 2;

        Matrix matrix = new Matrix();
        matrix.setScale(scaleX, scaleY, pivotPointX, pivotPointY);
        //transform the video viewing size
        mTextureView.setTransform(matrix);
        //set the width and height of playing view
        mTextureView.setLayoutParams(new FrameLayout.LayoutParams(viewWidth, viewHeight));
        //finally, play the video
        playVideo();
    }

Step 6 – Launch

When you launch application, you should notice that video is cropped correctly and displayed properly now. Of course, when width to height ratio is too big, video looses it quality as is scaled too much – as inImageView.setScaleType(ImageVIew.ScaleType.CENTER_CROP);

Dogecoin Mining: How to Mine Dogecoin – Beginners Guide

So, where would you like to start? The beginning? Great choice. Let’s have a quick look at how Dogecoin got started.

Table of Contents

  • 1. A (Very) Short History of Dogecoin
  • 2. Understanding Crypto Mining Bottom Line
  • 3. What is Dogecoin Mining?
  • 4.Mining Comparison
  • 5. How to Mine Dogecoin  
  • 5.1. Dogecoin Mining: Solo vs Pool
  • 5.2. What You Need To Start Mining Dogecoin
  • 5.3. Dogecoin Mining Hardware
  • 5.4. Dogecoin Mining Software
  • 5.5. Dogecoin Cloud Mining
  • 6. So, Is Dogecoin Mining Profitable?

A (Very) Short History of Dogecoin

In 2013, an Australian named Jackson Palmer and an American named Billy Markus became friends. They became friends because they both liked cryptocurrencies. However, they also thought the whole thing was getting too serious so they decided to create their own.

Palmer and Markus wanted their coin to be more fun and more friendly than other crypto coins. They wanted people who wouldn’t normally care about crypto to get involved.

Dogecoin mining: Dogecoin homepage.

They decided to use a popular meme as their mascot — a Shiba Inu dog.

Dogecoin was launched on December 6th2013. Since then it has become popular because it’s playful and good-natured. Just like its mascot!

Dogecoin has become well-known for its use in charitable acts and online tipping. In 2014, $50,000 worth of Dogecoin was donated to the Jamaican Bobsled Team so they could go to the Olympics. Dogecoin has also been used to build wells in KenyaIsn’t that awesome!

Users of social platforms – like Reddit – can use Dogecoin to tip or reward each other for posting good content.

Dogecoin has the 27th largest market cap of any cryptocurrency.

Note: A market cap (or market capitalization) is the total value of all coins on the market.

So, Dogecoin is a popular altcoin, known for being fun, friendly and kind. It’s a coin with a dog on it! You love it already, don’t you?

Next, I want to talk about how mining works

Understanding Crypto Mining Bottom Line

To understand mining, you first need to understand how cryptocurrencies work. Cryptocurrencies are peer-to-peer digital currencies. This means that they allow money to be transferred from one person to another without using a bank.

Every cryptocurrency transaction is recorded on a huge digital database called a blockchain. The database is stored across thousands of computers called nodes. Nodes put together groups of new transactions and add them to the blockchain. These groups are called blocks.

Each block of transactions has to be checked by all the nodes on the network before being added to the blockchain. If nodes didn’t check transactions, people could pretend that they have more money than they really do (I know I would!).

Confirming transactions (mining) requires a lot of computer power and electricity so it’s quite expensive.

Blockchains don’t have paid employees like banks, so they offer a reward to users who confirm transactions. The reward for confirming new transactions is new cryptocurrency. The process of being rewarded with new currency for confirming transactions is what we call “mining”!

Dogecoin mining meme

It is called mining because it’s a bit like digging for gold or diamonds. Instead of digging with a shovel for gold, you’re digging with your computer for crypto coins!

Each cryptocurrency has its own blockchain. Different ways of mining new currency are used by different coins where different rewards are offered.

So, how do you mine DogecoinWhat’s special about Dogecoin mining? Let’s see…

What is Dogecoin Mining?

Dogecoin mining is the process of being rewarded with new Dogecoin for checking transactions on the Dogecoin blockchain. Simple, right? Well no, it’s not quite that simple, nothing ever is!

Mining Dogecoin is like a lottery. To play the lottery you have to do some work. Well, actually your computer (or node) has to do some work! This work involves the confirming and checking of transactions which I talked about in the last section.

Purchasing Dogecoin takes much less effort, especially when using Binance or Kraken. This is the time when Dogecoin reached its all-time high and keeps increasing in price significantly. So if you do it now, you might still get on that train! The price of Dogecoin increased by more than 300% percent in one day, as you can see in the chart below.Buy Dogecoin: Dogecoin price.Buy Dogecoin on Binance NOW!

Lots of computers work on the same block of transactions at the same time but the only one can win the reward of new coins. The one that earns the new coins is the node that adds the new block of transactions to the old block of transactions. This is completed using complex mathematical equations.

The node that solves the mathematical problem first wins! It can then attach the newly confirmed block of transactions to the rest of the blockchain.

Most cryptocurrency mining happens this way. However, Dogecoin mining differs from other coins in several important areas. These areas are:

  • Algorithm: Each cryptocurrency has a set of rules for mining new currency. These rules are called a mining or hashing algorithm.
  • Block Time: This is the average length of time it takes for a new block of transactions to be checked and added to the blockchain.
  • Difficulty: This is a number that represents how hard it is to mine each new block of currency. You can use the difficulty number to work out how likely you are to win the mining lottery. Mining difficulty can go up or down depending on how many miners there are. The difficulty is also adjusted by the coin’s protocol to make sure that the block time stays the same.
  • Reward: This is the amount of new currency that is awarded to the miner of each new block.

Now, let’s compare how DogeCoin mining works compared to Litecoin and Bitcoin

Mining Comparison

 LitecoinBitcoinDogecoin
AlgorithmScryptSHA-256Scrypt
Difficult6802626.09553511060552899.722798252.1991
Block Time (In Minutes)2.5101
Reward (Per Block)2512.510,000
Reward (Per Block in USD)3,027.3586,391.6327.36

Source: www.coinwarz.com

Bitcoin uses SHA-256 to guide the mining of new currency and the other two use Scrypt. This is an important difference because Scrypt mining needs a lot less power and is a lot quicker than SHA-256. This makes mining easier for miners with less powerful computers. Fans of Litecoin and Dogecoin think that they are fairer than Bitcoin because more people can mine them.

Note: In 2014, Litecoin and Dogecoin merged mining. This means they made it possible to mine both coins in the same process. Dogecoin mining is now linked with Litecoin mining. It’s like two different football teams playing home games in the same stadium!

Mining Dogecoin is a lot faster than mining Litecoin or Bitcoin. The block reward is much higher too!

Don’t get too excited though (sorry!). Dogecoin is still worth a lot less than Bitcoin and Litecoin. A reward of ten thousand Dogecoin is worth less than thirty US Dollars. A reward of 12.5 Bitcoin is currently worth 86,391.63 US Dollars! 

Dogecoin Mining: How to Mine Dogecoin - Beginners Guide

Note: The numbers might be slightly different by the time you’re reading this guide. 

However, it’s not as bad as it sounds. Dogecoin mining difficulty is more than one million times less than Bitcoin mining difficulty. This means you are much more likely to win the block reward when you mine Dogecoin.

Now I’ve told you about what Dogecoin mining is and how it works, would you like to give it a try?

Let’s see what you need to do to become a Dogecoin miner…

How to Mine Dogecoin  

There are two ways to mine Dogecoinsolo (by yourself) or in a Dogecoin mining pool.

Note: A Dogecoin pool is a group of users who share their computing power to increase the odds of winning the race to confirm transactions. When one of the nodes in a pool confirms a transaction, it divides the reward between the users of the pool equally.

Dogecoin Mining: Solo vs Pool

When you mine as a part of a Dogecoin pool, you have to pay fees. Also, when the pool mines a block you will only receive a small portion of the total reward. However, pools mine blocks much more often than solo miners. So, your chance of earning a reward (even though it is shared) is increased. This can provide you with a steady new supply of Dogecoin.

If you choose to mine solo then you risk waiting a long time to confirm a transaction because there is a lot of competition. It could be weeks or even months before you mine your first block! However, when you do win, the whole reward will be yours. You won’t have to share it or pay any fees.

As a beginner, I would recommend joining a Dogecoin pool. This way you won’t have to wait as long to mine your first block of new currency. You’ll also feel like you’re part of the community and that’s what Dogecoin is all about!

What You Need To Start Mining Dogecoin

Before you start Dogecoin mining, you’ll need a few basics. They are:

  • A PC with either Windows, OS X or Linux operating system.
  • An internet connection.
  • A Shiba Inu puppy (just kidding!).

You’ll also need somewhere to keep the Dogecoin you mine. It’s not recommended to choose online wallets, pick software or hardware wallets instead. They include Ledger Nano STrezor Model T and Coinbase. The latter option is a software wallet, whereas the first two are hardware wallets. 

Note: A wallet is like an email account. It has a public address for sending/receiving Dogecoin and a private key to access them. Your private keys are like your email’s password. Private keys are very important and need to be kept completely secure. 

dogecoin mining

There are two different types; a light wallet and a full wallet. To mine Dogecoin, you’ll need the full wallet. It’s called Dogecoin Core.

Now that you’ve got a wallet, you need some software and hardware.

Dogecoin Mining Hardware

You can mine Dogecoin with:

  • Your PC’s CPU: The CPU in your PC is probably powerful enough to mine Dogecoin. However, it is not recommended. Mining can cause less powerful computers to overheat which causes damage.
  • A GPU: GPUs (or graphics cards) are used to improve computer graphics but they can also be used to mine Dogecoin. There are plenty of GPUs to choose from but here are a few to get you started:
  • A Scrypt ASIC Miner: This is a piece of hardware designed to do one job only. Scrypt ASIC miners are programmed to mine scrypt based currencies like Litecoin and Dogecoin. ASIC miners are very powerful. They are also very expensive, very loud and can get very hot! Here’s a few for you to check out:
    • Innosilicon A2 Terminator ($760)
    • Bitmain Antminer L3 ($1,649)
    • BW L21 Scrypt Miner ($7,700)

Dogecoin Mining Software

Whether you’re mining with an ASIC, a GPU or a CPU, you’ll need some software to go with it. You should try to use the software that works best with the hardware you’re using. Here’s a short list of the best free software for each choice of mining hardware;

  • CPU: If you just want to give mining a quick try, using your computer’s CPU will work fine. The only software I would recommend for mining using a CPU only is CPU miner which you can download for free here.
  • GPU: If you mine with a GPU there are more software options. Here are a few to check out;
    • CudaMiner–  Works best with Nvidia products.
    • CGminer–  Works with most GPU hardware.
    • EasyMiner–  User-friendly, so it’s good for beginners.
  • Scrypt ASIC miner:
    • MultiMiner– Great for mining scrypt based currencies like Litecoin and Dogecoin. It can also be used to mine SHA-256 currencies like Bitcoin.
    • CGminer and EasyMiner can also be used with ASIC miners.

Recommendations

You’re a beginner, so keep it simple! When you first start mining Dogecoin I would recommend using a GPU like the Radeon RX 580 with EasyMiner software. Then I would recommend joining a Dogecoin mining pool. The best pools to join are multi-currency pools like Multipool or AikaPool.

Dogecoin Mining: How to Mine Dogecoin - Beginners Guide

If you want to mine Dogecoin but don’t want to invest in all the tech, there is one other option…

Dogecoin Cloud Mining

Cloud mining is mining without mining! Put simply, you rent computer power from a huge data center for a monthly or yearly fee. The Dogecoin is mined at the center and then your share is sent to you.

All you need to cloud mine Dogecoin is a Dogecoin wallet. Then choose a cloud mining pool to join. EobotNice Hash and Genesis Mining all offer Scrypt-based cloud mining for a monthly fee.

There are pros and cons to Dogecoin cloud mining.

The Pros

  • It’s cheaper than setting up your own mining operation. There’s also no hot, noisy hardware lying around the house!
  • As a beginner, there isn’t a lot of technical stuff to think about.
  • You get a steady supply of new currency every month.

The Cons

  • Cloud mining pools don’t share much information about themselves and how they work. It can be hard to work out if a cloud mining contract is a good value for money.
  • You are only renting computer power. If the price of Dogecoin goes down, you will still have to pay the same amount for something that is worthless.
  • Dogecoin pools have fixed contracts. The world of crypto can change very quickly. You could be stuck with an unprofitable contract for two years!
  • It’s no fun letting someone else do the mining for you!

Now you know about all the different ways to mine Dogecoin we can ask the big question, can you make tons of money mining Dogecoin?

So, Is Dogecoin Mining Profitable?

The short answer is, not really. Dogecoin mining is not going to make you a crypto billionaire overnight. One Dogecoin is worth about 0.05 US Dollars.

If you choose to mine Dogecoin solo, it will be difficult to make a profit. You will probably spend more money on electricity and hardware than you will make from Dogecoin mining. Even if you choose a Dogecoin pool or a cloud pool your profits will be small.

However, if you think I am telling you to not mine Dogecoin, then you’re WRONG! Of course, I think you should mine Dogecoin, however, there are simply better ways to make money with DOGE. One of the best options is to start trading. If you decide to do that it’s recommended to choose reliable crypto exchanges, such as Binance.

Make sure not to keep your cryptocurrencies in an online wallet, choose secure wallets instead. Such options include Ledger Nano X and Trezor Model T

But why? Seriously…

Well, you should mine Dogecoin because it’s fun and you want to be a part of the Dogecoin family. Cryptocurrency is going to change the world and you want to be part of that change, right? Mining Dogecoin is a great way to get involved.

Dogecoin is the coin that puts a smile on people’s faces. By mining Dogecoin you’ll be supporting all the good work its community does. You’ll learn about mining from the friendliest gang in crypto. And who knows? In a few years, the Dogecoin you mine now could be worth thousands or even millions! In 2010, Bitcoin was worthless. Think about that!

Only you can choose whether to mine Dogecoin or not. You now know everything you need to know to make your choice. The future is here. So, what are you going to do?