Thursday, 17 September 2015

Ripple Effect in android for prelollipop devices

Hey, aren't you amused with the new ripple effect released with android 5.0. If you want the same effect in pre-lollipop device, then you could try this Library. With the few line of code you could get the same ripple effect as in android 5.0. More than that you could perform more operation on that. Check out the below code snippet

yourview.setOnClickListener(new View.OnClickListener() {
@Overridepublic void onClick(View view) {
        RippleView rippleView = new RippleView(MainActivity.this);

//finally call it to make ripples        rippleView.initRipple(view, viewParent);
        }
        });


Operations you could perform:-
  1. Change the ripple color.
  2. Change the ripple frequency.
  3. Change the ripple size

Material Design : Material in Depth

Hello Everyone , Today we are going in depth of the Material of Material Design. We will look for the answers of, What exactly the material is, what are the properties of the material, how it can play a crucial role to give a an attractive and meaningful looks to android. 1. Environment a. 3D World enviornmentA Surrounding or a 3D place where the material can place is called the material Environment. As you can see in the image the Edges of the device represent specific axis. Height of the device represent the Y axis, Width represents the X axis and thickness is used for Z-axis. b. Light and Shadow Within Material Environment, Virtual lights illuminate scene. There are two sources of light in the environment shadow cast    1. Key Light It creates directional shadow, which means the source of light is somewhere above the material throwing light at some angle. 2. Ambient Light It creates soft shadows from all angles, which means the light sources is placed exactly perpendicular to the material. ambient light In real time shadows are the result of obstruction of light by an object , similarly in android when material obstruct the light along z axis creates shadows. 2. Material Properties &npsb&npsba. Physical Properties 1. Materials May have varied height and width but with uniform thickness. As shown in the pictures, this way of representing material where the thickness is varying is not allowed. 2. Shadows cast should be natural, shadows must relate with relative elevation between material elements for a more natural feel. 3. Contents of any shape and color can be displayed within the material. Content thickness doesn't not effect the material thickness 4. Contents inside the material can behave like an independent object and can transform into different shape and size and can easily move along the material plane, but all happens within the bounds of the material. 5. Materials are solid. Thus, input event cannot pass through the material as shown in figure. This represents that the focus goes to below this material which is not recommended. 6.Material cannot occupy same dimension in space. If any such requirement you have, then use elevation technique to separate them in space. Here the way they are placed do not give a cue that the material is placed above the other material, it more looks like both the material gets dissolve together. 7. According to the physics two solids cannot penetrate each other, the similar behavior applied with material which restrict them to pass from one another. b. Transforming Properties - Material can change shape. Material can shrink or grow along its plane But material can not bend or folds. Concatenating two material sheet is allowed to make a single sheet of material. Material can split into parts and can join to regain its original state. c. Movement of Material Material can spontaneously generated and destroyed anywhere in the environment. Material can move along any axis. And Z-axis motion is specially a result of user interaction with the material. Objects in 3D Space:- Objects in the material design obey the same physical law which are applied for an real time object. They possessed the similar qualities of an real time object. Objects can stacked or affixed to one another, cast shadows and reflect light. So some points which we need to care while the development of an app, is The Objects Elevation and its relationship with the rest of the objects in the material environment. So lets look into Elevation first , and see how does it gives a real time effect in android. a. Elevation Its a relative difference between the two surfaces along z axis, its generally measured in dp. We can account the elevation difference between two objects by measuring difference from the top of one's surface to top of another one. Resting Elevation : Its a default elevation of an object, whenever any event results to change the elevation of that object as soon as the event completed the object must come back to its original elevation or the resting elevation. Responsive elevation and dynamic elevation Some components perform responsive elevation, the states like focused , pressed or normal which depends on the user input type may results for different elevation on different state. These elevation changes implemented through dynamic elevation offset. Dynamic elevation offset is the goal elevation for the component to move towards, relative to the component's resting state. They also ensure that the elevation changes are


whatismaterial_3d_elevation5consistent across actions and component types.
Here for example , if we are declaring the offset of 6dp for a particular state then for each component at that particular state the elevation raise would be 6 dp. Functional Shadows Shadows provides visual cues to objects depth and directional movement. Shadows can hint the amount of separation between two surfaces. We can determine the object's elevation by its shadow. And when objects are in motion its quite easy to determine the direction movement of the object by the appearance of its shadow. Like increase in elevation of an object results more dark and large shadow. b. Object Relationship Object Hierarchy a. Objects can moved independent to each other or constrained by objects higher in hierarchy b. All objects are a part of hierarchy, which defines the Parent child relationship c. Parent child relationship defines - Each object has one parent - Each object may have any number of child. - Children inherit trans formative properties from their parents - Siblings are objects at same level of hierarchy Exception There are some exceptions which do not follow the parent child relationship. Some primary UI elements, does not effect by the transformation of the other element in the layout. Views like, Floating action button, Navigation Drawer, Action Bar and Dialog they do not effect by the change in the state of their parent. Interaction Child having a relationship with their parents, must have minimal z axis elevation, so that no other object gets inserted in between them. Reference :- MATERIAL DESIGN ANDROID

