Thursday, 17 March 2016

Retrieving a list of Contacts and showing them like WhatsApp (ListView-Fragment-ViewPager)

Here is the official android developer example regarding Retrieving a List of Contacts, read and understand well. Though I am not going to use all the function. My aim is to display a list of contact from phone, to a swipe-able screen fragment-like favorites in WhatsApp.

Notes:
1.You can always use custom id for ListView in xml other than @android:id/list , say. @+id/mylist.
    Same goes for @android:id/text1.
2. Loader Manager is used to load data asynchronously in an activity or fragment.

 Here is the OnCreate() of my MainActivity.java


        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
      try {

          tabLayout.addTab(tabLayout.newTab().setText("helloo"));
          tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
          tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));
          tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
          }catch (Exception e)
                 {e.printStackTrace();}

        final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
        final PagerAdapter adapter = new PagerAdapter
                (getSupportFragmentManager(), tabLayout.getTabCount());
        viewPager.setAdapter(adapter);

        viewPager.addOnPageChangeListener(new
                             TabLayout.TabLayoutOnPageChangeListener(tabLayout));
        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                viewPager.setCurrentItem(tab.getPosition());
             }

I used Tabbed + swipe-able page...
tabLayout.addTab literally creates a new Tab with title written inside the setText().
A ViewPager is placed inside the xml code with id pager, and is initialized here, for navigation across the screen.
Also an object of PagerAdapter.class (

Here is activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.sunshelltechnologies.asimpletabact.MainActivity">

    <android.support.design.widget.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:elevation="6dp"
        android:minHeight="?attr/actionBarSize"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>

    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="fill_parent"
        android:layout_below="@id/tab_layout"/>
</RelativeLayout>



Another class PagerAdapter.java is created

public class PagerAdapter extends FragmentStatePagerAdapter {
    int mNumOfTabs;
    public PagerAdapter(FragmentManager fm, int NumOfTabs) {
                       super(fm);
          this.mNumOfTabs = NumOfTabs;
    }
    @Override
    public Fragment getItem(int position) {

        switch (position) {
            case 0:
                TabFragment1 tab1 = new TabFragment1();
                return tab1;
            case 1:
                TabFragment2 tab2 = new TabFragment2();
                return tab2;
            case 2:
                TabFragment3 tab3 = new TabFragment3();
                return tab3;
            default:
                return null;
        }
    }
    @Override
    public int getCount() {
        return mNumOfTabs;
    }
}

For each page,view, I created each java file naming them TabFragment1,2,3 as you can see.
The basic code inside these are:

public class TabFragment1 extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.tab_fragment_1, container, false);
    }
}


Although, for retrieving contact on the third screen, I added some codes in TabFragment3.java.

public class TabFragment3  extends Fragment {
    // Cursor Adapter for storing contacts data
    SimpleCursorAdapter adapter;
    // List View Widget
    ListView lvContacts;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.tab_fragment_3, container, false);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

      // OnActivityCreated work after onCreateView
        lvContacts = (ListView) getView().findViewById(R.id.fragment_3);
      // Initialize Content Resolver object to work with content Provider
        ContentResolver cr=getActivity().getContentResolver();
        Cursor c = cr.query(ContactsContract.Contacts.CONTENT_URI,
                new String[] { ContactsContract.Contacts._ID,
                        ContactsContract.Contacts.DISPLAY_NAME }, 

                        null, null,  null);

        Context context = getActivity();
        adapter = new SimpleCursorAdapter(context,
                           R.layout.single_item, //the layout containing TextView

                               c,   //the cursor
            new String[] { ContactsContract.Contacts.DISPLAY_NAME }, //content
                new int[] { R.id.myTextView },  //to where?
                0);       //flag 0=no requery loader
       

        lvContacts.setAdapter(adapter);
       }
}

Note that there are 3 xml for each view (tab_fragment_1.xml, tab_fragment_2.xml contain nothing inside).
tab_fragment_3.xml

<?xml version="1.0" encoding="utf-8"?>
<ListView android:id="@+id/fragment_3" xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
  />

single_item.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"
    >
<TextView
        android:id="@+id/myTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

Saturday, 20 February 2016

Core Building Blocks in Android

Android component is a simple piece of code that has well defined life cycle. These are the building blocks in Android

  • Activities — Your application’s presentation layer. The UI of your application is built around one or more extensions of the Activity class.
    Activities use Fragments and Views to layout and display information, and to respond to user actions. Compared to desktop development, Activities are equivalent to Forms.
  • Services — The invisible workers of your application. Service components run without a UI, updating your data sources and Activities, triggering Notifications, and broadcasting Intents.
    They’re used to perform long running tasks, or those that require no user interaction (such as network lookups or tasks that need to continue even when your application’s Activities aren’t active or visible.)
  • Content Providers — Shareable persistent data storage. Content Providers manage and persist application data and typically interact with SQL databases. They’re also the preferred means to share data across application boundaries.
    You can configure your application’s Content Providers to allow access from other applications, and you can access the Content Providers exposed by others.
    Android devices include several native Content Providers that expose
    useful databases such as the media store and contacts.
  • Intents — A powerful inter application message-passing framework. Intents are used extensively throughout Android.
    You can use Intents to start and stop Activities and Services, to broadcast messages system-wide or to an explicit Activity, Service, or Broadcast Receiver, or to request an action be performed on a particular piece of data.
  • Broadcast Receivers — Intent listeners. Broadcast Receivers enable your application to listen for Intents that match the criteria you specify. Broadcast Receivers start your application to react to any received Intent, making them perfect for creating event-driven applications.
  • Widgets — Visual application components that are typically added to the device home screen.
    A special variation of a Broadcast Receiver, widgets enable you to create dynamic, interactive application components for users to embed on their home screens.
  • Notifications — Notifications enable you to alert users to application events without stealing focus or interrupting their current Activity. They’re the preferred technique for getting a user’s attention when your application is not visible or active, particularly from within a Service or Broadcast Receiver.
    For example, when a device receives a text message or an email, the messaging and Gmail applications use Notifications to alert you by flashing lights, playing sounds, displaying icons, and scrolling a text summary.

Friday, 19 February 2016

Creating a UI layout in xml and java code

In xml



<?xml version=”1.0” encoding=”utf-8”?>
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
            android:orientation=”vertical”
            android:layout_width=”fill_parent”
            android:layout_height=”fill_parent”>
<TextView
           android:id=”@+id/myTextView”
           android:layout_width=”fill_parent”
           android:layout_height=”wrap_content”
           android:text=”@string/hello”  />
</LinearLayout>



Same can be done in code, although it is not generally considered as a good practice..

public void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);

           LinearLayout.LayoutParams lp;
           lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,
                                                                          LinearLayout.LayoutParams.FILL_PARENT);

           LinearLayout.LayoutParams textViewLP;
           textViewLP = new
                        LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,
                                                                       LinearLayout.LayoutParams.WRAP_CONTENT);
 
          LinearLayout ll = new LinearLayout(this);
          ll.setOrientation(LinearLayout.VERTICAL);

          TextView myTextView = new TextView(this);
          myTextView.setText(getString(R.string.hello));

          ll.addView(myTextView, textViewLP);
          this.addContentView(ll, lp); 

}