ExpandableListView with CheckedTextView

ExpandableListView

I was implementing a settings list activity with CheckedTextView and I found out that Android’s ExpandableListView is a handy component to display some hierarchical data. However in my case there was one weakness. You can not see which items are selected when a parent group is collapsed. I wanted to display the text of selected child items in the parent view. My biggest problem was that I couldn’t reach the parent view in reliably way when child item was clicked.

I tried to search from the internets are there any solutions ready, but I found nothing there (or I used wrong search terms). As earlier I made my own solution.

My ExpandableListView solution is based on this tutorial. 

I solved parent view issue by setting unique tag to parent view in Adapter class.

@Override
//in this method you must set the text to see the parent/group on the list
public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) {

if (view == null) {
view = inflater.inflate(R.layout.settings_list_item_parent, viewGroup,false);
}
// set category name as tag so view can be found view later
view.setTag(getGroup(i).toString());

….

}

Based on that tag I can find parent view later when child item is clicked.

@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {

CheckedTextView checkbox = (CheckedTextView)v.findViewById(R.id.list_item_text_child);
checkbox.toggle();

// find parent view by tag
View parentView = categoriesList.findViewWithTag(categories.get(groupPosition).name);


}

One nice feature that I have used in my ExpandableListView is autocollapse feature that I found here.

Get the full source code here: https://github.com/nevalla/expandablelistview-demo

Advertisements

Android libraries I have used recently

Liigavahti Android app
Liigavahti Android app

I have implemented an Android application called Liigavahti. It is only in Finnish, but basic idea is to provide Finnish ice hockey news streams to users. Application includes Twitter stream as well.

When implementing the application I found out couple of great libraries that helped me a lot and I would like to share them to you:

ActionBarSherlock [http://actionbarsherlock.com/]

ActionBarSherlock is an extension of the support library designed to facilitate the use of the action bar design pattern across all versions of Android with a single API.

Basically it provides same functionality than native ActionBar to older Android versions.

ViewPageIndicator [http://viewpagerindicator.com/]

ViewPageIndicator provides paging indicator widgets compatible with the ViewPager from the Android Support Library and ActionBarSherlock. Also here this library brings functinality of ViewPager to older Android versions

Android-PullToRefresh [https://github.com/chrisbanes/Android-PullToRefresh]

Android-PullToRefrehs project aims to provide a reusable Pull to Refresh widget for Android. You have seen this kind of functionality in several mobile apps like Twitter and Facebook. This library makes it easy to implement that kind of functionality.

GitHub Android App [https://github.com/github/android]

Actually this is not a library, but why I mention this is the reason that it helped me a lot to understand how to do things right way. So if you have some spare time I suggest you to check this out. Be careful you might learn something

When I was implementing my application I struggled a while with examples I found. So I will provide some simple tutorials how to use these libraries. So stay tuned!

How to implement TreeView with Backbone.js

I started to implement an application that uses backbone.js. One feature that I needed was some kind of treeview as a side menu. I searched some jQuery based treeviews (like jstree and jQuery plugin: Treeview) but they were not suitable as out of the box.

Finally I decided to implement feature by myself. I found that jstree had a very good model of <ul> and <li> element combinations and I went to that direction in my solution as well. See the DEMO

Basically I needed two Backbone View classes: TreeView and TreeViewItem.

TreeView

TreeView class just creates the master <ul>-element (templates/treeview/menu.jst.ejs)

<ul id="menu"></ul>

The class also fetches root level collection of MenuItems and creates TreeViewItem for each item.

TreeViewItem

TreeViewItem has one MenuItem model and a collection of TreeViewItems. In the template (templates/treeview/item.jst.ejs) name of the item is displayed and <ul> element is rendered as sub menu placeholder.

<ins>&nbsp;</ins>
<a href="#"><%= model.escape('name') %></a>
<ul></ul>

TreeViewItem handles clicks from arrow icon (<ins>-element has arrow image as a background) and opens/closes sub menu.

Both views extends Support.CompositeView (from backbone-support library).

Usage

application.js contains required libraries
backbone_treeview.js initializes TreeView class

window.BackboneTreeView = {
    Models: {},
    Collections: {},
    Views: {},

    menu: null,

    initialize: function() {

    },

    initializeMenu: function() {
        this.menu = new BackboneTreeView.Views.TreeView();
        this.menu.render();

    }

};
$(document).ready(function() {

    BackboneTreeView.initializeMenu();
});

How would you improve the implementation and should I make it as a library?

Link to project source: https://github.com/nevalla/backbone-treeview

Mongoid and assets problem on Ruby on Rails 3.2

I was doing my first Ruby on Rails application with MongoDB (via Mongoid gem). When I deployed the application to a production server, assets were compiled correctly but all javascript and css links were still pointing to stylesheets and javascripts folders, like

<link href=”/stylesheets/application.css” media=”screen” rel=”stylesheet” type=”text/css” />

I checked capistrano and server configurations, but nothing were wrong there. Finally I figured out what was causing the problem. I have not required “sprockets/railtie” in the config/application.rb

In the Mongoid documentation especially in ‘Configuration’ section is ‘Getting Rid of Active Record’ subsection which says:

Open myapp/config/application.rb and near the top, remove the line require "rails/all" and add the following lines so you end up with this:

require "action_controller/railtie"
require "action_mailer/railtie"
require "active_resource/railtie"
require "rails/test_unit/railtie"
# require "sprockets/railtie" # Uncomment this line for Rails 3.1+

In a rush I only saw number 3.1 and thought it is okay to leave it as uncommented. Current Rails version is 3.2.8 so should that line be uncommented as default on Mongoid documentation?

My favourite Prototype and Scriptaculous plugins

The unpleasant fact is that Prototype JavaScript framework is dead or at least dying. JQuery is nowadays a de facto JavaScript library and almost all the great tools are designed to use with JQuery (Bootstrap, from Twitter etc).

However there are still lots of people using Prototype or at least would be willing to use it with UI libraries by Scriptaculous and do some awesome stuff. In some level I still prefer Prototype and Scriptaculous to JQuery. Jarvis Badgley has summed this issue very good in his blog post.

If you are stuck with Prototype and Scriptaculous, there are still great and working plugins that extend Prototype and Scriptaculous. I will list now three plugins that I have lately found helpful.

Image gallery & Slideshow

Tom Doyle initially developed Simple image gallery and slideshow and Dave from ISOTOPE Communication has improved the script.

Carousel

Carousel is a highly configurable Prototype extension that creates a nice way of presenting content that is logically broken into several pieces / steps / etc

Accordion

Accordion by Kevin Miller is a lightweight accordion that supports both vertical and horizontal accordions.

Do you use still Prototype and Scriptaculous? Have you any hints or recommendations about great plugins?

How to implement CalendarView in Android

Android does not offer any calendar view in the SDK. That is a big loss from the developer’s point of view. There are lots of situations where it would be beneficial to display days of a month and provide some option for the user to choose the day.

One solution is to use a 3rd party component. The second one is to implement one by your own, like I did.

Picture 1. CalendarView

When I started to implement  the calendar view, I googled around with some search terms and found this tip.

AFAIK, there are no other way than implement your own calendar. So… what you would have to do is using a GridLayout with 7 columns and create a custom BaseAdapter to display data correctly.

That sounded reasonable and I went ahead and tried it. My aim was to implement a single calendar view where user can navigate between months and choose a date (Picture 1). You can see the result here: https://github.com/nevalla/CalendarView

Basically two classes are needed to create the implementation mentioned above. One class to display calendar grid and the other one to adapt calendar days and items into the grid.

CalendarView.java

CalendarView is  a class that encapsulates the UI of the Calendar:  a header (navigation and name of the month) and a GridView.  onCreate() method does some initializations and res/layout/calendar.xml is set for the content view. Then handler attribute is used to populate some calendar items into to the calendar. Finally some event listeners are set. GridView’s OnClickListener returns selected date as string format:

gridview.setOnItemClickListener(new OnItemClickListener() {
    public void onItemClick(AdapterView&lt;?&gt; parent, View v, int position, long id) {
    	TextView date = (TextView)v.findViewById(R.id.date);
        if(date instanceof TextView &amp;&amp; !date.getText().equals("")) {

        	Intent intent = new Intent();
        	String day = date.getText().toString();
        	if(day.length()==1) {
        		day = "0"+day;
        	}
        	// return selected date as string format
        	intent.putExtra("date", android.text.format.DateFormat.format("yyyy-MM", month)+"-"+day);
        	setResult(RESULT_OK, intent);
        	finish();
        }

    }
});

refreshCalendar() method asks calendar adapter to refresh itself and changes month name.
onNewItem() method captures date parameter and sets it as current date.

CalendarAdapter.java

CalendarAdapter is a class that handles the content of the calendar – how many days to display and whether to display calendar item icon or not.

refreshDays() method formats source array for the grid. Application assumes that weeks start on Monday, thus calculation is needed on how many empty days are before the first day of the month.

getView() method creates a view for each item referenced by the adapter. Layout of the view is defined in res/layout/calendar_item.xml.

CalendarViewSampleActivity.java

CalendarViewSampleActivity is an activity class that opens CalendarView. DatePicker’s date is updated by the return  value of the CalendarView.
So this is relatively simplified example of how to display calendar month and populate some items into it. How do you like it and how would you improve it?

UPDATE 1:

Since API level 11 (Android 3.0) there has been the native implementation of the CalendarView. However it’s just the view where you can pick a date, no calendar items can be shown.