Material Design : Goals & Principle

Hello Everyone, Today we will learn about the goals and the principles of Material design The concept behind the material design is To create a visual language to synthesizes the classic principle of good design" , which means a design which reflect the object state and its characteristic at single glance. The Purpose is to eliminate the virtuality by adopting the fundamentals of physics. Yes, it means what we see in the real world, we wanted it to be same as in the virtual android world. Now look at the principles of Material design 1 Material is a Metaphor. Metaphor implies the similarity between two no comparable objects, We are saying that the two objects are equivalent but we cant compare both. So in a way we are referring that the both objects are similar. Thus, Materials are the metaphoric representation of real time objects. Such representation facilitates easier recognition of objects. Like the surfaces and the edges gives a cues to determine the object state corresponding to its plane. Different perspective of objects can easily recognize by the human eye and if we see the same perspective in our devices then it would be the more easily recognition of object's state and more delightment for human eye. 2. Bold, graphic , intentional So when we design the application with some foundational elements provided by the android, so other than providing the best graphical looks , it must have meaning, hierarchy in the layout and should be focus drawable. Typography is basically terms which associated with the characteristics of a Text. So some vibrant color choices, and large scale typography and giving intentional white spaces between the elements provide the more bold and better graphic interface. 3. Motion provides meaning When the user perform any action in the design, it initiate motion results transforming the whole design, so when the transformation takes place the way we do the transformation should be meaning and purposeful, and after the completion of the event the all the objects should come back to their real state with the same meaningful transformation to maintain the continuity of the motion. Reference :- Material Design

listview-with-checkbox

Hi All! Its quite easy to handle the list view with the adapters class but some times it becomes mess in some cases. Handling Checkbox inside list is one of them. So Lets learn about handling checkboxes inside list view. Download Source

Add MainActivity.java
public class MainActivity extends ActionBarActivity implements TotalListener{

    private static final String TAG = Test.class.getSimpleName();
    ImageView articleImage;
    ListView mList;
    TextView total;
    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mList = (ListView) findViewById(R.id.list);
        total = (TextView) findViewById(R.id.total);
        String [] string = {};
        TestAdapter ad = new TestAdapter(this, R.layout.test, string);
        ad.setListener(this);
        mList.setAdapter(ad);

    }

    @Override    public void onTotalChanged(int sum) {
        total.setText("Total = " + String.valueOf(sum));
    }
}


Now add TestAdapter.java
import android.content.Context;
import android.content.res.TypedArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.TextView;
 

public class TestAdapter extends ArrayAdapter {
    private LayoutInflater mInflater;
    private String[] mStrings = {"10", "20", "30", "40", "50", "60", "70", "80", "90",
            "100", "110", "120", "130", "140", "10", "20", "30", "40", "50", "60", "70",
            "80", "90", "100", "110", "120", "130", "140"};
    private TypedArray mIcons;
    private int mViewResourceId;
    Holder holder;

    public void setListener(TotalListener listener) {
        this.listener = listener;
    }

    private TotalListener listener;
    ArrayList selectedStrings = new ArrayList();

    public TestAdapter(Context ctx, int viewResourceId, String[] strings) {
        super(ctx, viewResourceId, strings);
        mInflater = (LayoutInflater) ctx
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mStrings = strings;
        mViewResourceId = viewResourceId;
    }

    public int getCount() {
        return mStrings.length;
    }

    public String getItem(int position) {
        return mStrings[position];
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(final int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = mInflater.inflate(mViewResourceId, null);
            holder = new Holder();
            holder.textView = (TextView) convertView.findViewById(R.id.text);
            holder.checkBox = (CheckBox) convertView.findViewById(R.id.checkbox);
            convertView.setTag(holder);
        } else {
            holder = (Holder) convertView.getTag();
            holder.checkBox.setText(mStrings[position]);
            holder.textView.setText(mStrings[position]);
            holder.checkBox.setChecked(false);
            if (selectedStrings.size() <= position) {
                selectedStrings.add(position, false);
            } else holder.checkBox.setChecked(selectedStrings.get(position));
            holder.checkBox.setOnClickListener(new View.OnClickListener() {
                @Override                public void onClick(View v) {
                    boolean state = selectedStrings.get(position);
                    selectedStrings.remove(position);
                    selectedStrings.add(position, state ? false : true);
                    int sum = 0;
                    for (int i = 0; i < selectedStrings.size(); i++) {
                        if (selectedStrings.get(i)) {
                            sum += Integer.parseInt(mStrings[i]);
                        }
                        listener.onTotalChanged(sum);
                    }
                }
            });
            return convertView;
        }
        class Holder {
            CheckBox checkBox;
            TextView textView;
        }
    }
}
       

 Now add Interface TotalListener.java
