RSS

Monthly Archives: July 2012

Android User Interface Design: Horizontal View Paging

By: tutsplus.com

Perhaps you’ve seen some of the new user interface features available as part of the Android compatibility package. One such feature, horizontal view paging, allows for easy left and right swipes to load different screens (pages), controlled by a single Activity. This feature has been showcased in several high profile applications like the Android Market application and the Google+ Android client.

There are a number of classes in the Android compatibility package that can be used to implement horizontal page swiping behavior in your Android packages. The ViewPager control (android.support.v4.view.ViewPager) provides the horizontal swiping behavior. It can be used within your layouts much like a Gallery or other adapter-populated user interface control would be. The PagerAdapter (android.support.v4.view.PagerAdapter) class is used to define the data displayed by the ViewPager control. Today we’ll look at a simple example of how to use these classes to provide swiping behavior.


Step 0: Getting Started

We provide the full source code for the sample application discussed in this tutorial. You can download thesample source code we provide for review.


Step 1: Use the Compatibility Package

Horizontal view paging is based upon APIs only available with the Android Compatibility package v4, Revision 3; these APIs are not available in the standard Android SDK at this time. Therefore, you will need to add the Android compatibility package to your Android project to access the appropriate APIs.

To add the Android Compatibility package to your Eclipse Android project, right-click on the project in the Project Explorer. Choose Android Tools, Add Compatibility Library. You will now see the android-support-v4.jar file in your Referenced Libraries project folder. This means you have successfully added the package to your project and can now start using it.


Step 2: Define a ViewPager

Next, you’ll need to define a ViewPager control in your layout resource file. In our simple example, we update the main.xml layout resource used by our Activity class, and define a ViewPager control within that layout. This control must be referenced by its fully-qualified name: android.support.v4.view.ViewPager.

For example, here’s the updated main.xml layout resource with a ViewPager defined:

1
2
3
4
5
6
7
8
9
10
<?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">
<android.support.v4.view.ViewPager
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/myfivepanelpager"/>
</LinearLayout>

ViewPager controls often take up the entire screen, but this need not be the case. For this example, we will display five different layout “pages”, thus we call our ViewPager control by a unique identifier labeled myfivepanelpager.


Step 3: Create Page Layout Resources

Next, you’ll want to create a set of resources that will make up the “pages” or “panes” for horizontal swiping. You can use the same layout resource file for each page and add different content, or you can load completely different layout resources for the individual pages. For this example, we created five separate layout resource files, called farleft.xml, left.xml, middle.xml, right.xml, and farright.xml. Each layout resource has different contents to display. The contents of each layout resource are up to you. You can use static or dynamic controls. To keep this example simple, we’ll stick with static controls like TextView and ImageView controls. For the far left and far right pages, we’ll include some Button controls.

This image shows the five different layout resource file results:

Five different layout screens to page between

There is nothing special about the implementation of these layout files. Don’t forget to implement any Button onClick handlers in your Activity class. These layout resources will be loaded by the PagerAdapter at runtime for display on the screen. For implementation details, see the source code that accompanies this project.


Step 4: Implement a Custom PagerAdapter

Your ViewPager needs a data adapter to determine and load the appropriate content for each page the user swipes to. We have named our layout resource file “pages” in the order we want them to display, from far left to far right.

When you extend the PagerAdapter class, you’ll need to implement several key methods.

First, you’ll need to define the size of your paging range. In this case, we have a set of five pages to display. Therefore, you’ll want the getCount() method of the MyPagerAdapter class to return a page size of 5.

Next, you need to implement the instantiateItem() method to inflate the appropriate layout resource file, depending on the user’s swipe position. The farthest page to the left is in position 0, the next page to the right is position 1, and so on. The instantiateItem() method uses the LayoutInflater service to inflate the specific layout and add it to the collection used by the ViewPager.

This image shows the five different layout resource files and their “positions” in the terms of paging order:

Five screens in 'paging' order

