├── PagingScrollerExample ├── .classpath ├── .project ├── AndroidManifest.xml ├── default.properties ├── proguard.cfg ├── res │ ├── drawable-hdpi │ │ └── icon.png │ ├── drawable-ldpi │ │ └── icon.png │ ├── drawable-mdpi │ │ └── icon.png │ ├── layout │ │ ├── main.xml │ │ └── page.xml │ └── values │ │ └── strings.xml └── src │ └── com │ └── eightbitcloud │ └── pagingscroller │ ├── MainActivity.java │ ├── OnPageChangeListener.java │ ├── PageIndicator.java │ └── Pager.java ├── README └── WidgetExample ├── .classpath ├── .project ├── AndroidManifest.xml ├── default.properties ├── proguard.cfg ├── res ├── drawable-hdpi │ └── icon.png ├── drawable-ldpi │ └── icon.png ├── drawable-mdpi │ └── icon.png ├── drawable │ ├── background.xml │ └── preview.xml ├── layout │ ├── main.xml │ └── widget1.xml ├── values │ └── strings.xml └── xml │ └── widget1_info.xml └── src └── com └── eightbitcloud └── example └── widget ├── ExampleAppWidgetProvider.java └── WidgetExampleActivity.java /PagingScrollerExample/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PagingScrollerExample/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | PagingScrollerExample 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.wst.common.project.facet.core.builder 10 | 11 | 12 | 13 | 14 | com.android.ide.eclipse.adt.ResourceManagerBuilder 15 | 16 | 17 | 18 | 19 | com.android.ide.eclipse.adt.PreCompilerBuilder 20 | 21 | 22 | 23 | 24 | org.eclipse.jdt.core.javabuilder 25 | 26 | 27 | 28 | 29 | com.android.ide.eclipse.adt.ApkBuilder 30 | 31 | 32 | 33 | 34 | 35 | com.android.ide.eclipse.adt.AndroidNature 36 | org.eclipse.jdt.core.javanature 37 | org.eclipse.wst.common.project.facet.core.nature 38 | 39 | 40 | -------------------------------------------------------------------------------- /PagingScrollerExample/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /PagingScrollerExample/default.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system use, 7 | # "build.properties", and override values to adapt the script to your 8 | # project structure. 9 | 10 | # Project target. 11 | target=Google Inc.:Google APIs:4 12 | -------------------------------------------------------------------------------- /PagingScrollerExample/proguard.cfg: -------------------------------------------------------------------------------- 1 | -optimizationpasses 5 2 | -dontusemixedcaseclassnames 3 | -dontskipnonpubliclibraryclasses 4 | -dontpreverify 5 | -verbose 6 | -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* 7 | 8 | -keep public class * extends android.app.Activity 9 | -keep public class * extends android.app.Application 10 | -keep public class * extends android.app.Service 11 | -keep public class * extends android.content.BroadcastReceiver 12 | -keep public class * extends android.content.ContentProvider 13 | -keep public class com.android.vending.licensing.ILicensingService 14 | 15 | -keepclasseswithmembernames class * { 16 | native ; 17 | } 18 | 19 | -keepclasseswithmembernames class * { 20 | public (android.content.Context, android.util.AttributeSet); 21 | } 22 | 23 | -keepclasseswithmembernames class * { 24 | public (android.content.Context, android.util.AttributeSet, int); 25 | } 26 | 27 | -keepclassmembers enum * { 28 | public static **[] values(); 29 | public static ** valueOf(java.lang.String); 30 | } 31 | 32 | -keep class * implements android.os.Parcelable { 33 | public static final android.os.Parcelable$Creator *; 34 | } 35 | -------------------------------------------------------------------------------- /PagingScrollerExample/res/drawable-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucejcooper/Android-Examples/c0179600ffbbfd35ee351f527bae03234ec809a7/PagingScrollerExample/res/drawable-hdpi/icon.png -------------------------------------------------------------------------------- /PagingScrollerExample/res/drawable-ldpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucejcooper/Android-Examples/c0179600ffbbfd35ee351f527bae03234ec809a7/PagingScrollerExample/res/drawable-ldpi/icon.png -------------------------------------------------------------------------------- /PagingScrollerExample/res/drawable-mdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucejcooper/Android-Examples/c0179600ffbbfd35ee351f527bae03234ec809a7/PagingScrollerExample/res/drawable-mdpi/icon.png -------------------------------------------------------------------------------- /PagingScrollerExample/res/layout/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /PagingScrollerExample/res/layout/page.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /PagingScrollerExample/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | PagingScroller 4 | 5 | -------------------------------------------------------------------------------- /PagingScrollerExample/src/com/eightbitcloud/pagingscroller/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.eightbitcloud.pagingscroller; 2 | 3 | 4 | import android.app.Activity; 5 | import android.content.Context; 6 | import android.graphics.Color; 7 | import android.os.Bundle; 8 | import android.view.LayoutInflater; 9 | import android.view.View; 10 | import android.widget.TextView; 11 | 12 | public class MainActivity extends Activity { 13 | private Pager scroller; 14 | private PageIndicator indicator; 15 | 16 | private static final int NUM_PAGES = 5; 17 | private static int[] COLORS = new int[] { 18 | Color.RED, 19 | Color.GREEN, 20 | Color.BLUE, 21 | Color.CYAN, 22 | Color.MAGENTA, 23 | Color.YELLOW 24 | }; 25 | 26 | 27 | /** 28 | * Called when the activity is first created. Simply sets up an example Pager with 5 pages, 29 | * each of which shows the page number in a label 30 | */ 31 | @Override 32 | public void onCreate(Bundle savedInstanceState) { 33 | super.onCreate(savedInstanceState); 34 | setContentView(R.layout.main); 35 | 36 | scroller = ((Pager)findViewById(R.id.scrollView)); 37 | indicator = ((PageIndicator)findViewById(R.id.indicator)); 38 | indicator.setPager(scroller); 39 | 40 | LayoutInflater layoutInflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 41 | 42 | for (int i = 0; i < NUM_PAGES; i++) { 43 | View pageView = layoutInflater.inflate(R.layout.page, null); 44 | ((TextView) pageView.findViewById(R.id.pageText)).setText("Page " + (i+1)); 45 | pageView.setBackgroundColor(COLORS[i % COLORS.length]); 46 | 47 | scroller.addPage(pageView); 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /PagingScrollerExample/src/com/eightbitcloud/pagingscroller/OnPageChangeListener.java: -------------------------------------------------------------------------------- 1 | package com.eightbitcloud.pagingscroller; 2 | 3 | public interface OnPageChangeListener { 4 | 5 | /** 6 | * THis is a poorly named event listener. It gets called every time the page scroller updates its scroll position, 7 | * not just when a page changes. It does this because we want to be updated while in the middle of a scroll. 8 | */ 9 | public void onPageChange(Pager scroller); 10 | 11 | /** 12 | * Called whenever a page is added or removed from the pager, so that any page indicators can update themselves. 13 | * @param scroller 14 | */ 15 | public void onPageCountChange(Pager scroller); 16 | } 17 | -------------------------------------------------------------------------------- /PagingScrollerExample/src/com/eightbitcloud/pagingscroller/PageIndicator.java: -------------------------------------------------------------------------------- 1 | package com.eightbitcloud.pagingscroller; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Color; 6 | import android.graphics.Paint; 7 | import android.graphics.Rect; 8 | import android.graphics.RectF; 9 | import android.util.AttributeSet; 10 | import android.view.View; 11 | 12 | public class PageIndicator extends View { 13 | private Pager pager; 14 | private Paint textPaint; 15 | private Paint dotPaint; 16 | private int textHeight; 17 | private int ascent; 18 | private int cellSize; 19 | 20 | private OnPageChangeListener scrollListener = new OnPageChangeListener() { 21 | public void onPageChange(Pager scroller) { 22 | update(); 23 | } 24 | 25 | public void onPageCountChange(Pager scroller) { 26 | updatePageCount(); 27 | } 28 | }; 29 | 30 | public PageIndicator(Context context, AttributeSet attrs) { 31 | super(context, attrs); 32 | initPaints(); 33 | } 34 | 35 | 36 | public PageIndicator(Context context) { 37 | super(context); 38 | initPaints(); 39 | } 40 | 41 | 42 | 43 | private final void initPaints() { 44 | textPaint = new Paint(); 45 | textPaint.setAntiAlias(true); 46 | textPaint.setTextSize(10); 47 | textPaint.setColor(Color.BLACK); 48 | 49 | dotPaint = new Paint(); 50 | textPaint.setAntiAlias(true); 51 | dotPaint.setColor(Color.GRAY); 52 | 53 | ascent = -(int) textPaint.ascent(); 54 | textHeight = (int) (ascent + textPaint.descent()); 55 | cellSize = textHeight + 6; 56 | } 57 | 58 | 59 | public void setPager(Pager pager) { 60 | if (pager != null) { 61 | pager.removeOnPageChangeListener(scrollListener); 62 | } 63 | this.pager = pager; 64 | if (pager != null) { 65 | pager.addOnPageChangeListener(scrollListener ); 66 | } 67 | } 68 | 69 | 70 | public void update() { 71 | invalidate(); 72 | } 73 | public void updatePageCount() { 74 | requestLayout(); 75 | invalidate(); 76 | } 77 | 78 | private int getNumPages() { 79 | return pager == null ? 1 : pager.getPageCount(); 80 | } 81 | 82 | private int getActivePage() { 83 | return pager == null ? 0 : pager.getCurrentPage(); 84 | } 85 | 86 | 87 | /** 88 | * @see android.view.View#measure(int, int) 89 | */ 90 | @Override 91 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 92 | setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec)); 93 | } 94 | 95 | /** 96 | * Determines the width of this view 97 | * 98 | * @param measureSpec 99 | * A measureSpec packed into an int 100 | * @return The width of the view, honoring constraints from measureSpec 101 | */ 102 | private int measureWidth(int measureSpec) { 103 | int result = 0; 104 | int specMode = MeasureSpec.getMode(measureSpec); 105 | int specSize = MeasureSpec.getSize(measureSpec); 106 | 107 | if (specMode == MeasureSpec.EXACTLY) { 108 | // We were told how big to be 109 | result = specSize; 110 | } else { 111 | result = getNumPages() * cellSize; 112 | if (specMode == MeasureSpec.AT_MOST) { 113 | // Respect AT_MOST value if that was what is called for by 114 | // measureSpec 115 | result = Math.min(result, specSize); 116 | } 117 | } 118 | return result; 119 | } 120 | 121 | /** 122 | * Determines the height of this view 123 | * 124 | * @param measureSpec 125 | * A measureSpec packed into an int 126 | * @return The height of the view, honoring constraints from measureSpec 127 | */ 128 | private int measureHeight(int measureSpec) { 129 | int result = 0; 130 | int specMode = MeasureSpec.getMode(measureSpec); 131 | int specSize = MeasureSpec.getSize(measureSpec); 132 | 133 | 134 | if (specMode == MeasureSpec.EXACTLY) { 135 | // We were told how big to be 136 | result = specSize; 137 | } else { 138 | result = cellSize; 139 | if (specMode == MeasureSpec.AT_MOST) { 140 | // Respect AT_MOST value if that was what is called for by 141 | // measureSpec 142 | result = Math.min(result, specSize); 143 | } 144 | } 145 | return result; 146 | } 147 | 148 | /** 149 | * Render the pager 150 | * 151 | * @see android.view.View#onDraw(android.graphics.Canvas) 152 | */ 153 | @Override 154 | protected void onDraw(Canvas canvas) { 155 | super.onDraw(canvas); 156 | 157 | int count = getNumPages(); 158 | int current = getActivePage(); 159 | 160 | int x = 0; 161 | for (int i = 0; i < count; i++, x += cellSize) { 162 | if (i == current) { 163 | String txt = Integer.toString(i+1); 164 | Rect bounds = new Rect(); 165 | textPaint.getTextBounds(txt, 0, txt.length(), bounds); 166 | RectF oval = new RectF(x+1, 1, x+cellSize-2, cellSize-2); 167 | canvas.drawOval(oval, dotPaint); 168 | canvas.drawText(txt, x + (cellSize-bounds.width())/2, (cellSize - textHeight)/2 + ascent, textPaint); 169 | } else { 170 | int dotSize = 5; 171 | int dotOffset = (cellSize - dotSize)/2; 172 | RectF oval = new RectF(x+dotOffset, dotOffset, x+dotOffset+dotSize, dotOffset+dotSize); 173 | canvas.drawOval(oval, dotPaint); 174 | } 175 | } 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /PagingScrollerExample/src/com/eightbitcloud/pagingscroller/Pager.java: -------------------------------------------------------------------------------- 1 | package com.eightbitcloud.pagingscroller; 2 | 3 | import java.util.LinkedList; 4 | 5 | import android.content.Context; 6 | import android.util.AttributeSet; 7 | import android.view.MotionEvent; 8 | import android.view.View; 9 | import android.widget.HorizontalScrollView; 10 | import android.widget.LinearLayout; 11 | 12 | public class Pager extends HorizontalScrollView { 13 | private LinearLayout contents; 14 | private LinkedList listeners; 15 | 16 | public Pager(Context ctx, AttributeSet attrs) { 17 | super(ctx, attrs); 18 | contents = new LinearLayout(ctx); 19 | contents.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT)); 20 | 21 | addView(contents); 22 | setVerticalScrollBarEnabled(false); 23 | setHorizontalScrollBarEnabled(false); 24 | } 25 | 26 | @Override 27 | public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 28 | // int specMode = MeasureSpec.getMode(widthMeasureSpec); 29 | int specSize = MeasureSpec.getSize(widthMeasureSpec); 30 | 31 | for (int i = 0; i < contents.getChildCount(); i++) { 32 | View child = contents.getChildAt(i); 33 | if (child.getLayoutParams().width != specSize) { 34 | child.setLayoutParams(new LinearLayout.LayoutParams(specSize, LayoutParams.FILL_PARENT)); 35 | } 36 | 37 | } 38 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 39 | } 40 | 41 | @Override 42 | protected float getLeftFadingEdgeStrength() { 43 | return 0.0f; 44 | } 45 | 46 | @Override 47 | protected float getRightFadingEdgeStrength() { 48 | return 0.0f; 49 | } 50 | 51 | public void addPage(View child) { 52 | int width = getWidth(); 53 | child.setLayoutParams(new LayoutParams(width, LayoutParams.FILL_PARENT)); 54 | contents.addView(child); 55 | contents.requestLayout(); 56 | 57 | firePageCountChanged(); 58 | } 59 | 60 | @Override 61 | public boolean onTouchEvent(MotionEvent evt) { 62 | boolean result = super.onTouchEvent(evt); 63 | 64 | int width = getWidth(); 65 | 66 | if (evt.getAction() == MotionEvent.ACTION_UP) { 67 | int pg = (getScrollX() + width / 2) / width; 68 | smoothScrollTo(pg * width, 0); 69 | } 70 | 71 | 72 | return result; 73 | } 74 | 75 | @Override 76 | public void onScrollChanged(int l, int t, int oldl, int oldt) { 77 | if (listeners != null) { 78 | for (OnPageChangeListener list: listeners) { 79 | list.onPageChange(this); 80 | } 81 | } 82 | } 83 | 84 | public boolean hasPage(View v) { 85 | return contents.indexOfChild(v) != -1; 86 | } 87 | 88 | public void removePage(View v) { 89 | contents.removeView(v); 90 | firePageCountChanged(); 91 | 92 | } 93 | 94 | public int getCurrentPage() { 95 | int width = getWidth(); 96 | return (getScrollX() + width/2) / width; 97 | } 98 | 99 | public int getPageCount() { 100 | return contents.getChildCount(); 101 | } 102 | 103 | public void removeAllPages() { 104 | contents.removeAllViews(); 105 | firePageCountChanged(); 106 | 107 | } 108 | 109 | private void firePageCountChanged() { 110 | if (listeners != null) { 111 | for (OnPageChangeListener list: listeners) { 112 | list.onPageCountChange(this); 113 | } 114 | } 115 | } 116 | 117 | 118 | 119 | public void addOnPageChangeListener(OnPageChangeListener onPageChangeListener) { 120 | if (listeners == null) { 121 | listeners = new LinkedList(); 122 | } 123 | listeners.add(onPageChangeListener); 124 | } 125 | 126 | public boolean removeOnPageChangeListener(OnPageChangeListener l) { 127 | if (listeners != null) { 128 | return listeners.remove(l); 129 | } else 130 | return false; 131 | } 132 | 133 | } 134 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucejcooper/Android-Examples/c0179600ffbbfd35ee351f527bae03234ec809a7/README -------------------------------------------------------------------------------- /WidgetExample/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WidgetExample/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | WidgetExample 4 | 5 | 6 | 7 | 8 | 9 | com.android.ide.eclipse.adt.ResourceManagerBuilder 10 | 11 | 12 | 13 | 14 | com.android.ide.eclipse.adt.PreCompilerBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | com.android.ide.eclipse.adt.ApkBuilder 25 | 26 | 27 | 28 | 29 | 30 | com.android.ide.eclipse.adt.AndroidNature 31 | org.eclipse.jdt.core.javanature 32 | 33 | 34 | -------------------------------------------------------------------------------- /WidgetExample/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /WidgetExample/default.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system use, 7 | # "build.properties", and override values to adapt the script to your 8 | # project structure. 9 | 10 | # Project target. 11 | target=Google Inc.:Google APIs:8 12 | -------------------------------------------------------------------------------- /WidgetExample/proguard.cfg: -------------------------------------------------------------------------------- 1 | -optimizationpasses 5 2 | -dontusemixedcaseclassnames 3 | -dontskipnonpubliclibraryclasses 4 | -dontpreverify 5 | -verbose 6 | -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* 7 | 8 | -keep public class * extends android.app.Activity 9 | -keep public class * extends android.app.Application 10 | -keep public class * extends android.app.Service 11 | -keep public class * extends android.content.BroadcastReceiver 12 | -keep public class * extends android.content.ContentProvider 13 | -keep public class * extends android.app.backup.BackupAgentHelper 14 | -keep public class * extends android.preference.Preference 15 | -keep public class com.android.vending.licensing.ILicensingService 16 | 17 | -keepclasseswithmembernames class * { 18 | native ; 19 | } 20 | 21 | -keepclasseswithmembernames class * { 22 | public (android.content.Context, android.util.AttributeSet); 23 | } 24 | 25 | -keepclasseswithmembernames class * { 26 | public (android.content.Context, android.util.AttributeSet, int); 27 | } 28 | 29 | -keepclassmembers enum * { 30 | public static **[] values(); 31 | public static ** valueOf(java.lang.String); 32 | } 33 | 34 | -keep class * implements android.os.Parcelable { 35 | public static final android.os.Parcelable$Creator *; 36 | } 37 | -------------------------------------------------------------------------------- /WidgetExample/res/drawable-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucejcooper/Android-Examples/c0179600ffbbfd35ee351f527bae03234ec809a7/WidgetExample/res/drawable-hdpi/icon.png -------------------------------------------------------------------------------- /WidgetExample/res/drawable-ldpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucejcooper/Android-Examples/c0179600ffbbfd35ee351f527bae03234ec809a7/WidgetExample/res/drawable-ldpi/icon.png -------------------------------------------------------------------------------- /WidgetExample/res/drawable-mdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucejcooper/Android-Examples/c0179600ffbbfd35ee351f527bae03234ec809a7/WidgetExample/res/drawable-mdpi/icon.png -------------------------------------------------------------------------------- /WidgetExample/res/drawable/background.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WidgetExample/res/drawable/preview.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /WidgetExample/res/layout/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /WidgetExample/res/layout/widget1.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 |