public interface TotalListener {
    public void onTotalChanged(int sum);
}


Now add layouts in res/layout folder Add activity_main.xml Add test.xml Download Source

Fragment State Pager Adapter with Top Header Tabs using Fragment

Hi All, It looks very tough for those guys who are new in Android Development, but i would say that things becomes very handy when you gets used to of it. So Lets learn that how we can add Top Header Tabs in a Fragment with FragmentStatePager Adapter.

Add MainActivity.java
public class MainActivity extends FragmentActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

getSupportFragmentManager().beginTransaction()
.replace(R.id.container, new HomeFragment).commit();

}

}
Add HomeFragment.java
public class HomeFragment extends Fragment implements OnClickListener, OnPageChangeListener{

/*
* Views of home fragment
*/
private ViewPager mPager = null;
private TextView[] mBottomTabTextView = new TextView[2];
private TextView[] mBottomTabNameTextView = new TextView[2];
private static final int NUMBER_OF_VIEW_TO_ALIVE = 2;

/**
* @param isMyComicRequestSend : false to start mycomic request
*/

private HomePagerAdapter mAdapter = null;

/** Called when the activity is first created. */
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.home_screen null);
initialize(view);
registerListener();

setTabSelected(0);
mAdapter = new HomePagerAdapter(getActivity().getSupportFragmentManager());
mPager.setOffscreenPageLimit(NUMBER_OF_VIEW_TO_ALIVE);
mPager.setAdapter(mAdapter);

return view;
}

/**
* Initialize activity views
*/
public void initialize(View view) {
mPager = (ViewPager) view.findViewById(R.id.pager);
/*
* Initialize tab strips
*/
mBottomTabTextView[0] = (TextView) view.findViewById(R.id.txt_view_home_tab);
mBottomTabTextView[1] = (TextView) view.findViewById(R.id.txt_view_mycomic_tab);

/*
* Initialize bottom tab views
*/
mBottomTabNameTextView[0] = (TextView) view.findViewById(R.id.txt_view_tab_home);
mBottomTabNameTextView[1] = (TextView) view.findViewById(R.id.txt_view_tab_mycomic);

}

/**
* Called to register Listeners
*/
public void registerListener() {
// Add loop to register listener for Bottom tab image views
for (int i = 0; i < NUMBER_OF_VIEW_TO_ALIVE; i++) {
mBottomTabNameTextView[i].setOnClickListener(this);
}
mPager.setOnPageChangeListener(this);

}

/**
* Called to set the tab selected
* @param iPosition : Position of the Tab to be selected
*/
public void setTabSelected(int iPosition) {
boolean state = false;
/*
* Add loop for Adding selected and unselected drawable for the image view
*/
for (int i = 0; i < NUMBER_OF_VIEW_TO_ALIVE; i++) {
if (i == iPosition) {
mBottomTabNameTextView[i].setTextColor(getResources().getColor(R.color.dark_blue));
state = true;
} else {
mBottomTabNameTextView[i].setTextColor(getResources().getColor(R.color.black));
state = false;
}
mBottomTabTextView[i].setSelected(state);
}
}

/*
* @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageScrollStateChanged(int)
*/
@Override
public void onPageScrollStateChanged(int arg0) {
}

/*
* @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageScrolled(int, float, int)
*/
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {

}

/*
* @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageSelected(int)
*/
@Override
public void onPageSelected(int iPosition) {
/*
* if network is available
*/
//if position is 1 i.e mycomic and sMyComicRequest send is false
// then send my comic request
setTabSelected(iPosition);
Toast.makeText(getActivity(), "FRAGMENT " + (iPosition + 1),Toast.LENGTH_SHORT).show();

}

/*
* Called on bottom image click
* @see android.view.View.OnClickListener#onClick(android.view.View)
*/
@Override
public void onClick(View iView) {
/*
* if bottom tabs are clicked
*/
setmPagerOnTabClick(iView.getId());
}

