Monday, December 19, 2011

Android Custom Dialog Box with a Ratting Bar

This is an example for updating rating on a dialog box.

Activity Code:
Button rankBtn = (Button) findViewById(R.id.rank_button);
rankBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
rankDialog = new Dialog(MyActivity.this, R.style.FullHeightDialog);
rankDialog.setContentView(R.layout.rank_dialog);
rankDialog.setCancelable(true);
ratingBar = (RatingBar)rankDialog.findViewById(R.id.dialog_ratingbar);
ratingBar.setRating(userRankValue);

TextView text = (TextView) rankDialog.findViewById(R.id.rank_dialog_text1);
text.setText(name);

Button updateButton = (Button) rankDialog.findViewById(R.id.rank_dialog_button);
updateButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
rankDialog.dismiss();
}
});
//now that the dialog is set up, it's time to show it
rankDialog.show();
}
});

layout/rank_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="2dip">

<TextView android:text="Doctor's Name" android:id="@+id/rank_dialog_text1"
android:textSize="24dp" android:layout_marginTop="10dp"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center"/>

<RatingBar
android:layout_marginTop="10dp" android:layout_marginBottom="10dp"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:clickable="true"
android:id="@+id/dialog_ratingbar" android:layout_gravity="center"
android:numStars="5" android:stepSize="1.0" android:rating="2"
android:isIndicator="false"/>

<Button android:id="@+id/rank_dialog_button"
android:layout_height="wrap_content"
android:text="Update" android:focusable="false"
android:layout_margin="5dip" android:textColor="#FFF8C6"
android:textSize="20dip" android:layout_width="fill_parent" />

</LinearLayout>

values/my_style.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="FullHeightDialog" parent="android:style/Theme.Dialog">
<item name="android:windowNoTitle">true</item>
</style>
</resources>

Tuesday, December 13, 2011

Android TextWatcher(auto-complete-text-view) example

We often require a ListView with search option. Here is an example of a ListView with a TextEdit on top. The target of this program is to update the list items as user types into the TextEdit box.

Layout XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/item_top_wrapper" android:background="#991A1111"
android:paddingLeft="2dip" android:paddingRight="2dip"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:focusable="true"
android:focusableInTouchMode="true">
<EditText android:id="@+id/search_string"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dip"
android:hint="Search Key"
android:singleLine="true" />
</LinearLayout>

<ListView
android:id="@+id/itemList"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/item_top_wrapper"
android:background="#55E0FFFF"
android:cacheColorHint="#00000000"/>

</RelativeLayout>

Activity Code:
ListView itemListView = (ListView)findViewById(R.id.itemList);
TextView textView = (TextView)findViewById(R.id.search_string);
ArrayAdapter<String> autoCompleteAdapter =
new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line);
// This is so I don't have to manually sync whenever changed
autoCompleteAdapter.setNotifyOnChange(true);

itemListView.setAdapter(autoCompleteAdapter);

final TextWatcher textChecker = new TextWatcher() {

public void afterTextChanged(Editable s) {
textView.setEnabled(true);
}

public void beforeTextChanged(CharSequence s, int start, int count, int after) {
textView.setEnabled(false);
}

public void onTextChanged(CharSequence s, int start, int before, int count) {
autoCompleteAdapter.clear();
for (int i=1; i < nameArr.length; i++) {
if(nameArr[i].contains(s.toString()))
autoCompleteAdapter.add((String) nameArr[i]);
}
}
};
textView.addTextChangedListener(textChecker);

Android ListView Simple Adapter(custom style) example

This is an example of a very simple list view with custom style/layout.
ListView itemListView = (ListView)findViewById(R.id.itemChoseList);
List docList = new ArrayList();
HashMap<String,String> temp = new HashMap<String,String>();
temp.put("docTitile1", "My Title");
temp.put("docTitile2", "Sub title");
docList.add(temp);
simpleAdapter = new SimpleAdapter(
this,
docList,
R.layout.doc_row_lite,
new String[] {"docTitile1","docTitile2"},
new int[] {R.id.doc_lite_title1, R.id.doc_lite_title2});
itemListView.setAdapter(simpleAdapter);

doc_row_lite.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="wrap_content"
android:padding="2dip">

<TextView
android:id="@+id/doc_lite_title1"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:textColor="#000000"
android:textSize="18dip"
android:gravity="center_vertical"
/>
<TextView
android:id="@+id/doc_lite_title2"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:textSize="13dip"
android:text="shamim"
android:textColor="#111133"
android:singleLine="true"/>
</LinearLayout>

Android Custom Transparent Button Style

A fancy button/layout style is one of the most common things to use in a mobile application. This is how I use to do it..
<Button android:id="@+id/createNewBtn" 
android:background="@drawable/custom_button"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="Create New"
android:textColor="#FFF8C6"
android:textSize="15dip"/>

drawable-hdpi/custom_button.xml
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">

<item android:state_pressed="true" >
<shape>
<gradient
android:startColor="#FBB117"
android:endColor="#F88017"
android:angle="270" />
<stroke
android:width="2dp"
android:color="#646060" />
<corners android:radius="3dp" />
<padding android:left="10dp" android:top="5dp"
android:right="10dp" android:bottom="5dp" />
</shape>
</item>

