Showing posts with label list. Show all posts
Showing posts with label list. Show all posts

Wednesday, April 17, 2013

Creating QML ListView with Search support

In last post I posted initial implementation for my Audiobook Reader app for Ubuntu-Touch, I was able to add some more features to it then after. I added support for Adding and removing custom bookmark and play the custom bookmark.

I also added support for searching the books by title in book list view. Similar to email application in Nokia N9. In this post I will show how similar feature can be implemented in QML application.

In my implementation if you pull down the book list, then it will show the search box. You can type in that search box and it will try to show books that matches that typed text. If you don't type for some time, search box will gets disappear.

Here is demo,



Following is my code. First I created TextField where user can type search text. If user type some text then I am applying the filter to my list's data model using typed text and also resetting the timer, which is responsible in hiding the search field.
    ....
    TextField{
        id: searchField
        width: parent.width
        visible: false

        onTextChanged: {
            timer.restart();
            if(text.length > 0 ) {
                model.applyFilter(text);
            } else {
                model.reload();
            }
        }

        onVisibleChanged: {
            if( visible) focus = true
        }

        Behavior on visible {
            NumberAnimation{ duration: 200 }
        }
    }
Following is my list view, Here I am setting its y property based on visibility of search field. Data model implements method for showing filtered data or all the data. Other important function is onContentYChanged, this function makes search field visible if user pull down the book list view.

    ListView {
        id:listView
        clip: true
        width: parent.width
        height: parent.height
        y: searchField.visible ? searchField.height : 0

        Behavior on y {
            NumberAnimation{ duration: 200 }
        }

        model: ListModel {
            id: model
            Component.onCompleted: {
                reload();
            }

            function reload() {
                var bookList = DB.getAllBooks();
                model.clear();
                for( var i=0; i < bookList.length ; ++i ) {
                    model.append(bookList[i]);
                }
            }

            function applyFilter(bookName) {
                var bookList = DB.getBooksByName(bookName);
                model.clear();
                for( var i=0; i < bookList.length ; ++i ) {
                    model.append(bookList[i]);
                }
            }
        }

        delegate: listDelegate

        onContentYChanged: {
            if( contentY < -100 ) {
                searchField.visible = true;
                timer.running = true;
            }
        }
    }

Lastly the timer, which is responsible for hiding the search field if user don't type anything for certain duration.
    Timer{
        id: timer; running: false; interval: 7000; repeat: false
        onTriggered: {
            searchField.visible = false;
        }
    }
That's all needed to add search support to QML ListView.

Saturday, December 24, 2011

Creating custom list view and adaptor in Android

I recently got new toy for myself a imuz TX72 7" android tablet to satisfy my book reading hobby.

I will write a seperate post for tablet, but as I got this tablet, I thought to port my Audiobook reader app to Android so I can here my audiobook on this tablet as well.

As I started to port, First thing I need to learn is how to create view and specially list view. I required to create custom Listview so I can show thumnail and other audiobook details.

So to start, First you need to create is activity. I also wanted to put button on main activity so I did not derived my activity from ListActivity but derived it from Activity. For new people to android like me, Activity is something that we see on screen , a view.

My main activity goes like below.

    
public class AudiobookReaderActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       
       setContentView(R.layout.main);
       
       ListView list = (ListView) findViewById(R.id.BookList);
       list.setAdapter( new BookListAdaptor(this));  
    }  
}

Now we have list view, but how invidiual list item looks is decided by item's xml file, which provide layout and views details to be drawn as item.

Following is my list item, with one image and two text view.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=
       "http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >
    
    <ImageView
        android:id="@+id/AlbumArt"        
      android:layout_width="55dip"
  android:layout_height="55dip"/>
    
 <LinearLayout xmlns:android=
              "http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical" >    
 
  <TextView xmlns:android=
                "http://schemas.android.com/apk/res/android"
      android:id="@+id/BookName"     
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:textStyle="bold" 
      android:padding="3dp"
      android:textColor="#FFFF00" 
      android:textSize="16sp" >
  </TextView>
  
  <TextView xmlns:android=
                      "http://schemas.android.com/apk/res/android"
      android:id="@+id/TrackName"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:padding="3dp" >
  </TextView>
  
 </LinearLayout>
</LinearLayout>

Now look is set for list view, now we need to provide data to list, by creating adaptor class. Adaptor class act as model and provide data to list view.

Following is my custom list adaptor class to support Book data structure. Here getView method is importat as it uses our xml file to create liste item and decide our list view's look.

import java.util.ArrayList;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.content.Context;

public class BookListAdaptor extends BaseAdapter {
 
 public BookListAdaptor( Context context) {
  mContext = context;
  
  //load book list from file or database
  mBookList = new ArrayList();

  mBookList.add(new AudioBook("Harry Potter"));
  mBookList.add(new AudioBook("The Hobbit"));
 }

 @Override
 public int getCount() { 
  return mBookList.size();
 }

 @Override
 public Object getItem(int position) {
  return mBookList.get(position);
 }

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

 @Override
 public View getView(int position, View convertView, ViewGroup parent) {  
  
        if (convertView == null) {
   LayoutInflater layoutInflator = 
                             LayoutInflater.from(mContext);
   convertView = layoutInflator.
                             inflate(R.layout.list_item, null);
        }
     
        TextView bookName = (TextView) convertView.
                                      findViewById(R.id.BookName);
        TextView trackName = (TextView)convertView.
                                      findViewById(R.id.TrackName);
        ImageView imageView = (ImageView)convertView.
                                      findViewById(R.id.AlbumArt);
  
  
  AudioBook book = mBookList.get(position);
  bookName.setText(book.bookName());
  trackName.setText(book.bookName());
  imageView.setBackgroundResource(android.R.drawable.btn_plus);
  
  return convertView;
  
 }

    private Context mContext;
    private ArrayList mBookList;
}

Book class looks something like following.

package com.niku;

import java.util.ArrayList;


public class AudioBook {
 
    public AudioBook( String aBookName) {
 mBookName = aBookName;
    }
 
    public String bookName() 
    {
        return mBookName;
    }

    private String mBookName;
}  
That's all. Final list view will looks like followign snap. Thanks fo reading my blog.