/**
* Called to set page position on corresponding image click
* @param iTabId : Bottom Tab (Image View) id
*/
public void setmPagerOnTabClick(int iTabId) {
/*
* Add loop to find the id
*/
for (int i = 0; i < 4; i++) {
/*
* If view id match, the set page position
*/
if (mBottomTabNameTextView[i].getId() == iTabId) {
mPager.setCurrentItem(i);
setTabSelected(i);
break;
}
}
}
}
Add HomePagerAdapter.java
public class HomePagerAdapter extends FragmentStatePagerAdapter {

/**
* Number of Fragment pages in the view pager
*/
private static final int NUMBER_OF_PAGES = 2;
private Fragment2 mFragment2 ;
private Fragment1 mFragment1;
@Override
public Object instantiateItem(View container, int position) {
return super.instantiateItem(container, position);
}

@Override
public Object instantiateItem(ViewGroup arg0, int arg1) {
return super.instantiateItem(arg0, arg1);
}
/**
* @return : Instance of {@link Fragment2}
*/
public Fragment2 getFragment2() {
return mFragment2;
}
/**
* {@link HomePagerAdapter} {@link Constructor}
* @param fm : {@link FragmentManager} instance
*/
public HomePagerAdapter(FragmentManager fm) {

/*
* Instantiate view pager fragments
*/
super(fm);
if(mFragment1 == null){
mFragment1 = new Fragment1();
}
if (mFragment2 == null) {
mFragment2 = new Fragment2();
}
}

/*
* Called to get the selected fragment
* @see android.support.v4.app.FragmentPagerAdapter#getItem(int)
*/
@Override
public Fragment getItem(int iPosition) {

// Match the corresponding position
switch (iPosition) {
case 0:
return getmFragment1();
case 1:
return getFragment2();
default:
return null;
}
}

public Fragment1 getmFragment1() {
return mFragment1;
}

/*
* Called to get the number of fragment pages in the view pager
* @see android.support.v4.view.PagerAdapter#getCount()
*/
@Override
public int getCount() {
return NUMBER_OF_PAGES;
}
}
Now add two fragments inside the HomePagerAdapter Add Fragment1.java
public class Fragment1 extends Fragment{

@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_layout, null);
return view;
}
}
Add Fragment2.java
public class Fragment2 extends Fragment{

@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_layout, null);
return view;
}
}
Now add layout for Fragment1 and Fragment2's layout, here i am using the same layout for both fragments you can create distinct if you need fragment_layout.xml Now add layout constants in res/values folder Add strings constants in strings.xml, for below strings Search Recent Chat create colors.xml in values folder and add color codes for above used colors And That's all , you have done it, isnt it easy ?

Bottom Tabs with Fragment State PAger Adapter

Hi All, Today we learn about adding bottom tabs with fragment state pager adapter. Below code is generating four fragment pages, however you can modified it acocording to your need. Have fun :) Download Source Create a new project, and add MainApplication.java
import android.app.Application;
import android.content.Context;
public class MainApplication extends Application{
/**
* Context for Application
*/
private static Context sApplicationContext;
/**
* To get the context of the current activity
* @return Context of the current activity
*/
public static Context getsApplicationContext() {
return sApplicationContext;
}
/*
* Returning the context of the current activity
* @see android.app.Application#onCreate()
*/
@Override
public void onCreate(){
super.onCreate();
sApplicationContext = this;
}

}
Add HomeScreenActivity.java
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.TextView;

/**
* Home Screen Activity class, having Pager adapter and bottom tabs
* @author ABHISHEK
*/
public class HomeScreenActivity extends ActionBarActivity implements OnPageChangeListener, OnClickListener,
android.content.DialogInterface.OnClickListener {
/*
* Views of this Activity
*/
private ViewPager mPager = null;
private TextView[] mBottomTabTextView = new TextView[4];
private ImageView[] mBottomTabImageView = new ImageView[4];
private TextView[] mBottomTabNameTextView = new TextView[4];
private TextView mLogout = null;
private static final int NUMBER_OF_VIEW_TO_ALIVE = 4;

// Array of drawable for their corresponding states
private int[] mBottomImageResourceUnselected = { R.drawable.photo1, R.drawable.photo2, R.drawable.photo3,
R.drawable.photo4};
//private int[] mBottomImageResourceSelected = { R.drawable.home_selected, R.drawable.mycomic_selected,
// R.drawable.search_selected };
private int[] mBottomImageResourceSelected = { R.drawable.photo1, R.drawable.photo2, R.drawable.photo3,
R.drawable.photo4};

/**
* @param isMyComicRequestSend : false to start mycomic request
*/

private HomePagerAdapter mAdapter = null;
public static HomeScreenActivity sHomeScreen = null;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sHomeScreen = this;
setContentView(R.layout.home_screen_activity);
ActionBar actionBar = getSupportActionBar();
LayoutInflater mInflater = LayoutInflater.from(this);

View customView = mInflater.inflate(R.layout.home_screen_action_bar, null);
actionBar.setDisplayShowCustomEnabled(true);
actionBar.setCustomView(customView, new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT,
ActionBar.LayoutParams.MATCH_PARENT));
mLogout = (TextView) customView.findViewById(R.id.txt_view_log_out);
actionBar.setDisplayShowHomeEnabled(false); // remove app icon
actionBar.setDisplayShowTitleEnabled(false); // remove app title
actionBar.show();
initialize();
registerListener();

