Monday, July 14, 2014

Use Shape and Animation for GridView Childs

Here we will use shape using xml file to make border on gridview child, fill them with shape too and then animated them.
  • Create new android project.
  • Create 2 xml files under drawable-mdpi : shape1.xml, shape2.xml. Shape1.xml draw rectangle with rounded corner used as border on gridview child as foreground and shape2.xml draw circle used to fill gridview chlid as background.
  • To animate gridview child create anim folder under res directory and create 3 xml files named rotate.xml, zoom.xml, blink.xml.
  • We will make 3x3 gridview and a textview to display what is happening in gridview childs.

Shape1.xml define hollow rectangle use <shape> with attribute rectangle. In element solid attribute color=#00000000 means transparent and corners radius=”10dp” means round the corners by 10dp. In shape2.xml just define circle using rounded corners rectangle. Attribute pivotX=50% and pivotY=50% in rotate.xml and zoom.xml mean that it will rotate or zoom base on 50% relative to itself, if 50 (without %) mean relative to parent. Blink.xml is self-explain. Interpolator is the rate of change in an animation.
Layout acivity_main.xml just set gridview with numColumns=”3” place it on the top and a textview below it to display what is happening in any gridview childs. In MainActivity.java inside onCreate inflate both gridview and textview. Set adapter for gridview to fill the childs foreground shape with shape1.xml, named ImageAdapter so that you need to create a new class called ImageAdapter.java that extent BaseAdapter just like in Android websites example. Also instantiate integer array wih length 9 called gride at beginning of class. Still inside onCreate load animation (rotate.xml, zoom.xml, blink.xml) using AnimationUtils.loadAnimation. Set onItemClickListener to define onItemClick callback methode in gridview and inside it set background shape for each gridview child use setBackgroundResource, play animation use setAnimation and display to textview. Using position set gridview child 0-2 (child position start with 0) to be rotated, child 3-5 zommed and 6-8 blinked.
Additionally to set width of gridview child use DisplayMetrics.withPixels to get screen width and then devided by three.

This project need android API 8 or above and already tested with emulator.

Here are complete codes :

shape1.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="rectangle">
    
    	<solid
    	    android:color="#00000000"/>
    	<stroke
    	    android:width="4dp"
    	    android:color="#ffff0000"/>
    	<corners
    	    android:radius="10dp"/>
    	
</shape>
shape2.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="rectangle">
    
    <solid
        android:color="#ff00ffff"/>
    <corners
        android:radius="50dp"/>
    
</shape>
rotate.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    
     <rotate
        android:duration="100"
        android:fromDegrees="-30"
        android:toDegrees="30"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="5"
        android:repeatMode="reverse"
        android:startOffset="0"
        android:interpolator="@android:anim/cycle_interpolator" />
     
</set>
zoom.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    
    <scale
        android:duration="1000"
        android:fromXScale="1"
        android:fromYScale="1"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="2"
        android:toYScale="2" 
        android:repeatCount="1"
        android:repeatMode="reverse"
        android:startOffset="0"
        android:interpolator="@android:anim/linear_interpolator" />
     
</set>
blink.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    
    <alpha
        android:duration="100"
        android:fromAlpha="0.0"
        android:toAlpha="1.0"
        android:startOffset="0"
        android:repeatCount="10"
        android:repeatMode="reverse"
        android:interpolator="@android:anim/accelerate_interpolator"/>

</set>
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ff000000"
    tools:context=".MainActivity" >

    <GridView
        android:id="@+id/gview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:numColumns="3"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true" />
    
    <TextView
    	android:id="@+id/tview"
    	android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/gview"
        android:layout_centerHorizontal="true" />

</RelativeLayout>
MainActivity.java
package com.example.gridview;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.Color;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
import android.widget.TextView;

public class MainActivity extends Activity 
{
	private GridView gview;
	private Animation gridanim1,gridanim2,gridanim3;
	public static int gwidth;
	private TextView tview;
	@Override
	protected void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		DisplayMetrics dmetrics = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(dmetrics);
		//gridview column width
		gwidth = dmetrics.widthPixels/3;
		
		//load animation
		gridanim1 = AnimationUtils.loadAnimation(this,R.anim.rotate);
		gridanim2 = AnimationUtils.loadAnimation(this,R.anim.zoom);
		gridanim3 = AnimationUtils.loadAnimation(this,R.anim.blink);
		
		
		gview = (GridView) findViewById(R.id.gview);
		// set imageadapter
		gview.setAdapter(new ImageAdapter(this));
		
		tview= (TextView) findViewById(R.id.tview);
		tview.setTextColor(Color.YELLOW);
		tview.setTextSize(20);
		
		gview.setOnItemClickListener(new OnItemClickListener() 
                {
    	           @Override
    	           public void onItemClick(AdapterView<?> parent, View v, 
                                            int position, long id) 
    	           {
    		      if(position<=2)
    		      {
    			// set background shape
    			  v.setBackgroundResource(R.drawable.shape2);
    			//play animation
	    		  v.setAnimation(gridanim1); 
	    		// display on textview
	    		  tview.setText("Gridview child "+position+" is shaking"); 
    		      }
    		      else if(position>2 & position<=5)
    		      {
    			  v.setBackgroundResource(R.drawable.shape2);
	    		  v.setAnimation(gridanim2);
	    		  tview.setText("Gridview child "+position+" is zooming");
    		      }
    		      else
    		      {
    			  v.setBackgroundResource(R.drawable.shape2);
	    		  v.setAnimation(gridanim3);
	    		  tview.setText("Gridview child "+position+" is blinking");
    		      }
    	           }
                });
   
	}
}
ImageAdapter.java
package com.example.gridview;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;

public class ImageAdapter extends BaseAdapter 
{
	private Context mcontext;
	private int[] gride=new int[9]; //set gridview size 3x3
	private int gwidth = MainActivity.gwidth; //gridview column width
	
	// imageadapter constructor
	public ImageAdapter(Context context)
	{
		mcontext = context;
	}
	
	@Override
	public int getCount() {return gride.length;}

	@Override
	public Object getItem(int arg0) {return null;}

	@Override
	public long getItemId(int arg0) {return 0;}
	
	public View getView(int position, View convertView, ViewGroup parent) 
	{
	      ImageView imageView;
	      if (convertView == null) 
	      {  
	         imageView = new ImageView(mcontext);
	         imageView.setLayoutParams(new GridView.LayoutParams(gwidth,gwidth));
	         imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
	        
	      } 
	      else {imageView = (ImageView) convertView;}
	      
	    //set foreground image (border gridview child)
	      imageView.setImageResource(R.drawable.shape1);
	      
	      return imageView;
	   }

}


No comments:

Post a Comment