The last important method you need to implement is the destroyItem() method, which removes the specific layout from the collection used by the ViewPager when it is no longer being displayed.

Here is a basic implementation for a five-page horizontal pager adapter, called MyPagerAdapter, which implements these core methods as well as a few others:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
private class MyPagerAdapter extends PagerAdapter {
        public int getCount() {
            return 5;
        }
        public Object instantiateItem(View collection, int position) {
            LayoutInflater inflater = (LayoutInflater) collection.getContext()
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            int resId = 0;
            switch (position) {
            case 0:
                resId = R.layout.farleft;
                break;
            case 1:
                resId = R.layout.left;
                break;
            case 2:
                resId = R.layout.middle;
                break;
            case 3:
                resId = R.layout.right;
                break;
            case 4:
                resId = R.layout.farright;
                break;
            }
            View view = inflater.inflate(resId, null);
            ((ViewPager) collection).addView(view, 0);
            return view;
        }
        @Override
        public void destroyItem(View arg0, int arg1, Object arg2) {
            ((ViewPager) arg0).removeView((View) arg2);
        }
        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            return arg0 == ((View) arg1);
        }
        @Override
        public Parcelable saveState() {
            return null;
        }
}

Step 5: Bind MyPagerAdapter

Lastly, you need to update the onCreate() method of your Activity class to bind your MyPagerAdapter to the ViewPager control defined in your main.xml layout resource file.

You can also take this time to set the initial position of the pager. By default, it would start at position 0 (the far left layout with the simple Button control). However, we want to allow the user to swipe left and right so we set the initial position of the ViewPager to the middle layout (the monkey in the middle) using the setCurrentItem() method.

1
2
3
4
5
6
7
8
9
10
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    MyPagerAdapter adapter = new MyPagerAdapter();
    ViewPager myPager = (ViewPager) findViewById(R.id.myfivepanelpager);
    myPager.setAdapter(adapter);
    myPager.setCurrentItem(2);
}

Now if you run your application, you’ll begin with the monkey in the middle page, and be able to swipe two pages left or right, as shown here:

All five screens can now be swiped between

Conclusion

The horizontal view pager user interface control is a neat user interface control made available to Android developers through the Android compatibility package. Data for the individual “pages” is managed by a special data adapter called a PagerAdapter. There are also classes within the compatibility library for building fragment-compatible data adapters for driving ViewPager controls.

About the Authors

Mobile developers Lauren Darcey and Shane Conder have coauthored several books on Android development: an in-depth programming book entitled Android Wireless Application Development, Second Edition and Sams Teach Yourself Android Application Development in 24 Hours, Second Edition. When not writing, they spend their time developing mobile software at their company and providing consulting services. They can be reached at via email to androidwirelessdev+mt@gmail.com, via their blog atandroidbook.blogspot.com, and on Twitter @androidwireless.

Referenced by: http://mobile.tutsplus.com/tutorials/android/android-user-interface-design-horizontal-view-paging/

Advertisements
 
Leave a comment

Posted by on July 25, 2012 in Android, Mobile Development

 

Yii: use ajax function via htmlOptions attribute

By: lars

If you want to trigger an ajax call on a Yii form element onchange, you can pass an array of ajax attributes as one of the “htmlOptions” like so:

<?php echo $form->textField($model,'my_input_field',array(
	'ajax' => array(
		'type'=>'POST', //request type
		'url'=>$this->createUrl('site/ajaxAction'), // url to call controller action
		'success'=>' function(data) { $(\'#my_output_field\').val(data) }',// function to call onsuccess 
             // "data" is returned data and function can be regular js or jQuery
             // here we are are updating the value of another field that has id "my_output_field"
	),
	'size'=>60,
	'maxlength'=>128,
)); ?>

and the (site) controller action would look something like:

public function actionAjaxAction() {
  [check/filter inputs...]
  [data functions...]
  echo $my_val_string;
  Yii::app()->end()
}
 
Leave a comment

Posted by on July 11, 2012 in Yii

 