setTabSelected(0);
mAdapter = new HomePagerAdapter(getSupportFragmentManager());
mPager.setOffscreenPageLimit(NUMBER_OF_VIEW_TO_ALIVE);
mPager.setAdapter(mAdapter);
}

/*
* Clear the instance of comic detail screen, and delete the decrypted file
* @see android.support.v4.app.FragmentActivity#onResume()
*/
@Override
protected void onResume() {
super.onResume();

/*
* delete the Decrypted file if exist
*/
// File decryptedFile = new File(XpinnOffUtil.loadPreference(Constants.DECRYPTED_FILE_PATH));
//
// if(decryptedFile.exists()){
// decryptedFile.delete();
// XpinnOffUtil.clearPreference(Constants.DECRYPTED_FILE_PATH);
// XpinnOffUtil.clearPreference(Constants.DECRYPTED_FILE_KEY);
// }
}

/**
* Initialize activity views
*/
public void initialize() {
mPager = (ViewPager) findViewById(R.id.pager);
/*
* Initialize tab strips
*/
mBottomTabTextView[0] = (TextView) findViewById(R.id.txt_view_home_tab);
mBottomTabTextView[1] = (TextView) findViewById(R.id.txt_view_mycomic_tab);
mBottomTabTextView[2] = (TextView) findViewById(R.id.txt_view_free_tab);
mBottomTabTextView[3] = (TextView) findViewById(R.id.txt_view_search_tab);

/*
* Initialize bottom tab views
*/
mBottomTabImageView[0] = (ImageView) findViewById(R.id.img_view_home_tab);
mBottomTabImageView[1] = (ImageView) findViewById(R.id.img_view_mycomic_tab);
mBottomTabImageView[2] = (ImageView) findViewById(R.id.img_view_free_tab);
mBottomTabImageView[3] = (ImageView) findViewById(R.id.img_view_search_tab);
mBottomTabNameTextView[0] = (TextView) findViewById(R.id.txt_view_tab_home);
mBottomTabNameTextView[1] = (TextView) findViewById(R.id.txt_view_tab_mycomic);
mBottomTabNameTextView[2] = (TextView) findViewById(R.id.txt_view_tab_free);
mBottomTabNameTextView[3] = (TextView) findViewById(R.id.txt_view_tab_search);

}

/**
* Called to register Listeners
*/
public void registerListener() {
// Add loop to register listener for Bottom tab image views
for (int i = 0; i < 4; i++) {
mBottomTabImageView[i].setOnClickListener(this);
}
mPager.setOnPageChangeListener(this);
mLogout.setOnClickListener(this);
}

/**
* Called to set the tab selected
* @param iPosition : Position of the Tab to be selected
*/
public void setTabSelected(int iPosition) {
boolean state = false;
/*
* Add loop for Adding selected and unselected drawable for the image view
*/
for (int i = 0; i < 4; i++) {
if (i == iPosition) {
mBottomTabImageView[i].setImageDrawable(getResources().getDrawable(mBottomImageResourceSelected[i]));
mBottomTabNameTextView[i].setTextColor(getResources().getColor(R.color.dark_blue));
state = true;
} else {
mBottomTabImageView[i].setImageDrawable(getResources().getDrawable(mBottomImageResourceUnselected[i]));
mBottomTabNameTextView[i].setTextColor(getResources().getColor(R.color.black));
state = false;
}
mBottomTabTextView[i].setSelected(state);
}
}

/*
* @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageScrollStateChanged(int)
*/
@Override
public void onPageScrollStateChanged(int arg0) {
}

/*
* @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageScrolled(int, float, int)
*/
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {

}

/*
* @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageSelected(int)
*/
@Override
public void onPageSelected(int iPosition) {
/*
* if network is available
*/
//if position is 1 i.e mycomic and sMyComicRequest send is false
// then send my comic request
setTabSelected(iPosition);
}

/*
* Called on bottom image click
* @see android.view.View.OnClickListener#onClick(android.view.View)
*/
@Override
public void onClick(View iView) {
/*
* if logout image is clicked
*/
if (iView.getId() == R.id.txt_view_log_out) {
showDialog();
}
/*
* if bottom tabs are clicked
*/
else {
setmPagerOnTabClick(iView.getId());
}
}

