Android Tutorial - UI 20 exemple 1
1-ActionBar
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <FrameLayout android:id="@+id/fragment_content" android:layout_width="match_parent" android:layout_height="0dip" android:layout_weight="1" /> <LinearLayout android:layout_width="match_parent" android:layout_height="0dip" android:layout_weight="1" android:orientation="vertical"> <Button android:id="@+id/btn_add_tab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="btn_add_tab" android:onClick="onAddTab" /> <Button android:id="@+id/btn_remove_tab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="btn_remove_tab" android:onClick="onRemoveTab" /> <Button android:id="@+id/btn_toggle_tabs" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="btn_toggle_tabs" android:onClick="onToggleTabs" /> <Button android:id="@+id/btn_remove_all_tabs" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="btn_remove_all_tabs" android:onClick="onRemoveAllTabs" /> </LinearLayout> </LinearLayout>
package app.test; import android.app.Activity; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.widget.SearchView; import android.widget.SearchView.OnQueryTextListener; import android.widget.TextView; import android.widget.Toast; /** manActivity */ public class Test extends Activity implements OnQueryTextListener { TextView mSearchText; int mSortMode = -1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mSearchText = new TextView(this); setContentView(mSearchText); } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.my_menu, menu); SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView(); searchView.setOnQueryTextListener(this); return true; } @Override public boolean onPrepareOptionsMenu(Menu menu) { if (mSortMode != -1) { Drawable icon = menu.findItem(mSortMode).getIcon(); menu.findItem(R.id.action_sort).setIcon(icon); } return super.onPrepareOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { Toast.makeText(this, "Selected Item: " + item.getTitle(), Toast.LENGTH_SHORT).show(); return true; } public void onSort(MenuItem item) { mSortMode = item.getItemId(); invalidateOptionsMenu(); } public boolean onQueryTextChange(String newText) { newText = newText.isEmpty() ? "" : "Query so far: " + newText; mSearchText.setText(newText); return true; } public boolean onQueryTextSubmit(String query) { Toast.makeText(this, "Searching for: " + query + "...", Toast.LENGTH_SHORT).show(); return true; } }
2- ActionBar 2
//main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <FrameLayout android:id="@+id/fragment_content" android:layout_width="match_parent" android:layout_height="0dip" android:layout_weight="1" /> <LinearLayout android:layout_width="match_parent" android:layout_height="0dip" android:layout_weight="1" android:orientation="vertical"> <Button android:id="@+id/btn_add_tab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="btn_add_tab" android:onClick="onAddTab" /> <Button android:id="@+id/btn_remove_tab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="btn_remove_tab" android:onClick="onRemoveTab" /> <Button android:id="@+id/btn_toggle_tabs" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="btn_toggle_tabs" android:onClick="onToggleTabs" /> <Button android:id="@+id/btn_remove_all_tabs" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="btn_remove_all_tabs" android:onClick="onRemoveAllTabs" /> </LinearLayout> </LinearLayout>
//row.xml <?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" />
package app.test; import android.app.ActionBar; import android.app.ActionBar.Tab; import android.app.Activity; import android.app.Fragment; import android.app.FragmentTransaction; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import android.widget.Toast; public class Test extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } public void onAddTab(View v) { final ActionBar bar = getActionBar(); final int tabCount = bar.getTabCount(); final String text = "Tab " + tabCount; bar.addTab(bar.newTab() .setText(text) .setTabListener(new TabListener(new TabContentFragment(text)))); } public void onRemoveTab(View v) { final ActionBar bar = getActionBar(); bar.removeTabAt(bar.getTabCount() - 1); } public void onToggleTabs(View v) { final ActionBar bar = getActionBar(); if (bar.getNavigationMode() == ActionBar.NAVIGATION_MODE_TABS) { bar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); bar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE, ActionBar.DISPLAY_SHOW_TITLE); } else { bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE); } } public void onRemoveAllTabs(View v) { getActionBar().removeAllTabs(); } private class TabListener implements ActionBar.TabListener { private TabContentFragment mFragment; public TabListener(TabContentFragment fragment) { mFragment = fragment; } public void onTabSelected(Tab tab, FragmentTransaction ft) { ft.add(R.id.fragment_content, mFragment, mFragment.getText()); } public void onTabUnselected(Tab tab, FragmentTransaction ft) { ft.remove(mFragment); } public void onTabReselected(Tab tab, FragmentTransaction ft) { Toast.makeText(Test.this, "Reselected!", Toast.LENGTH_SHORT).show(); } } private class TabContentFragment extends Fragment { private String mText; public TabContentFragment(String text) { mText = text; } public String getText() { return mText; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View fragView = inflater.inflate(R.layout.row, container, false); TextView text = (TextView) fragView.findViewById(R.id.text); text.setText(mText); return fragView; } } }
3- ActivityInfo
package app.test; import java.io.File; import java.util.TimeZone; import android.app.Activity; import android.content.ContentValues; import android.content.Intent; import android.content.pm.ActivityInfo; import android.media.MediaScannerConnection; import android.media.MediaScannerConnection.MediaScannerConnectionClient; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.provider.MediaStore.Images.Media; import android.text.format.Time; import android.util.Log; import android.view.View; import android.widget.Toast; public class Test extends Activity implements MediaScannerConnectionClient { private File myImageFile = null; private Uri myPicture = null; private MediaScannerConnection conn = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } public void captureImage(View view) { ContentValues values = new ContentValues(); values.put(Media.TITLE, "My demo image"); values.put(Media.DESCRIPTION, "Image Captured by Camera via an Intent"); TimeZone myTZ = TimeZone.getDefault(); Time now = new Time(); values.put(Media.DATE_TAKEN, now.toMillis(false) - myTZ.getRawOffset()); myPicture = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values); myImageFile.delete(); myPicture = Uri.fromFile(myImageFile); Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); i.putExtra(MediaStore.EXTRA_OUTPUT, myPicture); startActivityForResult(i, 0); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if(requestCode==0 && resultCode==Activity.RESULT_OK) { startScan(); } } private void startScan() { if(conn !=null) { conn.disconnect(); } if(myImageFile.isFile()) { conn = new MediaScannerConnection(this, this); conn.connect(); } else { Toast.makeText(this, "Image file does not exist?!?!", Toast.LENGTH_SHORT).show(); } } @Override public void onMediaScannerConnected() { conn.scanFile(myImageFile.getPath(), null); } @Override public void onScanCompleted(String path, Uri uri) { try { if (uri != null) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(uri); startActivity(intent); } } finally { conn.disconnect(); conn = null; } } }
4-AdapterWrapper
//res\layout\main.xml <?xml version="1.0" encoding="utf-8"?> <com.commonsware.android.fancylists.seven.RateListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/list" android:layout_width="fill_parent" android:layout_height="fill_parent" android:drawSelectorOnTop="false" />
AdapterWrapper.java
package com.commonsware.android.fancylists.seven; import android.database.DataSetObserver; import android.widget.ListAdapter; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; public class AdapterWrapper implements ListAdapter { ListAdapter delegate=null; public AdapterWrapper(ListAdapter delegate) { this.delegate=delegate; } public int getCount() { return(delegate.getCount()); } public Object getItem(int position) { return(delegate.getItem(position)); } public long getItemId(int position) { return(delegate.getItemId(position)); } public View getView(int position, View convertView, ViewGroup parent) { return(delegate.getView(position, convertView, parent)); } public void registerDataSetObserver(DataSetObserver observer) { delegate.registerDataSetObserver(observer); } public boolean hasStableIds() { return(delegate.hasStableIds()); } public boolean isEmpty() { return(delegate.isEmpty()); } public int getViewTypeCount() { return(delegate.getViewTypeCount()); } public int getItemViewType(int position) { return(delegate.getItemViewType(position)); } public void unregisterDataSetObserver(DataSetObserver observer) { delegate.unregisterDataSetObserver(observer); } public boolean areAllItemsEnabled() { return(delegate.areAllItemsEnabled()); } public boolean isEnabled(int position) { return(delegate.isEnabled(position)); } }
RateListView.java
package com.commonsware.android.fancylists.seven; import android.content.Context; import android.util.AttributeSet; import android.widget.ListAdapter; import android.widget.ListView; public class RateListView extends ListView { public RateListView(Context context) { super(context); } public RateListView(Context context, AttributeSet attrs) { super(context, attrs); } public RateListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public void setAdapter(ListAdapter adapter) { super.setAdapter(new RateableWrapper(getContext(), adapter)); } }
RateListViewDemo
package com.commonsware.android.fancylists.seven; import android.app.Activity; import android.os.Bundle; import android.app.ListActivity; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.RatingBar; import android.widget.CompoundButton; import android.widget.ListView; public class RateListViewDemo extends ListActivity { String[] items={"lorem", "ipsum", "dolor", "sit", "amet", "consectetuer", "adipiscing", "elit", "morbi", "vel", "ligula", "vitae", "arcu", "aliquet", "mollis", "etiam", "vel", "erat", "placerat", "ante", "porttitor", "sodales", "pellentesque", "augue", "purus"}; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.main); setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, items)); } }
RateableWrapper.java
package com.commonsware.android.fancylists.seven; import android.content.Context; import android.database.DataSetObserver; import android.widget.ListAdapter; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; import android.widget.CompoundButton; import android.widget.RatingBar; import android.widget.LinearLayout; import java.util.ArrayList; import java.util.List; public class RateableWrapper extends AdapterWrapper { Context ctxt=null; float[] rates=null; public RateableWrapper(Context ctxt, ListAdapter delegate) { super(delegate); this.ctxt=ctxt; this.rates=new float[delegate.getCount()]; for (int i=0;i<delegate.getCount();i++) { this.rates[i]=2.0f; } } public View getView(int position, View convertView, ViewGroup parent) { ViewWrapper wrap=null; View row=convertView; if (convertView==null) { LinearLayout layout=new LinearLayout(ctxt); RatingBar rate=new RatingBar(ctxt); rate.setNumStars(3); rate.setStepSize(1.0f); View guts=delegate.getView(position, null, parent); layout.setOrientation(LinearLayout.HORIZONTAL); rate.setLayoutParams(new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.FILL_PARENT)); guts.setLayoutParams(new LinearLayout.LayoutParams( LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT)); RatingBar.OnRatingBarChangeListener l= new RatingBar.OnRatingBarChangeListener() { public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromTouch) { rates[(Integer)ratingBar.getTag()]=rating; } }; rate.setOnRatingBarChangeListener(l); layout.addView(rate); layout.addView(guts); wrap=new ViewWrapper(layout); wrap.setGuts(guts); layout.setTag(wrap); rate.setTag(new Integer(position)); rate.setRating(rates[position]); row=layout; } else { wrap=(ViewWrapper)convertView.getTag(); wrap.setGuts(delegate.getView(position, wrap.getGuts(), parent)); wrap.getRatingBar().setTag(new Integer(position)); wrap.getRatingBar().setRating(rates[position]); } return(row); } }
ViewWrapper.java
package com.commonsware.android.fancylists.seven; import android.view.View; import android.view.ViewGroup; import android.widget.RatingBar; class ViewWrapper { ViewGroup base; View guts=null; RatingBar rate=null; ViewWrapper(ViewGroup base) { this.base=base; } RatingBar getRatingBar() { if (rate==null) { rate=(RatingBar)base.getChildAt(0); } return(rate); } void setRatingBar(RatingBar rate) { this.rate=rate; } View getGuts() { if (guts==null) { guts=base.getChildAt(1); } return(guts); } void setGuts(View guts) { this.guts=guts; } }
5- AnalogClock
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <SlidingDrawer android:id="@+id/drawer" android:layout_width="320dip" android:layout_height="440dip" android:orientation="vertical" android:handle="@+id/handle" android:content="@+id/content"> <ImageView android:id="@+id/handle" android:layout_width="48dip" android:layout_height="48dip" android:src="@drawable/icon" /> <AnalogClock android:id="@+id/content" android:background="#D0A0A0" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </SlidingDrawer> </RelativeLayout>
package app.Test; import android.app.Activity; import android.os.Bundle; public class appTest extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } }
DigitalClock and AnalogClock
<?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" > <AnalogClock android:id="@+id/analog" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_alignParentTop="true" /> <DigitalClock android:id="@+id/digital" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_below="@id/analog" /> </RelativeLayout>
package app.test; import android.app.Activity; import android.os.Bundle; public class Test extends Activity { @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.main); } }
Define AnalogClock and DigitalClock in 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="fill_parent" > <AnalogClock android:layout_width="wrap_content" android:layout_height="wrap_content" /> <DigitalClock android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
package app.test; import android.app.Activity; import android.os.Bundle; public class Test extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } }
6-ArrayAdapter
//layout/main.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="fill_parent"> <EditText android:id="@+id/myEditText" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="" android:visibility="gone" /> <ListView android:id="@+id/myListView" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>
//layout/row.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/rowDate" android:layout_width="wrap_content" android:layout_height="fill_parent" android:padding="10dp" android:scrollbars="vertical" android:fadingEdge="vertical" android:layout_alignParentRight="true" /> <TextView android:id="@+id/row" android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="10dp" android:scrollbars="vertical" android:fadingEdge="vertical" android:layout_alignParentLeft="@+id/rowDate" /> </RelativeLayout>
package app.test; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Bundle; import android.util.AttributeSet; import android.view.ContextMenu; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnKeyListener; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; class ToDoItem { public String getTask() { return task; } String task; /** Get ToDo List item creation date */ public Date getCreated() { return created; } Date created; public ToDoItem(String _task) { this(_task, new Date(java.lang.System.currentTimeMillis())); } public ToDoItem(String _task, Date _created) { task = _task; created = _created; } @Override public String toString() { SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yy"); return "(" + sdf.format(created) + ") " + task; } } class ToDoItemAdapter extends ArrayAdapter<ToDoItem> { int resource; public ToDoItemAdapter(Context _context, int _resource, List<ToDoItem> _items) { super(_context, _resource, _items); resource = _resource; } @Override public View getView(int position, View convertView, ViewGroup parent) { LinearLayout todoView; ToDoItem item = getItem(position); String taskString = item.getTask(); Date createdDate = item.getCreated(); SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yy"); String dateString = sdf.format(createdDate); if (convertView == null) { todoView = new LinearLayout(getContext()); String inflater = Context.LAYOUT_INFLATER_SERVICE; LayoutInflater vi = (LayoutInflater) getContext().getSystemService( inflater); vi.inflate(resource, todoView, true); } else { todoView = (LinearLayout) convertView; } TextView dateView = (TextView) todoView.findViewById(R.id.rowDate); TextView taskView = (TextView) todoView.findViewById(R.id.row); dateView.setText(dateString); taskView.setText(taskString); return todoView; } } class TodoListItemView extends TextView { private Paint marginPaint; private Paint linePaint; private int paperColor; private float margin; public TodoListItemView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } public TodoListItemView(Context context) { super(context); init(); } public TodoListItemView(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { marginPaint = new Paint(Paint.ANTI_ALIAS_FLAG); marginPaint.setColor(Color.RED); linePaint = new Paint(Paint.ANTI_ALIAS_FLAG); linePaint.setColor(Color.BLACK); paperColor = Color.BLUE; margin = Color.CYAN; } @Override public void onDraw(Canvas canvas) { canvas.drawColor(paperColor); canvas.drawLine(0, 0, getMeasuredHeight(), 0, linePaint); canvas.drawLine(0, getMeasuredHeight(), getMeasuredWidth(), getMeasuredHeight(), linePaint); canvas.drawLine(margin, 0, margin, getMeasuredHeight(), marginPaint); canvas.save(); canvas.translate(margin, 0); super.onDraw(canvas); canvas.restore(); } } public class Test extends Activity { private ArrayList<ToDoItem> todoItems; private ListView myListView; private EditText myEditText; private ToDoItemAdapter aa; private boolean addingNew = false; static final private int ADD_NEW_TODO = Menu.FIRST; static final private int REMOVE_TODO = Menu.FIRST + 1; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.main); myListView = (ListView) findViewById(R.id.myListView); myEditText = (EditText) findViewById(R.id.myEditText); todoItems = new ArrayList<ToDoItem>(); aa = new ToDoItemAdapter(getApplicationContext(), R.layout.row, todoItems); myListView.setAdapter(aa); myEditText.setOnKeyListener(new OnKeyListener() { public boolean onKey(View v, int keyCode, KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_DOWN) if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { ToDoItem newItem = new ToDoItem(myEditText.getText().toString()); todoItems.add(0, newItem); myEditText.setText(""); aa.notifyDataSetChanged(); cancelAdd(); return true; } return false; } }); registerForContextMenu(myListView); } @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); MenuItem itemAdd = menu.add(0, ADD_NEW_TODO, Menu.NONE, "New"); MenuItem itemRem = menu.add(0, REMOVE_TODO, Menu.NONE, "Remove"); itemAdd.setIcon(R.drawable.icon); itemRem.setIcon(R.drawable.icon); itemAdd.setShortcut('0', 'a'); itemRem.setShortcut('1', 'r'); return true; } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); menu.setHeaderTitle("Selected To Do Item"); menu.add(0, REMOVE_TODO, Menu.NONE, "Remove"); } @Override public boolean onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); int idx = myListView.getSelectedItemPosition(); String removeTitle = "Title"; MenuItem removeItem = menu.findItem(REMOVE_TODO); removeItem.setTitle(removeTitle); removeItem.setVisible(addingNew || idx > -1); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { super.onOptionsItemSelected(item); int index = myListView.getSelectedItemPosition(); switch (item.getItemId()) { case (REMOVE_TODO): { if (addingNew) { cancelAdd(); } else { removeItem(index); } return true; } case (ADD_NEW_TODO): { addNewItem(); return true; } } return false; } @Override public boolean onContextItemSelected(MenuItem item) { super.onContextItemSelected(item); switch (item.getItemId()) { case (REMOVE_TODO): { AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item .getMenuInfo(); int index = menuInfo.position; removeItem(index); return true; } } return false; } private void cancelAdd() { addingNew = false; myEditText.setVisibility(View.GONE); } private void addNewItem() { addingNew = true; myEditText.setVisibility(View.VISIBLE); myEditText.requestFocus(); } private void removeItem(int _index) { todoItems.remove(_index); aa.notifyDataSetChanged(); } }
7-BaseAdapter
//main.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="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Images of San Francisco" /> <Gallery android:id="@+id/gallery1" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <ImageView android:id="@+id/image1" android:layout_width="320px" android:layout_height="250px" android:scaleType="fitXY" /> </LinearLayout>
package app.test; import android.app.Activity; import android.os.Bundle; import android.content.Context; import android.content.res.TypedArray; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.BaseAdapter; import android.widget.Gallery; import android.widget.ImageView; import android.widget.Toast; public class Test extends Activity { //---the images to display--- Integer[] imageIDs = { R.drawable.icon, R.drawable.icon, R.drawable.icon, R.drawable.icon, R.drawable.icon, R.drawable.icon, R.drawable.icon }; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Gallery gallery = (Gallery) findViewById(R.id.gallery1); gallery.setAdapter(new ImageAdapter(this)); gallery.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View v, int position, long id) { Toast.makeText(getBaseContext(), "pic" + (position + 1) + " selected", Toast.LENGTH_SHORT).show(); ImageView imageView = (ImageView) findViewById(R.id.image1); imageView.setImageResource(imageIDs[position]); } }); } public class ImageAdapter extends BaseAdapter { private Context context; private int itemBackground; public ImageAdapter(Context c) { context = c; //---setting the style--- TypedArray a = obtainStyledAttributes(R.styleable.Gallery1); itemBackground = a.getResourceId( R.styleable.Gallery1_android_galleryItemBackground, 0); a.recycle(); } //---returns the number of images--- public int getCount() { return imageIDs.length; } //---returns the ID of an item--- public Object getItem(int position) { return position; } //---returns the ID of an item--- public long getItemId(int position) { return position; } //---returns an ImageView view--- public View getView(int position, View convertView, ViewGroup parent) { ImageView imageView = new ImageView(context); imageView.setImageResource(imageIDs[position]); imageView.setScaleType(ImageView.ScaleType.FIT_XY); imageView.setLayoutParams(new Gallery.LayoutParams(150, 120)); imageView.setBackgroundResource(itemBackground); return imageView; } } }
8-CursorAdapter
Using SimpleCursorAdapter and ListView
//main.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="fill_parent"> <TextView android:id="@+id/itemTextView" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="10px" android:textSize="16px" android:textColor="#FFF" /> </LinearLayout>
package app.test; import android.app.Activity; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.provider.Contacts.People; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; import android.widget.SimpleCursorAdapter; import android.widget.AdapterView.OnItemClickListener; public class Test extends Activity { @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.main); String dataPath = getIntent().getData().toString(); final Uri data = Uri.parse(dataPath + "people/"); final Cursor c = managedQuery(data, null, null, null, null); String[] from = new String[] {People.NAME}; int[] to = new int[] { R.id.itemTextView }; SimpleCursorAdapter adapter = new SimpleCursorAdapter(getApplicationContext(), R.layout.listitemlayout, c, from, to); ListView lv = (ListView)findViewById(R.id.contactListView); lv.setAdapter(adapter); lv.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int pos, long id) { c.moveToPosition(pos); int rowId = c.getInt(c.getColumnIndexOrThrow("_id")); Uri outURI = Uri.parse(data.toString() + rowId); Intent outData = new Intent(); outData.setData(outURI); setResult(Activity.RESULT_OK, outData); finish(); } }); } }
Using SimpleCursorAdapter
package com.example.android.apis.view; import android.app.ListActivity; import android.database.Cursor; import android.provider.ContactsContract.Contacts; import android.os.Bundle; import android.widget.ListAdapter; import android.widget.SimpleCursorAdapter; /** * A list view example where the * data comes from a cursor. */ public class List2 extends ListActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Get a cursor with all people Cursor c = getContentResolver().query(Contacts.CONTENT_URI, CONTACT_PROJECTION, null, null, null); startManagingCursor(c); ListAdapter adapter = new SimpleCursorAdapter(this, // Use a template that displays a text view android.R.layout.simple_list_item_1, // Give the cursor to the list adatper c, // Map the NAME column in the people database to... new String[] {Contacts.DISPLAY_NAME}, // The "text1" view defined in the XML template new int[] {android.R.id.text1}); setListAdapter(adapter); } private static final String[] CONTACT_PROJECTION = new String[] { Contacts._ID, Contacts.DISPLAY_NAME }; }
extends CursorAdapter implements Filterable
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="autocomplete_4_instructions" /> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="autocomplete_4_name" /> <AutoCompleteTextView android:id="@+id/edit" android:completionThreshold="1" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="autocomplete_4_message" /> </LinearLayout>
package app.test; import android.app.Activity; import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.provider.ContactsContract.Contacts; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AutoCompleteTextView; import android.widget.CursorAdapter; import android.widget.FilterQueryProvider; import android.widget.Filterable; import android.widget.TextView; public class Test extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ContentResolver content = getContentResolver(); Cursor cursor = content.query(Contacts.CONTENT_URI, CONTACT_PROJECTION, null, null, null); ContactListAdapter adapter = new ContactListAdapter(this, cursor); AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.edit); textView.setAdapter(adapter); } // XXX compiler bug in javac 1.5.0_07-164, we need to implement Filterable // to make compilation work public static class ContactListAdapter extends CursorAdapter implements Filterable { public ContactListAdapter(Context context, Cursor c) { super(context, c); mContent = context.getContentResolver(); } @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { final LayoutInflater inflater = LayoutInflater.from(context); final TextView view = (TextView) inflater.inflate( android.R.layout.simple_dropdown_item_1line, parent, false); view.setText(cursor.getString(COLUMN_DISPLAY_NAME)); return view; } @Override public void bindView(View view, Context context, Cursor cursor) { ((TextView) view).setText(cursor.getString(COLUMN_DISPLAY_NAME)); } @Override public String convertToString(Cursor cursor) { return cursor.getString(COLUMN_DISPLAY_NAME); } @Override public Cursor runQueryOnBackgroundThread(CharSequence constraint) { FilterQueryProvider filter = getFilterQueryProvider(); if (filter != null) { return filter.runQuery(constraint); } Uri uri = Uri.withAppendedPath( Contacts.CONTENT_FILTER_URI, Uri.encode(constraint.toString())); return mContent.query(uri, CONTACT_PROJECTION, null, null, null); } private ContentResolver mContent; } public static final String[] CONTACT_PROJECTION = new String[] { Contacts._ID, Contacts.DISPLAY_NAME }; private static final int COLUMN_DISPLAY_NAME = 1; }
Using SimpleCursorAdapter and GridView
//main.xml <?xml version="1.0" encoding="utf-8"?> <!-- This file is at /res/layout/gridview.xml --> <GridView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/gridview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="10px" android:verticalSpacing="10px" android:horizontalSpacing="10px" android:numColumns="auto_fit" android:columnWidth="100px" android:stretchMode="columnWidth" android:gravity="center" />
package app.test; import android.app.Activity; import android.database.Cursor; import android.os.Bundle; import android.provider.Contacts.People; import android.widget.GridView; import android.widget.SimpleCursorAdapter; public class Test extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); GridView gv = (GridView)findViewById(R.id.gridview); Cursor c = managedQuery(People.CONTENT_URI, null, null, null, People.NAME); String[] cols = new String[]{People.NAME}; int[] views = new int[] {android.R.id.text1}; SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, c, cols, views); gv.setAdapter(adapter); } }
9-Drawer
//main.xml <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#FF4444CC" > <SlidingDrawer android:id="@+id/drawer" android:layout_width="fill_parent" android:layout_height="fill_parent" android:handle="@+id/handle" android:content="@+id/content"> <ImageView android:id="@id/handle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/icon" /> <Button android:id="@id/content" android:layout_width="fill_parent" android:layout_height="fill_parent" android:text="I'm in here!" /> </SlidingDrawer> </FrameLayout>
package app.test; import android.app.Activity; import android.os.Bundle; public class Test extends Activity { @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.main); } }
Image String Drawer
//package com.akjava.lib.android.opengl; import javax.microedition.khronos.opengles.GL10; import javax.microedition.khronos.opengles.GL11; import javax.microedition.khronos.opengles.GL11Ext; public class ImageStringDrawer { private int textureId; private int baseSize = 16;// ?? public float fontMargin = 0.5f;// ??? public static final float[] color_white = { 1, 1, 1, 1 }; public static final float[] color_black = { 0, 0, 0, 1 }; public static final float[] color_red = { 1, 0, 0, 1 }; public static final String FPS_LABEL = "FPS:"; public static final char[] numbers = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; /* * ???? ??????????????? */ public ImageStringDrawer(int textureId) { this.textureId = textureId; getImageFontRec_return = new int[] { 0, 0, baseSize, baseSize }; } public ImageStringDrawer(int textureId, int baseSize) { this.textureId = textureId; this.baseSize = baseSize; getImageFontRec_return = new int[] { 0, 0, baseSize, baseSize * 2 }; } int dx; int dy; char ch; int i; public int getStringWidth(StringBuffer text, final int fontSize, final float marginPersent) { return (int) (text.length() * fontSize * marginPersent) + fontSize / 2; } public synchronized void drawString(final GL10 gl, final StringBuffer text, final int startX, final int startY, final int fontSize, final float marginPersent) { dy = startY; dx = startX; gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId); for (i = 0; i < text.length(); i++) { ch = text.charAt(i); // gl.glDisable(GL10.GL_BLEND); ((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, getImageFontRec(ch), 0); ((GL11Ext) gl).glDrawTexiOES(dx, dy, 0, fontSize, fontSize * 2); dx += fontSize * marginPersent;// *marginPersent; // gl.glEnable(GL10.GL_BLEND); } } public synchronized void drawFpsString(final GL10 gl, final int fps, final int startX, final int startY, final int fontSize, final float marginPersent) { dy = startY; dx = startX; gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId); for (i = 0; i < FPS_LABEL.length(); i++) { ch = FPS_LABEL.charAt(i); ((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, getImageFontRec(ch), 0); ((GL11Ext) gl).glDrawTexiOES(dx, dy, 0, fontSize, fontSize * 2); dx += fontSize * marginPersent; } ((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, getImageFontRec(numbers[fps / 100]), 0); ((GL11Ext) gl).glDrawTexiOES(dx, dy, 0, fontSize, fontSize * 2); dx += fontSize * marginPersent; ((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, getImageFontRec(numbers[fps % 100 / 10]), 0); ((GL11Ext) gl).glDrawTexiOES(dx, dy, 0, fontSize, fontSize * 2); dx += fontSize * marginPersent; ((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, getImageFontRec(numbers[fps % 10]), 0); ((GL11Ext) gl).glDrawTexiOES(dx, dy, 0, fontSize, fontSize * 2); } public synchronized void drawString(final GL10 gl, final StringBuffer text, final int startX, final int startY, final int fontSize) { drawString(gl, text, startX, startY, fontSize, fontMargin); } public synchronized void drawShadowString(final GL10 gl, final StringBuffer text, final int startX, final int startY, final int fontSize, float[] shadowColor, float[] textColor, int shadowX, int shadowY) { gl.glColor4f(shadowColor[0], shadowColor[1], shadowColor[2], shadowColor[3]); drawString(gl, text, startX + shadowX, startY - shadowY, fontSize, fontMargin);// Y is mirroed gl.glColor4f(textColor[0], textColor[1], textColor[2], textColor[3]); drawString(gl, text, startX, startY, fontSize, fontMargin);// Y is // mirroed } /* * ???????????? */ public synchronized void drawBorderString(final GL10 gl, final StringBuffer text, final int startX, final int startY, final int fontSize, float marginPersent, float[] borderColor, float[] textColor, int border) { dy = startY; dx = startX; gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId); for (i = 0; i < text.length(); i++) { ch = text.charAt(i); gl.glColor4f(borderColor[0], borderColor[1], borderColor[2], borderColor[3]); ((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, getImageFontRec(ch), 0); ((GL11Ext) gl).glDrawTexiOES(dx, dy, 0, fontSize, fontSize); gl.glColor4f(textColor[0], textColor[1], textColor[2], textColor[3]); ((GL11Ext) gl).glDrawTexiOES(dx + border / 2, dy + border / 2, 0, fontSize - border, fontSize - border); dx += fontSize * marginPersent;// *marginPersent; } } int getImageFontRec_x; int getImageFontRec_y; int getImageFontRec_return[]; public synchronized int[] getImageFontRec(char ch) { getImageFontRec_x = ((int) ch) % 16; getImageFontRec_y = 7 - ((int) ch) / 16;// image size // Log.i("my","dx:"+dx+",dy="+dy); getImageFontRec_return[0] = baseSize * getImageFontRec_x; getImageFontRec_return[1] = baseSize * getImageFontRec_y * 2; return getImageFontRec_return; } }
10-Focus
Set focus
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="wrap_content" android:layout_width="match_parent" android:orientation="horizontal"> <Button android:id="@+id/leftButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="3dip" android:text="focus_2_left" android:nextFocusRight="@+id/rightButton"/> <!-- jump over middle! --> <Button android:id="@+id/centerButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="3dip" android:text="focus_2_jump" /> <Button android:id="@+id/rightButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="3dip" android:text="focus_2_right"/> </LinearLayout>
package com.example.android.apis.view; import com.example.android.apis.R; import android.app.Activity; import android.os.Bundle; public class Focus2 extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } }
Using three adjacent InternalSelectionView that report interesting rects when giving up focus
package com.example.android.apis.view; import android.app.Activity; import android.os.Bundle; import android.view.ViewGroup; import android.widget.LinearLayout; public class InternalSelectionFocus extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final LinearLayout layout = new LinearLayout(this); layout.setOrientation(LinearLayout.HORIZONTAL); layout.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT, 1); final InternalSelectionView leftColumn = new InternalSelectionView(this, 5, "left column"); leftColumn.setLayoutParams(params); leftColumn.setPadding(10, 10, 10, 10); layout.addView(leftColumn); final InternalSelectionView middleColumn = new InternalSelectionView(this, 5, "middle column"); middleColumn.setLayoutParams(params); middleColumn.setPadding(10, 10, 10, 10); layout.addView(middleColumn); final InternalSelectionView rightColumn = new InternalSelectionView(this, 5, "right column"); rightColumn.setLayoutParams(params); rightColumn.setPadding(10, 10, 10, 10); layout.addView(rightColumn); setContentView(layout); } }
package com.example.android.apis.view; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.util.AttributeSet; import android.view.KeyEvent; import android.view.View; public class InternalSelectionView extends View { private Paint mPainter = new Paint(); private Paint mTextPaint = new Paint(); private Rect mTempRect = new Rect(); private int mNumRows = 5; private int mSelectedRow = 0; private final int mEstimatedPixelHeight = 10; private Integer mDesiredHeight = null; private String mLabel = null; public InternalSelectionView(Context context, int numRows) { this(context, numRows, ""); } public InternalSelectionView(Context context, int numRows, String label) { super(context); mNumRows = numRows; mLabel = label; init(); } public InternalSelectionView(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { setFocusable(true); mTextPaint.setAntiAlias(true); mTextPaint.setTextSize(10); mTextPaint.setColor(Color.WHITE); } public int getNumRows() { return mNumRows; } public int getSelectedRow() { return mSelectedRow; } public void setDesiredHeight(int desiredHeight) { mDesiredHeight = desiredHeight; } public String getLabel() { return mLabel; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension( measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec)); } private int measureWidth(int measureSpec) { int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); int desiredWidth = 300 + getPaddingLeft() + getPaddingRight(); if (specMode == MeasureSpec.EXACTLY) { // We were told how big to be return specSize; } else if (specMode == MeasureSpec.AT_MOST) { return desiredWidth < specSize ? desiredWidth : specSize; } else { return desiredWidth; } } private int measureHeight(int measureSpec) { int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); int desiredHeight = mDesiredHeight != null ? mDesiredHeight : mNumRows * mEstimatedPixelHeight + getPaddingTop() + getPaddingBottom(); if (specMode == MeasureSpec.EXACTLY) { // We were told how big to be return specSize; } else if (specMode == MeasureSpec.AT_MOST) { return desiredHeight < specSize ? desiredHeight : specSize; } else { return desiredHeight; } } @Override protected void onDraw(Canvas canvas) { int rowHeight = getRowHeight(); int rectTop = getPaddingTop(); int rectLeft = getPaddingLeft(); int rectRight = getWidth() - getPaddingRight(); for (int i = 0; i < mNumRows; i++) { mPainter.setColor(Color.BLACK); mPainter.setAlpha(0x20); // draw background rect mTempRect.set(rectLeft, rectTop, rectRight, rectTop + rowHeight); canvas.drawRect(mTempRect, mPainter); // draw forground rect if (i == mSelectedRow && hasFocus()) { mPainter.setColor(Color.RED); mPainter.setAlpha(0xF0); mTextPaint.setAlpha(0xFF); } else { mPainter.setColor(Color.BLACK); mPainter.setAlpha(0x40); mTextPaint.setAlpha(0xF0); } mTempRect.set(rectLeft + 2, rectTop + 2, rectRight - 2, rectTop + rowHeight - 2); canvas.drawRect(mTempRect, mPainter); // draw text to help when visually inspecting canvas.drawText( Integer.toString(i), rectLeft + 2, rectTop + 2 - (int) mTextPaint.ascent(), mTextPaint); rectTop += rowHeight; } } private int getRowHeight() { return (getHeight() - getPaddingTop() - getPaddingBottom()) / mNumRows; } public void getRectForRow(Rect rect, int row) { final int rowHeight = getRowHeight(); final int top = getPaddingTop() + row * rowHeight; rect.set(getPaddingLeft(), top, getWidth() - getPaddingRight(), top + rowHeight); } void ensureRectVisible() { getRectForRow(mTempRect, mSelectedRow); requestRectangleOnScreen(mTempRect); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { switch(event.getKeyCode()) { case KeyEvent.KEYCODE_DPAD_UP: if (mSelectedRow > 0) { mSelectedRow--; invalidate(); ensureRectVisible(); return true; } break; case KeyEvent.KEYCODE_DPAD_DOWN: if (mSelectedRow < (mNumRows - 1)) { mSelectedRow++; invalidate(); ensureRectVisible(); return true; } break; } return false; } @Override public void getFocusedRect(Rect r) { getRectForRow(r, mSelectedRow); } @Override protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { super.onFocusChanged(focused, direction, previouslyFocusedRect); if (focused) { switch (direction) { case View.FOCUS_DOWN: mSelectedRow = 0; break; case View.FOCUS_UP: mSelectedRow = mNumRows - 1; break; case View.FOCUS_LEFT: // fall through case View.FOCUS_RIGHT: // set the row that is closest to the rect if (previouslyFocusedRect != null) { int y = previouslyFocusedRect.top + (previouslyFocusedRect.height() / 2); int yPerRow = getHeight() / mNumRows; mSelectedRow = y / yPerRow; } else { mSelectedRow = 0; } break; default: // can't gleam any useful information about what internal // selection should be... return; } invalidate(); } } @Override public String toString() { if (mLabel != null) { return mLabel; } return super.toString(); } }
Demonstrates using nextFocusForward to explicitly set sequential focus order.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="wrap_content" android:layout_width="match_parent" android:orientation="horizontal"> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="wrap_content" android:layout_width="wrap_content" android:orientation="vertical"> <Button android:id="@+id/button1" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="focus_5_button1" android:nextFocusForward="@+id/button2"/> <Button android:id="@+id/button2" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="focus_5_button2" android:nextFocusForward="@+id/button3"/> <Button android:id="@+id/button3" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="focus_5_button3" android:nextFocusForward="@+id/button4"/> </LinearLayout> <Button android:id="@+id/button4" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="focus_5_button4" android:nextFocusForward="@+id/button5"/> <Button android:id="@+id/button5" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="focus_5_button5" android:nextFocusForward="@+id/button1"/> </LinearLayout>
package com.example.android.apis.view; import android.app.Activity; import android.os.Bundle; import android.widget.Button; import com.example.android.apis.R; public class Focus5 extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } }
Demonstrates using nextLeft, nextRight, nextUp and nextDown to get focus behavior that would be difficult with default focus
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="10dip"> <Button android:id="@+id/top" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:nextFocusDown="@+id/bottom" android:text="focus_3_top"/> <Button android:id="@+id/right" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:nextFocusLeft="@+id/left" android:text="focus_3_right"/> <Button android:id="@+id/bottom" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:nextFocusUp="@+id/top" android:text="focus_3_bottom"/> <Button android:id="@+id/left" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:nextFocusRight="@+id/right" android:text="focus_3_left"/> </RelativeLayout>
package com.example.android.apis.view; import android.app.Activity; import android.os.Bundle; import android.widget.Button; public class Focus3 extends Activity { private Button mTopButton; private Button mBottomButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mTopButton = (Button) findViewById(R.id.top); mBottomButton = (Button) findViewById(R.id.bottom); } public Button getTopButton() { return mTopButton; } public Button getBottomButton() { return mBottomButton; } }
Demonstrates the use of non-focusable views.
package com.example.android.apis.view; import com.example.android.apis.R; import android.app.Activity; import android.os.Bundle; import android.webkit.WebView; import android.widget.ListView; import android.widget.ArrayAdapter; /** * Demonstrates the use of non-focusable views. */ public class Focus1 extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); WebView webView = (WebView) findViewById(R.id.rssWebView); webView.loadData( "<html><body>Can I focus?<br /><a href=\"#\">No I cannot!</a>.</body></html>", "text/html", "utf-8"); ListView listView = (ListView) findViewById(R.id.rssListView); listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, new String[] {"Ars Technica", "Slashdot", "GameKult"})); } }
11-FrameLayout
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/frmLayout" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ImageView android:id="@+id/oneImgView" android:src="@drawable/icon" android:scaleType="fitCenter" android:layout_width="fill_parent" android:layout_height="fill_parent"/> <ImageView android:id="@+id/twoImgView" android:src="@drawable/icon" android:scaleType="fitCenter" android:layout_width="fill_parent" android:layout_height="fill_parent" android:visibility="gone" /> </FrameLayout>
package app.test; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageView; public class Test extends Activity{ private ImageView one = null; private ImageView two = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); one = (ImageView)findViewById(R.id.oneImgView); two = (ImageView)findViewById(R.id.twoImgView); one.setOnClickListener(new OnClickListener(){ public void onClick(View view) { two.setVisibility(View.VISIBLE); view.setVisibility(View.GONE); }}); two.setOnClickListener(new OnClickListener(){ public void onClick(View view) { one.setVisibility(View.VISIBLE); view.setVisibility(View.GONE); }}); } }
12-RatingBar
<?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" > <RatingBar android:id="@+id/rate" android:layout_width="wrap_content" android:layout_height="wrap_content" android:numStars="3" android:stepSize="1" android:rating="2" /> <TextView android:id="@+id/label" android:paddingLeft="2px" android:paddingRight="2px" android:paddingTop="2px" android:textSize="40sp" android:layout_width="fill_parent" android:layout_height="wrap_content"/> </LinearLayout>
package com.commonsware.android.fancylists.six; import android.app.Activity; import android.os.Bundle; import android.app.ListActivity; import android.view.View; import android.view.ViewGroup; import android.view.LayoutInflater; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.RatingBar; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; import java.util.ArrayList; public class RateListDemo extends ListActivity { String[] items={"lorem", "ipsum", "dolor", "sit", "amet", "consectetuer", "adipiscing", "elit", "morbi", "vel", "ligula", "vitae", "arcu", "aliquet", "mollis", "etiam", "vel", "erat", "placerat", "ante", "porttitor", "sodales", "pellentesque", "augue", "purus"}; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); ArrayList<RowModel> list=new ArrayList<RowModel>(); for (String s : items) { list.add(new RowModel(s)); } setListAdapter(new RatingAdapter(list)); } private RowModel getModel(int position) { return(((RatingAdapter)getListAdapter()).getItem(position)); } class RatingAdapter extends ArrayAdapter<RowModel> { RatingAdapter(ArrayList<RowModel> list) { super(RateListDemo.this, R.layout.row, list); } public View getView(int position, View convertView, ViewGroup parent) { View row=convertView; ViewWrapper wrapper; RatingBar rate; if (row==null) { LayoutInflater inflater=getLayoutInflater(); row=inflater.inflate(R.layout.row, parent, false); wrapper=new ViewWrapper(row); row.setTag(wrapper); rate=wrapper.getRatingBar(); RatingBar.OnRatingBarChangeListener l= new RatingBar.OnRatingBarChangeListener() { public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromTouch) { Integer myPosition=(Integer)ratingBar.getTag(); RowModel model=getModel(myPosition); model.rating=rating; LinearLayout parent=(LinearLayout)ratingBar.getParent(); TextView label=(TextView)parent.findViewById(R.id.label); label.setText(model.toString()); } }; rate.setOnRatingBarChangeListener(l); } else { wrapper=(ViewWrapper)row.getTag(); rate=wrapper.getRatingBar(); } RowModel model=getModel(position); wrapper.getLabel().setText(model.toString()); rate.setTag(new Integer(position)); rate.setRating(model.rating); return(row); } } class RowModel { String label; float rating=2.0f; RowModel(String label) { this.label=label; } public String toString() { if (rating>=3.0) { return(label.toUpperCase()); } return(label); } } }
package com.commonsware.android.fancylists.six; import android.view.View; import android.widget.RatingBar; import android.widget.TextView; class ViewWrapper { View base; RatingBar rate=null; TextView label=null; ViewWrapper(View base) { this.base=base; } RatingBar getRatingBar() { if (rate==null) { rate=(RatingBar)base.findViewById(R.id.rate); } return(rate); } TextView getLabel() { if (label==null) { label=(TextView)base.findViewById(R.id.label); } return(label); } }
Demonstrates how to use a rating bar
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:paddingLeft="10dip" android:layout_width="match_parent" android:layout_height="match_parent"> <RatingBar android:id="@+id/ratingbar1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:numStars="3" android:rating="2.5" /> <RatingBar android:id="@+id/ratingbar2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:numStars="5" android:rating="2.25" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dip"> <TextView android:id="@+id/rating" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <RatingBar android:id="@+id/small_ratingbar" style="?android:attr/ratingBarStyleSmall" android:layout_marginLeft="5dip" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" /> </LinearLayout> <RatingBar android:id="@+id/indicator_ratingbar" style="?android:attr/ratingBarStyleIndicator" android:layout_marginLeft="5dip" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" /> </LinearLayout>
package com.example.android.apis.view; import android.app.Activity; import android.os.Bundle; import android.widget.RatingBar; import android.widget.TextView; import com.example.android.apis.R; /** * Demonstrates how to use a rating bar */ public class RatingBar1 extends Activity implements RatingBar.OnRatingBarChangeListener { RatingBar mSmallRatingBar; RatingBar mIndicatorRatingBar; TextView mRatingText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.ratingbar_1); mRatingText = (TextView) findViewById(R.id.rating); // We copy the most recently changed rating on to these indicator-only // rating bars mIndicatorRatingBar = (RatingBar) findViewById(R.id.indicator_ratingbar); mSmallRatingBar = (RatingBar) findViewById(R.id.small_ratingbar); // The different rating bars in the layout. Assign the listener to us. ((RatingBar)findViewById(R.id.ratingbar1)).setOnRatingBarChangeListener(this); ((RatingBar)findViewById(R.id.ratingbar2)).setOnRatingBarChangeListener(this); } public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromTouch) { final int numStars = ratingBar.getNumStars(); mRatingText.setText( getString(R.string.ratingbar_rating) + " " + rating + "/" + numStars); // Since this rating bar is updated to reflect any of the other rating // bars, we should update it to the current values. if (mIndicatorRatingBar.getNumStars() != numStars) { mIndicatorRatingBar.setNumStars(numStars); mSmallRatingBar.setNumStars(numStars); } if (mIndicatorRatingBar.getRating() != rating) { mIndicatorRatingBar.setRating(rating); mSmallRatingBar.setRating(rating); } final float ratingBarStepSize = ratingBar.getStepSize(); if (mIndicatorRatingBar.getStepSize() != ratingBarStepSize) { mIndicatorRatingBar.setStepSize(ratingBarStepSize); mSmallRatingBar.setStepSize(ratingBarStepSize); } } }
RatingBar Demo
//main.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"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="RatingBar" /> <RatingBar android:id="@+id/rating_bar" android:layout_width="wrap_content" android:layout_height="wrap_content" ratingBarStyleSmall="true" /> </LinearLayout>
package app.test; import android.app.Activity; import android.os.Bundle; public class Test extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setTitle("RatingBarActivity"); setContentView(R.layout.main); } }
13-RSSurfaceView
package com.example.android.rs.helloworld; import android.app.Activity; import android.os.Bundle; // Renderscript activity public class HelloWorld extends Activity { // Custom view to use with RenderScript private HelloWorldView mView; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); // Create our view and set it as the content of our Activity mView = new HelloWorldView(this); setContentView(mView); } @Override protected void onResume() { // Ideally an app should implement onResume() and onPause() // to take appropriate action when the activity loses focus super.onResume(); mView.resume(); } @Override protected void onPause() { // Ideally an app should implement onResume() and onPause() // to take appropriate action when the activity loses focus super.onPause(); mView.pause(); } }
package com.example.android.rs.helloworld; import android.content.res.Resources; import android.renderscript.*; // This is the renderer for the HelloWorldView public class HelloWorldRS { private Resources mRes; private RenderScriptGL mRS; private ScriptC_helloworld mScript; public HelloWorldRS() { } // This provides us with the renderscript context and resources that // allow us to create the script that does rendering public void init(RenderScriptGL rs, Resources res) { mRS = rs; mRes = res; initRS(); } public void onActionDown(int x, int y) { mScript.set_gTouchX(x); mScript.set_gTouchY(y); } private void initRS() { mScript = new ScriptC_helloworld(mRS, mRes, R.raw.helloworld); mRS.bindRootScript(mScript); } }
package com.example.android.rs.helloworld; import android.renderscript.RSSurfaceView; import android.renderscript.RenderScriptGL; import android.content.Context; import android.view.MotionEvent; public class HelloWorldView extends RSSurfaceView { // Renderscipt context private RenderScriptGL mRS; // Script that does the rendering private HelloWorldRS mRender; public HelloWorldView(Context context) { super(context); ensureRenderScript(); } private void ensureRenderScript() { if (mRS == null) { // Initialize renderscript with desired surface characteristics. // In this case, just use the defaults RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig(); mRS = createRenderScriptGL(sc); // Create an instance of the script that does the rendering mRender = new HelloWorldRS(); mRender.init(mRS, getResources()); } } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); ensureRenderScript(); } @Override protected void onDetachedFromWindow() { // Handle the system event and clean up mRender = null; if (mRS != null) { mRS = null; destroyRenderScriptGL(); } } @Override public boolean onTouchEvent(MotionEvent ev) { // Pass touch events from the system to the rendering script if (ev.getAction() == MotionEvent.ACTION_DOWN) { mRender.onActionDown((int)ev.getX(), (int)ev.getY()); return true; } return false; } }
helloworld.rs
//src\com\example\android\rs\helloworld\helloworld.rs #pragma version(1) // Tell which java package name the reflected files should belong to #pragma rs java_package_name(com.example.android.rs.helloworld) // Built-in header with graphics API's #include "rs_graphics.rsh" // gTouchX and gTouchY are variables that will be reflected for use // by the java API. We can use them to notify the script of touch events. int gTouchX; int gTouchY; // This is invoked automatically when the script is created void init() { gTouchX = 50.0f; gTouchY = 50.0f; } int root(int launchID) { // Clear the background color rsgClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Tell the runtime what the font color should be rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f); // Introuduce ourselves to the world by drawing a greeting // at the position user touched on the screen rsgDrawText("Hello World!", gTouchX, gTouchY); // Return value tells RS roughly how often to redraw // in this case 20 ms return 20; }
RenderScript Balls
package com.example.android.rs.balls; import android.renderscript.RSSurfaceView; import android.renderscript.RenderScript; import android.app.Activity; import android.content.res.Configuration; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.provider.Settings.System; import android.util.Config; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.Window; import android.widget.Button; import android.widget.ListView; import java.lang.Runtime; import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.view.View; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; public class Balls extends Activity implements SensorEventListener { //EventListener mListener = new EventListener(); private static final String LOG_TAG = "libRS_jni"; private static final boolean DEBUG = false; private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV; private BallsView mView; private SensorManager mSensorManager; // get the current looper (from your Activity UI thread for instance public void onSensorChanged(SensorEvent event) { //android.util.Log.d("rs", "sensor: " + event.sensor + ", x: " + event.values[0] + ", y: " + event.values[1] + ", z: " + event.values[2]); synchronized (this) { if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { if(mView != null) { mView.setAccel(event.values[0], event.values[1], event.values[2]); } } } } public void onAccuracyChanged(Sensor sensor, int accuracy) { } @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); // Create our Preview view and set it as the content of our // Activity mView = new BallsView(this); setContentView(mView); } @Override protected void onResume() { mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_FASTEST); // Ideally a game should implement onResume() and onPause() // to take appropriate action when the activity looses focus super.onResume(); mView.resume(); } @Override protected void onPause() { super.onPause(); mView.pause(); Runtime.getRuntime().exit(0); } @Override protected void onStop() { mSensorManager.unregisterListener(this); super.onStop(); } static void log(String message) { if (LOG_ENABLED) { Log.v(LOG_TAG, message); } } }
package com.example.android.rs.balls; import android.content.res.Resources; import android.renderscript.*; import android.util.Log; public class BallsRS { public static final int PART_COUNT = 900; public BallsRS() { } private Resources mRes; private RenderScriptGL mRS; private ScriptC_balls mScript; private ScriptC_ball_physics mPhysicsScript; private ProgramFragment mPFLines; private ProgramFragment mPFPoints; private ProgramVertex mPV; private ScriptField_Point mPoints; private ScriptField_VpConsts mVpConsts; void updateProjectionMatrices() { mVpConsts = new ScriptField_VpConsts(mRS, 1, Allocation.USAGE_SCRIPT | Allocation.USAGE_GRAPHICS_CONSTANTS); ScriptField_VpConsts.Item i = new ScriptField_VpConsts.Item(); Matrix4f mvp = new Matrix4f(); mvp.loadOrtho(0, mRS.getWidth(), mRS.getHeight(), 0, -1, 1); i.MVP = mvp; mVpConsts.set(i, 0, true); } private void createProgramVertex() { updateProjectionMatrices(); ProgramVertex.Builder sb = new ProgramVertex.Builder(mRS); String t = "varying vec4 varColor;\n" + "void main() {\n" + " vec4 pos = vec4(0.0, 0.0, 0.0, 1.0);\n" + " pos.xy = ATTRIB_position;\n" + " gl_Position = UNI_MVP * pos;\n" + " varColor = vec4(1.0, 1.0, 1.0, 1.0);\n" + " gl_PointSize = ATTRIB_size;\n" + "}\n"; sb.setShader(t); sb.addConstant(mVpConsts.getType()); sb.addInput(mPoints.getElement()); ProgramVertex pvs = sb.create(); pvs.bindConstants(mVpConsts.getAllocation(), 0); mRS.bindProgramVertex(pvs); } private Allocation loadTexture(int id) { final Allocation allocation = Allocation.createFromBitmapResource(mRS, mRes, id, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_GRAPHICS_TEXTURE); return allocation; } ProgramStore BLEND_ADD_DEPTH_NONE(RenderScript rs) { ProgramStore.Builder builder = new ProgramStore.Builder(rs); builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS); builder.setBlendFunc(ProgramStore.BlendSrcFunc.ONE, ProgramStore.BlendDstFunc.ONE); builder.setDitherEnabled(false); builder.setDepthMaskEnabled(false); return builder.create(); } public void init(RenderScriptGL rs, Resources res, int width, int height) { mRS = rs; mRes = res; ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs); pfb.setPointSpriteTexCoordinateReplacement(true); pfb.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE, ProgramFragmentFixedFunction.Builder.Format.RGBA, 0); pfb.setVaryingColor(true); mPFPoints = pfb.create(); pfb = new ProgramFragmentFixedFunction.Builder(rs); pfb.setVaryingColor(true); mPFLines = pfb.create(); android.util.Log.e("rs", "Load texture"); mPFPoints.bindTexture(loadTexture(R.drawable.flares), 0); mPoints = new ScriptField_Point(mRS, PART_COUNT, Allocation.USAGE_SCRIPT); Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS); smb.addVertexAllocation(mPoints.getAllocation()); smb.addIndexSetType(Mesh.Primitive.POINT); Mesh smP = smb.create(); mPhysicsScript = new ScriptC_ball_physics(mRS, mRes, R.raw.ball_physics); mScript = new ScriptC_balls(mRS, mRes, R.raw.balls); mScript.set_partMesh(smP); mScript.set_physics_script(mPhysicsScript); mScript.bind_point(mPoints); mScript.bind_balls1(new ScriptField_Ball(mRS, PART_COUNT, Allocation.USAGE_SCRIPT)); mScript.bind_balls2(new ScriptField_Ball(mRS, PART_COUNT, Allocation.USAGE_SCRIPT)); mScript.set_gPFLines(mPFLines); mScript.set_gPFPoints(mPFPoints); createProgramVertex(); mRS.bindProgramStore(BLEND_ADD_DEPTH_NONE(mRS)); mPhysicsScript.set_gMinPos(new Float2(5, 5)); mPhysicsScript.set_gMaxPos(new Float2(width - 5, height - 5)); mScript.invoke_initParts(width, height); mRS.bindRootScript(mScript); } public void newTouchPosition(float x, float y, float pressure, int id) { mPhysicsScript.invoke_touch(x, y, pressure, id); } public void setAccel(float x, float y) { mPhysicsScript.set_gGravityVector(new Float2(x, y)); } }
package com.example.android.rs.balls; import java.io.Writer; import java.util.ArrayList; import java.util.concurrent.Semaphore; import android.renderscript.RSSurfaceView; import android.renderscript.RenderScript; import android.renderscript.RenderScriptGL; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.Log; import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.KeyEvent; import android.view.MotionEvent; public class BallsView extends RSSurfaceView { public BallsView(Context context) { super(context); //setFocusable(true); } private RenderScriptGL mRS; private BallsRS mRender; public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { super.surfaceChanged(holder, format, w, h); if (mRS == null) { RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig(); mRS = createRenderScriptGL(sc); mRS.setSurface(holder, w, h); mRender = new BallsRS(); mRender.init(mRS, getResources(), w, h); } mRender.updateProjectionMatrices(); } @Override protected void onDetachedFromWindow() { if(mRS != null) { mRS = null; destroyRenderScriptGL(); } } @Override public boolean onTouchEvent(MotionEvent ev) { int act = ev.getActionMasked(); if (act == ev.ACTION_UP) { mRender.newTouchPosition(0, 0, 0, ev.getPointerId(0)); return false; } else if (act == MotionEvent.ACTION_POINTER_UP) { // only one pointer going up, we can get the index like this int pointerIndex = ev.getActionIndex(); int pointerId = ev.getPointerId(pointerIndex); mRender.newTouchPosition(0, 0, 0, pointerId); return false; } int count = ev.getHistorySize(); int pcount = ev.getPointerCount(); for (int p=0; p < pcount; p++) { int id = ev.getPointerId(p); mRender.newTouchPosition(ev.getX(p), ev.getY(p), ev.getPressure(p), id); for (int i=0; i < count; i++) { mRender.newTouchPosition(ev.getHistoricalX(p, i), ev.getHistoricalY(p, i), ev.getHistoricalPressure(p, i), id); } } return true; } void setAccel(float x, float y, float z) { if (mRender == null) { return; } mRender.setAccel(x, -y); } }
ball_physics.rs
//src\com\example\android\rs\balls\ball_physics.rs #pragma version(1) #pragma rs java_package_name(com.example.android.rs.balls) #include "balls.rsh" float2 gGravityVector = {0.f, 9.8f}; float2 gMinPos = {0.f, 0.f}; float2 gMaxPos = {1280.f, 700.f}; static float2 touchPos[10]; static float touchPressure[10]; void touch(float x, float y, float pressure, int id) { if (id >= 10) { return; } touchPos[id].x = x; touchPos[id].y = y; touchPressure[id] = pressure; } void root(const Ball_t *ballIn, Ball_t *ballOut, const BallControl_t *ctl, uint32_t x) { float2 fv = {0, 0}; float2 pos = ballIn->position; int arcID = -1; float arcInvStr = 100000; const Ball_t * bPtr = rsGetElementAt(ctl->ain, 0); for (uint32_t xin = 0; xin < ctl->dimX; xin++) { float2 vec = bPtr[xin].position - pos; float2 vec2 = vec * vec; float len2 = vec2.x + vec2.y; if (len2 < 10000) { //float minDist = ballIn->size + bPtr[xin].size; float forceScale = ballIn->size * bPtr[xin].size; forceScale *= forceScale; if (len2 > 16 /* (minDist*minDist)*/) { // Repulsion float len = sqrt(len2); fv -= (vec / (len * len * len)) * 20000.f * forceScale; } else { if (len2 < 1) { if (xin == x) { continue; } ballOut->delta = 0.f; ballOut->position = ballIn->position; if (xin > x) { ballOut->position.x += 1.f; } else { ballOut->position.x -= 1.f; } //ballOut->color.rgb = 1.f; //ballOut->arcID = -1; //ballOut->arcStr = 0; return; } // Collision float2 axis = normalize(vec); float e1 = dot(axis, ballIn->delta); float e2 = dot(axis, bPtr[xin].delta); float e = (e1 - e2) * 0.45f; if (e1 > 0) { fv -= axis * e; } else { fv += axis * e; } } } } fv /= ballIn->size * ballIn->size * ballIn->size; fv -= gGravityVector * 4.f; fv *= ctl->dt; for (int i=0; i < 10; i++) { if (touchPressure[i] > 0.1f) { float2 vec = touchPos[i] - ballIn->position; float2 vec2 = vec * vec; float len2 = max(2.f, vec2.x + vec2.y); fv -= (vec / len2) * touchPressure[i] * 300.f; } } ballOut->delta = (ballIn->delta * (1.f - 0.004f)) + fv; ballOut->position = ballIn->position + (ballOut->delta * ctl->dt); const float wallForce = 400.f; if (ballOut->position.x > (gMaxPos.x - 20.f)) { float d = gMaxPos.x - ballOut->position.x; if (d < 0.f) { if (ballOut->delta.x > 0) { ballOut->delta.x *= -0.7; } ballOut->position.x = gMaxPos.x; } else { ballOut->delta.x -= min(wallForce / (d * d), 10.f); } } if (ballOut->position.x < (gMinPos.x + 20.f)) { float d = ballOut->position.x - gMinPos.x; if (d < 0.f) { if (ballOut->delta.x < 0) { ballOut->delta.x *= -0.7; } ballOut->position.x = gMinPos.x + 1.f; } else { ballOut->delta.x += min(wallForce / (d * d), 10.f); } } if (ballOut->position.y > (gMaxPos.y - 20.f)) { float d = gMaxPos.y - ballOut->position.y; if (d < 0.f) { if (ballOut->delta.y > 0) { ballOut->delta.y *= -0.7; } ballOut->position.y = gMaxPos.y; } else { ballOut->delta.y -= min(wallForce / (d * d), 10.f); } } if (ballOut->position.y < (gMinPos.y + 20.f)) { float d = ballOut->position.y - gMinPos.y; if (d < 0.f) { if (ballOut->delta.y < 0) { ballOut->delta.y *= -0.7; } ballOut->position.y = gMinPos.y + 1.f; } else { ballOut->delta.y += min(wallForce / (d * d * d), 10.f); } } ballOut->size = ballIn->size; //rsDebug("physics pos out", ballOut->position); }
balls.rs
//src\com\example\android\rs\balls\balls.rs #pragma version(1) #pragma rs java_package_name(com.example.android.rs.balls) #include "rs_graphics.rsh" #include "balls.rsh" #pragma stateVertex(parent) #pragma stateStore(parent) rs_program_fragment gPFPoints; rs_program_fragment gPFLines; rs_mesh partMesh; typedef struct __attribute__((packed, aligned(4))) Point { float2 position; float size; } Point_t; Point_t *point; typedef struct VpConsts { rs_matrix4x4 MVP; } VpConsts_t; VpConsts_t *vpConstants; rs_script physics_script; Ball_t *balls1; Ball_t *balls2; static int frame = 0; void initParts(int w, int h) { uint32_t dimX = rsAllocationGetDimX(rsGetAllocation(balls1)); for (uint32_t ct=0; ct < dimX; ct++) { balls1[ct].position.x = rsRand(0.f, (float)w); balls1[ct].position.y = rsRand(0.f, (float)h); balls1[ct].delta.x = 0.f; balls1[ct].delta.y = 0.f; balls1[ct].size = 1.f; float r = rsRand(100.f); if (r > 90.f) { balls1[ct].size += pow(10.f, rsRand(0.f, 2.f)) * 0.07; } } } int root() { rsgClearColor(0.f, 0.f, 0.f, 1.f); BallControl_t bc; Ball_t *bout; if (frame & 1) { rsSetObject(&bc.ain, rsGetAllocation(balls2)); rsSetObject(&bc.aout, rsGetAllocation(balls1)); bout = balls2; } else { rsSetObject(&bc.ain, rsGetAllocation(balls1)); rsSetObject(&bc.aout, rsGetAllocation(balls2)); bout = balls1; } bc.dimX = rsAllocationGetDimX(bc.ain); bc.dt = 1.f / 30.f; rsForEach(physics_script, bc.ain, bc.aout, &bc); for (uint32_t ct=0; ct < bc.dimX; ct++) { point[ct].position = bout[ct].position; point[ct].size = 6.f /*+ bout[ct].color.g * 6.f*/ * bout[ct].size; } frame++; rsgBindProgramFragment(gPFPoints); rsgDrawMesh(partMesh); rsClearObject(&bc.ain); rsClearObject(&bc.aout); return 1; }
balls.rsh
//src\com\example\android\rs\balls\balls.rsh typedef struct __attribute__((packed, aligned(4))) Ball { float2 delta; float2 position; //float3 color; float size; //int arcID; //float arcStr; } Ball_t; Ball_t *balls; typedef struct BallControl { uint32_t dimX; rs_allocation ain; rs_allocation aout; float dt; } BallControl_t;
RenderScript Fountain
package com.example.android.rs.fountain; import android.renderscript.RSSurfaceView; import android.renderscript.RenderScript; import android.app.Activity; import android.content.res.Configuration; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.provider.Settings.System; import android.util.Config; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.Window; import android.widget.Button; import android.widget.ListView; import java.lang.Runtime; public class Fountain extends Activity { //EventListener mListener = new EventListener(); private static final String LOG_TAG = "libRS_jni"; private static final boolean DEBUG = false; private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV; private FountainView mView; // get the current looper (from your Activity UI thread for instance @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); // Create our Preview view and set it as the content of our // Activity mView = new FountainView(this); setContentView(mView); } @Override protected void onResume() { Log.e("rs", "onResume"); // Ideally a game should implement onResume() and onPause() // to take appropriate action when the activity looses focus super.onResume(); mView.resume(); } @Override protected void onPause() { Log.e("rs", "onPause"); // Ideally a game should implement onResume() and onPause() // to take appropriate action when the activity looses focus super.onPause(); mView.pause(); //Runtime.getRuntime().exit(0); } static void log(String message) { if (LOG_ENABLED) { Log.v(LOG_TAG, message); } } }
C:\Java_Dev\sdk\Android\android-sdk\samples\android-13\RenderScript\Fountain\src\com\example\android\rs\fountain\FountainRS.java package com.example.android.rs.fountain; import android.content.res.Resources; import android.renderscript.*; import android.util.Log; public class FountainRS { public static final int PART_COUNT = 50000; public FountainRS() { } private Resources mRes; private RenderScriptGL mRS; private ScriptC_fountain mScript; public void init(RenderScriptGL rs, Resources res, int width, int height) { mRS = rs; mRes = res; ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs); pfb.setVaryingColor(true); rs.bindProgramFragment(pfb.create()); ScriptField_Point points = new ScriptField_Point(mRS, PART_COUNT);// // Allocation.USAGE_GRAPHICS_VERTEX); Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS); smb.addVertexAllocation(points.getAllocation()); smb.addIndexSetType(Mesh.Primitive.POINT); Mesh sm = smb.create(); mScript = new ScriptC_fountain(mRS, mRes, R.raw.fountain); mScript.set_partMesh(sm); mScript.bind_point(points); mRS.bindRootScript(mScript); } boolean holdingColor[] = new boolean[10]; public void newTouchPosition(float x, float y, float pressure, int id) { if (id >= holdingColor.length) { return; } int rate = (int)(pressure * pressure * 500.f); if (rate > 500) { rate = 500; } if (rate > 0) { mScript.invoke_addParticles(rate, x, y, id, !holdingColor[id]); holdingColor[id] = true; } else { holdingColor[id] = false; } } }
C:\Java_Dev\sdk\Android\android-sdk\samples\android-13\RenderScript\Fountain\src\com\example\android\rs\fountain\FountainView.java package com.example.android.rs.fountain; import java.io.Writer; import java.util.ArrayList; import java.util.concurrent.Semaphore; import android.renderscript.RSSurfaceView; import android.renderscript.RenderScript; import android.renderscript.RenderScriptGL; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.Log; import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.KeyEvent; import android.view.MotionEvent; public class FountainView extends RSSurfaceView { public FountainView(Context context) { super(context); //setFocusable(true); } private RenderScriptGL mRS; private FountainRS mRender; public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { super.surfaceChanged(holder, format, w, h); if (mRS == null) { RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig(); mRS = createRenderScriptGL(sc); mRS.setSurface(holder, w, h); mRender = new FountainRS(); mRender.init(mRS, getResources(), w, h); } } @Override protected void onDetachedFromWindow() { if (mRS != null) { mRS = null; destroyRenderScriptGL(); } } @Override public boolean onTouchEvent(MotionEvent ev) { int act = ev.getActionMasked(); if (act == ev.ACTION_UP) { mRender.newTouchPosition(0, 0, 0, ev.getPointerId(0)); return false; } else if (act == MotionEvent.ACTION_POINTER_UP) { // only one pointer going up, we can get the index like this int pointerIndex = ev.getActionIndex(); int pointerId = ev.getPointerId(pointerIndex); mRender.newTouchPosition(0, 0, 0, pointerId); } int count = ev.getHistorySize(); int pcount = ev.getPointerCount(); for (int p=0; p < pcount; p++) { int id = ev.getPointerId(p); mRender.newTouchPosition(ev.getX(p), ev.getY(p), ev.getPressure(p), id); for (int i=0; i < count; i++) { mRender.newTouchPosition(ev.getHistoricalX(p, i), ev.getHistoricalY(p, i), ev.getHistoricalPressure(p, i), id); } } return true; } }
C:\Java_Dev\sdk\Android\android-sdk\samples\android-13\RenderScript\Fountain\src\com\example\android\rs\fountain\fountain.rs // Fountain test script #pragma version(1) #pragma rs java_package_name(com.example.android.rs.fountain) #pragma stateFragment(parent) #include "rs_graphics.rsh" static int newPart = 0; rs_mesh partMesh; typedef struct __attribute__((packed, aligned(4))) Point { float2 delta; float2 position; uchar4 color; } Point_t; Point_t *point; int root() { float dt = min(rsGetDt(), 0.1f); rsgClearColor(0.f, 0.f, 0.f, 1.f); const float height = rsgGetHeight(); const int size = rsAllocationGetDimX(rsGetAllocation(point)); float dy2 = dt * (10.f); Point_t * p = point; for (int ct=0; ct < size; ct++) { p->delta.y += dy2; p->position += p->delta; if ((p->position.y > height) && (p->delta.y > 0)) { p->delta.y *= -0.3f; } p++; } rsgDrawMesh(partMesh); return 1; } static float4 partColor[10]; void addParticles(int rate, float x, float y, int index, bool newColor) { if (newColor) { partColor[index].x = rsRand(0.5f, 1.0f); partColor[index].y = rsRand(1.0f); partColor[index].z = rsRand(1.0f); } float rMax = ((float)rate) * 0.02f; int size = rsAllocationGetDimX(rsGetAllocation(point)); uchar4 c = rsPackColorTo8888(partColor[index]); Point_t * np = &point[newPart]; float2 p = {x, y}; while (rate--) { float angle = rsRand(3.14f * 2.f); float len = rsRand(rMax); np->delta.x = len * sin(angle); np->delta.y = len * cos(angle); np->position = p; np->color = c; newPart++; np++; if (newPart >= size) { newPart = 0; np = &point[newPart]; } } }
14-SeekBar
Using SeekBar
<?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"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="SeekBar" /> <SeekBar android:id="@+id/seek" android:layout_width="fill_parent" android:layout_height="wrap_content" android:max="100" android:thumb="@drawable/icon" android:progress="50"/> </LinearLayout>
package app.test; import android.app.Activity; import android.os.Bundle; public class Test extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setTitle("SeekBarActivity"); setContentView(R.layout.main); } }
Transform views in 2D and 3D, scaling them, translating them, and rotating them (in 2D and 3D)
rotating_view.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/container" android:splitMotionEvents="true" > <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dip" android:splitMotionEvents="true" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="5dip" android:paddingRight="5dip" android:textStyle="bold" android:text="TX" /> <SeekBar android:orientation="horizontal" android:layout_weight="1" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/translationX" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="15dip" android:paddingRight="5dip" android:textStyle="bold" android:text="TY" /> <SeekBar android:orientation="horizontal" android:layout_weight="1" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/translationY" /> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dip" android:splitMotionEvents="true" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="5dip" android:paddingRight="5dip" android:textStyle="bold" android:text="SX" /> <SeekBar android:orientation="horizontal" android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/scaleX" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="15dip" android:paddingRight="5dip" android:textStyle="bold" android:text="SY" /> <SeekBar android:orientation="horizontal" android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/scaleY" /> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dip" android:splitMotionEvents="true" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="5dip" android:paddingRight="5dip" android:textStyle="bold" android:text="X" /> <SeekBar android:orientation="horizontal" android:layout_weight="1" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/rotationX" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="15dip" android:paddingRight="5dip" android:textStyle="bold" android:text="Y" /> <SeekBar android:orientation="horizontal" android:layout_weight="1" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/rotationY" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="15dip" android:paddingRight="5dip" android:textStyle="bold" android:text="Z" /> <SeekBar android:orientation="horizontal" android:layout_weight="1" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/rotationZ" /> </LinearLayout> <Button android:layout_width="200dip" android:layout_height="150dip" android:layout_marginLeft="50dip" android:layout_marginTop="50dip" android:text="Rotating Button" android:id="@+id/rotatingButton" /> </LinearLayout>
package com.example.android.apis.view; // Need the following import to get access to the app resources, since this // class is in a sub-package. import com.example.android.apis.R; import android.app.Activity; import android.os.Bundle; import android.widget.Button; import android.widget.SeekBar; /** * This application demonstrates the ability to transform views in 2D and 3D, scaling them, * translating them, and rotating them (in 2D and 3D). Use the seek bars to set the various * transform properties of the button. */ public class RotatingButton extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.rotating_view); final Button rotatingButton = (Button) findViewById(R.id.rotatingButton); SeekBar seekBar; seekBar = (SeekBar) findViewById(R.id.translationX); seekBar.setMax(400); seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { public void onStopTrackingTouch(SeekBar seekBar) { } public void onStartTrackingTouch(SeekBar seekBar) { } public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { rotatingButton.setTranslationX((float)progress); } }); seekBar = (SeekBar) findViewById(R.id.translationY); seekBar.setMax(800); seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { public void onStopTrackingTouch(SeekBar seekBar) { } public void onStartTrackingTouch(SeekBar seekBar) { } public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { rotatingButton.setTranslationY((float)progress); } }); seekBar = (SeekBar) findViewById(R.id.scaleX); seekBar.setMax(50); seekBar.setProgress(10); seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { public void onStopTrackingTouch(SeekBar seekBar) { } public void onStartTrackingTouch(SeekBar seekBar) { } public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { rotatingButton.setScaleX((float)progress/10f); } }); seekBar = (SeekBar) findViewById(R.id.scaleY); seekBar.setMax(50); seekBar.setProgress(10); seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { public void onStopTrackingTouch(SeekBar seekBar) { } public void onStartTrackingTouch(SeekBar seekBar) { } public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { rotatingButton.setScaleY((float)progress/10f); } }); seekBar = (SeekBar) findViewById(R.id.rotationX); seekBar.setMax(360); seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { public void onStopTrackingTouch(SeekBar seekBar) { } public void onStartTrackingTouch(SeekBar seekBar) { } public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { // prevent seeking on app creation rotatingButton.setRotationX((float)progress); } }); seekBar = (SeekBar) findViewById(R.id.rotationY); seekBar.setMax(360); seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { public void onStopTrackingTouch(SeekBar seekBar) { } public void onStartTrackingTouch(SeekBar seekBar) { } public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { // prevent seeking on app creation rotatingButton.setRotationY((float)progress); } }); seekBar = (SeekBar) findViewById(R.id.rotationZ); seekBar.setMax(360); seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { public void onStopTrackingTouch(SeekBar seekBar) { } public void onStartTrackingTouch(SeekBar seekBar) { } public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { // prevent seeking on app creation rotatingButton.setRotation((float)progress); } }); } }
Demonstrates how to use a seek bar
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <SeekBar android:id="@+id/seek" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="100" android:progress="50" android:secondaryProgress="75" /> <TextView android:id="@+id/progress" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/tracking" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
package com.example.android.apis.view; import android.app.Activity; import android.os.Bundle; import android.widget.SeekBar; import android.widget.TextView; /** * Demonstrates how to use a seek bar */ public class SeekBar1 extends Activity implements SeekBar.OnSeekBarChangeListener { SeekBar mSeekBar; TextView mProgressText; TextView mTrackingText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.seekbar_1); mSeekBar = (SeekBar)findViewById(R.id.seek); mSeekBar.setOnSeekBarChangeListener(this); mProgressText = (TextView)findViewById(R.id.progress); mTrackingText = (TextView)findViewById(R.id.tracking); } public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) { mProgressText.setText(progress + " " + getString(R.string.seekbar_from_touch) + "=" + fromTouch); } public void onStartTrackingTouch(SeekBar seekBar) { mTrackingText.setText(getString(R.string.seekbar_tracking_on)); } public void onStopTrackingTouch(SeekBar seekBar) { mTrackingText.setText(getString(R.string.seekbar_tracking_off)); } }
15-SurfaceView
Demonstration of overlays placed on top of a SurfaceView.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <FrameLayout android:layout_width="match_parent" android:layout_height="0px" android:layout_weight="1"> <android.opengl.GLSurfaceView android:id="@+id/glsurfaceview" android:layout_width="match_parent" android:layout_height="match_parent" /> <LinearLayout android:id="@+id/hidecontainer" android:orientation="vertical" android:visibility="gone" android:background="@drawable/translucent_background" android:gravity="center" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/hideme1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:visibility="gone" android:text="@string/hide_me"/> <Button android:id="@+id/hideme2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:visibility="gone" android:text="@string/hide_me"/> </LinearLayout> </FrameLayout> <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"> <Button android:id="@+id/vis" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/visibility_1_vis"/> <Button android:id="@+id/invis" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/visibility_1_invis"/> <Button android:id="@+id/gone" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/visibility_1_gone"/> </LinearLayout> </LinearLayout>
package app.test; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.IntBuffer; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.app.Activity; import android.opengl.GLSurfaceView; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; /** * Demonstration of overlays placed on top of a SurfaceView. */ public class Test extends Activity { View mVictimContainer; View mVictim1; View mVictim2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.surface_view_overlay); GLSurfaceView glSurfaceView = (GLSurfaceView) findViewById(R.id.glsurfaceview); glSurfaceView.setRenderer(new CubeRenderer(false)); // Find the views whose visibility will change mVictimContainer = findViewById(R.id.hidecontainer); mVictim1 = findViewById(R.id.hideme1); mVictim1.setOnClickListener(new HideMeListener(mVictim1)); mVictim2 = findViewById(R.id.hideme2); mVictim2.setOnClickListener(new HideMeListener(mVictim2)); // Find our buttons Button visibleButton = (Button) findViewById(R.id.vis); Button invisibleButton = (Button) findViewById(R.id.invis); Button goneButton = (Button) findViewById(R.id.gone); // Wire each button to a click listener visibleButton.setOnClickListener(mVisibleListener); invisibleButton.setOnClickListener(mInvisibleListener); goneButton.setOnClickListener(mGoneListener); } @Override protected void onResume() { // Ideally a game should implement onResume() and onPause() // to take appropriate action when the activity looses focus super.onResume(); } @Override protected void onPause() { // Ideally a game should implement onResume() and onPause() // to take appropriate action when the activity looses focus super.onPause(); } class HideMeListener implements OnClickListener { final View mTarget; HideMeListener(View target) { mTarget = target; } public void onClick(View v) { mTarget.setVisibility(View.INVISIBLE); } } OnClickListener mVisibleListener = new OnClickListener() { public void onClick(View v) { mVictim1.setVisibility(View.VISIBLE); mVictim2.setVisibility(View.VISIBLE); mVictimContainer.setVisibility(View.VISIBLE); } }; OnClickListener mInvisibleListener = new OnClickListener() { public void onClick(View v) { mVictim1.setVisibility(View.INVISIBLE); mVictim2.setVisibility(View.INVISIBLE); mVictimContainer.setVisibility(View.INVISIBLE); } }; OnClickListener mGoneListener = new OnClickListener() { public void onClick(View v) { mVictim1.setVisibility(View.GONE); mVictim2.setVisibility(View.GONE); mVictimContainer.setVisibility(View.GONE); } }; } /** * A vertex shaded cube. */ class Cube { public Cube() { int one = 0x10000; int vertices[] = { -one, -one, -one, one, -one, -one, one, one, -one, -one, one, -one, -one, -one, one, one, -one, one, one, one, one, -one, one, one, }; int colors[] = { 0, 0, 0, one, one, 0, 0, one, one, one, 0, one, 0, one, 0, one, 0, 0, one, one, one, 0, one, one, one, one, one, one, 0, one, one, one, }; byte indices[] = { 0, 4, 5, 0, 5, 1, 1, 5, 6, 1, 6, 2, 2, 6, 7, 2, 7, 3, 3, 7, 4, 3, 4, 0, 4, 7, 6, 4, 6, 5, 3, 0, 1, 3, 1, 2 }; // Buffers to be passed to gl*Pointer() functions // must be direct, i.e., they must be placed on the // native heap where the garbage collector cannot // move them. // // Buffers with multi-byte datatypes (e.g., short, int, float) // must have their byte order set to native order ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4); vbb.order(ByteOrder.nativeOrder()); mVertexBuffer = vbb.asIntBuffer(); mVertexBuffer.put(vertices); mVertexBuffer.position(0); ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4); cbb.order(ByteOrder.nativeOrder()); mColorBuffer = cbb.asIntBuffer(); mColorBuffer.put(colors); mColorBuffer.position(0); mIndexBuffer = ByteBuffer.allocateDirect(indices.length); mIndexBuffer.put(indices); mIndexBuffer.position(0); } public void draw(GL10 gl) { gl.glFrontFace(GL10.GL_CW); gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer); gl.glColorPointer(4, GL10.GL_FIXED, 0, mColorBuffer); gl.glDrawElements(GL10.GL_TRIANGLES, 36, GL10.GL_UNSIGNED_BYTE, mIndexBuffer); } private IntBuffer mVertexBuffer; private IntBuffer mColorBuffer; private ByteBuffer mIndexBuffer; } /** * Render a pair of tumbling cubes. */ class CubeRenderer implements GLSurfaceView.Renderer { public CubeRenderer(boolean useTranslucentBackground) { mTranslucentBackground = useTranslucentBackground; mCube = new Cube(); } public void onDrawFrame(GL10 gl) { /* * Usually, the first thing one might want to do is to clear the screen. * The most efficient way of doing this is to use glClear(). */ gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); /* * Now we're ready to draw some 3D objects */ gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); gl.glTranslatef(0, 0, -3.0f); gl.glRotatef(mAngle, 0, 1, 0); gl.glRotatef(mAngle * 0.25f, 1, 0, 0); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_COLOR_ARRAY); mCube.draw(gl); gl.glRotatef(mAngle * 2.0f, 0, 1, 1); gl.glTranslatef(0.5f, 0.5f, 0.5f); mCube.draw(gl); mAngle += 1.2f; } public void onSurfaceChanged(GL10 gl, int width, int height) { gl.glViewport(0, 0, width, height); /* * Set our projection matrix. This doesn't have to be done each time we * draw, but usually a new projection needs to be set when the viewport * is resized. */ float ratio = (float) width / height; gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10); } public void onSurfaceCreated(GL10 gl, EGLConfig config) { /* * By default, OpenGL enables features that improve quality but reduce * performance. One might want to tweak that especially on software * renderer. */ gl.glDisable(GL10.GL_DITHER); /* * Some one-time OpenGL initialization can be made here probably based * on features of this particular context */ gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST); if (mTranslucentBackground) { gl.glClearColor(0, 0, 0, 0); } else { gl.glClearColor(1, 1, 1, 1); } gl.glEnable(GL10.GL_CULL_FACE); gl.glShadeModel(GL10.GL_SMOOTH); gl.glEnable(GL10.GL_DEPTH_TEST); } private boolean mTranslucentBackground; private Cube mCube; private float mAngle; }
Tappable SurfaceView
import android.content.Context; import android.view.GestureDetector; import android.view.GestureDetector.SimpleOnGestureListener; import android.view.MotionEvent; import android.view.SurfaceView; import android.util.AttributeSet; import java.util.ArrayList; public class TappableSurfaceView extends SurfaceView { private ArrayList<TapListener> listeners = new ArrayList<TapListener>(); private GestureDetector gesture = null; public TappableSurfaceView(Context context, AttributeSet attrs) { super(context, attrs); } public TappableSurfaceView(Context context) { super(context); } public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { gestureListener.onSingleTapUp(event); } return (true); } public void addTapListener(TapListener l) { listeners.add(l); } public void removeTapListener(TapListener l) { listeners.remove(l); } private GestureDetector.SimpleOnGestureListener gestureListener = new GestureDetector.SimpleOnGestureListener() { @Override public boolean onSingleTapUp(MotionEvent e) { for (TapListener l : listeners) { l.onTap(e); } return (true); } }; public interface TapListener { void onTap(MotionEvent event); } }
Wrapper activity demonstrating the use of {@link GLSurfaceView} to display translucent 3D graphics.
package app.test; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.IntBuffer; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.app.Activity; import android.graphics.PixelFormat; import android.opengl.GLSurfaceView; import android.os.Bundle; /** * A vertex shaded cube. */ class Cube { public Cube() { int one = 0x10000; int vertices[] = { -one, -one, -one, one, -one, -one, one, one, -one, -one, one, -one, -one, -one, one, one, -one, one, one, one, one, -one, one, one, }; int colors[] = { 0, 0, 0, one, one, 0, 0, one, one, one, 0, one, 0, one, 0, one, 0, 0, one, one, one, 0, one, one, one, one, one, one, 0, one, one, one, }; byte indices[] = { 0, 4, 5, 0, 5, 1, 1, 5, 6, 1, 6, 2, 2, 6, 7, 2, 7, 3, 3, 7, 4, 3, 4, 0, 4, 7, 6, 4, 6, 5, 3, 0, 1, 3, 1, 2 }; // Buffers to be passed to gl*Pointer() functions // must be direct, i.e., they must be placed on the // native heap where the garbage collector cannot // move them. // // Buffers with multi-byte datatypes (e.g., short, int, float) // must have their byte order set to native order ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4); vbb.order(ByteOrder.nativeOrder()); mVertexBuffer = vbb.asIntBuffer(); mVertexBuffer.put(vertices); mVertexBuffer.position(0); ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4); cbb.order(ByteOrder.nativeOrder()); mColorBuffer = cbb.asIntBuffer(); mColorBuffer.put(colors); mColorBuffer.position(0); mIndexBuffer = ByteBuffer.allocateDirect(indices.length); mIndexBuffer.put(indices); mIndexBuffer.position(0); } public void draw(GL10 gl) { gl.glFrontFace(GL10.GL_CW); gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer); gl.glColorPointer(4, GL10.GL_FIXED, 0, mColorBuffer); gl.glDrawElements(GL10.GL_TRIANGLES, 36, GL10.GL_UNSIGNED_BYTE, mIndexBuffer); } private IntBuffer mVertexBuffer; private IntBuffer mColorBuffer; private ByteBuffer mIndexBuffer; } /** * Render a pair of tumbling cubes. */ class CubeRenderer implements GLSurfaceView.Renderer { public CubeRenderer(boolean useTranslucentBackground) { mTranslucentBackground = useTranslucentBackground; mCube = new Cube(); } public void onDrawFrame(GL10 gl) { /* * Usually, the first thing one might want to do is to clear the screen. * The most efficient way of doing this is to use glClear(). */ gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); /* * Now we're ready to draw some 3D objects */ gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); gl.glTranslatef(0, 0, -3.0f); gl.glRotatef(mAngle, 0, 1, 0); gl.glRotatef(mAngle * 0.25f, 1, 0, 0); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_COLOR_ARRAY); mCube.draw(gl); gl.glRotatef(mAngle * 2.0f, 0, 1, 1); gl.glTranslatef(0.5f, 0.5f, 0.5f); mCube.draw(gl); mAngle += 1.2f; } public void onSurfaceChanged(GL10 gl, int width, int height) { gl.glViewport(0, 0, width, height); /* * Set our projection matrix. This doesn't have to be done each time we * draw, but usually a new projection needs to be set when the viewport * is resized. */ float ratio = (float) width / height; gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10); } public void onSurfaceCreated(GL10 gl, EGLConfig config) { /* * By default, OpenGL enables features that improve quality but reduce * performance. One might want to tweak that especially on software * renderer. */ gl.glDisable(GL10.GL_DITHER); /* * Some one-time OpenGL initialization can be made here probably based * on features of this particular context */ gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST); if (mTranslucentBackground) { gl.glClearColor(0, 0, 0, 0); } else { gl.glClearColor(1, 1, 1, 1); } gl.glEnable(GL10.GL_CULL_FACE); gl.glShadeModel(GL10.GL_SMOOTH); gl.glEnable(GL10.GL_DEPTH_TEST); } private boolean mTranslucentBackground; private Cube mCube; private float mAngle; } /** * Wrapper activity demonstrating the use of {@link GLSurfaceView} to * display translucent 3D graphics. */ public class TranslucentGLSurfaceViewActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Create our Preview view and set it as the content of our // Activity mGLSurfaceView = new GLSurfaceView(this); // We want an 8888 pixel format because that's required for // a translucent window. // And we want a depth buffer. mGLSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0); // Tell the cube renderer that we want to render a translucent version // of the cube: mGLSurfaceView.setRenderer(new CubeRenderer(true)); // Use a surface format with an Alpha channel: mGLSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT); setContentView(mGLSurfaceView); } @Override protected void onResume() { super.onResume(); mGLSurfaceView.onResume(); } @Override protected void onPause() { super.onPause(); mGLSurfaceView.onPause(); } private GLSurfaceView mGLSurfaceView; }
16-TableRow
Set gravity for TableRow
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:stretchColumns="1"> <TableRow> <TextView android:text="@string/table_layout_10_user" android:textStyle="bold" android:gravity="right" android:padding="3dip" /> <EditText android:id="@+id/username" android:text="@string/table_layout_10_username_text" android:padding="3dip" android:scrollHorizontally="true" /> </TableRow> <TableRow> <TextView android:text="@string/table_layout_10_password" android:textStyle="bold" android:gravity="right" android:padding="3dip" /> <EditText android:id="@+id/password" android:text="@string/table_layout_10_password_text" android:password="true" android:padding="3dip" android:scrollHorizontally="true" /> </TableRow> <TableRow android:gravity="right"> <Button android:id="@+id/cancel" android:text="@string/table_layout_10_cancel" /> <Button android:id="@+id/login" android:text="@string/table_layout_10_login" /> </TableRow> </TableLayout>
package com.example.android.apis.view; import com.example.android.apis.R; import android.app.Activity; import android.os.Bundle; public class TableLayout10 extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.table_layout_10); } }
Using View to separate TableRow
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:stretchColumns="1"> <TableRow> <TextView android:layout_column="1" android:text="table_layout_6_open" android:padding="3dip" /> <TextView android:text="table_layout_6_open_shortcut" android:gravity="right" android:padding="3dip" /> </TableRow> <TableRow> <TextView android:layout_column="1" android:text="table_layout_6_save" android:padding="3dip" /> <TextView android:text="table_layout_6_save_shortcut" android:gravity="right" android:padding="3dip" /> </TableRow> <TableRow> <TextView android:layout_column="1" android:text="table_layout_6_save_as" android:padding="3dip" /> <TextView android:text="table_layout_6_save_as_shortcut" android:gravity="right" android:padding="3dip" /> </TableRow> <View android:layout_height="2dip" android:background="#FF909090" /> <TableRow> <TextView android:text="table_layout_6_x" android:padding="3dip" /> <TextView android:text="table_layout_6_import" android:padding="3dip" /> </TableRow> <TableRow> <TextView android:text="table_layout_6_x" android:padding="3dip" /> <TextView android:text="table_layout_6_export" android:padding="3dip" /> <TextView android:text="table_layout_6_export_shortcut" android:gravity="right" android:padding="3dip" /> </TableRow> <View android:layout_height="2dip" android:background="#FF909090" /> <TableRow> <TextView android:layout_column="1" android:text="table_layout_6_quit" android:padding="3dip" /> </TableRow> </TableLayout>
package com.example.android.apis.view; import com.example.android.apis.R; import android.app.Activity; import android.os.Bundle; public class TableLayout6 extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.table_layout_6); } }
17-VelocityTracker
package app.test; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.MotionEvent; import android.view.VelocityTracker; public class Test extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } private VelocityTracker vTracker = null; public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); switch(action) { case MotionEvent.ACTION_DOWN: if(vTracker == null) { vTracker = VelocityTracker.obtain(); } else { vTracker.clear(); } vTracker.addMovement(event); break; case MotionEvent.ACTION_MOVE: vTracker.addMovement(event); vTracker.computeCurrentVelocity(1000); Log.v("", "X velocity is " + vTracker.getXVelocity() +" pixels per second"); Log.v("", "Y velocity is " + vTracker.getYVelocity() +" pixels per second"); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: vTracker.recycle(); break; } return true; } }
18-ViewGroup
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:orientation="vertical" android:padding="10dip" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/secure_view_description" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="secure_view_description"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dip" android:textStyle="bold" android:text="secure_view_step1_heading"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="secure_view_step1_detail"/> <Button android:id="@+id/secure_view_toast_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="secure_view_pop_toast"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dip" android:textStyle="bold" android:text="secure_view_step2_heading"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="secure_view_step2_detail"/> <Button android:id="@+id/secure_view_unsecure_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:textColor="#833" android:text="secure_view_button"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dip" android:textStyle="bold" android:text="secure_view_step3_heading"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="secure_view_step3_detail"/> <Button android:id="@+id/secure_view_builtin_secure_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:filterTouchesWhenObscured="true" android:textColor="#833" android:text="secure_view_button"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dip" android:textStyle="bold" android:text="secure_view_step4_heading"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="secure_view_step4_detail"/> <Button android:id="@+id/secure_view_custom_secure_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:textColor="#833" android:text="secure_view_button"/> </LinearLayout> </ScrollView>
package com.example.android.apis.view; import android.app.Activity; import android.app.AlertDialog; import android.os.Bundle; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; import android.widget.Button; import android.widget.Toast; import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; /** * This view is part of the {@link SecureView} demonstration activity. * * This view is constructed in such a way as to obscure the buttons and descriptive * text of the activity in a poor attempt to fool the user into clicking on the buttons * despite the activity telling the user that they may be harmful. */ class SecureViewOverlay extends ViewGroup { private SecureView mActivity; public SecureViewOverlay(Context context, AttributeSet attrs) { super(context, attrs); } public void setActivityToSpoof(SecureView activity) { this.mActivity = activity; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { measureChildren(widthMeasureSpec, heightMeasureSpec); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { spoofLayout(findViewById(R.id.secure_view_overlay_description), mActivity.findViewById(R.id.secure_view_description)); spoofLayout(findViewById(R.id.secure_view_overlay_button1), mActivity.findViewById(R.id.secure_view_unsecure_button)); spoofLayout(findViewById(R.id.secure_view_overlay_button2), mActivity.findViewById(R.id.secure_view_builtin_secure_button)); spoofLayout(findViewById(R.id.secure_view_overlay_button3), mActivity.findViewById(R.id.secure_view_custom_secure_button)); } private void spoofLayout(View spoof, View original) { final int[] globalPos = new int[2]; getLocationOnScreen(globalPos); int x = globalPos[0]; int y = globalPos[1]; original.getLocationOnScreen(globalPos); x = globalPos[0] - x; y = globalPos[1] - y; spoof.layout(x, y, x + original.getWidth(), y + original.getHeight()); } } public class SecureView extends Activity { private int mClickCount; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.secure_view); Button toastButton = (Button) findViewById(R.id.secure_view_toast_button); toastButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { showOverlay(); } }); Button unsecureButton = (Button) findViewById(R.id.secure_view_unsecure_button); setClickedAction(unsecureButton); Button builtinSecureButton = (Button) findViewById(R.id.secure_view_builtin_secure_button); setClickedAction(builtinSecureButton); Button customSecureButton = (Button) findViewById(R.id.secure_view_custom_secure_button); setClickedAction(customSecureButton); setTouchFilter(customSecureButton); } private void showOverlay() { // Generate a toast view with a special layout that will position itself right // on top of this view's interesting widgets. Sneaky huh? SecureViewOverlay overlay = (SecureViewOverlay) getLayoutInflater().inflate(R.layout.secure_view_overlay, null); overlay.setActivityToSpoof(this); Toast toast = new Toast(getApplicationContext()); toast.setGravity(Gravity.FILL, 0, 0); toast.setView(overlay); toast.show(); } private void setClickedAction(Button button) { button.setOnClickListener(new OnClickListener() { public void onClick(View v) { String[] messages = getResources().getStringArray(R.array.secure_view_clicked); String message = messages[mClickCount++ % messages.length]; new AlertDialog.Builder(SecureView.this) .setTitle(R.string.secure_view_action_dialog_title) .setMessage(message) .setNeutralButton(getResources().getString( R.string.secure_view_action_dialog_dismiss), null) .show(); } }); } private void setTouchFilter(Button button) { button.setOnTouchListener(new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { if ((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0) { if (event.getAction() == MotionEvent.ACTION_UP) { new AlertDialog.Builder(SecureView.this) .setTitle(R.string.secure_view_caught_dialog_title) .setMessage(R.string.secure_view_caught_dialog_message) .setNeutralButton(getResources().getString( R.string.secure_view_caught_dialog_dismiss), null) .show(); } // Return true to prevent the button from processing the touch. return true; } return false; } }); } }
This demo shows how various action bar display option flags can be combined and their effects.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:id="@+id/toggle_home_as_up" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="toggle_home_as_up" /> <Button android:id="@+id/toggle_show_home" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="toggle_show_home" /> <Button android:id="@+id/toggle_use_logo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="toggle_use_logo" /> <Button android:id="@+id/toggle_show_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="toggle_show_title" /> <Button android:id="@+id/toggle_show_custom" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="toggle_show_custom" /> <Button android:id="@+id/toggle_navigation" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="toggle_navigation" /> <Button android:id="@+id/cycle_custom_gravity" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="cycle_custom_gravity" /> </LinearLayout>
package app.test; import android.app.ActionBar; import android.app.ActionBar.Tab; import android.app.Activity; import android.app.FragmentTransaction; import android.os.Bundle; import android.view.Gravity; import android.view.Menu; import android.view.View; import android.view.ViewGroup.LayoutParams; /** * This demo shows how various action bar display option flags can be combined and their effects. */ public class Test extends Activity implements View.OnClickListener, ActionBar.TabListener { private View mCustomView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); findViewById(R.id.toggle_home_as_up).setOnClickListener(this); findViewById(R.id.toggle_show_home).setOnClickListener(this); findViewById(R.id.toggle_use_logo).setOnClickListener(this); findViewById(R.id.toggle_show_title).setOnClickListener(this); findViewById(R.id.toggle_show_custom).setOnClickListener(this); findViewById(R.id.toggle_navigation).setOnClickListener(this); findViewById(R.id.cycle_custom_gravity).setOnClickListener(this); mCustomView = getLayoutInflater().inflate(R.layout.action_bar_display_options_custom, null); // Configure several action bar elements that will be toggled by display options. final ActionBar bar = getActionBar(); bar.setCustomView(mCustomView, new ActionBar.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); bar.addTab(bar.newTab().setText("Tab 1").setTabListener(this)); bar.addTab(bar.newTab().setText("Tab 2").setTabListener(this)); bar.addTab(bar.newTab().setText("Tab 3").setTabListener(this)); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.my_menu, menu); return true; } public void onClick(View v) { final ActionBar bar = getActionBar(); int flags = 0; switch (v.getId()) { case R.id.toggle_home_as_up: flags = ActionBar.DISPLAY_HOME_AS_UP; break; case R.id.toggle_show_home: flags = ActionBar.DISPLAY_SHOW_HOME; break; case R.id.toggle_use_logo: flags = ActionBar.DISPLAY_USE_LOGO; break; case R.id.toggle_show_title: flags = ActionBar.DISPLAY_SHOW_TITLE; break; case R.id.toggle_show_custom: flags = ActionBar.DISPLAY_SHOW_CUSTOM; break; case R.id.toggle_navigation: bar.setNavigationMode( bar.getNavigationMode() == ActionBar.NAVIGATION_MODE_STANDARD ? ActionBar.NAVIGATION_MODE_TABS : ActionBar.NAVIGATION_MODE_STANDARD); return; case R.id.cycle_custom_gravity: ActionBar.LayoutParams lp = (ActionBar.LayoutParams) mCustomView.getLayoutParams(); int newGravity = 0; switch (lp.gravity & Gravity.HORIZONTAL_GRAVITY_MASK) { case Gravity.LEFT: newGravity = Gravity.CENTER_HORIZONTAL; break; case Gravity.CENTER_HORIZONTAL: newGravity = Gravity.RIGHT; break; case Gravity.RIGHT: newGravity = Gravity.LEFT; break; } lp.gravity = lp.gravity & ~Gravity.HORIZONTAL_GRAVITY_MASK | newGravity; bar.setCustomView(mCustomView, lp); return; } int change = bar.getDisplayOptions() ^ flags; bar.setDisplayOptions(change, flags); } public void onTabSelected(Tab tab, FragmentTransaction ft) { } public void onTabUnselected(Tab tab, FragmentTransaction ft) { } public void onTabReselected(Tab tab, FragmentTransaction ft) { } }
View attached to window event
package app.test; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Picture; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import android.util.AttributeSet; import android.util.Config; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; public class Test extends GraphicsActivity { private static final String TAG = "Compass"; private SensorManager mSensorManager; private Sensor mSensor; private SampleView mView; private float[] mValues; private final SensorEventListener mListener = new SensorEventListener() { public void onSensorChanged(SensorEvent event) { if (Config.DEBUG) Log.d(TAG, "sensorChanged (" + event.values[0] + ", " + event.values[1] + ", " + event.values[2] + ")"); mValues = event.values; if (mView != null) { mView.invalidate(); } } public void onAccuracyChanged(Sensor sensor, int accuracy) { } }; @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE); mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); mView = new SampleView(this); setContentView(mView); } @Override protected void onResume() { if (Config.DEBUG) Log.d(TAG, "onResume"); super.onResume(); mSensorManager.registerListener(mListener, mSensor, SensorManager.SENSOR_DELAY_GAME); } @Override protected void onStop() { if (Config.DEBUG) Log.d(TAG, "onStop"); mSensorManager.unregisterListener(mListener); super.onStop(); } private class SampleView extends View { private Paint mPaint = new Paint(); private Path mPath = new Path(); private boolean mAnimate; public SampleView(Context context) { super(context); // Construct a wedge-shaped path mPath.moveTo(0, -50); mPath.lineTo(-20, 60); mPath.lineTo(0, 50); mPath.lineTo(20, 60); mPath.close(); } @Override protected void onDraw(Canvas canvas) { Paint paint = mPaint; canvas.drawColor(Color.WHITE); paint.setAntiAlias(true); paint.setColor(Color.BLACK); paint.setStyle(Paint.Style.FILL); int w = canvas.getWidth(); int h = canvas.getHeight(); int cx = w / 2; int cy = h / 2; canvas.translate(cx, cy); if (mValues != null) { canvas.rotate(-mValues[0]); } canvas.drawPath(mPath, mPaint); } @Override protected void onAttachedToWindow() { mAnimate = true; if (Config.DEBUG) Log.d(TAG, "onAttachedToWindow. mAnimate=" + mAnimate); super.onAttachedToWindow(); } @Override protected void onDetachedFromWindow() { mAnimate = false; if (Config.DEBUG) Log.d(TAG, "onDetachedFromWindow. mAnimate=" + mAnimate); super.onDetachedFromWindow(); } } } class GraphicsActivity extends Activity { // set to true to test Picture private static final boolean TEST_PICTURE = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void setContentView(View view) { if (TEST_PICTURE) { ViewGroup vg = new PictureLayout(this); vg.addView(view); view = vg; } super.setContentView(view); } } class PictureLayout extends ViewGroup { private final Picture mPicture = new Picture(); public PictureLayout(Context context) { super(context); } public PictureLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override public void addView(View child) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child); } @Override public void addView(View child, int index) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, index); } @Override public void addView(View child, LayoutParams params) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, params); } @Override public void addView(View child, int index, LayoutParams params) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, index, params); } @Override protected LayoutParams generateDefaultLayoutParams() { return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int count = getChildCount(); int maxHeight = 0; int maxWidth = 0; for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { measureChild(child, widthMeasureSpec, heightMeasureSpec); } } maxWidth += getPaddingLeft() + getPaddingRight(); maxHeight += getPaddingTop() + getPaddingBottom(); Drawable drawable = getBackground(); if (drawable != null) { maxHeight = Math.max(maxHeight, drawable.getMinimumHeight()); maxWidth = Math.max(maxWidth, drawable.getMinimumWidth()); } setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec), resolveSize(maxHeight, heightMeasureSpec)); } private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx, float sy) { canvas.save(); canvas.translate(x, y); canvas.clipRect(0, 0, w, h); canvas.scale(0.5f, 0.5f); canvas.scale(sx, sy, w, h); canvas.drawPicture(mPicture); canvas.restore(); } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight())); mPicture.endRecording(); int x = getWidth() / 2; int y = getHeight() / 2; if (false) { canvas.drawPicture(mPicture); } else { drawPict(canvas, 0, 0, x, y, 1, 1); drawPict(canvas, x, 0, x, y, -1, 1); drawPict(canvas, 0, y, x, y, 1, -1); drawPict(canvas, x, y, x, y, -1, -1); } } @Override public ViewParent invalidateChildInParent(int[] location, Rect dirty) { location[0] = getLeft(); location[1] = getTop(); dirty.set(0, 0, getWidth(), getHeight()); return getParent(); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = super.getChildCount(); for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final int childLeft = getPaddingLeft(); final int childTop = getPaddingTop(); child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight()); } } } }
Compass
package app.test; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Picture; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import android.util.AttributeSet; import android.util.Config; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; public class Test extends GraphicsActivity { private static final String TAG = "Compass"; private SensorManager mSensorManager; private Sensor mSensor; private SampleView mView; private float[] mValues; private final SensorEventListener mListener = new SensorEventListener() { public void onSensorChanged(SensorEvent event) { if (Config.DEBUG) Log.d(TAG, "sensorChanged (" + event.values[0] + ", " + event.values[1] + ", " + event.values[2] + ")"); mValues = event.values; if (mView != null) { mView.invalidate(); } } public void onAccuracyChanged(Sensor sensor, int accuracy) { } }; @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE); mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); mView = new SampleView(this); setContentView(mView); } @Override protected void onResume() { if (Config.DEBUG) Log.d(TAG, "onResume"); super.onResume(); mSensorManager.registerListener(mListener, mSensor, SensorManager.SENSOR_DELAY_GAME); } @Override protected void onStop() { if (Config.DEBUG) Log.d(TAG, "onStop"); mSensorManager.unregisterListener(mListener); super.onStop(); } private class SampleView extends View { private Paint mPaint = new Paint(); private Path mPath = new Path(); private boolean mAnimate; public SampleView(Context context) { super(context); // Construct a wedge-shaped path mPath.moveTo(0, -50); mPath.lineTo(-20, 60); mPath.lineTo(0, 50); mPath.lineTo(20, 60); mPath.close(); } @Override protected void onDraw(Canvas canvas) { Paint paint = mPaint; canvas.drawColor(Color.WHITE); paint.setAntiAlias(true); paint.setColor(Color.BLACK); paint.setStyle(Paint.Style.FILL); int w = canvas.getWidth(); int h = canvas.getHeight(); int cx = w / 2; int cy = h / 2; canvas.translate(cx, cy); if (mValues != null) { canvas.rotate(-mValues[0]); } canvas.drawPath(mPath, mPaint); } @Override protected void onAttachedToWindow() { mAnimate = true; if (Config.DEBUG) Log.d(TAG, "onAttachedToWindow. mAnimate=" + mAnimate); super.onAttachedToWindow(); } @Override protected void onDetachedFromWindow() { mAnimate = false; if (Config.DEBUG) Log.d(TAG, "onDetachedFromWindow. mAnimate=" + mAnimate); super.onDetachedFromWindow(); } } } class GraphicsActivity extends Activity { // set to true to test Picture private static final boolean TEST_PICTURE = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void setContentView(View view) { if (TEST_PICTURE) { ViewGroup vg = new PictureLayout(this); vg.addView(view); view = vg; } super.setContentView(view); } } class PictureLayout extends ViewGroup { private final Picture mPicture = new Picture(); public PictureLayout(Context context) { super(context); } public PictureLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override public void addView(View child) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child); } @Override public void addView(View child, int index) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, index); } @Override public void addView(View child, LayoutParams params) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, params); } @Override public void addView(View child, int index, LayoutParams params) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, index, params); } @Override protected LayoutParams generateDefaultLayoutParams() { return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int count = getChildCount(); int maxHeight = 0; int maxWidth = 0; for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { measureChild(child, widthMeasureSpec, heightMeasureSpec); } } maxWidth += getPaddingLeft() + getPaddingRight(); maxHeight += getPaddingTop() + getPaddingBottom(); Drawable drawable = getBackground(); if (drawable != null) { maxHeight = Math.max(maxHeight, drawable.getMinimumHeight()); maxWidth = Math.max(maxWidth, drawable.getMinimumWidth()); } setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec), resolveSize(maxHeight, heightMeasureSpec)); } private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx, float sy) { canvas.save(); canvas.translate(x, y); canvas.clipRect(0, 0, w, h); canvas.scale(0.5f, 0.5f); canvas.scale(sx, sy, w, h); canvas.drawPicture(mPicture); canvas.restore(); } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight())); mPicture.endRecording(); int x = getWidth() / 2; int y = getHeight() / 2; if (false) { canvas.drawPicture(mPicture); } else { drawPict(canvas, 0, 0, x, y, 1, 1); drawPict(canvas, x, 0, x, y, -1, 1); drawPict(canvas, 0, y, x, y, 1, -1); drawPict(canvas, x, y, x, y, -1, -1); } } @Override public ViewParent invalidateChildInParent(int[] location, Rect dirty) { location[0] = getLeft(); location[1] = getTop(); dirty.set(0, 0, getWidth(), getHeight()); return getParent(); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = super.getChildCount(); for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final int childLeft = getPaddingLeft(); final int childTop = getPaddingTop(); child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight()); } } } }
19-AdapterView
implements AdapterView.OnItemSelectedListener
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="10dip" android:layout_width="match_parent" android:layout_height="wrap_content" android:clipToPadding="false"> <TextView android:id="@+id/target" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="26sp" android:text="animation_3_text"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dip" android:layout_marginBottom="5dip" android:text="animation_2_instructions" /> <Spinner android:id="@+id/spinner" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
package app.test; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.animation.AnimationUtils; import android.view.animation.Animation; import android.view.animation.TranslateAnimation; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Spinner; public class Test extends Activity implements AdapterView.OnItemSelectedListener { private static final String[] INTERPOLATORS = { "Accelerate", "Decelerate", "Accelerate/Decelerate", "Anticipate", "Overshoot", "Anticipate/Overshoot", "Bounce" }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Spinner s = (Spinner) findViewById(R.id.spinner); ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, INTERPOLATORS); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); s.setAdapter(adapter); s.setOnItemSelectedListener(this); } public void onItemSelected(AdapterView<?> parent, View v, int position, long id) { final View target = findViewById(R.id.target); final View targetParent = (View) target.getParent(); Animation a = new TranslateAnimation(0.0f, targetParent.getWidth() - target.getWidth() - targetParent.getPaddingLeft() - targetParent.getPaddingRight(), 0.0f, 0.0f); a.setDuration(1000); a.setStartOffset(300); a.setRepeatMode(Animation.RESTART); a.setRepeatCount(Animation.INFINITE); switch (position) { case 0: a.setInterpolator(AnimationUtils.loadInterpolator(this, android.R.anim.accelerate_interpolator)); break; case 1: a.setInterpolator(AnimationUtils.loadInterpolator(this, android.R.anim.decelerate_interpolator)); break; case 2: a.setInterpolator(AnimationUtils.loadInterpolator(this, android.R.anim.accelerate_decelerate_interpolator)); break; case 3: a.setInterpolator(AnimationUtils.loadInterpolator(this, android.R.anim.anticipate_interpolator)); break; case 4: a.setInterpolator(AnimationUtils.loadInterpolator(this, android.R.anim.overshoot_interpolator)); break; case 5: a.setInterpolator(AnimationUtils.loadInterpolator(this, android.R.anim.anticipate_overshoot_interpolator)); break; case 6: a.setInterpolator(AnimationUtils.loadInterpolator(this, android.R.anim.bounce_interpolator)); break; } target.startAnimation(a); } public void onNothingSelected(AdapterView<?> parent) { } }
20-AppWidgetManager
Get Widget Id
import android.appwidget.AppWidgetManager; import android.content.Intent; import android.os.Bundle; class UtilHelper { public static int getWidgetId(Intent intent) { Bundle extras = intent.getExtras(); int appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID; if (extras != null) { appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); } return appWidgetId; } }