Friday, October 31, 2014

Loading ".gif" animation in android (a painless guide)

Today at eveing my friend asked me if I could manage to create a custom loading dialog with a gif in android.

He told me to use a .gif file and not use sprites (frames in xml). I searched online and found out that ImageView doesn't show animation. I thought of using Hipmob/gifanimateddrawable but it was not what my friend wanted.

So, I started from scratch and made my own view class.

public class GIFView extends View {
 private Movie movie;        //class that loads the animation
 private int gifID;         //stores the id of the drawable gif file
 private long movieStart;       //the time of start of movie
 private float x, y;         //stores the x and y position of the view from the parent layout

 public int getGifID() {
  return gifID;
 }

 public void setGifID(int gifID) {
  this.gifID = gifID;
 }

 public GIFView(Context context) {
  super(context);
 }

 public GIFView(Context context, AttributeSet attrs) {
  super(context, attrs);
  //initialize the view and the above variables from the attributes
  initializeView(context, attrs); 
 }


This class extends View class. And to load gif from drawable folder we will need an integer. I've used getter/setter for the gifID and the integers x and y will be explained in a moment. There isn't much about Movie class on developers.android.com. But by searching online I found a way to use that class.

private void initializeView(Context context, AttributeSet attrs) {                                    
        
        //the name of the stylable as defined in the attrs.xml
        TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.GIFView, 0, 0);
        
        //extract the src string
        String gifSource = a.getString(R.styleable.GIFView_src);
        String sourceName = Uri.parse(gifSource).getLastPathSegment()
                .replace(".gif", "");
        gifID = getResources().getIdentifier(sourceName, "drawable",
                getContext().getPackageName());
        a.recycle();
        
        //setting the x and y co-ordinate of the view
        x = getX();
        y = getY();
        if (gifID != 0) {
            InputStream is = getContext().getResources().openRawResource(gifID);
            movie = Movie.decodeStream(is);
            movieStart = 0;                                                    
        }
    }

The initializeView method initializes the gifID and the movie variable. Here we get the x and y co-ordinate of the view from the layout for future use. Now we will override the onDraw() method of the view class

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT);
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        super.onDraw(canvas);
        long now = android.os.SystemClock.uptimeMillis();

        if (movieStart == 0) {
            movieStart = now;
        }
        if (movie != null) {
            int relTime = (int) ((now - movieStart) % movie.duration());
            movie.setTime(relTime);
            movie.draw(canvas, x, y);
            this.invalidate();
        }
    }

Here we set canvas draw color to transparent, get the current time and then load the movie into the view. After that we invalidate so onDraw() method get called every time a new frame is to be loaded and that way we show the animation.

You can download the project from github.com

Tuesday, September 23, 2014

Dynamic Stack using struct in C

Here's a simple implementation of dynamic stack in c.

/*
 * ----------------------------------------------------------------------------
 * "THE BURGER-WARE LICENSE" (Revision 42):
 *  wrote this file. As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy me a burger in return. Abhishek Baddi
 * ----------------------------------------------------------------------------
 */

#include<stdio.h>
#include<stdlib.h>

struct stack {
    int *data;                          //the data will be saved via this pointer
    int size;                           //this is the size of the stack
    int cursor;                         //the current position of cursor
};

void init(struct stack *x, int s) {               //initialize a stack "x" of size "s"
    x->data = (int *) malloc(s*sizeof(int)+1);    //allocate space for "s" integers on the stack
    x->size = s;                                  //remember the size
    x->cursor = 0;                                //initialize the cursor to 0
}


void push(struct stack *x, int item) {                       //push an "item" onto the stack
    if(x->cursor<x->size) {                                  //check if cursor hasn't reached the end
        x->data[x->cursor++] = item;                         //if so, copy "item" and then increment cursor
    }
    else {                                                   //cursor is at the end
        printf("[Error: %d] Stack is full.\n", x->cursor);   //print the error
    }
    //printf("cursor = %d.\n", x->cursor);
}

int pop(struct stack *x) {                           //pop an "item" from the stack
    if(x->cursor>0) {                                //if cursor is not at the base
        x->cursor--;                                 //decrement the cursor first
        //printf("cursor = %d.\n", x->cursor);
        return x->data[x->cursor];                   //then return the "item"
                                                     //we don't bother to clear the memory here.
    }
    else {
        printf("[Error: %d] Stack is empty.\n", x->cursor);        //same as before
        //printf("cursor = %d.\n", x->cursor);
        return 0;                                                  //print the error and return 0;
    }
}

int del(struct stack *x) {                      //"del" frees up the memory allocated by malloc()
    free(x->data);                              //free() requires the pointer to the allocated memory
    printf("--------------\nFreed\n--------------\n");
}

int main() {
    struct stack stk;
    int i, j;
    init(&stk, 5);                              //we initialize a stack of 5 elements

    for(i=0; i<10; ++i) {                       //we push more elements than the stack can handle
        push(&stk, i);
        printf("Pushing %d onto the stack.\n", i);
        /*
        for(j=0;j<5;++j) {
            printf("stk.data[%d]=%d\n",j,stk.data[j]);      //printing the contents of the stack after every push
        }
        */
    }
    printf("--------------\nPushing over.\n--------------\n");

    for(i=0; i<10; ++i) {
        printf("Pop %dth element: %d\n", i, pop(&stk));
    }
    del(&stk);
    return 0;
}

Every line of the code is commented. So, it'll be easier to understand.

Saturday, July 5, 2014

Star Wars in ASCII

Almost everyone has watched Star Wars on television, computer or in a theater. But have you watched an ASCII version of Star Wars?

There is a complete copy of Star Wars done entirely in ASCII characters that you can watch in your terminal (command prompt) using telnet!

Here's how:
  1. Open the terminal ('cmd.exe' for windows).
  2. Type "telnet towel.blinkenlights.nl" and press Enter.



Now, did you enjoy watching this new version of Star Wars? Well, I did and know it for sure that you would have too.