/**
* Called to set page position on corresponding image click
* @param iTabId : Bottom Tab (Image View) id
*/
public void setmPagerOnTabClick(int iTabId) {
/*
* Add loop to find the id
*/
for (int i = 0; i < 4; i++) {
/*
* If view id match, the set page position
*/
if (mBottomTabImageView[i].getId() == iTabId) {
mPager.setCurrentItem(i);
setTabSelected(i);
break;
}
}
}

/**
*Called to show Dialog for logout
*/
public void showDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("INFO");
builder.setMessage("EXIT_MESSAGE");
builder.setPositiveButton("OK", this);
builder.setNegativeButton("CANCEL", this);
builder.show();
}

/*
* Called on logout dialog click
* @see android.content.DialogInterface.OnClickListener#onClick(android.content.DialogInterface, int)
*/
@Override
public void onClick(DialogInterface iDialog, int iWhich) {
/*
* If ok button clicked then logout app
*/
if (iWhich == DialogInterface.BUTTON_POSITIVE) {
System.exit(0);
}
/*
* if cancel button clicked then hide the dialog
*/
else {
iDialog.dismiss();
}
}

/*
* Prompt message to logout
* @see android.support.v4.app.FragmentActivity#onBackPressed()
*/
@Override
public void onBackPressed() {
showDialog();
}

/*
* @see android.support.v4.app.FragmentActivity#onDestroy()
*/
@Override
protected void onDestroy() {
super.onDestroy();
sHomeScreen = null;
}
}
Add HomePagerAdapter.java
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;

/**
* View pager Adapter of {@link HomeScreenActivity}
* @author ABHISHEK
*/
public class HomePagerAdapter extends FragmentStatePagerAdapter {

/**
* Number of Fragment pages in the view pager
*/
private static final int NUMBER_OF_PAGES = 4;
private Fragment2 mFragment2 ;
private Fragment4 mFragment4 ;
private Fragment3 mFragment3 ;
private Fragment1 mFragment1;

/**
* @return : Instance of {@link Fragment3}
*/
public Fragment3 getmFragment3() {
return mFragment3;
}

/**
* @return : Instance of {@link Fragment2}
*/
public Fragment2 getFragment2() {
return mFragment2;
}

/**
* @return : Instance of {@link Fragment4}
*/
public Fragment4 getmFragment4() {
return mFragment4;
}

/**
* {@link HomePagerAdapter} {@link Constructor}
* @param fm : {@link FragmentManager} instance
*/
public HomePagerAdapter(FragmentManager fm) {

/*
* Instantiate view pager fragments
*/
super(fm);
if(mFragment1 == null){
mFragment1 = new Fragment1();
}
if (mFragment2 == null) {
mFragment2 = new Fragment2();
}
if (mFragment4 == null) {
mFragment4 = new Fragment4();
}
if (mFragment3 == null) {
mFragment3 = new Fragment3();
}
}

/*
* Called to get the selected fragment
* @see android.support.v4.app.FragmentPagerAdapter#getItem(int)
*/
@Override
public Fragment getItem(int iPosition) {

// Match the corresponding position
switch (iPosition) {
case 0:
return getmFragment1();
case 1:
return getFragment2();
case 2:
return getmFragment3();
case 3:
return getmFragment4();
default:
return null;
}
}

public Fragment1 getmFragment1() {
return mFragment1;
}

/*
* Called to get the number of fragment pages in the view pager
* @see android.support.v4.view.PagerAdapter#getCount()
*/
@Override
public int getCount() {
return NUMBER_OF_PAGES;
}
}
In Above code, we have created adapter for four fragments. Below are four fragments and their layout, and only single layout is used for all fragments. You can create your layouts as per your need Fragment1.java
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

public class Fragment1 extends Fragment{

private ImageView mImage;
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_layout, null);
mImage = (ImageView) view.findViewById(R.id.image);
mImage.setImageResource(R.drawable.photo1);
return view;
}
}

Fragment2.java

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

public class Fragment2 extends Fragment{

private ImageView mImage;
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_layout, null);
mImage = (ImageView) view.findViewById(R.id.image);
mImage.setImageResource(R.drawable.photo2);
return view;
}
}

Fragment3.java

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

public class Fragment3 extends Fragment{

private ImageView mImage;
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_layout, null);
mImage = (ImageView) view.findViewById(R.id.image);
mImage.setImageResource(R.drawable.photo3);
return view;
}
}

Fragment4.java

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

public class Fragment4 extends Fragment{

private ImageView mImage;
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_layout, null);
mImage = (ImageView) view.findViewById(R.id.image);
mImage.setImageResource(R.drawable.photo4);
return view;
}
}
Add below layouts in res/layout fragment_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

</LinearLayout>
home_screen_action_bar.xml
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white" >

<TextView
android:id="@+id/txt_view_log_out"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:gravity="center_vertical"
android:padding="@dimen/ten"
android:text="@string/logout"
android:textColor="@color/black" />

