Custom spinner widget in android ?

Android Spinner has problems like.,

1.OnItemSelected listener will be fired when data is loadint at first time.

2.We can’t give label to the spinner(by default text).

Hbspinner.java overcomes this problems as per our basic need.

==>Hbspinner extends from button.It is added more methods seems to be Android spinner

==>Hbspinner provides Four types of spinners

=>Normal spinner: which is working just like Android spinner.

=>singleChoice spinner: spinner populates with single choice items.

=>multipleChoice spinner: spinner populates with multi choice items(with checkboxes).you can select more items

=>spinner using adapter:spinner is populating by using adapter.(in my example i am using android default layout: “android.R.layout.select_dialog_item”)

attr.xml:

<pre><?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="spinner">
 <attr name="spinnervaluearray" format="reference" />
 <attr name="prompt" format="string" />
 <attr name="src" format="reference" />
 <attr name="mode">
 <enum name="single" value="0" />
 <enum name="multiple" value="1" />
 <enum name="single_radio" value="2" />
 </attr>
 </declare-styleable>

</resources>

In layout/main.xml ,your declaration should be like this.


<pre><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:pref="http://schemas.android.com/apk/res/com.ramesh.spinner.demo"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:gravity="center"
 android:orientation="vertical" >
<com.ramesh.spinner.demo.HbSpinner
 android:id="@+id/hbSpinner2"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:drawableRight="@drawable/arrow_down_float"
 android:text="Using Xml Attributes for Spinner "
 pref:mode="single"
 pref:prompt="Web Development"
 pref:spinnervaluearray="@array/web"
 pref:src="@drawable/ic_launcher" />
</LinearLayout>

Hbspinner.java:


package com.ramesh.spinner.demo;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.SparseBooleanArray;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListAdapter;
import android.widget.ListView;

public class HbSpinner extends Button {

private AlertDialog dialog;
 private final static int INVALID = -1;
 private CharSequence[] singeItems;
 private OnSingleItemCallback listener;
 private static OnMultiItemsSelectionCallback multilistener;
 private String title = null;
 private int icon = INVALID;
 private Drawable iconDrawable;
 private int mMode;
 public static final int SINGLE = 0;
 public static final int MULTIPLE = 1;
 public static final int SINGLE_RADIO = 2;

public HbSpinner(Context context) {
 super(context, null);
 }

public HbSpinner(Context context, AttributeSet attrs) {
 super(context, attrs);
 if (attrs != null) {
 TypedArray a = getResources().obtainAttributes(attrs,
 R.styleable.spinner);
 int count = a.getIndexCount();

for (int i = 0; i < count; i++) {
 int type = a.getIndex(i);
 switch (type) {
 case R.styleable.spinner_mode: {
 setChoiceMode(a.getInt(type, 0));
 }
 break;
 case R.styleable.spinner_spinnervaluearray: {
 singeItems = a.getTextArray(type);
 }
 break;
 case R.styleable.spinner_prompt: {
 title = a.getString(type);
 }
 break;
 case R.styleable.spinner_src: {
 iconDrawable = a.getDrawable(type);
 }
 break;
 default:
 break;
 }
 }
 a.recycle();
 }

init();
 }

public void init() {
 setOnClickListener(onClick);
 }

public void setDefaultText(String string) {
 if (string != null)
 this.setText(string);
 }

public void setIcon(int icon) {
 this.icon = icon;
 }

public void setChoiceMode(int mode) {
 if (mode < 3 && mode > INVALID)
 mMode = mode;
 // else
 // new Exception(new Throwable("Illegal Mode selection"));
 }

public void setPrompt(String title) {
 this.title = title;
 }

public void setSingleDataItems(String[] items) {
 singeItems = items;
 mMode = SINGLE;

}

/**
 * Set on single items selection.
 *
 * @param callback
 */
 public void setOnSingleItemSelectedListener(OnSingleItemCallback callback) {
 listener = callback;
 }

/**
 * Set on Multiple items selection
 *
 * @param listener
 */
 public void setOnMultiItemSelectedListener(
 OnMultiItemsSelectionCallback listener) {
 multilistener = listener;
 }

@Override
 protected void onDetachedFromWindow() {
 super.onDetachedFromWindow();
 if (dialog != null && dialog.isShowing())
 dialog.dismiss();
 }

public OnClickListener onClick = new View.OnClickListener() {

@Override
 public void onClick(View v) {

if (adapter != null) {
 popupSpinnerAdapter();
 } else if (SINGLE == mMode) {
 popupSingleSpinner();
 } else if (mMode == MULTIPLE) {
 popupMultipleSpinner();
 } else if (mMode == SINGLE_RADIO) {
 popupSingleRadioSpinner();
 }
 }
 };

public CharSequence[] getItems() {
 return singeItems;
 }

private void popupSingleSpinner() {
 if (dialog != null && dialog.isShowing())
 dialog.dismiss();
 if (singeItems.length == 0) {
 singeItems = new String[] { "" };
 }

AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
 if (title != null)
 builder.setTitle(title);
 if (icon != INVALID) {
 builder.setIcon(icon);
 } else if (iconDrawable != null) {
 builder.setIcon(iconDrawable);
 }
 builder.setItems(singeItems, onDialogClick);
 dialog = builder.create();
 dialog.show();
 }

private void popupMultipleSpinner() {
 if (dialog != null && dialog.isShowing())
 dialog.dismiss();
 if (singeItems.length == 0) {
 singeItems = new String[] { "" };
 }

AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
 if (title != null)
 builder.setTitle(title);
 if (icon != INVALID) {
 builder.setIcon(icon);
 } else if (iconDrawable != null) {
 builder.setIcon(iconDrawable);
 }
 builder.setMultiChoiceItems(singeItems, null, onMultiClick);

builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {

@Override
 public void onClick(DialogInterface dialog, int which) {
 if (multilistener != null && checkedPositions.length > 0) {
 multilistener.setMultiSelectedItemsCallback(HbSpinner.this,
 checkedPositions);
 checkedPositions = new int[0];
 }
 }
 });
 builder.setNegativeButton("Cancel", null);

dialog = builder.create();
 dialog.show();
 dialog.getListView().setOnItemClickListener(onItemSelected);

}

