Pages

Showing posts with label ui. Show all posts
Showing posts with label ui. Show all posts

Tuesday, April 19, 2016

Creating Android UI Programmatically


So far, in all my examples, I have been using the declarative way of creating an Android UI using XML. However, there could arise certain situations when you may have to create UI programmatically. Sincere advice would be to avoid such a design since android has a wonderful architecture where the UI and the program are well separated. However, for those few exceptional cases where we may need too… here is how we do it.
Every single view or viewgroupelement has an equivalent java class in the SDK. The structure and naming of the classes and methods is very similar to the XML vocabulary that we are used to so far.
Let us start with a LinearLayout. How would we declare it in an XML?
<?xml version="1.0"encoding="utf-8"?>
<LinearLayout >="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/hello"
    />
</LinearLayout>
This just contains a TextViewembedded in a LinearLayout. A very trivial example. But serves the purpose intended. Let me show how almost every single element here corresponds to a class or a method call in the class.  So the equivalent code in the onCreate(…)  method of an activity would be like this:
         super.onCreate(savedInstanceState);
      
        lLayout = newLinearLayout(this);
        lLayout.setOrientation(LinearLayout.VERTICAL);
        //-1(LayoutParams.MATCH_PARENT) is fill_parent or match_parent since API level 8
        //-2(LayoutParams.WRAP_CONTENT) is wrap_content
        lLayout.setLayoutParams(new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
        tView = newTextView(this);
        tView.setText("Hello, This is a view created programmatically! " +
                  "You CANNOT change me that easily :-)");
        tView.setLayoutParams(new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
        lLayout.addView(tView);
        setContentView(lLayout);

Like this any layout view can be created. But from this small example you can notice two outstanding things – very tedious to code for every attribute of the view. And any simple change in the view, you need to change the code, compile, deploy and only then you see the effect of the change – unlike in a layout editor. 


You can download the sample code here.
Read More..

Friday, April 15, 2016

Sudoku 10000 Plus Free Paid Android

Sudoku 10'000 Plus Download





15'000+ puzzles, eight difficulty levels, the world's best hint functionality and statistics. The only Sudoku app you'll ever need!

Read More..

Friday, March 18, 2016

nbsp;&n"

local,service,android,tutorial,for,beginners,–,part,7
Read More..

Thursday, March 10, 2016

Introduction to UI in Android

Layouts in android is constructed from two objects: View and ViewGroup.


The View class is the base class for many widgets sub classes such as TextView and Button classes.

The ViewGroup is a view that conatains other views. The Viewgroup class is the base class for many layouts in android.

The UI Hierarchy is described in this picture from the android online sdk documentation



As you can see the root node is a view group which can be any layout that contains child views or even other viewgroups.


The root node appears on the activity by calling setcontentview ( method). Which in turn draws its child nodes and each child node draws its child nodes

In the following posts we are going to explore the categories of android widgets which are:
 
1. Text Controls


2. Button controls

3. List controls

4. Grid controls

5. Date and time controls

6. Menus

7. Dialogs

8. Adapters
Read More..

Monday, February 29, 2016

Android Content Providers

Remember when we created a sqlite database android application. We saw that the database file is stored in the file system directories of that application meaning that the database cannot be accessed from another application. You can apply the same thing on any resources within your application (Files, images, videos, …).
But there is a method to expose your data across multiple applications: Content Providers.
Content Providers expose an application’s data across all other applications, you can use content providers to store or retrieve data of one application from any other application.
In this post we’re going to see how to deal with the existing default content providers by retrieving and manipulating data through them.
Android default content providers:
There are many built-in content providers supplied by OS. They are defined in the android.provider package, they include:
·         Browser.
·         Calllog.
·         Live Folders.
·         Contacts Contract.
·         Media Store.
·         Settings

content providers basics:

the concept of content providers is pretty similar to the concept of ASP.NET Web Services they provide data encapsulation through exposing data by URis. Any content provider is invoked by a URi in the form of content://provider_name . for example the URi of the Contacts content provider that retrieves all contacts is in the following form content://contacts/people. If you want to retrieve a particular contact (by its ID) then it would be in this form: content://contacts/people/5.

You do not need to write the URis of the content providers manually as they are stored as constant values in their respective content provider classes.

The Uri of the Contacts phones content provider is defined in
ContactsContract.CommonDataKinds.Phone.CONTENT_URI
(content://com.android.contacts/data/phones)

The Uri of the browser Bookmarks content provider is defined in
Browser.BOOKMARKS_URI
(content://browser/bookmarks)

The Media store (Video) stored in external device (SD Card) is defined in
MediaStore.Video.Media.EXTERNAL_CONTENT_URI
(content://media/external/video/media) and so on.

content providers allow you to perform basic CRUD operations: Create,Read, Update and Delete on data.

Making Queries

to retrieve data from a content provider we run a sql-like query using ManagedQuery object. The ManagedQuery object returns a cursor holding the result set.

To retrieve a list of all contacts and display them in a ListView
We first define our activity xml layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android_orientation="vertical"
android_layout_width="fill_parent"
android_layout_height="fill_parent"
>
<TextView
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_id="@+id/txt"
/>
<ListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/list"
/>
</LinearLayout>

And define the layout of each row in the ListView:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout

android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_orientation="horizontal"
>
<TextView
android_layout_width="100px"
android_layout_height="wrap_content"
android_id="@+id/txtName"
android_layout_weight="1"
/>
<TextView
android_layout_width="100px"
android_layout_height="wrap_content"
android_id="@+id/txtNumber"
android_layout_weight="1"
/>
</LinearLayout>

Remember to add the following permission to the manifest.xml file
<uses-permission android_name="android.permission.READ_CONTACTS"></uses-permission>

To retrieve the contacts and bind them to the listView:
String [] projection=new String[]{ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,ContactsContract.CommonDataKinds.Phone.NUMBER,ContactsContract.CommonDataKinds.Phone._ID};
txt.setText(ContactsContract.PhoneLookup.CONTENT_FILTER_URI.toString());
Uri contacts = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;

Cursor managedCursor = managedQuery(contacts,projection,null,null,null);
//Cursor managedCursor =cr.query(contacts, projection, null, null, null);
ListAdapter sca=new SimpleCursorAdapter(this,R.layout.listrow,managedCursor,projection,to);
list.setAdapter(sca);


the above code retrieves all the contacts in the following steps:
  1. We first define the projection of our query, we define the columns we want to retrieve in the result set.We define a String array containing the names of the columns we want to retreieve.The contacts column names are defined in ContactsContract.CommonDataKinds.Phone class.Note that we need to retrieve the _ID column as the cursor that retrieves the data expects such a column to be there.
  2. We specify the Uri of the content provider ContactsContract.CommonDataKinds.Phone.CONTENT_URI
  3. We retrieve the data by a cursor
    Cursor managedCursor = managedQuery(contacts,projection,null,null,null);The cursor is retrieved by executing a managedQuery which has the following parameters:
    1. The Uri of the content provider.
    2. A String Array of the columns to be retrieved (projection)
    3. Where clause.
    4. String array containing selection arguments values.
    5. String representing the order by clause, we can use it but here it will be null. If we want to sort the contacts by name it would be ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME +“ asc”
  4. Then we create a list adapeter using the cursor and bind the ListView to it.

The previous example retrieves all the contacts but what if we want to retrieve a certain contact by name:
There are two ways:
  1. Using the same code above but adding a where clause and selection arguments to the managed wuery so it becomes like this:
    Cursor managedCursor = managedQuery(contacts,projection,ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME+"=?",new String[]{"Jack"},null);
    This retrieves contact info of a person named Jack.

  2. The other method is to inject the query in the Uri, instead of using Uri
    contacts = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
    we use
    Uri contacts=Uri.withAppendedPath(ContactsContract.CommonDataKinds.Phone.CONTENT_FILTER_URI,Uri.encode("Jack"));
    This is equivalent to the following Uri content://com.android.contacts/data/phones/Jack

Inserting,updating and deleting:

to insert data using a content provider there are two methods

First:
Using the Insert() method of your activity’s content resolver object. Like this example t insert a new bookmark to the browser:
ContentValues cv=new ContentValues();
cv.put(Browser.BookmarkColumns.TITLE, "End Gadget");
cv.put(Browser.BookmarkColumns.URL, "http://www.engadget.com/");
cv.put(Browser.BookmarkColumns.BOOKMARK,1);
Uri u= getContentResolver().insert(Browser.BOOKMARKS_URI, cv);

We create a ContentValues object and add to it all the required fields, then we call getContentResolver().insert method which returns the Uri of the newly inserted item.
It would be in this example content://browser/bookmarks/17
We can use the generated Uri to update or delete the item later.

Second:
We can replace the getcontentresolver().insert() method with bulkInsert method if we want to insert multiple items at a time.
The bulkInsert(Uri url,ContentValues[] values) method returns the number of new items created.

Updating info using Content Providers:

To update data using content providers, we use getContnetResolver.Update() method:
This code updates the title of an existing browser bookmark:
ContentValues cv=new ContentValues();
cv.put(Browser.BookmarkColumns.TITLE, "End Gadget mod");
//uriBook= getContentResolver().insert(Browser.BOOKMARKS_URI, cv);
getContentResolver().update(Browser.BOOKMARKS_URI, cv, BookmarkColumns.TITLE+"=?", new String[]{"End Gadget"});

the Update method has the following parameters:
  • Content Providers Uri
  • ContentValues object having the new values
  • Where clause
  • String array of the where clause arguments values

Deleting info using Content Providers:

To delete info we use getContentResolver.Delete() method
To delete a bookmark:
getContentResolver().delete(Browser.BOOKMARKS_URI,BookmarkColumns.TITLE+"=?", new String[]{"End Gadget"});

the delete function has the following parameters:
  • Content Providers Uri
  • Where clause
  • String array of the where clause arguments values

Remember to add the following permissions to the manifest.xml to add and read browser bookmarks:
<uses-permission android_name="android.permission.WRITE_CONTACTS"></uses-permission>
<uses-permission android_name="com.android.browser.permission.WRITE_HISTORY_BOOKMARKS"></uses-permission>

Read More..

Friday, February 26, 2016

Android UI – Inflate from XML Dynamic UI Creation


We have seen that we can declare User Interface in Android through XML or we can even create the UI Programmatically. Now, we will see how we can mix the two and use it for building dynamic User Interfaces. One example of such a case would be when on a particular action of the user on one of the UI elements, you need more UI elements to appear on the same screen. How do we achieve this?
You can do it in two ways:
1.       The dynamic part of the UI can be created programmatically. However we saw in my earlier tutorial that it is not a very good way to mix UI and code.  So, we can
2.       Define the dynamic UI too as an XML and use XML inflation to include it into the existing UI.
We will see how to do the 2ndway, which probably is a good practice too.
As always, again a very simple example. Assume I have a very simple linear layout. In that I want to include a button. I can do it as part of the mail XML itself. However, assume that this button is supposed to be reused in many activities and hence I have defined it as a separate XML. How do I include it into the main XML?
So, here is the main.xml
<?xml version="1.0"encoding="utf-8"?>
<LinearLayout >="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/layout1"
    >
</LinearLayout>
Here is the buttons.xml that is also created in the res/layout folder:
<?xml version="1.0"encoding="utf-8"?>

<Button >="http://schemas.android.com/apk/res/android"
        android:id="@+id/button_small_left"
 style="?android:attr/buttonStyleSmall"
        android:text="Press to close"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
And here is the Activity’s onCreate(…) method of the InflateView class:
    public voidonCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        final LayoutInflater  inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        Button b = (Button)inflater.inflate(R.layout.buttons,
                null);
       
        lLayout = (LinearLayout)findViewById(R.id.layout1);
        lLayout.addView(b);
First 3 lines must be familiar. In the 4thline, I am getting a handle to the LayoutInflater through the getSystemService(…) method.  This inflater has a method inflate to which I pass the buttons.xml by passing the parameter R.layout.buttons. Then, I try to append this button to the Linear Layout that already exists and is set as the view in line 2 setContentView(R.layout.main). How to append? I get a handle to the LinearLayoutlLayout and add the new button to it in the last line!
That simple to inflate an XML and append it to an existing view!
However, I have gone ahead and added another bit to this program as shown below:
        b.setOnClickListener(new OnClickListener() {
           
            public void onClick(View v) {
                  //restrict to adding only 1 textview child element
                  if (lLayout.getChildAt(2) == null)
                  {
                  TextView tv = (TextView)inflater.inflate(R.layout.text, null);
                  lLayout.addView(tv);
                  }
            }
        });
On the click of this dynamically added button, I am showing how we can add more to the UI dynamically through inflation. Assume, on the click of the button, you want to show some new text. This TextView is defined in another XML called text.xml which is also in the res/layout folder.
So, I am inflating from this XML and appending it to the LinearLayout view. So, a lot can be achieved for dynamic UI through inflation.

You can download the complete sample code here.
Read More..

Wednesday, February 24, 2016

Android Developers Backstage Episode 6 System UI

In this episode, we delve into the world of the Android System UI, including tangents on notifications new and old, status bar icons, implementing user experience designs, and Android logos.

Click here to download the Podcast directly!
Read More..

Saturday, February 20, 2016

Android Code Coverage Unit Testing

This is a very small post for all those who have been strugling to generate the Android Test Coverage Using the ant scripts give by android sdk itself.


I am assuming that you have created one project containing the actual source code to be tested - assume it is called "MyProject" and you have created another test project that tests MyProject, that is named MyProjectTest.


Then, you have written jUnit tests using the inherent testing support framework with android. Now, you have run your unit tests and they run successfully in ecplise. You then, what to check on the code coverage of these unit tests. Here are the steps for the same:



  •    At the command prompt, change directory to the MyProject folder
  •    Rename the existing build.xml to build_orig.xml
  •    Run this command:
android update project -p . (including the last dot)
  •    Then change directory to cd ..MyProjectTest
  •    Rename the existing build.xml to build_orig.xml
  •    Run this command:
android update test-project -m D:/..../source/MyProject -p .  (including the last dot and where you give your complete path to the MyProject folder after -m)
  •    Then, run the  command -
ant emma debug install test
This should generate a html report of the coverage under MyProjectTest/coverage


Troubleshooting:

  •    Incase you get an error "remote object coverage.ec does not exist" then start adb shell in another command prompt - in order to give write permissions to the sdcard for writing the coverage.ec file
  •    Then, run the following command at the shell
mount -o remount rw /sdcard
  •    Then you should be able to generate the report.


Read More..