</RelativeLayout>
home_screen_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/footer" />

<EditText
android:id="@+id/dummy_edt_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone" />

<LinearLayout
android:id="@+id/footer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@color/grey_background"
android:orientation="vertical" >

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >

<TextView
android:id="@+id/txt_view_home_tab"
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_weight="1"
android:background="@drawable/strip_selector" />

<TextView
android:id="@+id/txt_view_mycomic_tab"
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_weight="1"
android:background="@drawable/strip_selector" />

<TextView
android:id="@+id/txt_view_free_tab"
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_weight="1"
android:background="@drawable/strip_selector" />

<TextView
android:id="@+id/txt_view_search_tab"
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_weight="1"
android:background="@drawable/strip_selector" />
</LinearLayout>

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="horizontal" >

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@color/white"
android:orientation="vertical" >

<ImageView
android:id="@+id/img_view_home_tab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/photo1" />

<TextView
android:id="@+id/txt_view_tab_home"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/home" />
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@color/white"
android:orientation="vertical" >

<ImageView
android:id="@+id/img_view_mycomic_tab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/photo2" />

<TextView
android:id="@+id/txt_view_tab_mycomic"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/mycomic" />
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@color/white"
android:orientation="vertical" >

<ImageView
android:id="@+id/img_view_free_tab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/photo3" />

<TextView
android:id="@+id/txt_view_tab_free"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/free" />
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@color/white"
android:orientation="vertical" >

<ImageView
android:id="@+id/img_view_search_tab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/photo4" />

<TextView
android:id="@+id/txt_view_tab_search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/search" />
</LinearLayout>
</LinearLayout>
</LinearLayout>

</RelativeLayout>
Add Selector in res/drawable
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:drawable="@color/white" android:state_selected="false"/>
<item android:drawable="@color/bright_blue" android:state_selected="true"/>

</selector>
Add color file in res/value folder colors.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- Colors constants -->

<resources>

<color name = "white" >#FFFFFF</color>
<color name = "black" >#000000</color>
<color name = "grey_background" >#4F4F51</color>

<color name = "bright_blue" >#BBE5FF</color>
<color name = "dark_blue" >#1F7EC2</color>

</resources>
Add dimen file in res/values folder dimen.xml
<?xml version = "1.0" encoding = "utf-8"?>
<!-- Constants related with dimensions used in xmls -->

<resources>

<dimen name = "ten">10dp</dimen>

</resources>
Add strings file in res/values folder strings.xml
<!-- String constants used in xmls -->
<resources>

<string name = "app_name" >Test</string>
<string name = "logout" >Log Out</string>
<string name = "home" >Home</string>
<string name = "free" >Free </string>
<string name = "mycomic" >My Comics</string>
<string name = "search" >Search</string>
<string name = "cancel" >Cancel</string>
<string name = "ok" >OK</string>

</resources>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.test"
android:versionCode="1"
android:versionName="1.0" >

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

<application
android:name="com.example.test.MainApplication"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.test.HomeScreenActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>
Note : All you need to add four images photo1.png, photo2.png, photo3.png, photo4.png  in res/drawable Download Source

a-look-over-manifest-attributes-used-in-google-play-filtering


                   When a user searches for an app in play store, Google play filtered his searches to provide him/her the best suited result for him/her. The google play get an idea about filtering, from the several types of app metadata and configuration settings, including manifest declarations, required libraries,architecture dependencies, and distribution controls set in the Google Play Developer Console, such as geographic targeting, pricing, and more. We will look into some manifest attribute, their purposes and their specialties.

1. <support-screens>
       This attribute is used to define the screen sizes of the devices, into which you supposed your application should be installed. Accordingly Google play filters your application and put it into the list of devices into which your application can be installed. As a general rule Google Play assume that smaller layout can be easily fit into the large screen devices. But not the larger layouts in the smaller devices. So thus, if any application declares support for normal screen size then Google Play allows that app to be installed for both normal and the larger screen size devices.
And If an application does not declare this attribute in their manifest , then Google Play picks up the default values, vary by API Levels
Suppose: The manifest declares <uses-sdk android:minSdkVersion="3"> and does not include a<supports-screens> element.
Result: Google Play will not show the app to a user of a small-screen device, but will show it to users of normal and large-screen devices, unless other filters apply.
Suppose: The manifest declares <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="4"> and does not include a<supports-screens> element.
Result: Google Play will show the app to users on all devices, unless other filters apply.
To Know, How to declare the <support-screens> attribute, see <support-screens>.
      1. <uses-configuration>