Creating a CSS Driven Drop Down Menu using CMenu

By: Yii

CMenu offers great functionality and the ability to customize just about every aspect of the output. There are many times when I need to create a drop down menu or simply modify the look to make the designers happy. Because this seems to be a common task for me, I figured I would share my code to create a very simple drop down menu that other people could use.

There are many ways to approach this but I wanted to start out very simply so we are going to accomplish this using nothing but CSS.

Here is our desired output:

<div id="menu-top"> 
  <ul id="yw1">
    <li id="itemCompany"><a id="menuCompany" href="/company/index">Company</a>
      <ul>
        <li class="active"><a href="/company/index">Our Mission</a></li>
        <li><a href="/company/aboutUs">About Us</a></li>
        <li><a href="/company/careers">Careers</a></li>
        <li><a href="/company/contactUs">Contact Us</a></li>
        <li><a href="/company/storeLocator">Store Locator</a></li>
      </ul>
    </li>
    <li><a id="menuBlog" href="/blog/post/index">Blog</a></li>
    <li id="itemChange"><a id="menuChange" href="/change/index">Change</a>
      <ul>
        <li><a href="/change/index">Community Involvement</a></li>
        <li><a href="/change/ecoPolicy">Eco Responsibility</a></li>
        <li><a href="/change/responsibility">Responsibility</a></li>
      </ul>
    </li>
    <li><a id="menuBuy" href="/shop">Shop</a></li>
  </ul>
</div>

And here is the code we are going to use to create this output:

<div id="menu-top">
<?php
$this->widget('zii.widgets.CMenu',array(
  'activeCssClass'=>'active',
  'activateParents'=>true,
  'items'=>array(
    array(
      'label'=>'Company',
      'url'=>array('/company/index'),
      'linkOptions'=>array('id'=>'menuCompany'),
      'itemOptions'=>array('id'=>'itemCompany'),
      'items'=>array(
        array('label'=>'Our Mission', 'url'=>array('/company/index')),
        array('label'=>'About Us', 'url'=>array('/company/aboutUs')),
        array('label'=>'Careers', 'url'=>array('/company/careers')),
        array('label'=>'Contact Us', 'url'=>array('/company/contactUs')),
        array('label'=>'Store Locator', 'url'=>array('/company/storeLocator')),
      ),
    ),
    array(
      'label'=>'Blog',
      'url'=>array('/blog/post/index'),
      'linkOptions'=>array('id'=>'menuBlog')
    ),
    array(
      'label'=>'Change',
      'url'=>array('/change/index'),
      'linkOptions'=>array('id'=>'menuChange'),
      'itemOptions'=>array('id'=>'itemChange'),
      'items'=>array(
        array('label'=>'Community Involvement', 'url'=>array('/change/index')),
        array('label'=>'Eco Responsibility', 'url'=>array('/change/ecoPolicy')),
        array('label'=>'Responsibility', 'url'=>array('/change/responsibility')),
      ),
    ),
    array(
      'label'=>'Shop',
      'url'=>array('/shop'),
      'linkOptions'=>array('id'=>'menuBuy')
    ),
  ),
)); ?>
</div>

Let’s dig into the code to see what is happening here.

CMenu::activeCssClass is simply the CSS class that will be assigned to the active menu item. The active menu item simply indicates the current page you are viewing by adding some style to that menu link.CMenu::activateParents means that when a child item is activated, the parent of that item will be given the ‘active’ css class assignment as well.

You will notice that the ‘Company’ item has another CMenu::items array set under it that will be the items that show up in the drop down when a user hovers over ‘Company’ in the menu.

Also, in the parent items ( Company, Blog, Affecting Change, Shop ) you will see that we take advantage of theCMenu::linkOptions property in order to add an ID to tag that Yii will output wrapping the label. I needed to do this because the menu I am creating uses sprites which means I need an ID for each menu item to specify the background-position property of each item independently.