<item android:state_focused="true" >
<shape>
<gradient
android:endColor="#7E3117"
android:startColor="#7E3817"
android:angle="270" />
<stroke
android:width="3dp"
android:color="#646060" />
<corners android:radius="3dp" />
<padding android:left="10dp" android:top="5dp"
android:right="10dp" android:bottom="5dp" />
</shape>
</item>

<item>
<shape>
<gradient
android:startColor="#991A1111"
android:endColor="#991A1111"
android:angle="270" />
<stroke
android:width="0dp"
android:color="#646060" />
<corners android:radius="5dp" />
<padding android:left="10dp" android:top="5dp"
android:right="10dp" android:bottom="5dp" />
</shape>
</item>
</selector>

Sunday, December 11, 2011

Custom animation on Activity Transition

This is an easy way to apply custom animation on Activity Transition. Here I created three xml files for animation and put them into res/anim folder. And then just apply the animation to any Activity.

res/anim/zoom_enter.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<alpha
android:fromAlpha="0"
android:toAlpha="1.0"
android:duration="700"/>

</set>

res/anim/zoom_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<scale
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromXScale="1.0"
android:toXScale="5.0"
android:fromYScale="1.0"
android:toYScale="5.0"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="false"
android:duration="300" />

</set>

res/anim/zoom_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<scale
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromXScale="1.0"
android:toXScale="0.0"
android:fromYScale="1.0"
android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="false"
android:duration="500" />

</set>

Activity Class:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
overridePendingTransition(R.anim.zoom_enter, R.anim.zoom_in);
...
}

@Override
public void onBackPressed () {
super.onBackPressed ();
this.overridePendingTransition(R.anim.zoom_enter, R.anim.zoom_out);
}

Thursday, December 8, 2011

Android Ratting Bar Styles

Things to know about Android ratting bar before we use them,
a. RattingBar is not editable by default until we set the isIndicator property to "false".
b. There are few styles available for Ratting Bar, one is "?android:attr/ratingBarStyleSmall".

<RatingBar 
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:id="@+id/doc_dialog_ratingbar"
android:numStars="5"
android:stepSize="1.0"
android:rating="2"
android:isIndicator="false"/>

<RatingBar android:id="@+id/list_ratingbar_small"
android:layout_width="wrap_content" android:focusable="false"
android:layout_height="wrap_content"
style="?android:attr/ratingBarStyleSmall"
android:rating="3"
android:numStars="5"/>

AsyncTask to Show Image with loading

Following code will show a progress bar(ajax-loading) instead of the image I want to show.
docImage.setVisibility(View.GONE);
pBar.setVisibility(View.VISIBLE);
new DownloadFilesTask().execute(new URL("http://..."));

Once the download is complete the target image will be shown and the progress bar will be gone. To make this code work we need to put both target-image and progress-bar in the same layout position.
private class DownloadFilesTask extends AsyncTask {

Drawable d;

public Object fetch(URL url) throws MalformedURLException,IOException {
Object content = url.getContent();
return content;
}

protected Long doInBackground(URL... urls) {
long totalSize = 0;
URL url = urls[0];
try {
InputStream is = (InputStream) this.fetch(url);
d = Drawable.createFromStream(is, "src");
} catch (Exception e) {
e.printStackTrace();
return 0L;
}
return totalSize;
}

protected void onProgressUpdate(Integer... progress) {
//setProgressPercent(progress[0]);
}

protected void onPostExecute(Long result) {
docImage.setImageDrawable(d);
pBar.setVisibility(View.GONE);
docImage.setVisibility(View.VISIBLE);
}
}

Thursday, December 1, 2011

Android/SQLite FTS (Full Text Search)

First thing we need to do is create an index table using following sql statement. This virtual table can be treated as an ordinary table. But there are few rules for FTS3 such as, all the columns must be string/text.

CREATE VIRTUAL TABLE  t_doc_fts USING FTS3(doc_id, text)

Insert Data as any other table. Put all searchable strings comma separated in 'text' column. And reference id in 'doc_id' column. Here reference id is the primary key of the actual search table. If 'doc_id' column is still confusing please see the search method below.

public void populateFTS(long docId, String[] data){
db.execSQL("INSERT INTO t_doc_fts(doc_id, text) values( "+docId
+", '"+data[1]+","+data[2]+","
+data[3]+","+data[4]+","+data[5]+","+data[6]+","+data[7]+"')");
}

public long insert(String[] data) throws RuntimeException{
long id = db.insert(...);
/* populate FTS table */
populateFTS(id, data);
return id;
}

Search Method:
public Cursor fetchDocumentFTS(String code) throws RuntimeException {
key = code.replace(' ', '*');
key = key+"*";

System.out.println("FTS KEY="+key);
Cursor cur0 = dbr.query(true, "t_doc_fts",
new String[]{"doc_id","text"},
"text MATCH '"+key+"'",
null, null, null, null, null);
String ids = "";
if(cur0 != null){
cur0.moveToFirst();
for(int i=0; i < cur0.getCount(); i++){
if(i == 0)
ids = cur0.getString(0);
else
ids = ids+","+cur0.getString(0);
cur0.moveToNext();
}
cur0.close();
}
System.out.println("FTS IDS="+ids);
Cursor cur = dbr.query(true, "t_document", new String[]{...},
"_id IN ("+ids+")",
null, null, null, null, null);
if(cur!=null)
cur.moveToFirst();
return cur;
}