This attribute helps Google Play to filter the apps which have any special hardware requirement.
Suppose:The manifest includes <uses-configuration android:reqFiveWayNav="true" />, and a user is searching for apps on a device that does not have a five-way navigational control.
Result: Google Play will not show the app to the user.
Suppose: The manifest does not include a <uses-configuration>element.
Result: Google Play will show the app to all users, unless other filters apply.
To Know, How to declare the <uses-configuration> attribute, see <uses-configuration>

3. <uses-feature>
        If any application uses this attribute in their manifest, then Google Play categorized that app for the list of devices which satisfy the required device features. This Fuctionality was introduced in Android 2.0.

Suppose: The manifest includes <uses-feature android:name="android.hardware.sensor.light" />, and a user is searching for apps on a device that does not have a light sensor.

Result: Google Play will not show the app to the user.
An application may also require a specific Open-GL ES version support, using the 
 <uses-feature  android:openGlEsVersion="int"> attribute.

Suppose: An app requests multiple OpenGL-ES versions by specifying openGlEsVersion multiple times in the manifest.
Result: Google Play assumes that the app requires the highest of the indicated versions.
Suppose: An app requests OpenGL-ES version 1.1, and a user is searching for apps on a device that supports OpenGL-ES version 2.0.
Result: Google Play will show the app to the user, unless other filters apply. If a device reports that it supports OpenGL-ES version X, Google Play assumes that it also supports any version earlier than X.
Suppose: A user is searching for apps on a device that does not report an OpenGL-ES version (for example, a device running Android 1.5 or earlier).
Result: Google Play assumes that the device supports only OpenGL-ES 1.0. Google Play will only show the user apps that do not specify openGlEsVersion, or apps that do not specify an OpenGL-ES version higher than 1.0.
To Know, How to declare the <uses-feature> attribute, see <uses-feature>
      1. <uses-library>
If application uses this attribute in the manifest, then it means that the application wants that the specific shared library should be present on the devices. It creates a filter for the google play to show only those apps whose library need satisfy by the device.
Suppose: An app requires the com.google.android.maps library, and a user is searching for apps on a device that does not have the com.google.android.maps library.
Result: Google Play will not show the app to the user.
Suppose:The manifest does not include a <uses-library> element.
Result: Google Play will show the app to all users, unless other filters apply.
To Know, How to declare the <uses-library> attribute, see <uses-library>
      1. <uses-permission>
        If in any app the <uses-feature> attribute is not declared properly, then Google Play managed itself through <uses-permission> attribute whether the app has reqiurement of the hardware feature or not. For example, if an application requests the CAMERA permission but does not declare a <uses-feature> element for android.hardware.camera, Google Play considers that the application requires a camera and should not be shown to users whose devices do not offer a camera.
In general, if an application requests hardware-related permissions, Google Play assumes that the application requires the underlying hardware features, even though there might be no corresponding to <uses-feature>declarations. Google Play then sets up filtering based on the features implied by the <uses-feature> declarations.
For a list of permissions that imply hardware features, see the documentation for the <uses-feature> element.
      1. <uses-sdk>
        An application can require a minimum API level.
Minimum Framework Version (minSdkVersion)
Suppose: The manifest includes <uses-sdk android:minSdkVersion="3">, and the app uses APIs that were introduced in API Level 3. A user is searching for apps on a device that has API Level 2
Result: Google Play will not show the app to the user.
Suppose: The manifest does not include minSdkVersion, and the app uses APIs that were introduced in API Level 3. A user is searching for apps on a device that has API Level 2.
Result: Google Play assumes that minSdkVersion is "1" and that the app is compatible with all versions of Android. Google Play shows the app to the user and allows the user to download the app. The app crashes at runtime.
Because you want to avoid this second scenario, we recommend that you always declare a minSdkVersion. For details, see android:minSdkVersion.
Maximum Framework Version (maxSdkVersion)
Deprecated. Android 2.1 and later do not check or enforce the maxSdkVersion attribute, and the SDK will not compile if maxSdkVersion is set in an app's manifest. For devices already compiled with maxSdkVersion, Google Play will respect it and use it for filtering.
Declaring maxSdkVersion is not recommended. For details, see android:maxSdkVersion.
There are few attributes used in manifest as a filter for Google Play, but they trigger in exceptional cases. Used in some high – performance gamens and similar application, Most application should never used these filters.
Advanced Manifest Filters
1.<compatible-screens>
Google Play filters the application if the device screen size and density does not match any of the screen configurations (declared by a <screen> element) in the <compatible-screens> element.
Caution: Normally, you should not use this manifest element. It will resuce the user base for your application, instead of using this use <support-screens> manifest element (described above) to enable screen compatibility mode for screen configurations you have not accounted for with alternative resources.
2.<support-gl-texture>
Google Play filters the application unless one or more of the GL texture compression formats supported by the application are also supported by the device.
Reference :- Google Play Filters
Download :- Google Play Filtering