public DialogInterface.OnClickListener onDialogClick = new DialogInterface.OnClickListener() {
 @Override
 public void onClick(DialogInterface dialog, int which) {
 if (mMode == SINGLE_RADIO)
 checkedItem = which;

if (listener != null)
 listener.onItemSelectedListener(HbSpinner.this,
 singeItems[which], which);
 HbSpinner.this.setText(singeItems[which]);
 dialog.dismiss();
 }
 };
 public DialogInterface.OnMultiChoiceClickListener onMultiClick = new DialogInterface.OnMultiChoiceClickListener() {

@Override
 public void onClick(DialogInterface dialog, int which, boolean isChecked) {

}
 };

private int[] checkedPositions = new int[0];
 public OnItemClickListener onItemSelected = new OnItemClickListener() {
 @Override
 public void onItemClick(AdapterView<?> arg0, View arg1, int position,
 long arg3) {
 ListView view = (ListView) arg0;
 SparseBooleanArray sp = view.getCheckedItemPositions();
 checkedPositions = new int[sp.size()];
 for (int i = 0; i < sp.size(); i++)
 checkedPositions[i] = sp.keyAt(i);
 }
 };

private int checkedItem = INVALID;

private void popupSingleRadioSpinner() {
 if (dialog != null && dialog.isShowing())
 dialog.dismiss();
 if (singeItems.length == 0) {
 singeItems = new String[] { "" };
 }

AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
 if (title != null)
 builder.setTitle(title);
 if (icon != INVALID) {
 builder.setIcon(icon);
 } else if (iconDrawable != null) {
 builder.setIcon(iconDrawable);
 }
 builder.setSingleChoiceItems(singeItems, checkedItem, onDialogClick);
 dialog = builder.create();
 dialog.show();
 }

public ListAdapter adapter;

public void setAdapter(ListAdapter adapter,
 HbSpinnerAdapterCallback callbackAdapter) {
 this.adapter = adapter;
 this.callbackAdapter = callbackAdapter;
 }

private void popupSpinnerAdapter() {
 if (dialog != null && dialog.isShowing())
 dialog.dismiss();
 AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
 if (title != null)
 builder.setTitle(title);
 if (icon != INVALID) {
 builder.setIcon(icon);
 } else if (iconDrawable != null) {
 builder.setIcon(iconDrawable);
 }
 builder.setAdapter(adapter, new DialogInterface.OnClickListener() {

@Override
 public void onClick(DialogInterface dialog, int which) {
 if (callbackAdapter != null)
 callbackAdapter.onItemselectionAdapter(HbSpinner.this,
 which);
 }
 });// setSingleChoiceItems(singeItems,
 // builder.setItems(singeItems, onDialogClick);
 dialog = builder.create();
 dialog.show();
 }

public void setOnAdapterItemSelectionListener(
 HbSpinnerAdapterCallback callback) {
 callbackAdapter = callback;
 }

public ListAdapter getAdapter() {
 return adapter;
 }

HbSpinnerAdapterCallback callbackAdapter;

interface HbSpinnerAdapterCallback {
 /**
 * Adapter items selection callback
 *
 * @param spinner
 * {@link HbSpinner}
 * @param position
 * clicked position
 */
 public void onItemselectionAdapter(HbSpinner spinner, int position);
 }

interface OnMultiItemsSelectionCallback {

/**
 * Multiple items selection callback
 *
 * @param spinner
 * {@link HbSpinner}
 * @param checked
 * integer array which contains checked indexes
 */
 public void setMultiSelectedItemsCallback(HbSpinner spinner,
 int[] checked);
 }

interface OnSingleItemCallback {
 /**
 * Single items selection callback
 *
 * @param spinner
 * {@link HbSpinner}
 * @param selectedItem
 * selected item
 * @param position
 * selected position
 */
 public void onItemSelectedListener(HbSpinner spinner,
 CharSequence selectedItem, int position);
 }
}

you can find the source code here.
Screenshot:

screen shot

Custom spinner widget

Advertisements

One thought on “Custom spinner widget in android ?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s