Ok so now that we have our PHP setup, let’s dig into the CSS part. I am also not going to include the code for the sprites to keep things simple.

#menu-top ul { list-style: none; margin: 0; padding: 0; position: relative; height: 30px; }

#menu-top ul li { display: block; height: 28px; float: left; overflow: visible; }
#menu-top ul li:hover > ul { display: block; }

#menu-top ul li a { float: left; display: block; }

#menu-top ul li ul { display: none; position: absolute; top: 100%;
                    background: #000; color: #fff; height: auto;
}

#menu-top ul li ul li a { color: #ccc; padding: 4px 14px; display: block; }

#menu-top ul li ul li.active a,
#menu-top ul li ul li a:hover { color: #fff; }

An important part to pay attention to is setting the overflow to visible on the ‘#menu-top ul li’ elements. Otherwise, when you mouseover an parent item, the child items will not be visible.

The line that does all the magic is: #menu-top ul li:hover > ul { display: block; }

This simply means that when a user hovers over a parent item ( ul li ), take any child ul elements and switch them from ‘display: none;’ to ‘display: block;’ making them visible.

Once you put this all together, you should have a nice little drop down menu with active highlighting.

Referenced by: http://www.yiiframework.com/wiki/211/creating-a-css-driven-drop-down-menu-using-cmenu/

 
1 Comment

Posted by on July 8, 2012 in Yii

 

How to create a Custom Pagination Widget for Yii Framework

By:

Agile Web Application Development with Yii 1.1 and PHP5Yii Framework is great, I truly like this framework, makes complicated things an easy task and its learning curve quite easy. But… yeah man, is always a but… what happens to all those fellow programmers, like me, that do not like the way ‘automated things’ are? Where are the tutorials to change and improve the framework and make it work just the way we like? There are not many around…

Again, a programmer needs to investigate the guts of the framework, in order to find out how to properly do it. But don’t worry, if you have a question in the format: would I be able to do this with Yii? The answer will be always positive. It is a great framework.

So, I would like to share with you guys my personal experience and put some small tutorials to ‘open’ the minds of others begginning with this framework. This will be the first of a set of small tuts on this Framework.

Creating a Custom Pagination Widget

A pagination Widget is the responsible of displaying a set of numbered links that lead to different pages of target. When you first create a Web application through the yiic tool – this tool creates the skeleton of the application, the automated CMS works with CLinkPager widget and its style and Page Links were not suitable for my project. My project had to end up making AJAX calls and its STYLE like the following picture:

Please not that if you want to just change its style, you can create a skin as exposed here:http://www.yiiframework.com/doc/guide/topics.theming#customizing-widgets-globally. Once I look at the code, I realized that creating a custom widget was easier than I thought. The first thing we need to do is to extend our new Widget class from CLinkPager, my class is named SimplaPager as I have used a template admin theme called SIMPLA.

1
class SimplaPager extends CLinkPager

Now, there are three methods to override from our father and grandfather classes (CLinkPager and CBasePager). The parent methods we need to override are run and createPageButtons and from our grandfather class createPageUrl.

a)  run Function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public function run()
{
     //
     // here we call our createPageButtons
     //
     $buttons=$this->createPageButtons();
     //
     // if there is nothing to display return
     if(empty($buttons))
          return;
     //
     // display the buttons
     //
     echo $this->header; // if any
     echo implode("&nbsp;",$buttons);
     echo $this->footer;  // if any
 }

b) createPageButton Function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
 * Creates a page button.
 * You may override this method to customize the page buttons.
 * @param string the text label for the button
 * @param integer the page number
 * @param string the CSS class for the page button. This could be 'page', 'first', 'last', 'next' or 'previous'.
 * @param boolean whether this page button is visible
 * @param boolean whether this page button is selected
 * @return string the generated button
 */
