Yeah, I effing did it!!!!!!!!!! (Sorry, still pumped from finally getting this to work.)
First off: giving credit where credit is due. Many many many thanks to my sources:
http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/
http://www.mail-archive.com/android-developers@googlegroups.com/msg28194.html
http://www.chriskopec.com/blog/2010/mar/13/deploying-android-apps-with-large-databases/
My project requires a preformed database (SQLite), which in total comes out to a whopping 17mb. Ridiculous I know, but my boss wants it all packaged with the app, and not just to be available online. Hypothetically, getting this to work should be as easy as creating a blank db and then copying the existing one over it from assets or raw. And this totally works-- if your db is smaller than 1mb. So I went and got some free file splitting software (http://www.dekabyte.com/filesplitter/) and split my db file into 1mb pieces. I put the pieces in the raw directory.
I created the DataBaseHelper class and made the necessary tweaks:
public class DataBaseHelper extends SQLiteOpenHelper {
// The Android's default system path of your application database.
private static final String DB_PATH = "/data/data/com.instacare/databases/";
private static final String DB_NAME = "MDAtHand";
private SQLiteDatabase myDataBase;
private final Context myContext;
Resources resources;
/**
* Constructor Takes and keeps a reference of the passed context in order to
* access to the application assets and resources.
*
* @param context
*/
public DataBaseHelper(Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
// super(context, DB_NAME, null, 1);
resources = context.getResources();
}
/**
* Creates a empty database on the system and rewrites it with your own
* database.
* */
public void createDataBase() throws IOException {
boolean dbExist = checkDataBase();
if (dbExist) {
// do nothing - database already exist
copyDataBase();
} else {
// By calling this method and empty database will be created into
// the default system path
// of your application so we are gonna be able to overwrite that
// database with our database.
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
/**
* Check if the database already exist to avoid re-copying the file each
* time you open the application.
*
* @return true if it exists, false if it doesn't
*/
private boolean checkDataBase() {
SQLiteDatabase checkDB = null;
try {
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READONLY);
} catch (SQLiteException e) {
// database does't exist yet.
}
if (checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
/**
* Copies your database from your local assets-folder to the just created
* empty database in the system folder, from where it can be accessed and
* handled. This is done by transfering bytestream.
* */
private void copyDataBase() throws IOException {
// Open your local db as the input stream
// InputStream myInput = myContext.getAssets().open(DB_NAME);
// Path to the just created empty db
// String outFileName = DB_PATH + DB_NAME;
// Open the empty db as the output stream
// OutputStream myOutput = new FileOutputStream(outFileName);
// transfer bytes from the inputfile to the outputfile
// byte[] buffer = new byte[1024];
// int length;
// while ((length = myInput.read(buffer))>0){
// myOutput.write(buffer, 0, length);
// }
// Close the streams
// myOutput.flush();
// myOutput.close();
// myInput.close();
InputStream databaseInput = null;
// String outFileName = DB_PATH + DbConsts.DATABASE_NAME;
String outFileName = DB_PATH + DB_NAME;
OutputStream databaseOutput = new FileOutputStream(outFileName);
byte[] buffer = new byte[1024];
int length;
databaseInput = resources.openRawResource(R.raw.datafile01);
while ((length = databaseInput.read(buffer)) > 0) {
databaseOutput.write(buffer, 0, length);
databaseOutput.flush();
}
databaseInput.close();
databaseInput = resources.openRawResource(R.raw.datafile02);
while((length = databaseInput.read(buffer)) > 0) {
databaseOutput.write(buffer, 0, length);
databaseOutput.flush();
}
databaseInput.close();
databaseInput = resources.openRawResource(R.raw.datafile03);
while((length = databaseInput.read(buffer)) > 0) {
databaseOutput.write(buffer, 0, length);
databaseOutput.flush();
}
databaseInput.close();
databaseInput = resources.openRawResource(R.raw.datafile04);
while((length = databaseInput.read(buffer)) > 0) {
databaseOutput.write(buffer, 0, length);
databaseOutput.flush();
}
databaseInput.close();
databaseInput = resources.openRawResource(R.raw.datafile05);
while((length = databaseInput.read(buffer)) > 0) {
databaseOutput.write(buffer, 0, length);
databaseOutput.flush();
}
databaseInput.close();
databaseInput = resources.openRawResource(R.raw.datafile06);
while((length = databaseInput.read(buffer)) > 0) {
databaseOutput.write(buffer, 0, length);
databaseOutput.flush();
}
databaseInput.close();
databaseInput = resources.openRawResource(R.raw.datafile07);
while((length = databaseInput.read(buffer)) > 0) {
databaseOutput.write(buffer, 0, length);
databaseOutput.flush();
}
databaseInput.close();
databaseInput = resources.openRawResource(R.raw.datafile08);
while((length = databaseInput.read(buffer)) > 0) {
databaseOutput.write(buffer, 0, length);
databaseOutput.flush();
}
databaseInput.close();
databaseInput = resources.openRawResource(R.raw.datafile09);
while((length = databaseInput.read(buffer)) > 0) {
databaseOutput.write(buffer, 0, length);
databaseOutput.flush();
}
databaseInput.close();
databaseInput = resources.openRawResource(R.raw.datafile10);
while((length = databaseInput.read(buffer)) > 0) {
databaseOutput.write(buffer, 0, length);
databaseOutput.flush();
}
databaseInput.close();
databaseInput = resources.openRawResource(R.raw.datafile11);
while((length = databaseInput.read(buffer)) > 0) {
databaseOutput.write(buffer, 0, length);
databaseOutput.flush();
}
databaseInput.close();
databaseInput = resources.openRawResource(R.raw.datafile12);
while((length = databaseInput.read(buffer)) > 0) {
databaseOutput.write(buffer, 0, length);
databaseOutput.flush();
}
databaseInput.close();
databaseInput = resources.openRawResource(R.raw.datafile13);
while((length = databaseInput.read(buffer)) > 0) {
databaseOutput.write(buffer, 0, length);
databaseOutput.flush();
}
databaseInput.close();
databaseInput = resources.openRawResource(R.raw.datafile14);
while((length = databaseInput.read(buffer)) > 0) {
databaseOutput.write(buffer, 0, length);
databaseOutput.flush();
}
databaseInput.close();
databaseInput = resources.openRawResource(R.raw.datafile15);
while((length = databaseInput.read(buffer)) > 0) {
databaseOutput.write(buffer, 0, length);
databaseOutput.flush();
}
databaseInput.close();
databaseInput = resources.openRawResource(R.raw.datafile16);
while((length = databaseInput.read(buffer)) > 0) {
databaseOutput.write(buffer, 0, length);
databaseOutput.flush();
}
databaseInput.close();
databaseInput = resources.openRawResource(R.raw.datafile17);
while((length = databaseInput.read(buffer)) > 0) {
databaseOutput.write(buffer, 0, length);
databaseOutput.flush();
}
databaseInput.close();
databaseOutput.flush();
databaseOutput.close();
}
public void openDataBase() throws SQLException {
// Open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READONLY);
}
@Override
public synchronized void close() {
if (myDataBase != null)
myDataBase.close();
super.close();
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
// Add your public helper methods to access and get content from the
// database.
// You could return cursors by doing "return myDataBase.query(....)" so it'd
// be easy
// to you to create adapters for your views.
}
Then I added this awesomeness to the main.java file
DataBaseHelper myDbHelper = new DataBaseHelper(this);
//myDbHelper = new DataBaseHelper(this);
try {
myDbHelper.createDataBase();
} catch (IOException ioe) {
throw new Error("Unable to create database");
}
try {
myDbHelper.openDataBase();
}catch(SQLException sqle){
throw sqle;
}
Thats it :)
Wednesday, April 27, 2011
Wednesday, February 9, 2011
Deleting Single Choice Listview Items
This post assumes you know how to create a single choice listview and a button in xml.
1) First, define these three variables:
public static List<String> strings;
public static ListAdapter adapter;
ListView lv;
2) Next, set up the listview in onCreate:
strings = new ArrayList<String>();
lv = getListView();
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_single_choice, strings);
lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
lv.setAdapter(adapter);
3) Last, set up the delete button:
Button btnRemove = (Button) findViewById(R.id.ButtonEditLabOrderForm_Remove);
btnRemove.setOnClickListener(new View.OnClickListener() {
@SuppressWarnings("unchecked")
public void onClick(View v) {
// Code below only works with ONE CHECKED ITEM at a time
int len = lv.getCount();
SparseBooleanArray checked = lv.getCheckedItemPositions();
for (int i = 0; i < len; i++)
if (checked.get(i)) {
String item = strings.get(i);
// do whatever you want with the checked item
strings.remove(item);
((ArrayAdapter<String>) adapter).notifyDataSetChanged();
}
}
});
Thats it !
Still trying to figure out how to delete multiple items in a multiple choice list :(
1) First, define these three variables:
public static List<String> strings;
public static ListAdapter adapter;
ListView lv;
2) Next, set up the listview in onCreate:
strings = new ArrayList<String>();
lv = getListView();
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_single_choice, strings);
lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
lv.setAdapter(adapter);
3) Last, set up the delete button:
Button btnRemove = (Button) findViewById(R.id.ButtonEditLabOrderForm_Remove);
btnRemove.setOnClickListener(new View.OnClickListener() {
@SuppressWarnings("unchecked")
public void onClick(View v) {
// Code below only works with ONE CHECKED ITEM at a time
int len = lv.getCount();
SparseBooleanArray checked = lv.getCheckedItemPositions();
for (int i = 0; i < len; i++)
if (checked.get(i)) {
String item = strings.get(i);
// do whatever you want with the checked item
strings.remove(item);
((ArrayAdapter<String>) adapter).notifyDataSetChanged();
}
}
});
Thats it !
Still trying to figure out how to delete multiple items in a multiple choice list :(
Tuesday, February 1, 2011
Button with Image and Text
This all goes down in the XML file with the button in question. This can also be accomplished dynamically (not shown.) Here is the excerpt from the xml file defining the button. The image should be located in the drawable folder. The image is called from android:drawable. Use drawableLeft, drawableRight, drawableTop, drawableBottom depending on how you want to place the image in relation to the text. Adjust the padding to suit your aesthetic.
<Button
android:layout_width="wrap_content"
android:text="Sample Text"
android:id="@+id/Button01"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/search"
android:drawablePadding="0px"
android:padding="0px">
</Button>
<Button
android:layout_width="wrap_content"
android:text="Sample Text"
android:id="@+id/Button01"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/search"
android:drawablePadding="0px"
android:padding="0px">
</Button>
Friday, January 28, 2011
Custom Spinner Row Layout & Custom Spinner Adapter
The custom spinner adapter is similar to the custom list row & adapter, because we can use LayoutInflater.
(*edit: This code may not run as-is. Therefore, I have included project files associated with this post available for download at the end of this post.)
1) The spinner layout. This is how each row will look when the spinner is selected. In my example there are three text views as three rows.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:orientation="vertical">
<TextView
android:layout_height="wrap_content"
android:id="@+id/TextView01"
android:textSize="12px"
android:layout_width="match_parent"
android:textColor="#000000">
</TextView>
<TextView
android:layout_height="wrap_content"
android:id="@+id/TextView02"
android:layout_width="match_parent"
android:textSize="12px" android:textColor="#000000"></TextView>
<TextView
android:layout_height="wrap_content"
android:id="@+id/TextView03"
android:layout_width="match_parent"
android:textSize="12px"
android:textColor="#000000">
</TextView>
</LinearLayout>
2) The custom adapter
// CUSTOM SPINNER ADAPTER
public class MyCustomSpinnerAdapter extends ArrayAdapter<String> {
public MyCustomSpinnerAdapter(Context context, int textViewResourceId,
String[] objects) {
super(context, textViewResourceId, objects);
// TODO Auto-generated constructor stub
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
return getCustomView(position, convertView, parent);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
return getCustomView(position, convertView, parent);
}
public View getCustomView(int position, View convertView,ViewGroup parent) {
// TODO Auto-generated method stub
// return super.getView(position, convertView, parent);
LayoutInflater inflater = getLayoutInflater();
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.customspinneritem, null);
holder = new ViewHolder();
holder.txt01 = (TextView) convertView.findViewById(R.id.TextView01);
holder.txt02 = (TextView) convertView.findViewById(R.id.TextView02);
holder.txt03 = (TextView) convertView.findViewById(R.id.TextView03);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.txt01.setText("Route")
holder.txt02.setText("Strength");
holder.txt03.setText("Form");
return convertView;
}
class ViewHolder {
TextView txt01;
TextView txt02;
TextView txt03;
}
} // end custom adapter
3) Calling the spinner & setting the adapter
Spinner spinner = (Spinner) findViewById(R.id.spinner1);
spinner.setPrompt("Select One");
spinner.setAdapter(new MyCustomSpinnerAdapter(this, 0, items));
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
// your code here
}
@Override
>public void onNothingSelected(AdapterView<?> parentView) {
// your code here
}
});
4) Setting string items
String[] items = { "Route 1, Strength 1, Form 1", "Route 2, Strength 2, Form 2", "Route 3, Strength 3, Form 3" };
Downloads:
main.xml
customspinneritem.xml
CustomSpinnerActivity.java (select "qui")
Resources:
My previous Spinner post
Android Dev Tutorial - Hello Spinner
Custom List Row Layout w/ Adapter
(*edit: This code may not run as-is. Therefore, I have included project files associated with this post available for download at the end of this post.)
1) The spinner layout. This is how each row will look when the spinner is selected. In my example there are three text views as three rows.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:orientation="vertical">
<TextView
android:layout_height="wrap_content"
android:id="@+id/TextView01"
android:textSize="12px"
android:layout_width="match_parent"
android:textColor="#000000">
</TextView>
<TextView
android:layout_height="wrap_content"
android:id="@+id/TextView02"
android:layout_width="match_parent"
android:textSize="12px" android:textColor="#000000"></TextView>
<TextView
android:layout_height="wrap_content"
android:id="@+id/TextView03"
android:layout_width="match_parent"
android:textSize="12px"
android:textColor="#000000">
</TextView>
</LinearLayout>
2) The custom adapter
// CUSTOM SPINNER ADAPTER
public class MyCustomSpinnerAdapter extends ArrayAdapter<String> {
public MyCustomSpinnerAdapter(Context context, int textViewResourceId,
String[] objects) {
super(context, textViewResourceId, objects);
// TODO Auto-generated constructor stub
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
return getCustomView(position, convertView, parent);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
return getCustomView(position, convertView, parent);
}
public View getCustomView(int position, View convertView,ViewGroup parent) {
// TODO Auto-generated method stub
// return super.getView(position, convertView, parent);
LayoutInflater inflater = getLayoutInflater();
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.customspinneritem, null);
holder = new ViewHolder();
holder.txt01 = (TextView) convertView.findViewById(R.id.TextView01);
holder.txt02 = (TextView) convertView.findViewById(R.id.TextView02);
holder.txt03 = (TextView) convertView.findViewById(R.id.TextView03);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.txt01.setText("Route")
holder.txt02.setText("Strength");
holder.txt03.setText("Form");
return convertView;
}
class ViewHolder {
TextView txt01;
TextView txt02;
TextView txt03;
}
} // end custom adapter
3) Calling the spinner & setting the adapter
Spinner spinner = (Spinner) findViewById(R.id.spinner1);
spinner.setPrompt("Select One");
spinner.setAdapter(new MyCustomSpinnerAdapter(this, 0, items));
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
// your code here
}
@Override
>public void onNothingSelected(AdapterView<?> parentView) {
// your code here
}
});
4) Setting string items
String[] items = { "Route 1, Strength 1, Form 1", "Route 2, Strength 2, Form 2", "Route 3, Strength 3, Form 3" };
Downloads:
main.xml
customspinneritem.xml
CustomSpinnerActivity.java (select "qui")
Resources:
My previous Spinner post
Android Dev Tutorial - Hello Spinner
Custom List Row Layout w/ Adapter
Simple Spinner w/ Array Adapter
Very basic stuff here, people. If you haven't yet, get acquainted with android spinner using the dev tutorial.
1) Calling the spinner, defining the array adapter.
Spinner spinner= (Spinner) findViewById(R.id.spinner);
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>(
this, android.R.layout.simple_spinner_item, items);
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setPrompt("Select One");
spinner.setAdapter(spinnerArrayAdapter );
spnRoute.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parentView,
View selectedItemView, int position, long id) {
// your code here
}
@Override
public void onNothingSelected(AdapterView<?> parentView) {
// your code here
}
});
2) The string array
String[] items = { "lorem", "ipsum", "dolor", "sit", "amet"};
1) Calling the spinner, defining the array adapter.
Spinner spinner= (Spinner) findViewById(R.id.spinner);
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>(
this, android.R.layout.simple_spinner_item, items);
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setPrompt("Select One");
spinner.setAdapter(spinnerArrayAdapter );
spnRoute.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parentView,
View selectedItemView, int position, long id) {
// your code here
}
@Override
public void onNothingSelected(AdapterView<?> parentView) {
// your code here
}
});
2) The string array
String[] items = { "lorem", "ipsum", "dolor", "sit", "amet"};
Friday, January 14, 2011
Seriously, this is how I made a multi-column list item populated by strings!!
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/LinearLayout01"
android:layout_alignParentLeft="true"
android:layout_height="fill_parent"
android:orientation="vertical"
android:layout_width="fill_parent">
<TextView
android:layout_height="wrap_content"
android:id="@+id/TextView_Title"
android:text="Title"
android:textSize="15px"
android:layout_width="fill_parent"></TextView>
<LinearLayout
android:id="@+id/LinearLayout02"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:layout_height="wrap_content"
android:id="@+id/TextView_Item1"
android:text="Item1"
android:layout_width="wrap_content"
android:textSize="10px" android:layout_weight="1"/>
<TextView
android:layout_height="wrap_content"
android:id="@+id/TextView_Item2"
android:text="Item2"
android:layout_width="wrap_content"
android:textSize="10px" android:layout_weight="1"/>
<TextView
android:layout_height="wrap_content"
android:id="@+id/TextView_Item3"
android:text="Item3"
android:layout_width="wrap_content"
android:textSize="10px" android:layout_weight="1"/>
</LinearLayout>
</LinearLayout>
2) Build the custom adapter:
// CUSTOM TWO ROW LIST ADAPTER
static class EfficientAdapter extends BaseAdapter {
private LayoutInflater mInflater;
public EfficientAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
public int getCount() {
return title.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.listitem_addrx, null);
holder = new ViewHolder();
holder.txtTitle = (TextView) convertView.findViewById(R.id.TextView_Title);
holder.txtItem1 = (TextView) convertView.findViewById(R.id.TextView_Item1);
holder.txtItem2 = (TextView) convertView.findViewById(R.id.TextView_Item2);
holder.txtItem3 = (TextView) convertView.findViewById(R.id.TextView_Item3);
convertView.setTag(holder);
holder = (ViewHolder) convertView.getTag();
}
holder.txtTitle.setText(title.get(position));
holder.txtItem1.setText(one.get(position));
holder.txtItem2.setText(two.get(position));
holder.txtItem3.setText(three.get(position));
return convertView;
}
static class ViewHolder {
TextView txtTitle;
TextView txtItem1;
TextView txtItem2;
TextView txtItem3;
}
} // end custom adapter
3) Call the following items:
static ListView lv;
public static ListAdapter adapter;
String selected;
static final ArrayList<String> title = new ArrayList<String>();
static final ArrayList<String> one = new ArrayList<String>();
static final ArrayList<String> two = new ArrayList<String>();
static final ArrayList<String> three = new ArrayList<String>();
4) Set the list adapter:
lv = (ListView) getListView();
lv.setAdapter(new EfficientAdapter(this));
5) Add entries to list:
Either define a string array when you call the variables in step 3 or add items dynamically:
title.add(selected);
route.add(selected);
strength.add(selected);
form.add(selected);
lv.setAdapter(new EfficientAdapter(getBaseContext()));
References (& many, many thanks to):
Custom list row & adapter: http://www.androidpeople.com/android-custom-dynamic-listview/
Custom spinner row & adapter: http://android-er.blogspot.com/2010/12/custom-arrayadapter-for-spinner-with.html
Update with my version later...
Custom Button Using XML
1. Create a custombuttonlayout.xml file in the drawable folder
Selector: this element surrounds the entire xml. It defines this drawable as a selecter (e.g. buttons, list rows, or anything that can be "selected")
Items: There are three buttons states that must be defined: pressed, focused, normal. However, there are a total of seven states that can be defined(pressed, focused, selected, checkable, checked, enabled, and window_focused).These are defined as three separate "items". Due to the nature of the way java programs are read (basically from the top down) you need to define items in this specific order, with pressed first, focused next, and normal last to get the buttons to display correctly.
Gradient: Android buttons typically have a highlight/lowlight gradient, so you should define two colors, and the angle of the "shadow".
Stroke: I think this defines the outline style of the button? Not too sure...
Corners: creates a rounded button corner. The default android radius value is "5dp".
Padding: This defines the blank space between the button text and the button borders.
custombuttonlayout.xml
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="true">
<shape>
<gradient
android:startColor="#FFFF40"
android:endColor="#FFFFC0"
android:angle="270" />
<stroke
android:width="1dp"
android:color="#000000" />
<corners
android:radius="5dp" />
<padding
android:left="10dp"
android:top="15dp"
android:right="10dp"
android:bottom="15dp" />
</shape>
</item>
<item
android:state_focused="true">
<shape>
<gradient
android:endColor="#8080FF"
android:startColor="#C0C0C0"
android:angle="270" />
<stroke
android:width="1dp"
android:color="#4A494A" />
<corners
android:radius="5dp" />
<padding
android:left="10dp"
android:top="15dp"
android:right="10dp"
android:bottom="15dp" />
</shape>
</item>
<item>
<shape>
<gradient
android:endColor="#8080FF"
android:startColor="#C0C0C0"
android:angle="270" />
<stroke
android:width="1dp"
android:color="#000000" />
<corners
android:radius="5dp" />
<padding
android:left="10dp"
android:top="15dp"
android:right="10dp"
android:bottom="15dp" />
</shape>
</item>
</selector>
2. In the main.xml layout when you insert a button that you want to apply the layout to:
Define the button background source as the drawable/custombuttonlayout.xml from above.
excerpt from main.xml:
<Button
android:layout_width="wrap_content"
android:text="Sample Text"
android:id="@+id/Button01"
android:layout_height="wrap_content"
android:background="@drawable/custombuttonlayout"></Button>
Resources:
1) http://developer.android.com/guide/topics/resources/drawable-resource.html#StateList
2) http://developer.android.com/guide/topics/resources/color-list-resource.html
3) http://developer.android.com/reference/android/widget/Button.html
4) http://androiddrawableexplorer.appspot.com/
5) http://developer.android.com/guide/topics/resources/drawable-resource.html#Shape
Selector: this element surrounds the entire xml. It defines this drawable as a selecter (e.g. buttons, list rows, or anything that can be "selected")
Items: There are three buttons states that must be defined: pressed, focused, normal. However, there are a total of seven states that can be defined(pressed, focused, selected, checkable, checked, enabled, and window_focused).These are defined as three separate "items". Due to the nature of the way java programs are read (basically from the top down) you need to define items in this specific order, with pressed first, focused next, and normal last to get the buttons to display correctly.
Gradient: Android buttons typically have a highlight/lowlight gradient, so you should define two colors, and the angle of the "shadow".
Stroke: I think this defines the outline style of the button? Not too sure...
Corners: creates a rounded button corner. The default android radius value is "5dp".
Padding: This defines the blank space between the button text and the button borders.
custombuttonlayout.xml
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="true">
<shape>
<gradient
android:startColor="#FFFF40"
android:endColor="#FFFFC0"
android:angle="270" />
<stroke
android:width="1dp"
android:color="#000000" />
<corners
android:radius="5dp" />
<padding
android:left="10dp"
android:top="15dp"
android:right="10dp"
android:bottom="15dp" />
</shape>
</item>
<item
android:state_focused="true">
<shape>
<gradient
android:endColor="#8080FF"
android:startColor="#C0C0C0"
android:angle="270" />
<stroke
android:width="1dp"
android:color="#4A494A" />
<corners
android:radius="5dp" />
<padding
android:left="10dp"
android:top="15dp"
android:right="10dp"
android:bottom="15dp" />
</shape>
</item>
<item>
<shape>
<gradient
android:endColor="#8080FF"
android:startColor="#C0C0C0"
android:angle="270" />
<stroke
android:width="1dp"
android:color="#000000" />
<corners
android:radius="5dp" />
<padding
android:left="10dp"
android:top="15dp"
android:right="10dp"
android:bottom="15dp" />
</shape>
</item>
</selector>
2. In the main.xml layout when you insert a button that you want to apply the layout to:
Define the button background source as the drawable/custombuttonlayout.xml from above.
excerpt from main.xml:
<Button
android:layout_width="wrap_content"
android:text="Sample Text"
android:id="@+id/Button01"
android:layout_height="wrap_content"
android:background="@drawable/custombuttonlayout"></Button>
Resources:
1) http://developer.android.com/guide/topics/resources/drawable-resource.html#StateList
2) http://developer.android.com/guide/topics/resources/color-list-resource.html
3) http://developer.android.com/reference/android/widget/Button.html
4) http://androiddrawableexplorer.appspot.com/
5) http://developer.android.com/guide/topics/resources/drawable-resource.html#Shape
Subscribe to:
Posts (Atom)