protected function createPageButton($label,$page,$class,$hidden,$selected)
{
       //
       // CSS_HIDDEN_PAGE and CSS_SELECTED_PAGE
       // are constants that we use to apply our styles
       //
    if($hidden || $selected)
        $class=' '.($hidden ? self::CSS_HIDDEN_PAGE : self::CSS_SELECTED_PAGE);
    $class .= ' number';
       //
       // here I write my custom link - site.call is a JS function that takes care of an AJAX call
       //
    return CHtml::link($label,'#',array(
                'class'=>$class,
                'onclick'=>"site.call(CONST_MAIN_LAYER,'{$this->createPageUrl($this->getController(),$page)}');"));
}

c) createPageUrl Function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* Creates the URL suitable for pagination.
* This method is mainly called by pagers when creating URLs used to
* perform pagination. The default implementation is to call
* the controller's createUrl method with the page information.
* @param CController the controller that will create the actual URL
* @param integer the page that the URL should point to. This is a zero-based index.
* @return string the created URL
*/
public function createPageUrl($controller,$page)
{
    // HERE I USE POST AS I DO AJAX CALLS VIA POST NOT GET AS IT IS BY
    // DEFAULT ON YII
    $params=$this->getPages()->params===null ? $_POST : $this->getPages()->params;
    if($page>0) // page 0 is the default
       $params[$this->getPages()->pageVar]=$page+1;
   else
      unset($params[$this->getPages()->pageVar]);
   return $controller->createUrl($this->getPages()->route,$params);
}

Styling is controlled by a couple of constants in CLinkPager class, so the only thing we need to do is to override those constants.

1
2
const CSS_HIDDEN_PAGE='hidden';
const CSS_SELECTED_PAGE='current';

How to use the Widget

In order to use this widget first we create a widget subfolder in our application’s protected folder (in my case I saved a file named SimplaPager.php) and call it in our views like this:

1
2
3
$this->widget('application.widgets.SimplaPager', array(
    'pages'=>$pagination,
));

I have created another widget to display records in a table because I had the same problems than with the pagination so I use the the pagination within the Table Widget I created like this:

1
2
3
4
5
/**
 * @var array the configuration for the pager. Defaults to <code>array('class'=>'CLinkPager')</code>.
* @see enablePagination
 */
public $pager=array('class'=>'application.widgets.SimplaPager');

I promise I will discuss how to create a Table Widget in the next post :) . Nevertheless, you can view how both widgets look at the end:

SimplaTable and SimplaPager working together

DOWNLOAD

Please remember than this class has some AJAX calls in its createPageButton function that is exclusive for my project. Change that part to suit your needs. This class was for you to better understand how to create custom Widgets by extending those from Yii framework.

 
1 Comment

Posted by on July 7, 2012 in Yii

 

How to create a breadcrumb widget

By:

Here’s a simple way to create a breadcrumb widget to be used in your templates. The idea is just to isolate how the breadcrumb is generated based on an array of crumbs.

Info: Please note, that new versions of Yii Framework already contain a bulit-in breadcrumbs widget. See this class reference chapter for more information. Information in this article may be, however, usable to build custom one, not descending from bulit-in one.

components/BreadCrumb.php:

<?php
class BreadCrumb extends CWidget {

    public $crumbs = array();
    public $delimiter = ' / ';

    public function run() {
        $this->render('breadCrumb');
    }

}
?>

components/views/breadCrumb.php:

<div id="breadCrumb">   
    <?php 
    foreach($this->crumbs as $crumb) {
        if(isset($crumb['url'])) {
            echo CHtml::link($crumb['name'], $crumb['url']);
        } else {
            echo $crumb['name'];
        }
        if(next($this->crumbs)) {
            echo $this->delimiter;
        }
    }
    ?>
</div>

Usage in views

<?php $this->widget('application.components.BreadCrumb', array(
  'crumbs' => array(
    array('name' => 'Home', 'url' => array('site/index')),
    array('name' => 'Login'),
  ),
  'delimiter' => ' &rarr; ', // if you want to change it
)); ?>
 
Leave a comment

Posted by on July 5, 2012 in PHP, Yii