diff --git a/wheel-demo/.classpath b/wheel-demo/.classpath deleted file mode 100644 index 00b0209..0000000 --- a/wheel-demo/.classpath +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/wheel-demo/.gitignore b/wheel-demo/.gitignore new file mode 100644 index 0000000..17c1fe6 --- /dev/null +++ b/wheel-demo/.gitignore @@ -0,0 +1,105 @@ +# Created by https://www.gitignore.io/api/android,intellij,gradle + +.DS_Store + +### Android ### +# Built application files +*.apk +*.ap_ + +# Files for the Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +gen/ + +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +### Android Patch ### +gen-external-apklibs + + +### Intellij ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm + +*.iml + +## Directory-based project format: +.idea/ +# if you remove the above rule, at least ignore the following: + +# User-specific stuff: +.idea/workspace.xml +# .idea/tasks.xml +# .idea/dictionaries +# .idea/shelf + +# Sensitive or high-churn files: +# .idea/dataSources.ids +# .idea/dataSources.xml +# .idea/sqlDataSources.xml +# .idea/dynamic.xml +# .idea/uiDesigner.xml + +# Gradle: +# .idea/gradle.xml +.idea/libraries + +# Mongo Explorer plugin: +# .idea/mongoSettings.xml + +## File-based project format: +*.ipr +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + + +### Gradle ### +.gradle +build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache diff --git a/wheel-demo/.project b/wheel-demo/.project deleted file mode 100644 index 6906965..0000000 --- a/wheel-demo/.project +++ /dev/null @@ -1,40 +0,0 @@ - - - wheel-demo - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - - - - wheel_src - 2 - _android_wheel_6bdbb5b/src - - - diff --git a/wheel-demo/app/.gitignore b/wheel-demo/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/wheel-demo/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/wheel-demo/app/build.gradle b/wheel-demo/app/build.gradle new file mode 100644 index 0000000..a8c2b53 --- /dev/null +++ b/wheel-demo/app/build.gradle @@ -0,0 +1,26 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 23 + buildToolsVersion "23.0.1" + + defaultConfig { + applicationId "kankan.wheel.demo.extended" + minSdkVersion 5 + targetSdkVersion 23 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile project(':wheel-release') + compile fileTree(dir: 'libs', include: ['*.jar']) + testCompile 'junit:junit:4.12' +} diff --git a/wheel-demo/app/proguard-rules.pro b/wheel-demo/app/proguard-rules.pro new file mode 100644 index 0000000..0b3ef79 --- /dev/null +++ b/wheel-demo/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/penaa/.android/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/wheel-demo/app/src/androidTest/java/kankan/wheel/demo/extended/ApplicationTest.java b/wheel-demo/app/src/androidTest/java/kankan/wheel/demo/extended/ApplicationTest.java new file mode 100644 index 0000000..6920669 --- /dev/null +++ b/wheel-demo/app/src/androidTest/java/kankan/wheel/demo/extended/ApplicationTest.java @@ -0,0 +1,13 @@ +package kankan.wheel.demo.extended; + +import android.app.Application; +import android.test.ApplicationTestCase; + +/** + * Testing Fundamentals + */ +public class ApplicationTest extends ApplicationTestCase { + public ApplicationTest() { + super(Application.class); + } +} \ No newline at end of file diff --git a/wheel-demo/AndroidManifest.xml b/wheel-demo/app/src/main/AndroidManifest.xml similarity index 77% rename from wheel-demo/AndroidManifest.xml rename to wheel-demo/app/src/main/AndroidManifest.xml index 3eda0ea..6f1b7ce 100644 --- a/wheel-demo/AndroidManifest.xml +++ b/wheel-demo/app/src/main/AndroidManifest.xml @@ -1,25 +1,24 @@ - - - - - + package="kankan.wheel.demo.extended"> + + - - + + - - - + + + - + @@ -32,24 +31,24 @@ - - + + - + - - + + - + @@ -62,8 +61,6 @@ - - - \ No newline at end of file + diff --git a/wheel-demo/src/kankan/wheel/demo/extended/CitiesActivity.java b/wheel-demo/app/src/main/java/kankan/wheel/demo/extended/CitiesActivity.java similarity index 95% rename from wheel-demo/src/kankan/wheel/demo/extended/CitiesActivity.java rename to wheel-demo/app/src/main/java/kankan/wheel/demo/extended/CitiesActivity.java index 250f721..2389639 100644 --- a/wheel-demo/src/kankan/wheel/demo/extended/CitiesActivity.java +++ b/wheel-demo/app/src/main/java/kankan/wheel/demo/extended/CitiesActivity.java @@ -1,114 +1,113 @@ -package kankan.wheel.demo.extended; - -import kankan.wheel.demo.extended.R; -import kankan.wheel.widget.OnWheelChangedListener; -import kankan.wheel.widget.OnWheelScrollListener; -import kankan.wheel.widget.WheelView; -import kankan.wheel.widget.adapters.AbstractWheelTextAdapter; -import kankan.wheel.widget.adapters.ArrayWheelAdapter; - -import android.app.Activity; -import android.content.Context; -import android.os.Bundle; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; - -public class CitiesActivity extends Activity { - // Scrolling flag - private boolean scrolling = false; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.cities_layout); - - final WheelView country = (WheelView) findViewById(R.id.country); - country.setVisibleItems(3); - country.setViewAdapter(new CountryAdapter(this)); - - final String cities[][] = new String[][] { - new String[] {"New York", "Washington", "Chicago", "Atlanta", "Orlando"}, - new String[] {"Ottawa", "Vancouver", "Toronto", "Windsor", "Montreal"}, - new String[] {"Kiev", "Dnipro", "Lviv", "Kharkiv"}, - new String[] {"Paris", "Bordeaux"}, - }; - - final WheelView city = (WheelView) findViewById(R.id.city); - city.setVisibleItems(5); - - country.addChangingListener(new OnWheelChangedListener() { - @Override - public void onChanged(WheelView wheel, int oldValue, int newValue) { - if (!scrolling) { - updateCities(city, cities, newValue); - } - } - }); - - country.addScrollingListener( new OnWheelScrollListener() { - @Override - public void onScrollingStarted(WheelView wheel) { - scrolling = true; - } - @Override - public void onScrollingFinished(WheelView wheel) { - scrolling = false; - updateCities(city, cities, country.getCurrentItem()); - } - }); - - country.setCurrentItem(1); - } - - /** - * Updates the city wheel - */ - private void updateCities(WheelView city, String cities[][], int index) { - ArrayWheelAdapter adapter = - new ArrayWheelAdapter(this, cities[index]); - adapter.setTextSize(18); - city.setViewAdapter(adapter); - city.setCurrentItem(cities[index].length / 2); - } - - /** - * Adapter for countries - */ - private class CountryAdapter extends AbstractWheelTextAdapter { - // Countries names - private String countries[] = - new String[] {"USA", "Canada", "Ukraine", "France"}; - // Countries flags - private int flags[] = - new int[] {R.drawable.usa, R.drawable.canada, R.drawable.ukraine, R.drawable.france}; - - /** - * Constructor - */ - protected CountryAdapter(Context context) { - super(context, R.layout.country_layout, NO_RESOURCE); - - setItemTextResource(R.id.country_name); - } - - @Override - public View getItem(int index, View cachedView, ViewGroup parent) { - View view = super.getItem(index, cachedView, parent); - ImageView img = (ImageView) view.findViewById(R.id.flag); - img.setImageResource(flags[index]); - return view; - } - - @Override - public int getItemsCount() { - return countries.length; - } - - @Override - protected CharSequence getItemText(int index) { - return countries[index]; - } - } -} +package kankan.wheel.demo.extended; + +import android.app.Activity; +import android.content.Context; +import android.os.Bundle; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; + +import kankan.wheel.widget.OnWheelChangedListener; +import kankan.wheel.widget.OnWheelScrollListener; +import kankan.wheel.widget.WheelView; +import kankan.wheel.widget.adapters.AbstractWheelTextAdapter; +import kankan.wheel.widget.adapters.ArrayWheelAdapter; + +public class CitiesActivity extends Activity { + // Scrolling flag + private boolean scrolling = false; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.cities_layout); + + final WheelView country = (WheelView) findViewById(R.id.country); + country.setVisibleItems(3); + country.setViewAdapter(new CountryAdapter(this)); + + final String cities[][] = new String[][] { + new String[] {"New York", "Washington", "Chicago", "Atlanta", "Orlando"}, + new String[] {"Ottawa", "Vancouver", "Toronto", "Windsor", "Montreal"}, + new String[] {"Kiev", "Dnipro", "Lviv", "Kharkiv"}, + new String[] {"Paris", "Bordeaux"}, + }; + + final WheelView city = (WheelView) findViewById(R.id.city); + city.setVisibleItems(5); + + country.addChangingListener(new OnWheelChangedListener() { + @Override + public void onChanged(WheelView wheel, int oldValue, int newValue) { + if (!scrolling) { + updateCities(city, cities, newValue); + } + } + }); + + country.addScrollingListener( new OnWheelScrollListener() { + @Override + public void onScrollingStarted(WheelView wheel) { + scrolling = true; + } + @Override + public void onScrollingFinished(WheelView wheel) { + scrolling = false; + updateCities(city, cities, country.getCurrentItem()); + } + }); + + country.setCurrentItem(1); + } + + /** + * Updates the city wheel + */ + private void updateCities(WheelView city, String cities[][], int index) { + ArrayWheelAdapter adapter = + new ArrayWheelAdapter(this, cities[index]); + adapter.setTextSize(18); + city.setViewAdapter(adapter); + city.setCurrentItem(cities[index].length / 2); + } + + /** + * Adapter for countries + */ + private class CountryAdapter extends AbstractWheelTextAdapter { + // Countries names + private String countries[] = + new String[] {"USA", "Canada", "Ukraine", "France"}; + // Countries flags + private int flags[] = + new int[] {R.drawable.usa, R.drawable.canada, R.drawable.ukraine, R.drawable.france}; + + /** + * Constructor + */ + protected CountryAdapter(Context context) { + super(context, R.layout.country_layout, NO_RESOURCE); + + setItemTextResource(R.id.country_name); + } + + @Override + public View getItem(int index, View cachedView, ViewGroup parent) { + View view = super.getItem(index, cachedView, parent); + ImageView img = (ImageView) view.findViewById(R.id.flag); + img.setImageResource(flags[index]); + return view; + } + + @Override + public int getItemsCount() { + return countries.length; + } + + @Override + protected CharSequence getItemText(int index) { + return countries[index]; + } + } +} diff --git a/wheel-demo/src/kankan/wheel/demo/extended/DateActivity.java b/wheel-demo/app/src/main/java/kankan/wheel/demo/extended/DateActivity.java similarity index 100% rename from wheel-demo/src/kankan/wheel/demo/extended/DateActivity.java rename to wheel-demo/app/src/main/java/kankan/wheel/demo/extended/DateActivity.java diff --git a/wheel-demo/src/kankan/wheel/demo/extended/HoloWheelActivity.java b/wheel-demo/app/src/main/java/kankan/wheel/demo/extended/HoloWheelActivity.java similarity index 100% rename from wheel-demo/src/kankan/wheel/demo/extended/HoloWheelActivity.java rename to wheel-demo/app/src/main/java/kankan/wheel/demo/extended/HoloWheelActivity.java diff --git a/wheel-demo/src/kankan/wheel/demo/extended/PasswActivity.java b/wheel-demo/app/src/main/java/kankan/wheel/demo/extended/PasswActivity.java similarity index 96% rename from wheel-demo/src/kankan/wheel/demo/extended/PasswActivity.java rename to wheel-demo/app/src/main/java/kankan/wheel/demo/extended/PasswActivity.java index 75e4dc2..6ddd0c8 100644 --- a/wheel-demo/src/kankan/wheel/demo/extended/PasswActivity.java +++ b/wheel-demo/app/src/main/java/kankan/wheel/demo/extended/PasswActivity.java @@ -1,134 +1,134 @@ -package kankan.wheel.demo.extended; - -import kankan.wheel.demo.extended.R; -import kankan.wheel.widget.OnWheelChangedListener; -import kankan.wheel.widget.OnWheelScrollListener; -import kankan.wheel.widget.WheelView; -import kankan.wheel.widget.adapters.NumericWheelAdapter; -import android.app.Activity; -import android.os.Bundle; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.animation.AnticipateOvershootInterpolator; -import android.widget.Button; -import android.widget.TextView; - -public class PasswActivity extends Activity { - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.passw_layout); - initWheel(R.id.passw_1); - initWheel(R.id.passw_2); - initWheel(R.id.passw_3); - initWheel(R.id.passw_4); - - Button mix = (Button)findViewById(R.id.btn_mix); - mix.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - mixWheel(R.id.passw_1); - mixWheel(R.id.passw_2); - mixWheel(R.id.passw_3); - mixWheel(R.id.passw_4); - } - }); - - updateStatus(); - } - - // Wheel scrolled flag - private boolean wheelScrolled = false; - - // Wheel scrolled listener - OnWheelScrollListener scrolledListener = new OnWheelScrollListener() { - @Override - public void onScrollingStarted(WheelView wheel) { - wheelScrolled = true; - } - @Override - public void onScrollingFinished(WheelView wheel) { - wheelScrolled = false; - updateStatus(); - } - }; - - // Wheel changed listener - private OnWheelChangedListener changedListener = new OnWheelChangedListener() { - @Override - public void onChanged(WheelView wheel, int oldValue, int newValue) { - if (!wheelScrolled) { - updateStatus(); - } - } - }; - - /** - * Updates entered PIN status - */ - private void updateStatus() { - TextView text = (TextView) findViewById(R.id.pwd_status); - if (testPin(2, 4, 6, 1)) { - text.setText("Congratulation!"); - } else { - text.setText("Invalid PIN"); - } - } - - /** - * Initializes wheel - * @param id the wheel widget Id - */ - private void initWheel(int id) { - WheelView wheel = getWheel(id); - wheel.setViewAdapter(new NumericWheelAdapter(this, 0, 9)); - wheel.setCurrentItem((int)(Math.random() * 10)); - - wheel.addChangingListener(changedListener); - wheel.addScrollingListener(scrolledListener); - wheel.setCyclic(true); - wheel.setInterpolator(new AnticipateOvershootInterpolator()); - } - - /** - * Returns wheel by Id - * @param id the wheel Id - * @return the wheel with passed Id - */ - private WheelView getWheel(int id) { - return (WheelView) findViewById(id); - } - - /** - * Tests entered PIN - * @param v1 - * @param v2 - * @param v3 - * @param v4 - * @return true - */ - private boolean testPin(int v1, int v2, int v3, int v4) { - return testWheelValue(R.id.passw_1, v1) && testWheelValue(R.id.passw_2, v2) && - testWheelValue(R.id.passw_3, v3) && testWheelValue(R.id.passw_4, v4); - } - - /** - * Tests wheel value - * @param id the wheel Id - * @param value the value to test - * @return true if wheel value is equal to passed value - */ - private boolean testWheelValue(int id, int value) { - return getWheel(id).getCurrentItem() == value; - } - - /** - * Mixes wheel - * @param id the wheel id - */ - private void mixWheel(int id) { - WheelView wheel = getWheel(id); - wheel.scroll(-25 + (int)(Math.random() * 50), 2000); - } -} +package kankan.wheel.demo.extended; + +import kankan.wheel.demo.extended.R; +import kankan.wheel.widget.OnWheelChangedListener; +import kankan.wheel.widget.OnWheelScrollListener; +import kankan.wheel.widget.WheelView; +import kankan.wheel.widget.adapters.NumericWheelAdapter; +import android.app.Activity; +import android.os.Bundle; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.animation.AnticipateOvershootInterpolator; +import android.widget.Button; +import android.widget.TextView; + +public class PasswActivity extends Activity { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.passw_layout); + initWheel(R.id.passw_1); + initWheel(R.id.passw_2); + initWheel(R.id.passw_3); + initWheel(R.id.passw_4); + + Button mix = (Button)findViewById(R.id.btn_mix); + mix.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + mixWheel(R.id.passw_1); + mixWheel(R.id.passw_2); + mixWheel(R.id.passw_3); + mixWheel(R.id.passw_4); + } + }); + + updateStatus(); + } + + // Wheel scrolled flag + private boolean wheelScrolled = false; + + // Wheel scrolled listener + OnWheelScrollListener scrolledListener = new OnWheelScrollListener() { + @Override + public void onScrollingStarted(WheelView wheel) { + wheelScrolled = true; + } + @Override + public void onScrollingFinished(WheelView wheel) { + wheelScrolled = false; + updateStatus(); + } + }; + + // Wheel changed listener + private OnWheelChangedListener changedListener = new OnWheelChangedListener() { + @Override + public void onChanged(WheelView wheel, int oldValue, int newValue) { + if (!wheelScrolled) { + updateStatus(); + } + } + }; + + /** + * Updates entered PIN status + */ + private void updateStatus() { + TextView text = (TextView) findViewById(R.id.pwd_status); + if (testPin(2, 4, 6, 1)) { + text.setText("Congratulation!"); + } else { + text.setText("Invalid PIN"); + } + } + + /** + * Initializes wheel + * @param id the wheel widget Id + */ + private void initWheel(int id) { + WheelView wheel = getWheel(id); + wheel.setViewAdapter(new NumericWheelAdapter(this, 0, 9)); + wheel.setCurrentItem((int)(Math.random() * 10)); + + wheel.addChangingListener(changedListener); + wheel.addScrollingListener(scrolledListener); + wheel.setCyclic(true); + wheel.setInterpolator(new AnticipateOvershootInterpolator()); + } + + /** + * Returns wheel by Id + * @param id the wheel Id + * @return the wheel with passed Id + */ + private WheelView getWheel(int id) { + return (WheelView) findViewById(id); + } + + /** + * Tests entered PIN + * @param v1 + * @param v2 + * @param v3 + * @param v4 + * @return true + */ + private boolean testPin(int v1, int v2, int v3, int v4) { + return testWheelValue(R.id.passw_1, v1) && testWheelValue(R.id.passw_2, v2) && + testWheelValue(R.id.passw_3, v3) && testWheelValue(R.id.passw_4, v4); + } + + /** + * Tests wheel value + * @param id the wheel Id + * @param value the value to test + * @return true if wheel value is equal to passed value + */ + private boolean testWheelValue(int id, int value) { + return getWheel(id).getCurrentItem() == value; + } + + /** + * Mixes wheel + * @param id the wheel id + */ + private void mixWheel(int id) { + WheelView wheel = getWheel(id); + wheel.scroll(-25 + (int)(Math.random() * 50), 2000); + } +} diff --git a/wheel-demo/src/kankan/wheel/demo/extended/SlotMachineActivity.java b/wheel-demo/app/src/main/java/kankan/wheel/demo/extended/SlotMachineActivity.java similarity index 100% rename from wheel-demo/src/kankan/wheel/demo/extended/SlotMachineActivity.java rename to wheel-demo/app/src/main/java/kankan/wheel/demo/extended/SlotMachineActivity.java diff --git a/wheel-demo/src/kankan/wheel/demo/extended/SpeedActivity.java b/wheel-demo/app/src/main/java/kankan/wheel/demo/extended/SpeedActivity.java similarity index 100% rename from wheel-demo/src/kankan/wheel/demo/extended/SpeedActivity.java rename to wheel-demo/app/src/main/java/kankan/wheel/demo/extended/SpeedActivity.java diff --git a/wheel-demo/src/kankan/wheel/demo/extended/Time2Activity.java b/wheel-demo/app/src/main/java/kankan/wheel/demo/extended/Time2Activity.java similarity index 100% rename from wheel-demo/src/kankan/wheel/demo/extended/Time2Activity.java rename to wheel-demo/app/src/main/java/kankan/wheel/demo/extended/Time2Activity.java diff --git a/wheel-demo/src/kankan/wheel/demo/extended/TimeActivity.java b/wheel-demo/app/src/main/java/kankan/wheel/demo/extended/TimeActivity.java similarity index 96% rename from wheel-demo/src/kankan/wheel/demo/extended/TimeActivity.java rename to wheel-demo/app/src/main/java/kankan/wheel/demo/extended/TimeActivity.java index 27753fb..397e12a 100644 --- a/wheel-demo/src/kankan/wheel/demo/extended/TimeActivity.java +++ b/wheel-demo/app/src/main/java/kankan/wheel/demo/extended/TimeActivity.java @@ -1,119 +1,119 @@ -package kankan.wheel.demo.extended; - -import java.util.Calendar; - -import kankan.wheel.demo.extended.R; -import kankan.wheel.widget.OnWheelChangedListener; -import kankan.wheel.widget.OnWheelClickedListener; -import kankan.wheel.widget.OnWheelScrollListener; -import kankan.wheel.widget.WheelView; -import kankan.wheel.widget.adapters.NumericWheelAdapter; - -import android.app.Activity; -import android.os.Bundle; -import android.widget.TimePicker; - -public class TimeActivity extends Activity { - // Time changed flag - private boolean timeChanged = false; - - // Time scrolled flag - private boolean timeScrolled = false; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.time_layout); - - final WheelView hours = (WheelView) findViewById(R.id.hour); - hours.setViewAdapter(new NumericWheelAdapter(this, 0, 23)); - - final WheelView mins = (WheelView) findViewById(R.id.mins); - mins.setViewAdapter(new NumericWheelAdapter(this, 0, 59, "%02d")); - mins.setCyclic(true); - - final TimePicker picker = (TimePicker) findViewById(R.id.time); - picker.setIs24HourView(true); - - // set current time - Calendar c = Calendar.getInstance(); - int curHours = c.get(Calendar.HOUR_OF_DAY); - int curMinutes = c.get(Calendar.MINUTE); - - hours.setCurrentItem(curHours); - mins.setCurrentItem(curMinutes); - - picker.setCurrentHour(curHours); - picker.setCurrentMinute(curMinutes); - - // add listeners - addChangingListener(mins, "min"); - addChangingListener(hours, "hour"); - - OnWheelChangedListener wheelListener = new OnWheelChangedListener() { - @Override - public void onChanged(WheelView wheel, int oldValue, int newValue) { - if (!timeScrolled) { - timeChanged = true; - picker.setCurrentHour(hours.getCurrentItem()); - picker.setCurrentMinute(mins.getCurrentItem()); - timeChanged = false; - } - } - }; - hours.addChangingListener(wheelListener); - mins.addChangingListener(wheelListener); - - OnWheelClickedListener click = new OnWheelClickedListener() { - @Override - public void onItemClicked(WheelView wheel, int itemIndex) { - wheel.setCurrentItem(itemIndex, true); - } - }; - hours.addClickingListener(click); - mins.addClickingListener(click); - - OnWheelScrollListener scrollListener = new OnWheelScrollListener() { - @Override - public void onScrollingStarted(WheelView wheel) { - timeScrolled = true; - } - @Override - public void onScrollingFinished(WheelView wheel) { - timeScrolled = false; - timeChanged = true; - picker.setCurrentHour(hours.getCurrentItem()); - picker.setCurrentMinute(mins.getCurrentItem()); - timeChanged = false; - } - }; - - hours.addScrollingListener(scrollListener); - mins.addScrollingListener(scrollListener); - - picker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() { - @Override - public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { - if (!timeChanged) { - hours.setCurrentItem(hourOfDay, true); - mins.setCurrentItem(minute, true); - } - } - }); - } - - /** - * Adds changing listener for wheel that updates the wheel label - * @param wheel the wheel - * @param label the wheel label - */ - private void addChangingListener(final WheelView wheel, final String label) { - wheel.addChangingListener(new OnWheelChangedListener() { - @Override - public void onChanged(WheelView wheel, int oldValue, int newValue) { - //wheel.setLabel(newValue != 1 ? label + "s" : label); - } - }); - } -} +package kankan.wheel.demo.extended; + +import java.util.Calendar; + +import kankan.wheel.demo.extended.R; +import kankan.wheel.widget.OnWheelChangedListener; +import kankan.wheel.widget.OnWheelClickedListener; +import kankan.wheel.widget.OnWheelScrollListener; +import kankan.wheel.widget.WheelView; +import kankan.wheel.widget.adapters.NumericWheelAdapter; + +import android.app.Activity; +import android.os.Bundle; +import android.widget.TimePicker; + +public class TimeActivity extends Activity { + // Time changed flag + private boolean timeChanged = false; + + // Time scrolled flag + private boolean timeScrolled = false; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.time_layout); + + final WheelView hours = (WheelView) findViewById(R.id.hour); + hours.setViewAdapter(new NumericWheelAdapter(this, 0, 23)); + + final WheelView mins = (WheelView) findViewById(R.id.mins); + mins.setViewAdapter(new NumericWheelAdapter(this, 0, 59, "%02d")); + mins.setCyclic(true); + + final TimePicker picker = (TimePicker) findViewById(R.id.time); + picker.setIs24HourView(true); + + // set current time + Calendar c = Calendar.getInstance(); + int curHours = c.get(Calendar.HOUR_OF_DAY); + int curMinutes = c.get(Calendar.MINUTE); + + hours.setCurrentItem(curHours); + mins.setCurrentItem(curMinutes); + + picker.setCurrentHour(curHours); + picker.setCurrentMinute(curMinutes); + + // add listeners + addChangingListener(mins, "min"); + addChangingListener(hours, "hour"); + + OnWheelChangedListener wheelListener = new OnWheelChangedListener() { + @Override + public void onChanged(WheelView wheel, int oldValue, int newValue) { + if (!timeScrolled) { + timeChanged = true; + picker.setCurrentHour(hours.getCurrentItem()); + picker.setCurrentMinute(mins.getCurrentItem()); + timeChanged = false; + } + } + }; + hours.addChangingListener(wheelListener); + mins.addChangingListener(wheelListener); + + OnWheelClickedListener click = new OnWheelClickedListener() { + @Override + public void onItemClicked(WheelView wheel, int itemIndex) { + wheel.setCurrentItem(itemIndex, true); + } + }; + hours.addClickingListener(click); + mins.addClickingListener(click); + + OnWheelScrollListener scrollListener = new OnWheelScrollListener() { + @Override + public void onScrollingStarted(WheelView wheel) { + timeScrolled = true; + } + @Override + public void onScrollingFinished(WheelView wheel) { + timeScrolled = false; + timeChanged = true; + picker.setCurrentHour(hours.getCurrentItem()); + picker.setCurrentMinute(mins.getCurrentItem()); + timeChanged = false; + } + }; + + hours.addScrollingListener(scrollListener); + mins.addScrollingListener(scrollListener); + + picker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() { + @Override + public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { + if (!timeChanged) { + hours.setCurrentItem(hourOfDay, true); + mins.setCurrentItem(minute, true); + } + } + }); + } + + /** + * Adds changing listener for wheel that updates the wheel label + * @param wheel the wheel + * @param label the wheel label + */ + private void addChangingListener(final WheelView wheel, final String label) { + wheel.addChangingListener(new OnWheelChangedListener() { + @Override + public void onChanged(WheelView wheel, int oldValue, int newValue) { + //wheel.setLabel(newValue != 1 ? label + "s" : label); + } + }); + } +} diff --git a/wheel-demo/src/kankan/wheel/demo/extended/WheelDemo.java b/wheel-demo/app/src/main/java/kankan/wheel/demo/extended/WheelDemo.java similarity index 96% rename from wheel-demo/src/kankan/wheel/demo/extended/WheelDemo.java rename to wheel-demo/app/src/main/java/kankan/wheel/demo/extended/WheelDemo.java index 822e4ee..85ccb3f 100644 --- a/wheel-demo/src/kankan/wheel/demo/extended/WheelDemo.java +++ b/wheel-demo/app/src/main/java/kankan/wheel/demo/extended/WheelDemo.java @@ -1,128 +1,128 @@ -package kankan.wheel.demo.extended; - -import java.text.Collator; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import android.app.ListActivity; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.os.Bundle; -import android.view.View; -import android.widget.ListView; -import android.widget.SimpleAdapter; - -public class WheelDemo extends ListActivity { - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - Intent intent = getIntent(); - String path = intent.getStringExtra("com.example.android.apis.Path"); - - if (path == null) { - path = ""; - } - - setListAdapter(new SimpleAdapter(this, getData(path), - android.R.layout.simple_list_item_1, new String[] { "title" }, - new int[] { android.R.id.text1 })); - } - - protected List getData(String prefix) { - List myData = new ArrayList(); - - Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); - mainIntent.addCategory("kankan.wheel.extended.WHEEL_SAMPLE"); - - PackageManager pm = getPackageManager(); - List list = pm.queryIntentActivities(mainIntent, 0); - - if (null == list) - return myData; - - String[] prefixPath; - - if (prefix.equals("")) { - prefixPath = null; - } else { - prefixPath = prefix.split("/"); - } - - int len = list.size(); - - Map entries = new HashMap(); - - for (int i = 0; i < len; i++) { - ResolveInfo info = list.get(i); - CharSequence labelSeq = info.loadLabel(pm); - String label = labelSeq != null - ? labelSeq.toString() - : info.activityInfo.name; - - if (prefix.length() == 0 || label.startsWith(prefix)) { - - String[] labelPath = label.split("/"); - - String nextLabel = prefixPath == null ? labelPath[0] : labelPath[prefixPath.length]; - - if ((prefixPath != null ? prefixPath.length : 0) == labelPath.length - 1) { - addItem(myData, nextLabel, activityIntent( - info.activityInfo.applicationInfo.packageName, - info.activityInfo.name)); - } else { - if (entries.get(nextLabel) == null) { - addItem(myData, nextLabel, browseIntent(prefix.equals("") ? nextLabel : prefix + "/" + nextLabel)); - entries.put(nextLabel, true); - } - } - } - } - - Collections.sort(myData, sDisplayNameComparator); - - return myData; - } - - private final static Comparator sDisplayNameComparator = new Comparator() { - private final Collator collator = Collator.getInstance(); - - @Override - public int compare(Map map1, Map map2) { - return collator.compare(map1.get("title"), map2.get("title")); - } - }; - - protected Intent activityIntent(String pkg, String componentName) { - Intent result = new Intent(); - result.setClassName(pkg, componentName); - return result; - } - - protected Intent browseIntent(String path) { - Intent result = new Intent(); - result.setClass(this, WheelDemo.class); - result.putExtra("com.example.android.apis.Path", path); - return result; - } - - protected void addItem(List data, String name, Intent intent) { - Map temp = new HashMap(); - temp.put("title", name); - temp.put("intent", intent); - data.add(temp); - } - - @Override - protected void onListItemClick(ListView l, View v, int position, long id) { - Map map = (Map) l.getItemAtPosition(position); - - Intent intent = (Intent) map.get("intent"); - startActivity(intent); - } -} +package kankan.wheel.demo.extended; + +import android.app.ListActivity; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.os.Bundle; +import android.view.View; +import android.widget.ListView; +import android.widget.SimpleAdapter; + +import java.text.Collator; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class WheelDemo extends ListActivity { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Intent intent = getIntent(); + String path = intent.getStringExtra("com.example.android.apis.Path"); + + if (path == null) { + path = ""; + } + + setListAdapter(new SimpleAdapter(this, getData(path), + android.R.layout.simple_list_item_1, new String[] { "title" }, + new int[] { android.R.id.text1 })); + } + + protected List getData(String prefix) { + List myData = new ArrayList(); + + Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); + mainIntent.addCategory("kankan.wheel.extended.WHEEL_SAMPLE"); + + PackageManager pm = getPackageManager(); + List list = pm.queryIntentActivities(mainIntent, 0); + + if (null == list) + return myData; + + String[] prefixPath; + + if (prefix.equals("")) { + prefixPath = null; + } else { + prefixPath = prefix.split("/"); + } + + int len = list.size(); + + Map entries = new HashMap(); + + for (int i = 0; i < len; i++) { + ResolveInfo info = list.get(i); + CharSequence labelSeq = info.loadLabel(pm); + String label = labelSeq != null + ? labelSeq.toString() + : info.activityInfo.name; + + if (prefix.length() == 0 || label.startsWith(prefix)) { + + String[] labelPath = label.split("/"); + + String nextLabel = prefixPath == null ? labelPath[0] : labelPath[prefixPath.length]; + + if ((prefixPath != null ? prefixPath.length : 0) == labelPath.length - 1) { + addItem(myData, nextLabel, activityIntent( + info.activityInfo.applicationInfo.packageName, + info.activityInfo.name)); + } else { + if (entries.get(nextLabel) == null) { + addItem(myData, nextLabel, browseIntent(prefix.equals("") ? nextLabel : prefix + "/" + nextLabel)); + entries.put(nextLabel, true); + } + } + } + } + + Collections.sort(myData, sDisplayNameComparator); + + return myData; + } + + private final static Comparator sDisplayNameComparator = new Comparator() { + private final Collator collator = Collator.getInstance(); + + @Override + public int compare(Map map1, Map map2) { + return collator.compare(map1.get("title"), map2.get("title")); + } + }; + + protected Intent activityIntent(String pkg, String componentName) { + Intent result = new Intent(); + result.setClassName(pkg, componentName); + return result; + } + + protected Intent browseIntent(String path) { + Intent result = new Intent(); + result.setClass(this, WheelDemo.class); + result.putExtra("com.example.android.apis.Path", path); + return result; + } + + protected void addItem(List data, String name, Intent intent) { + Map temp = new HashMap(); + temp.put("title", name); + temp.put("intent", intent); + data.add(temp); + } + + @Override + protected void onListItemClick(ListView l, View v, int position, long id) { + Map map = (Map) l.getItemAtPosition(position); + + Intent intent = (Intent) map.get("intent"); + startActivity(intent); + } +} diff --git a/wheel-demo/res/drawable/canada.png b/wheel-demo/app/src/main/res/drawable/canada.png similarity index 100% rename from wheel-demo/res/drawable/canada.png rename to wheel-demo/app/src/main/res/drawable/canada.png diff --git a/wheel-demo/res/drawable/france.png b/wheel-demo/app/src/main/res/drawable/france.png similarity index 100% rename from wheel-demo/res/drawable/france.png rename to wheel-demo/app/src/main/res/drawable/france.png diff --git a/wheel-demo/res/drawable/layout_bg.xml b/wheel-demo/app/src/main/res/drawable/layout_bg.xml similarity index 97% rename from wheel-demo/res/drawable/layout_bg.xml rename to wheel-demo/app/src/main/res/drawable/layout_bg.xml index 6c53b9b..95de773 100644 --- a/wheel-demo/res/drawable/layout_bg.xml +++ b/wheel-demo/app/src/main/res/drawable/layout_bg.xml @@ -1,27 +1,27 @@ - - - - - - - + + + + + + + diff --git a/wheel-demo/res/drawable/layout_bg_holo.xml b/wheel-demo/app/src/main/res/drawable/layout_bg_holo.xml similarity index 97% rename from wheel-demo/res/drawable/layout_bg_holo.xml rename to wheel-demo/app/src/main/res/drawable/layout_bg_holo.xml index e0edad5..7a7194d 100644 --- a/wheel-demo/res/drawable/layout_bg_holo.xml +++ b/wheel-demo/app/src/main/res/drawable/layout_bg_holo.xml @@ -1,27 +1,27 @@ - - - - - - - + + + + + + + diff --git a/wheel-demo/res/drawable/ukraine.png b/wheel-demo/app/src/main/res/drawable/ukraine.png similarity index 100% rename from wheel-demo/res/drawable/ukraine.png rename to wheel-demo/app/src/main/res/drawable/ukraine.png diff --git a/wheel-demo/res/drawable/usa.png b/wheel-demo/app/src/main/res/drawable/usa.png similarity index 100% rename from wheel-demo/res/drawable/usa.png rename to wheel-demo/app/src/main/res/drawable/usa.png diff --git a/wheel-demo/res/drawable/wheel_bg_holo.xml b/wheel-demo/app/src/main/res/drawable/wheel_bg_holo.xml similarity index 97% rename from wheel-demo/res/drawable/wheel_bg_holo.xml rename to wheel-demo/app/src/main/res/drawable/wheel_bg_holo.xml index 02a54ac..5282e2a 100644 --- a/wheel-demo/res/drawable/wheel_bg_holo.xml +++ b/wheel-demo/app/src/main/res/drawable/wheel_bg_holo.xml @@ -1,31 +1,31 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/wheel-demo/res/drawable/wheel_val_holo.xml b/wheel-demo/app/src/main/res/drawable/wheel_val_holo.xml similarity index 100% rename from wheel-demo/res/drawable/wheel_val_holo.xml rename to wheel-demo/app/src/main/res/drawable/wheel_val_holo.xml diff --git a/wheel-demo/res/layout/cities_holo_layout.xml b/wheel-demo/app/src/main/res/layout/cities_holo_layout.xml similarity index 100% rename from wheel-demo/res/layout/cities_holo_layout.xml rename to wheel-demo/app/src/main/res/layout/cities_holo_layout.xml diff --git a/wheel-demo/res/layout/cities_layout.xml b/wheel-demo/app/src/main/res/layout/cities_layout.xml similarity index 100% rename from wheel-demo/res/layout/cities_layout.xml rename to wheel-demo/app/src/main/res/layout/cities_layout.xml diff --git a/wheel-demo/res/layout/city_holo_layout.xml b/wheel-demo/app/src/main/res/layout/city_holo_layout.xml similarity index 100% rename from wheel-demo/res/layout/city_holo_layout.xml rename to wheel-demo/app/src/main/res/layout/city_holo_layout.xml diff --git a/wheel-demo/res/layout/country_layout.xml b/wheel-demo/app/src/main/res/layout/country_layout.xml similarity index 100% rename from wheel-demo/res/layout/country_layout.xml rename to wheel-demo/app/src/main/res/layout/country_layout.xml diff --git a/wheel-demo/res/layout/date_layout.xml b/wheel-demo/app/src/main/res/layout/date_layout.xml similarity index 100% rename from wheel-demo/res/layout/date_layout.xml rename to wheel-demo/app/src/main/res/layout/date_layout.xml diff --git a/wheel-demo/res/layout/passw_layout.xml b/wheel-demo/app/src/main/res/layout/passw_layout.xml similarity index 100% rename from wheel-demo/res/layout/passw_layout.xml rename to wheel-demo/app/src/main/res/layout/passw_layout.xml diff --git a/wheel-demo/res/layout/slot_item.xml b/wheel-demo/app/src/main/res/layout/slot_item.xml similarity index 100% rename from wheel-demo/res/layout/slot_item.xml rename to wheel-demo/app/src/main/res/layout/slot_item.xml diff --git a/wheel-demo/res/layout/slot_machine_layout.xml b/wheel-demo/app/src/main/res/layout/slot_machine_layout.xml similarity index 100% rename from wheel-demo/res/layout/slot_machine_layout.xml rename to wheel-demo/app/src/main/res/layout/slot_machine_layout.xml diff --git a/wheel-demo/res/layout/speed1_layout.xml b/wheel-demo/app/src/main/res/layout/speed1_layout.xml similarity index 100% rename from wheel-demo/res/layout/speed1_layout.xml rename to wheel-demo/app/src/main/res/layout/speed1_layout.xml diff --git a/wheel-demo/res/layout/time2_day.xml b/wheel-demo/app/src/main/res/layout/time2_day.xml similarity index 100% rename from wheel-demo/res/layout/time2_day.xml rename to wheel-demo/app/src/main/res/layout/time2_day.xml diff --git a/wheel-demo/res/layout/time2_layout.xml b/wheel-demo/app/src/main/res/layout/time2_layout.xml similarity index 100% rename from wheel-demo/res/layout/time2_layout.xml rename to wheel-demo/app/src/main/res/layout/time2_layout.xml diff --git a/wheel-demo/res/layout/time_layout.xml b/wheel-demo/app/src/main/res/layout/time_layout.xml similarity index 100% rename from wheel-demo/res/layout/time_layout.xml rename to wheel-demo/app/src/main/res/layout/time_layout.xml diff --git a/wheel-demo/res/layout/units_item.xml b/wheel-demo/app/src/main/res/layout/units_item.xml similarity index 100% rename from wheel-demo/res/layout/units_item.xml rename to wheel-demo/app/src/main/res/layout/units_item.xml diff --git a/wheel-demo/res/layout/wheel_text_item.xml b/wheel-demo/app/src/main/res/layout/wheel_text_item.xml similarity index 100% rename from wheel-demo/res/layout/wheel_text_item.xml rename to wheel-demo/app/src/main/res/layout/wheel_text_item.xml diff --git a/wheel-demo/app/src/main/res/mipmap-hdpi/ic_launcher.png b/wheel-demo/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..cde69bc Binary files /dev/null and b/wheel-demo/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/wheel-demo/app/src/main/res/mipmap-mdpi/ic_launcher.png b/wheel-demo/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..c133a0c Binary files /dev/null and b/wheel-demo/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/wheel-demo/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/wheel-demo/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..bfa42f0 Binary files /dev/null and b/wheel-demo/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/wheel-demo/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/wheel-demo/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..324e72c Binary files /dev/null and b/wheel-demo/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/wheel-demo/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/wheel-demo/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..aee44e1 Binary files /dev/null and b/wheel-demo/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/wheel-demo/app/src/main/res/values/colors.xml b/wheel-demo/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..3ab3e9c --- /dev/null +++ b/wheel-demo/app/src/main/res/values/colors.xml @@ -0,0 +1,6 @@ + + + #3F51B5 + #303F9F + #FF4081 + diff --git a/wheel-demo/app/src/main/res/values/strings.xml b/wheel-demo/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..f9768ba --- /dev/null +++ b/wheel-demo/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + Android Wheel Demo + diff --git a/wheel-demo/app/src/main/res/values/styles.xml b/wheel-demo/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..f11f745 --- /dev/null +++ b/wheel-demo/app/src/main/res/values/styles.xml @@ -0,0 +1,3 @@ + + + diff --git a/wheel-demo/app/src/test/java/kankan/wheel/demo/extended/ExampleUnitTest.java b/wheel-demo/app/src/test/java/kankan/wheel/demo/extended/ExampleUnitTest.java new file mode 100644 index 0000000..829645e --- /dev/null +++ b/wheel-demo/app/src/test/java/kankan/wheel/demo/extended/ExampleUnitTest.java @@ -0,0 +1,15 @@ +package kankan.wheel.demo.extended; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * To work on unit tests, switch the Test Artifact in the Build Variants view. + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() throws Exception { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/wheel-demo/build.gradle b/wheel-demo/build.gradle new file mode 100644 index 0000000..e0b366a --- /dev/null +++ b/wheel-demo/build.gradle @@ -0,0 +1,23 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:1.5.0' + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + jcenter() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/wheel-demo/gradle.properties b/wheel-demo/gradle.properties new file mode 100644 index 0000000..1d3591c --- /dev/null +++ b/wheel-demo/gradle.properties @@ -0,0 +1,18 @@ +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +# Default value: -Xmx10248m -XX:MaxPermSize=256m +# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true \ No newline at end of file diff --git a/wheel-demo/gradle/wrapper/gradle-wrapper.jar b/wheel-demo/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..05ef575 Binary files /dev/null and b/wheel-demo/gradle/wrapper/gradle-wrapper.jar differ diff --git a/wheel-demo/gradle/wrapper/gradle-wrapper.properties b/wheel-demo/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..f23df6e --- /dev/null +++ b/wheel-demo/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Wed Oct 21 11:34:03 PDT 2015 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip diff --git a/wheel-demo/gradlew b/wheel-demo/gradlew new file mode 100755 index 0000000..9d82f78 --- /dev/null +++ b/wheel-demo/gradlew @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/wheel-demo/gradlew.bat b/wheel-demo/gradlew.bat new file mode 100644 index 0000000..8a0b282 --- /dev/null +++ b/wheel-demo/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/wheel-demo/project.properties b/wheel-demo/project.properties deleted file mode 100644 index a0302a8..0000000 --- a/wheel-demo/project.properties +++ /dev/null @@ -1,17 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system edit -# "ant.properties", and override values to adapt the script to your -# project structure. -# -# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): -#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt - -# Indicates whether an apk should be generated for each density. -split.density=false -android.library.reference.1=../wheel -# Project target. -target=Google Inc.:Google APIs:4 diff --git a/wheel-demo/res/drawable-hdpi/icon.png b/wheel-demo/res/drawable-hdpi/icon.png deleted file mode 100644 index 8074c4c..0000000 Binary files a/wheel-demo/res/drawable-hdpi/icon.png and /dev/null differ diff --git a/wheel-demo/res/drawable-hdpi/my_icon.png b/wheel-demo/res/drawable-hdpi/my_icon.png deleted file mode 100644 index 549a485..0000000 Binary files a/wheel-demo/res/drawable-hdpi/my_icon.png and /dev/null differ diff --git a/wheel-demo/res/drawable-hdpi/wheel.png b/wheel-demo/res/drawable-hdpi/wheel.png deleted file mode 100644 index efdeb5f..0000000 Binary files a/wheel-demo/res/drawable-hdpi/wheel.png and /dev/null differ diff --git a/wheel-demo/res/drawable-ldpi/icon.png b/wheel-demo/res/drawable-ldpi/icon.png deleted file mode 100644 index 1095584..0000000 Binary files a/wheel-demo/res/drawable-ldpi/icon.png and /dev/null differ diff --git a/wheel-demo/res/drawable-mdpi/icon.png b/wheel-demo/res/drawable-mdpi/icon.png deleted file mode 100644 index a07c69f..0000000 Binary files a/wheel-demo/res/drawable-mdpi/icon.png and /dev/null differ diff --git a/wheel-demo/settings.gradle b/wheel-demo/settings.gradle new file mode 100644 index 0000000..7f8906b --- /dev/null +++ b/wheel-demo/settings.gradle @@ -0,0 +1 @@ +include ':app', ':wheel-release' diff --git a/wheel-demo/wheel-release/build.gradle b/wheel-demo/wheel-release/build.gradle new file mode 100644 index 0000000..55f59c9 --- /dev/null +++ b/wheel-demo/wheel-release/build.gradle @@ -0,0 +1,2 @@ +configurations.create("default") +artifacts.add("default", file('wheel-release.aar')) \ No newline at end of file diff --git a/wheel-demo/wheel-release/wheel-release.aar b/wheel-demo/wheel-release/wheel-release.aar new file mode 100644 index 0000000..533a928 Binary files /dev/null and b/wheel-demo/wheel-release/wheel-release.aar differ diff --git a/wheel/.classpath b/wheel/.classpath deleted file mode 100644 index 4160c21..0000000 --- a/wheel/.classpath +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/wheel/.gitignore b/wheel/.gitignore new file mode 100644 index 0000000..17c1fe6 --- /dev/null +++ b/wheel/.gitignore @@ -0,0 +1,105 @@ +# Created by https://www.gitignore.io/api/android,intellij,gradle + +.DS_Store + +### Android ### +# Built application files +*.apk +*.ap_ + +# Files for the Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +gen/ + +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +### Android Patch ### +gen-external-apklibs + + +### Intellij ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm + +*.iml + +## Directory-based project format: +.idea/ +# if you remove the above rule, at least ignore the following: + +# User-specific stuff: +.idea/workspace.xml +# .idea/tasks.xml +# .idea/dictionaries +# .idea/shelf + +# Sensitive or high-churn files: +# .idea/dataSources.ids +# .idea/dataSources.xml +# .idea/sqlDataSources.xml +# .idea/dynamic.xml +# .idea/uiDesigner.xml + +# Gradle: +# .idea/gradle.xml +.idea/libraries + +# Mongo Explorer plugin: +# .idea/mongoSettings.xml + +## File-based project format: +*.ipr +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + + +### Gradle ### +.gradle +build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache diff --git a/wheel/.project b/wheel/.project deleted file mode 100644 index 7ff0e44..0000000 --- a/wheel/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - wheel - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - - diff --git a/wheel/AndroidManifest.xml b/wheel/AndroidManifest.xml deleted file mode 100644 index a71e25e..0000000 --- a/wheel/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - diff --git a/wheel/build.gradle b/wheel/build.gradle new file mode 100644 index 0000000..e0b366a --- /dev/null +++ b/wheel/build.gradle @@ -0,0 +1,23 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:1.5.0' + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + jcenter() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/wheel/gradle.properties b/wheel/gradle.properties new file mode 100644 index 0000000..1d3591c --- /dev/null +++ b/wheel/gradle.properties @@ -0,0 +1,18 @@ +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +# Default value: -Xmx10248m -XX:MaxPermSize=256m +# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true \ No newline at end of file diff --git a/wheel/gradle/wrapper/gradle-wrapper.jar b/wheel/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..05ef575 Binary files /dev/null and b/wheel/gradle/wrapper/gradle-wrapper.jar differ diff --git a/wheel/gradle/wrapper/gradle-wrapper.properties b/wheel/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..f23df6e --- /dev/null +++ b/wheel/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Wed Oct 21 11:34:03 PDT 2015 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip diff --git a/wheel/gradlew b/wheel/gradlew new file mode 100755 index 0000000..9d82f78 --- /dev/null +++ b/wheel/gradlew @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/wheel/gradlew.bat b/wheel/gradlew.bat new file mode 100644 index 0000000..8a0b282 --- /dev/null +++ b/wheel/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/wheel/project.properties b/wheel/project.properties deleted file mode 100644 index 5d433a1..0000000 --- a/wheel/project.properties +++ /dev/null @@ -1,17 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system edit -# "ant.properties", and override values to adapt the script to your -# project structure. -# -# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): -#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt - -android.library=true -# Indicates whether an apk should be generated for each density. -split.density=false -# Project target. -target=android-7 diff --git a/wheel/settings.gradle b/wheel/settings.gradle new file mode 100644 index 0000000..b600c00 --- /dev/null +++ b/wheel/settings.gradle @@ -0,0 +1 @@ +include ':wheel' diff --git a/wheel/wheel/.gitignore b/wheel/wheel/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/wheel/wheel/.gitignore @@ -0,0 +1 @@ +/build diff --git a/wheel/wheel/build.gradle b/wheel/wheel/build.gradle new file mode 100644 index 0000000..6d3e598 --- /dev/null +++ b/wheel/wheel/build.gradle @@ -0,0 +1,24 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion 23 + buildToolsVersion "23.0.1" + + defaultConfig { + minSdkVersion 5 + targetSdkVersion 23 + versionCode 3 + versionName "2.2" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + testCompile 'junit:junit:4.12' +} diff --git a/wheel/wheel/proguard-rules.pro b/wheel/wheel/proguard-rules.pro new file mode 100644 index 0000000..0b3ef79 --- /dev/null +++ b/wheel/wheel/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/penaa/.android/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/wheel/wheel/src/androidTest/java/kankan/wheel/widget/ApplicationTest.java b/wheel/wheel/src/androidTest/java/kankan/wheel/widget/ApplicationTest.java new file mode 100644 index 0000000..27c3284 --- /dev/null +++ b/wheel/wheel/src/androidTest/java/kankan/wheel/widget/ApplicationTest.java @@ -0,0 +1,13 @@ +package kankan.wheel.widget; + +import android.app.Application; +import android.test.ApplicationTestCase; + +/** + * Testing Fundamentals + */ +public class ApplicationTest extends ApplicationTestCase { + public ApplicationTest() { + super(Application.class); + } +} \ No newline at end of file diff --git a/wheel/wheel/src/main/AndroidManifest.xml b/wheel/wheel/src/main/AndroidManifest.xml new file mode 100644 index 0000000..19367cf --- /dev/null +++ b/wheel/wheel/src/main/AndroidManifest.xml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/wheel/src/kankan/wheel/widget/ItemsRange.java b/wheel/wheel/src/main/java/kankan/wheel/widget/ItemsRange.java similarity index 100% rename from wheel/src/kankan/wheel/widget/ItemsRange.java rename to wheel/wheel/src/main/java/kankan/wheel/widget/ItemsRange.java diff --git a/wheel/src/kankan/wheel/widget/OnWheelChangedListener.java b/wheel/wheel/src/main/java/kankan/wheel/widget/OnWheelChangedListener.java similarity index 100% rename from wheel/src/kankan/wheel/widget/OnWheelChangedListener.java rename to wheel/wheel/src/main/java/kankan/wheel/widget/OnWheelChangedListener.java diff --git a/wheel/src/kankan/wheel/widget/OnWheelClickedListener.java b/wheel/wheel/src/main/java/kankan/wheel/widget/OnWheelClickedListener.java similarity index 100% rename from wheel/src/kankan/wheel/widget/OnWheelClickedListener.java rename to wheel/wheel/src/main/java/kankan/wheel/widget/OnWheelClickedListener.java diff --git a/wheel/src/kankan/wheel/widget/OnWheelScrollListener.java b/wheel/wheel/src/main/java/kankan/wheel/widget/OnWheelScrollListener.java similarity index 100% rename from wheel/src/kankan/wheel/widget/OnWheelScrollListener.java rename to wheel/wheel/src/main/java/kankan/wheel/widget/OnWheelScrollListener.java diff --git a/wheel/src/kankan/wheel/widget/WheelAdapter.java b/wheel/wheel/src/main/java/kankan/wheel/widget/WheelAdapter.java similarity index 96% rename from wheel/src/kankan/wheel/widget/WheelAdapter.java rename to wheel/wheel/src/main/java/kankan/wheel/widget/WheelAdapter.java index 5705bb0..efd6191 100644 --- a/wheel/src/kankan/wheel/widget/WheelAdapter.java +++ b/wheel/wheel/src/main/java/kankan/wheel/widget/WheelAdapter.java @@ -1,46 +1,46 @@ -/* - * Copyright 2010 Yuri Kanivets - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package kankan.wheel.widget; - -/** - * Wheel adapter interface - * - * @deprecated Use WheelViewAdapter - */ -public interface WheelAdapter { - /** - * Gets items count - * @return the count of wheel items - */ - public int getItemsCount(); - - /** - * Gets a wheel item by index. - * - * @param index the item index - * @return the wheel item text or null - */ - public String getItem(int index); - - /** - * Gets maximum item length. It is used to determine the wheel width. - * If -1 is returned there will be used the default wheel width. - * - * @return the maximum item length or -1 - */ - public int getMaximumLength(); -} +/* + * Copyright 2010 Yuri Kanivets + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package kankan.wheel.widget; + +/** + * Wheel adapter interface + * + * @deprecated Use WheelViewAdapter + */ +public interface WheelAdapter { + /** + * Gets items count + * @return the count of wheel items + */ + public int getItemsCount(); + + /** + * Gets a wheel item by index. + * + * @param index the item index + * @return the wheel item text or null + */ + public String getItem(int index); + + /** + * Gets maximum item length. It is used to determine the wheel width. + * If -1 is returned there will be used the default wheel width. + * + * @return the maximum item length or -1 + */ + public int getMaximumLength(); +} diff --git a/wheel/src/kankan/wheel/widget/WheelRecycle.java b/wheel/wheel/src/main/java/kankan/wheel/widget/WheelRecycle.java similarity index 100% rename from wheel/src/kankan/wheel/widget/WheelRecycle.java rename to wheel/wheel/src/main/java/kankan/wheel/widget/WheelRecycle.java index 45c050b..817fc2e 100644 --- a/wheel/src/kankan/wheel/widget/WheelRecycle.java +++ b/wheel/wheel/src/main/java/kankan/wheel/widget/WheelRecycle.java @@ -19,12 +19,12 @@ package kankan.wheel.widget; -import java.util.LinkedList; -import java.util.List; - import android.view.View; import android.widget.LinearLayout; +import java.util.LinkedList; +import java.util.List; + /** * Recycle stores wheel items to reuse. */ diff --git a/wheel/src/kankan/wheel/widget/WheelScroller.java b/wheel/wheel/src/main/java/kankan/wheel/widget/WheelScroller.java similarity index 100% rename from wheel/src/kankan/wheel/widget/WheelScroller.java rename to wheel/wheel/src/main/java/kankan/wheel/widget/WheelScroller.java diff --git a/wheel/src/kankan/wheel/widget/WheelView.java b/wheel/wheel/src/main/java/kankan/wheel/widget/WheelView.java similarity index 95% rename from wheel/src/kankan/wheel/widget/WheelView.java rename to wheel/wheel/src/main/java/kankan/wheel/widget/WheelView.java index 49851db..e1fbf36 100644 --- a/wheel/src/kankan/wheel/widget/WheelView.java +++ b/wheel/wheel/src/main/java/kankan/wheel/widget/WheelView.java @@ -1,938 +1,938 @@ -/* - * Android Wheel Control. - * https://code.google.com/p/android-wheel/ - * - * Copyright 2011 Yuri Kanivets - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package kankan.wheel.widget; - -import java.util.LinkedList; -import java.util.List; - -import kankan.wheel.R; -import kankan.wheel.widget.adapters.WheelViewAdapter; -import android.content.Context; -import android.database.DataSetObserver; -import android.graphics.Canvas; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.GradientDrawable; -import android.graphics.drawable.GradientDrawable.Orientation; -import android.util.AttributeSet; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup.LayoutParams; -import android.view.animation.Interpolator; -import android.widget.LinearLayout; - -/** - * Numeric wheel view. - * - * @author Yuri Kanivets - */ -public class WheelView extends View { - - /** Top and bottom shadows colors */ - private int[] SHADOWS_COLORS = new int[] { 0xFF111111, - 0x00AAAAAA, 0x00AAAAAA }; - - /** Top and bottom items offset (to hide that) */ - private static final int ITEM_OFFSET_PERCENT = 0; - - /** Left and right padding value */ - private static final int PADDING = 10; - - /** Default count of visible items */ - private static final int DEF_VISIBLE_ITEMS = 5; - - // Wheel Values - private int currentItem = 0; - - // Count of visible items - private int visibleItems = DEF_VISIBLE_ITEMS; - - // Item height - private int itemHeight = 0; - - // Center Line - private Drawable centerDrawable; - - // Wheel drawables - private int wheelBackground = R.drawable.wheel_bg; - private int wheelForeground = R.drawable.wheel_val; - - // Shadows drawables - private GradientDrawable topShadow; - private GradientDrawable bottomShadow; - - // Draw Shadows - private boolean drawShadows = true; - - // Scrolling - private WheelScroller scroller; - private boolean isScrollingPerformed; - private int scrollingOffset; - - // Cyclic - boolean isCyclic = false; - - // Items layout - private LinearLayout itemsLayout; - - // The number of first item in layout - private int firstItem; - - // View adapter - private WheelViewAdapter viewAdapter; - - // Recycle - private WheelRecycle recycle = new WheelRecycle(this); - - // Listeners - private List changingListeners = new LinkedList(); - private List scrollingListeners = new LinkedList(); - private List clickingListeners = new LinkedList(); - - /** - * Constructor - */ - public WheelView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - initData(context); - } - - /** - * Constructor - */ - public WheelView(Context context, AttributeSet attrs) { - super(context, attrs); - initData(context); - } - - /** - * Constructor - */ - public WheelView(Context context) { - super(context); - initData(context); - } - - /** - * Initializes class data - * @param context the context - */ - private void initData(Context context) { - scroller = new WheelScroller(getContext(), scrollingListener); - } - - // Scrolling listener - WheelScroller.ScrollingListener scrollingListener = new WheelScroller.ScrollingListener() { - @Override - public void onStarted() { - isScrollingPerformed = true; - notifyScrollingListenersAboutStart(); - } - - @Override - public void onScroll(int distance) { - doScroll(distance); - - int height = getHeight(); - if (scrollingOffset > height) { - scrollingOffset = height; - scroller.stopScrolling(); - } else if (scrollingOffset < -height) { - scrollingOffset = -height; - scroller.stopScrolling(); - } - } - - @Override - public void onFinished() { - if (isScrollingPerformed) { - notifyScrollingListenersAboutEnd(); - isScrollingPerformed = false; - } - - scrollingOffset = 0; - invalidate(); - } - - @Override - public void onJustify() { - if (Math.abs(scrollingOffset) > WheelScroller.MIN_DELTA_FOR_SCROLLING) { - scroller.scroll(scrollingOffset, 0); - } - } - }; - - /** - * Set the the specified scrolling interpolator - * @param interpolator the interpolator - */ - public void setInterpolator(Interpolator interpolator) { - scroller.setInterpolator(interpolator); - } - - /** - * Gets count of visible items - * - * @return the count of visible items - */ - public int getVisibleItems() { - return visibleItems; - } - - /** - * Sets the desired count of visible items. - * Actual amount of visible items depends on wheel layout parameters. - * To apply changes and rebuild view call measure(). - * - * @param count the desired count for visible items - */ - public void setVisibleItems(int count) { - visibleItems = count; - } - - /** - * Gets view adapter - * @return the view adapter - */ - public WheelViewAdapter getViewAdapter() { - return viewAdapter; - } - - // Adapter listener - private DataSetObserver dataObserver = new DataSetObserver() { - @Override - public void onChanged() { - invalidateWheel(false); - } - - @Override - public void onInvalidated() { - invalidateWheel(true); - } - }; - - /** - * Sets view adapter. Usually new adapters contain different views, so - * it needs to rebuild view by calling measure(). - * - * @param viewAdapter the view adapter - */ - public void setViewAdapter(WheelViewAdapter viewAdapter) { - if (this.viewAdapter != null) { - this.viewAdapter.unregisterDataSetObserver(dataObserver); - } - this.viewAdapter = viewAdapter; - if (this.viewAdapter != null) { - this.viewAdapter.registerDataSetObserver(dataObserver); - } - - invalidateWheel(true); - } - - /** - * Adds wheel changing listener - * @param listener the listener - */ - public void addChangingListener(OnWheelChangedListener listener) { - changingListeners.add(listener); - } - - /** - * Removes wheel changing listener - * @param listener the listener - */ - public void removeChangingListener(OnWheelChangedListener listener) { - changingListeners.remove(listener); - } - - /** - * Notifies changing listeners - * @param oldValue the old wheel value - * @param newValue the new wheel value - */ - protected void notifyChangingListeners(int oldValue, int newValue) { - for (OnWheelChangedListener listener : changingListeners) { - listener.onChanged(this, oldValue, newValue); - } - } - - /** - * Adds wheel scrolling listener - * @param listener the listener - */ - public void addScrollingListener(OnWheelScrollListener listener) { - scrollingListeners.add(listener); - } - - /** - * Removes wheel scrolling listener - * @param listener the listener - */ - public void removeScrollingListener(OnWheelScrollListener listener) { - scrollingListeners.remove(listener); - } - - /** - * Notifies listeners about starting scrolling - */ - protected void notifyScrollingListenersAboutStart() { - for (OnWheelScrollListener listener : scrollingListeners) { - listener.onScrollingStarted(this); - } - } - - /** - * Notifies listeners about ending scrolling - */ - protected void notifyScrollingListenersAboutEnd() { - for (OnWheelScrollListener listener : scrollingListeners) { - listener.onScrollingFinished(this); - } - } - - /** - * Adds wheel clicking listener - * @param listener the listener - */ - public void addClickingListener(OnWheelClickedListener listener) { - clickingListeners.add(listener); - } - - /** - * Removes wheel clicking listener - * @param listener the listener - */ - public void removeClickingListener(OnWheelClickedListener listener) { - clickingListeners.remove(listener); - } - - /** - * Notifies listeners about clicking - */ - protected void notifyClickListenersAboutClick(int item) { - for (OnWheelClickedListener listener : clickingListeners) { - listener.onItemClicked(this, item); - } - } - - /** - * Gets current value - * - * @return the current value - */ - public int getCurrentItem() { - return currentItem; - } - - /** - * Sets the current item. Does nothing when index is wrong. - * - * @param index the item index - * @param animated the animation flag - */ - public void setCurrentItem(int index, boolean animated) { - if (viewAdapter == null || viewAdapter.getItemsCount() == 0) { - return; // throw? - } - - int itemCount = viewAdapter.getItemsCount(); - if (index < 0 || index >= itemCount) { - if (isCyclic) { - while (index < 0) { - index += itemCount; - } - index %= itemCount; - } else{ - return; // throw? - } - } - if (index != currentItem) { - if (animated) { - int itemsToScroll = index - currentItem; - if (isCyclic) { - int scroll = itemCount + Math.min(index, currentItem) - Math.max(index, currentItem); - if (scroll < Math.abs(itemsToScroll)) { - itemsToScroll = itemsToScroll < 0 ? scroll : -scroll; - } - } - scroll(itemsToScroll, 0); - } else { - scrollingOffset = 0; - - int old = currentItem; - currentItem = index; - - notifyChangingListeners(old, currentItem); - - invalidate(); - } - } - } - - /** - * Sets the current item w/o animation. Does nothing when index is wrong. - * - * @param index the item index - */ - public void setCurrentItem(int index) { - setCurrentItem(index, false); - } - - /** - * Tests if wheel is cyclic. That means before the 1st item there is shown the last one - * @return true if wheel is cyclic - */ - public boolean isCyclic() { - return isCyclic; - } - - /** - * Set wheel cyclic flag - * @param isCyclic the flag to set - */ - public void setCyclic(boolean isCyclic) { - this.isCyclic = isCyclic; - invalidateWheel(false); - } - - /** - * Determine whether shadows are drawn - * @return true is shadows are drawn - */ - public boolean drawShadows() { - return drawShadows; - } - - /** - * Set whether shadows should be drawn - * @param drawShadows flag as true or false - */ - public void setDrawShadows(boolean drawShadows) { - this.drawShadows = drawShadows; - } - - /** - * Set the shadow gradient color - * @param start - * @param middle - * @param end - */ - public void setShadowColor(int start, int middle, int end) { - SHADOWS_COLORS = new int[] {start, middle, end}; - } - - /** - * Sets the drawable for the wheel background - * @param resource - */ - public void setWheelBackground(int resource) { - wheelBackground = resource; - setBackgroundResource(wheelBackground); - } - - /** - * Sets the drawable for the wheel foreground - * @param resource - */ - public void setWheelForeground(int resource) { - wheelForeground = resource; - centerDrawable = getContext().getResources().getDrawable(wheelForeground); - } - - /** - * Invalidates wheel - * @param clearCaches if true then cached views will be clear - */ - public void invalidateWheel(boolean clearCaches) { - if (clearCaches) { - recycle.clearAll(); - if (itemsLayout != null) { - itemsLayout.removeAllViews(); - } - scrollingOffset = 0; - } else if (itemsLayout != null) { - // cache all items - recycle.recycleItems(itemsLayout, firstItem, new ItemsRange()); - } - - invalidate(); - } - - /** - * Initializes resources - */ - private void initResourcesIfNecessary() { - if (centerDrawable == null) { - centerDrawable = getContext().getResources().getDrawable(wheelForeground); - } - - if (topShadow == null) { - topShadow = new GradientDrawable(Orientation.TOP_BOTTOM, SHADOWS_COLORS); - } - - if (bottomShadow == null) { - bottomShadow = new GradientDrawable(Orientation.BOTTOM_TOP, SHADOWS_COLORS); - } - - setBackgroundResource(wheelBackground); - } - - /** - * Calculates desired height for layout - * - * @param layout - * the source layout - * @return the desired layout height - */ - private int getDesiredHeight(LinearLayout layout) { - if (layout != null && layout.getChildAt(0) != null) { - itemHeight = layout.getChildAt(0).getMeasuredHeight(); - } - - int desired = itemHeight * visibleItems - itemHeight * ITEM_OFFSET_PERCENT / 50; - - return Math.max(desired, getSuggestedMinimumHeight()); - } - - /** - * Returns height of wheel item - * @return the item height - */ - private int getItemHeight() { - if (itemHeight != 0) { - return itemHeight; - } - - if (itemsLayout != null && itemsLayout.getChildAt(0) != null) { - itemHeight = itemsLayout.getChildAt(0).getHeight(); - return itemHeight; - } - - return getHeight() / visibleItems; - } - - /** - * Calculates control width and creates text layouts - * @param widthSize the input layout width - * @param mode the layout mode - * @return the calculated control width - */ - private int calculateLayoutWidth(int widthSize, int mode) { - initResourcesIfNecessary(); - - // TODO: make it static - itemsLayout.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); - itemsLayout.measure(MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.UNSPECIFIED), - MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); - int width = itemsLayout.getMeasuredWidth(); - - if (mode == MeasureSpec.EXACTLY) { - width = widthSize; - } else { - width += 2 * PADDING; - - // Check against our minimum width - width = Math.max(width, getSuggestedMinimumWidth()); - - if (mode == MeasureSpec.AT_MOST && widthSize < width) { - width = widthSize; - } - } - - itemsLayout.measure(MeasureSpec.makeMeasureSpec(width - 2 * PADDING, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); - - return width; - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int widthMode = MeasureSpec.getMode(widthMeasureSpec); - int heightMode = MeasureSpec.getMode(heightMeasureSpec); - int widthSize = MeasureSpec.getSize(widthMeasureSpec); - int heightSize = MeasureSpec.getSize(heightMeasureSpec); - - buildViewForMeasuring(); - - int width = calculateLayoutWidth(widthSize, widthMode); - - int height; - if (heightMode == MeasureSpec.EXACTLY) { - height = heightSize; - } else { - height = getDesiredHeight(itemsLayout); - - if (heightMode == MeasureSpec.AT_MOST) { - height = Math.min(height, heightSize); - } - } - - setMeasuredDimension(width, height); - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - layout(r - l, b - t); - } - - /** - * Sets layouts width and height - * @param width the layout width - * @param height the layout height - */ - private void layout(int width, int height) { - int itemsWidth = width - 2 * PADDING; - - itemsLayout.layout(0, 0, itemsWidth, height); - } - - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - - if (viewAdapter != null && viewAdapter.getItemsCount() > 0) { - updateView(); - - drawItems(canvas); - drawCenterRect(canvas); - } - - if (drawShadows) drawShadows(canvas); - } - - /** - * Draws shadows on top and bottom of control - * @param canvas the canvas for drawing - */ - private void drawShadows(Canvas canvas) { - int height = (int)(1.5 * getItemHeight()); - topShadow.setBounds(0, 0, getWidth(), height); - topShadow.draw(canvas); - - bottomShadow.setBounds(0, getHeight() - height, getWidth(), getHeight()); - bottomShadow.draw(canvas); - } - - /** - * Draws items - * @param canvas the canvas for drawing - */ - private void drawItems(Canvas canvas) { - canvas.save(); - - int top = (currentItem - firstItem) * getItemHeight() + (getItemHeight() - getHeight()) / 2; - canvas.translate(PADDING, - top + scrollingOffset); - - itemsLayout.draw(canvas); - - canvas.restore(); - } - - /** - * Draws rect for current value - * @param canvas the canvas for drawing - */ - private void drawCenterRect(Canvas canvas) { - int center = getHeight() / 2; - int offset = (int) (getItemHeight() / 2 * 1.2); - centerDrawable.setBounds(0, center - offset, getWidth(), center + offset); - centerDrawable.draw(canvas); - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - if (!isEnabled() || getViewAdapter() == null) { - return true; - } - - switch (event.getAction()) { - case MotionEvent.ACTION_MOVE: - if (getParent() != null) { - getParent().requestDisallowInterceptTouchEvent(true); - } - break; - - case MotionEvent.ACTION_UP: - if (!isScrollingPerformed) { - int distance = (int) event.getY() - getHeight() / 2; - if (distance > 0) { - distance += getItemHeight() / 2; - } else { - distance -= getItemHeight() / 2; - } - int items = distance / getItemHeight(); - if (items != 0 && isValidItemIndex(currentItem + items)) { - notifyClickListenersAboutClick(currentItem + items); - } - } - break; - } - - return scroller.onTouchEvent(event); - } - - /** - * Scrolls the wheel - * @param delta the scrolling value - */ - private void doScroll(int delta) { - scrollingOffset += delta; - - int itemHeight = getItemHeight(); - int count = scrollingOffset / itemHeight; - - int pos = currentItem - count; - int itemCount = viewAdapter.getItemsCount(); - - int fixPos = scrollingOffset % itemHeight; - if (Math.abs(fixPos) <= itemHeight / 2) { - fixPos = 0; - } - if (isCyclic && itemCount > 0) { - if (fixPos > 0) { - pos--; - count++; - } else if (fixPos < 0) { - pos++; - count--; - } - // fix position by rotating - while (pos < 0) { - pos += itemCount; - } - pos %= itemCount; - } else { - // - if (pos < 0) { - count = currentItem; - pos = 0; - } else if (pos >= itemCount) { - count = currentItem - itemCount + 1; - pos = itemCount - 1; - } else if (pos > 0 && fixPos > 0) { - pos--; - count++; - } else if (pos < itemCount - 1 && fixPos < 0) { - pos++; - count--; - } - } - - int offset = scrollingOffset; - if (pos != currentItem) { - setCurrentItem(pos, false); - } else { - invalidate(); - } - - // update offset - scrollingOffset = offset - count * itemHeight; - if (scrollingOffset > getHeight()) { - if(getHeight() <= 0){ - scrollingOffset = 0; - }else { - scrollingOffset = scrollingOffset % getHeight() + getHeight(); - } - } - } - - /** - * Scroll the wheel - * @param itemsToSkip items to scroll - * @param time scrolling duration - */ - public void scroll(int itemsToScroll, int time) { - int distance = itemsToScroll * getItemHeight() - scrollingOffset; - scroller.scroll(distance, time); - } - - /** - * Calculates range for wheel items - * @return the items range - */ - private ItemsRange getItemsRange() { - if (getItemHeight() == 0) { - return null; - } - - int first = currentItem; - int count = 1; - - while (count * getItemHeight() < getHeight()) { - first--; - count += 2; // top + bottom items - } - - if (scrollingOffset != 0) { - if (scrollingOffset > 0) { - first--; - } - count++; - - // process empty items above the first or below the second - int emptyItems = scrollingOffset / getItemHeight(); - first -= emptyItems; - count += Math.asin(emptyItems); - } - return new ItemsRange(first, count); - } - - /** - * Rebuilds wheel items if necessary. Caches all unused items. - * - * @return true if items are rebuilt - */ - private boolean rebuildItems() { - boolean updated = false; - ItemsRange range = getItemsRange(); - if (itemsLayout != null) { - int first = recycle.recycleItems(itemsLayout, firstItem, range); - updated = firstItem != first; - firstItem = first; - } else { - createItemsLayout(); - updated = true; - } - - if (!updated) { - updated = firstItem != range.getFirst() || itemsLayout.getChildCount() != range.getCount(); - } - - if (firstItem > range.getFirst() && firstItem <= range.getLast()) { - for (int i = firstItem - 1; i >= range.getFirst(); i--) { - if (!addViewItem(i, true)) { - break; - } - firstItem = i; - } - } else { - firstItem = range.getFirst(); - } - - int first = firstItem; - for (int i = itemsLayout.getChildCount(); i < range.getCount(); i++) { - if (!addViewItem(firstItem + i, false) && itemsLayout.getChildCount() == 0) { - first++; - } - } - firstItem = first; - - return updated; - } - - /** - * Updates view. Rebuilds items and label if necessary, recalculate items sizes. - */ - private void updateView() { - if (rebuildItems()) { - calculateLayoutWidth(getWidth(), MeasureSpec.EXACTLY); - layout(getWidth(), getHeight()); - } - } - - /** - * Creates item layouts if necessary - */ - private void createItemsLayout() { - if (itemsLayout == null) { - itemsLayout = new LinearLayout(getContext()); - itemsLayout.setOrientation(LinearLayout.VERTICAL); - } - } - - /** - * Builds view for measuring - */ - private void buildViewForMeasuring() { - // clear all items - if (itemsLayout != null) { - recycle.recycleItems(itemsLayout, firstItem, new ItemsRange()); - } else { - createItemsLayout(); - } - - // add views - // all items must be included to measure width correctly - for (int i = viewAdapter.getItemsCount()-1; i >= 0; i--){ - if (addViewItem(i, true)) { - firstItem = i; - } - } - } - - /** - * Adds view for item to items layout - * @param index the item index - * @param first the flag indicates if view should be first - * @return true if corresponding item exists and is added - */ - private boolean addViewItem(int index, boolean first) { - View view = getItemView(index); - if (view != null) { - if (first) { - itemsLayout.addView(view, 0); - } else { - itemsLayout.addView(view); - } - - return true; - } - - return false; - } - - /** - * Checks whether intem index is valid - * @param index the item index - * @return true if item index is not out of bounds or the wheel is cyclic - */ - private boolean isValidItemIndex(int index) { - return viewAdapter != null && viewAdapter.getItemsCount() > 0 && - (isCyclic || index >= 0 && index < viewAdapter.getItemsCount()); - } - - /** - * Returns view for specified item - * @param index the item index - * @return item view or empty view if index is out of bounds - */ - private View getItemView(int index) { - if (viewAdapter == null || viewAdapter.getItemsCount() == 0) { - return null; - } - int count = viewAdapter.getItemsCount(); - if (!isValidItemIndex(index)) { - return viewAdapter.getEmptyItem(recycle.getEmptyItem(), itemsLayout); - } else { - while (index < 0) { - index = count + index; - } - } - - index %= count; - return viewAdapter.getItem(index, recycle.getItem(), itemsLayout); - } - - /** - * Stops scrolling - */ - public void stopScrolling() { - scroller.stopScrolling(); - } -} +/* + * Android Wheel Control. + * https://code.google.com/p/android-wheel/ + * + * Copyright 2011 Yuri Kanivets + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package kankan.wheel.widget; + +import android.content.Context; +import android.database.DataSetObserver; +import android.graphics.Canvas; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.GradientDrawable; +import android.graphics.drawable.GradientDrawable.Orientation; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup.LayoutParams; +import android.view.animation.Interpolator; +import android.widget.LinearLayout; + +import java.util.LinkedList; +import java.util.List; + +import kankan.wheel.widget.adapters.WheelViewAdapter; + +/** + * Numeric wheel view. + * + * @author Yuri Kanivets + */ +public class WheelView extends View { + + /** Top and bottom shadows colors */ + private int[] SHADOWS_COLORS = new int[] { 0xFF111111, + 0x00AAAAAA, 0x00AAAAAA }; + + /** Top and bottom items offset (to hide that) */ + private static final int ITEM_OFFSET_PERCENT = 0; + + /** Left and right padding value */ + private static final int PADDING = 10; + + /** Default count of visible items */ + private static final int DEF_VISIBLE_ITEMS = 5; + + // Wheel Values + private int currentItem = 0; + + // Count of visible items + private int visibleItems = DEF_VISIBLE_ITEMS; + + // Item height + private int itemHeight = 0; + + // Center Line + private Drawable centerDrawable; + + // Wheel drawables + private int wheelBackground = R.drawable.wheel_bg; + private int wheelForeground = R.drawable.wheel_val; + + // Shadows drawables + private GradientDrawable topShadow; + private GradientDrawable bottomShadow; + + // Draw Shadows + private boolean drawShadows = true; + + // Scrolling + private WheelScroller scroller; + private boolean isScrollingPerformed; + private int scrollingOffset; + + // Cyclic + boolean isCyclic = false; + + // Items layout + private LinearLayout itemsLayout; + + // The number of first item in layout + private int firstItem; + + // View adapter + private WheelViewAdapter viewAdapter; + + // Recycle + private WheelRecycle recycle = new WheelRecycle(this); + + // Listeners + private List changingListeners = new LinkedList(); + private List scrollingListeners = new LinkedList(); + private List clickingListeners = new LinkedList(); + + /** + * Constructor + */ + public WheelView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + initData(context); + } + + /** + * Constructor + */ + public WheelView(Context context, AttributeSet attrs) { + super(context, attrs); + initData(context); + } + + /** + * Constructor + */ + public WheelView(Context context) { + super(context); + initData(context); + } + + /** + * Initializes class data + * @param context the context + */ + private void initData(Context context) { + scroller = new WheelScroller(getContext(), scrollingListener); + } + + // Scrolling listener + WheelScroller.ScrollingListener scrollingListener = new WheelScroller.ScrollingListener() { + @Override + public void onStarted() { + isScrollingPerformed = true; + notifyScrollingListenersAboutStart(); + } + + @Override + public void onScroll(int distance) { + doScroll(distance); + + int height = getHeight(); + if (scrollingOffset > height) { + scrollingOffset = height; + scroller.stopScrolling(); + } else if (scrollingOffset < -height) { + scrollingOffset = -height; + scroller.stopScrolling(); + } + } + + @Override + public void onFinished() { + if (isScrollingPerformed) { + notifyScrollingListenersAboutEnd(); + isScrollingPerformed = false; + } + + scrollingOffset = 0; + invalidate(); + } + + @Override + public void onJustify() { + if (Math.abs(scrollingOffset) > WheelScroller.MIN_DELTA_FOR_SCROLLING) { + scroller.scroll(scrollingOffset, 0); + } + } + }; + + /** + * Set the the specified scrolling interpolator + * @param interpolator the interpolator + */ + public void setInterpolator(Interpolator interpolator) { + scroller.setInterpolator(interpolator); + } + + /** + * Gets count of visible items + * + * @return the count of visible items + */ + public int getVisibleItems() { + return visibleItems; + } + + /** + * Sets the desired count of visible items. + * Actual amount of visible items depends on wheel layout parameters. + * To apply changes and rebuild view call measure(). + * + * @param count the desired count for visible items + */ + public void setVisibleItems(int count) { + visibleItems = count; + } + + /** + * Gets view adapter + * @return the view adapter + */ + public WheelViewAdapter getViewAdapter() { + return viewAdapter; + } + + // Adapter listener + private DataSetObserver dataObserver = new DataSetObserver() { + @Override + public void onChanged() { + invalidateWheel(false); + } + + @Override + public void onInvalidated() { + invalidateWheel(true); + } + }; + + /** + * Sets view adapter. Usually new adapters contain different views, so + * it needs to rebuild view by calling measure(). + * + * @param viewAdapter the view adapter + */ + public void setViewAdapter(WheelViewAdapter viewAdapter) { + if (this.viewAdapter != null) { + this.viewAdapter.unregisterDataSetObserver(dataObserver); + } + this.viewAdapter = viewAdapter; + if (this.viewAdapter != null) { + this.viewAdapter.registerDataSetObserver(dataObserver); + } + + invalidateWheel(true); + } + + /** + * Adds wheel changing listener + * @param listener the listener + */ + public void addChangingListener(OnWheelChangedListener listener) { + changingListeners.add(listener); + } + + /** + * Removes wheel changing listener + * @param listener the listener + */ + public void removeChangingListener(OnWheelChangedListener listener) { + changingListeners.remove(listener); + } + + /** + * Notifies changing listeners + * @param oldValue the old wheel value + * @param newValue the new wheel value + */ + protected void notifyChangingListeners(int oldValue, int newValue) { + for (OnWheelChangedListener listener : changingListeners) { + listener.onChanged(this, oldValue, newValue); + } + } + + /** + * Adds wheel scrolling listener + * @param listener the listener + */ + public void addScrollingListener(OnWheelScrollListener listener) { + scrollingListeners.add(listener); + } + + /** + * Removes wheel scrolling listener + * @param listener the listener + */ + public void removeScrollingListener(OnWheelScrollListener listener) { + scrollingListeners.remove(listener); + } + + /** + * Notifies listeners about starting scrolling + */ + protected void notifyScrollingListenersAboutStart() { + for (OnWheelScrollListener listener : scrollingListeners) { + listener.onScrollingStarted(this); + } + } + + /** + * Notifies listeners about ending scrolling + */ + protected void notifyScrollingListenersAboutEnd() { + for (OnWheelScrollListener listener : scrollingListeners) { + listener.onScrollingFinished(this); + } + } + + /** + * Adds wheel clicking listener + * @param listener the listener + */ + public void addClickingListener(OnWheelClickedListener listener) { + clickingListeners.add(listener); + } + + /** + * Removes wheel clicking listener + * @param listener the listener + */ + public void removeClickingListener(OnWheelClickedListener listener) { + clickingListeners.remove(listener); + } + + /** + * Notifies listeners about clicking + */ + protected void notifyClickListenersAboutClick(int item) { + for (OnWheelClickedListener listener : clickingListeners) { + listener.onItemClicked(this, item); + } + } + + /** + * Gets current value + * + * @return the current value + */ + public int getCurrentItem() { + return currentItem; + } + + /** + * Sets the current item. Does nothing when index is wrong. + * + * @param index the item index + * @param animated the animation flag + */ + public void setCurrentItem(int index, boolean animated) { + if (viewAdapter == null || viewAdapter.getItemsCount() == 0) { + return; // throw? + } + + int itemCount = viewAdapter.getItemsCount(); + if (index < 0 || index >= itemCount) { + if (isCyclic) { + while (index < 0) { + index += itemCount; + } + index %= itemCount; + } else{ + return; // throw? + } + } + if (index != currentItem) { + if (animated) { + int itemsToScroll = index - currentItem; + if (isCyclic) { + int scroll = itemCount + Math.min(index, currentItem) - Math.max(index, currentItem); + if (scroll < Math.abs(itemsToScroll)) { + itemsToScroll = itemsToScroll < 0 ? scroll : -scroll; + } + } + scroll(itemsToScroll, 0); + } else { + scrollingOffset = 0; + + int old = currentItem; + currentItem = index; + + notifyChangingListeners(old, currentItem); + + invalidate(); + } + } + } + + /** + * Sets the current item w/o animation. Does nothing when index is wrong. + * + * @param index the item index + */ + public void setCurrentItem(int index) { + setCurrentItem(index, false); + } + + /** + * Tests if wheel is cyclic. That means before the 1st item there is shown the last one + * @return true if wheel is cyclic + */ + public boolean isCyclic() { + return isCyclic; + } + + /** + * Set wheel cyclic flag + * @param isCyclic the flag to set + */ + public void setCyclic(boolean isCyclic) { + this.isCyclic = isCyclic; + invalidateWheel(false); + } + + /** + * Determine whether shadows are drawn + * @return true is shadows are drawn + */ + public boolean drawShadows() { + return drawShadows; + } + + /** + * Set whether shadows should be drawn + * @param drawShadows flag as true or false + */ + public void setDrawShadows(boolean drawShadows) { + this.drawShadows = drawShadows; + } + + /** + * Set the shadow gradient color + * @param start + * @param middle + * @param end + */ + public void setShadowColor(int start, int middle, int end) { + SHADOWS_COLORS = new int[] {start, middle, end}; + } + + /** + * Sets the drawable for the wheel background + * @param resource + */ + public void setWheelBackground(int resource) { + wheelBackground = resource; + setBackgroundResource(wheelBackground); + } + + /** + * Sets the drawable for the wheel foreground + * @param resource + */ + public void setWheelForeground(int resource) { + wheelForeground = resource; + centerDrawable = getContext().getResources().getDrawable(wheelForeground); + } + + /** + * Invalidates wheel + * @param clearCaches if true then cached views will be clear + */ + public void invalidateWheel(boolean clearCaches) { + if (clearCaches) { + recycle.clearAll(); + if (itemsLayout != null) { + itemsLayout.removeAllViews(); + } + scrollingOffset = 0; + } else if (itemsLayout != null) { + // cache all items + recycle.recycleItems(itemsLayout, firstItem, new ItemsRange()); + } + + invalidate(); + } + + /** + * Initializes resources + */ + private void initResourcesIfNecessary() { + if (centerDrawable == null) { + centerDrawable = getContext().getResources().getDrawable(wheelForeground); + } + + if (topShadow == null) { + topShadow = new GradientDrawable(Orientation.TOP_BOTTOM, SHADOWS_COLORS); + } + + if (bottomShadow == null) { + bottomShadow = new GradientDrawable(Orientation.BOTTOM_TOP, SHADOWS_COLORS); + } + + setBackgroundResource(wheelBackground); + } + + /** + * Calculates desired height for layout + * + * @param layout + * the source layout + * @return the desired layout height + */ + private int getDesiredHeight(LinearLayout layout) { + if (layout != null && layout.getChildAt(0) != null) { + itemHeight = layout.getChildAt(0).getMeasuredHeight(); + } + + int desired = itemHeight * visibleItems - itemHeight * ITEM_OFFSET_PERCENT / 50; + + return Math.max(desired, getSuggestedMinimumHeight()); + } + + /** + * Returns height of wheel item + * @return the item height + */ + private int getItemHeight() { + if (itemHeight != 0) { + return itemHeight; + } + + if (itemsLayout != null && itemsLayout.getChildAt(0) != null) { + itemHeight = itemsLayout.getChildAt(0).getHeight(); + return itemHeight; + } + + return getHeight() / visibleItems; + } + + /** + * Calculates control width and creates text layouts + * @param widthSize the input layout width + * @param mode the layout mode + * @return the calculated control width + */ + private int calculateLayoutWidth(int widthSize, int mode) { + initResourcesIfNecessary(); + + // TODO: make it static + itemsLayout.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); + itemsLayout.measure(MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.UNSPECIFIED), + MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); + int width = itemsLayout.getMeasuredWidth(); + + if (mode == MeasureSpec.EXACTLY) { + width = widthSize; + } else { + width += 2 * PADDING; + + // Check against our minimum width + width = Math.max(width, getSuggestedMinimumWidth()); + + if (mode == MeasureSpec.AT_MOST && widthSize < width) { + width = widthSize; + } + } + + itemsLayout.measure(MeasureSpec.makeMeasureSpec(width - 2 * PADDING, MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); + + return width; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int widthMode = MeasureSpec.getMode(widthMeasureSpec); + int heightMode = MeasureSpec.getMode(heightMeasureSpec); + int widthSize = MeasureSpec.getSize(widthMeasureSpec); + int heightSize = MeasureSpec.getSize(heightMeasureSpec); + + buildViewForMeasuring(); + + int width = calculateLayoutWidth(widthSize, widthMode); + + int height; + if (heightMode == MeasureSpec.EXACTLY) { + height = heightSize; + } else { + height = getDesiredHeight(itemsLayout); + + if (heightMode == MeasureSpec.AT_MOST) { + height = Math.min(height, heightSize); + } + } + + setMeasuredDimension(width, height); + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + layout(r - l, b - t); + } + + /** + * Sets layouts width and height + * @param width the layout width + * @param height the layout height + */ + private void layout(int width, int height) { + int itemsWidth = width - 2 * PADDING; + + itemsLayout.layout(0, 0, itemsWidth, height); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + if (viewAdapter != null && viewAdapter.getItemsCount() > 0) { + updateView(); + + drawItems(canvas); + drawCenterRect(canvas); + } + + if (drawShadows) drawShadows(canvas); + } + + /** + * Draws shadows on top and bottom of control + * @param canvas the canvas for drawing + */ + private void drawShadows(Canvas canvas) { + int height = (int)(1.5 * getItemHeight()); + topShadow.setBounds(0, 0, getWidth(), height); + topShadow.draw(canvas); + + bottomShadow.setBounds(0, getHeight() - height, getWidth(), getHeight()); + bottomShadow.draw(canvas); + } + + /** + * Draws items + * @param canvas the canvas for drawing + */ + private void drawItems(Canvas canvas) { + canvas.save(); + + int top = (currentItem - firstItem) * getItemHeight() + (getItemHeight() - getHeight()) / 2; + canvas.translate(PADDING, - top + scrollingOffset); + + itemsLayout.draw(canvas); + + canvas.restore(); + } + + /** + * Draws rect for current value + * @param canvas the canvas for drawing + */ + private void drawCenterRect(Canvas canvas) { + int center = getHeight() / 2; + int offset = (int) (getItemHeight() / 2 * 1.2); + centerDrawable.setBounds(0, center - offset, getWidth(), center + offset); + centerDrawable.draw(canvas); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (!isEnabled() || getViewAdapter() == null) { + return true; + } + + switch (event.getAction()) { + case MotionEvent.ACTION_MOVE: + if (getParent() != null) { + getParent().requestDisallowInterceptTouchEvent(true); + } + break; + + case MotionEvent.ACTION_UP: + if (!isScrollingPerformed) { + int distance = (int) event.getY() - getHeight() / 2; + if (distance > 0) { + distance += getItemHeight() / 2; + } else { + distance -= getItemHeight() / 2; + } + int items = distance / getItemHeight(); + if (items != 0 && isValidItemIndex(currentItem + items)) { + notifyClickListenersAboutClick(currentItem + items); + } + } + break; + } + + return scroller.onTouchEvent(event); + } + + /** + * Scrolls the wheel + * @param delta the scrolling value + */ + private void doScroll(int delta) { + scrollingOffset += delta; + + int itemHeight = getItemHeight(); + int count = scrollingOffset / itemHeight; + + int pos = currentItem - count; + int itemCount = viewAdapter.getItemsCount(); + + int fixPos = scrollingOffset % itemHeight; + if (Math.abs(fixPos) <= itemHeight / 2) { + fixPos = 0; + } + if (isCyclic && itemCount > 0) { + if (fixPos > 0) { + pos--; + count++; + } else if (fixPos < 0) { + pos++; + count--; + } + // fix position by rotating + while (pos < 0) { + pos += itemCount; + } + pos %= itemCount; + } else { + // + if (pos < 0) { + count = currentItem; + pos = 0; + } else if (pos >= itemCount) { + count = currentItem - itemCount + 1; + pos = itemCount - 1; + } else if (pos > 0 && fixPos > 0) { + pos--; + count++; + } else if (pos < itemCount - 1 && fixPos < 0) { + pos++; + count--; + } + } + + int offset = scrollingOffset; + if (pos != currentItem) { + setCurrentItem(pos, false); + } else { + invalidate(); + } + + // update offset + scrollingOffset = offset - count * itemHeight; + if (scrollingOffset > getHeight()) { + if(getHeight() <= 0){ + scrollingOffset = 0; + }else { + scrollingOffset = scrollingOffset % getHeight() + getHeight(); + } + } + } + + /** + * Scroll the wheel + * @param itemsToSkip items to scroll + * @param time scrolling duration + */ + public void scroll(int itemsToScroll, int time) { + int distance = itemsToScroll * getItemHeight() - scrollingOffset; + scroller.scroll(distance, time); + } + + /** + * Calculates range for wheel items + * @return the items range + */ + private ItemsRange getItemsRange() { + if (getItemHeight() == 0) { + return null; + } + + int first = currentItem; + int count = 1; + + while (count * getItemHeight() < getHeight()) { + first--; + count += 2; // top + bottom items + } + + if (scrollingOffset != 0) { + if (scrollingOffset > 0) { + first--; + } + count++; + + // process empty items above the first or below the second + int emptyItems = scrollingOffset / getItemHeight(); + first -= emptyItems; + count += Math.asin(emptyItems); + } + return new ItemsRange(first, count); + } + + /** + * Rebuilds wheel items if necessary. Caches all unused items. + * + * @return true if items are rebuilt + */ + private boolean rebuildItems() { + boolean updated = false; + ItemsRange range = getItemsRange(); + if (itemsLayout != null) { + int first = recycle.recycleItems(itemsLayout, firstItem, range); + updated = firstItem != first; + firstItem = first; + } else { + createItemsLayout(); + updated = true; + } + + if (!updated) { + updated = firstItem != range.getFirst() || itemsLayout.getChildCount() != range.getCount(); + } + + if (firstItem > range.getFirst() && firstItem <= range.getLast()) { + for (int i = firstItem - 1; i >= range.getFirst(); i--) { + if (!addViewItem(i, true)) { + break; + } + firstItem = i; + } + } else { + firstItem = range.getFirst(); + } + + int first = firstItem; + for (int i = itemsLayout.getChildCount(); i < range.getCount(); i++) { + if (!addViewItem(firstItem + i, false) && itemsLayout.getChildCount() == 0) { + first++; + } + } + firstItem = first; + + return updated; + } + + /** + * Updates view. Rebuilds items and label if necessary, recalculate items sizes. + */ + private void updateView() { + if (rebuildItems()) { + calculateLayoutWidth(getWidth(), MeasureSpec.EXACTLY); + layout(getWidth(), getHeight()); + } + } + + /** + * Creates item layouts if necessary + */ + private void createItemsLayout() { + if (itemsLayout == null) { + itemsLayout = new LinearLayout(getContext()); + itemsLayout.setOrientation(LinearLayout.VERTICAL); + } + } + + /** + * Builds view for measuring + */ + private void buildViewForMeasuring() { + // clear all items + if (itemsLayout != null) { + recycle.recycleItems(itemsLayout, firstItem, new ItemsRange()); + } else { + createItemsLayout(); + } + + // add views + // all items must be included to measure width correctly + for (int i = viewAdapter.getItemsCount()-1; i >= 0; i--){ + if (addViewItem(i, true)) { + firstItem = i; + } + } + } + + /** + * Adds view for item to items layout + * @param index the item index + * @param first the flag indicates if view should be first + * @return true if corresponding item exists and is added + */ + private boolean addViewItem(int index, boolean first) { + View view = getItemView(index); + if (view != null) { + if (first) { + itemsLayout.addView(view, 0); + } else { + itemsLayout.addView(view); + } + + return true; + } + + return false; + } + + /** + * Checks whether intem index is valid + * @param index the item index + * @return true if item index is not out of bounds or the wheel is cyclic + */ + private boolean isValidItemIndex(int index) { + return viewAdapter != null && viewAdapter.getItemsCount() > 0 && + (isCyclic || index >= 0 && index < viewAdapter.getItemsCount()); + } + + /** + * Returns view for specified item + * @param index the item index + * @return item view or empty view if index is out of bounds + */ + private View getItemView(int index) { + if (viewAdapter == null || viewAdapter.getItemsCount() == 0) { + return null; + } + int count = viewAdapter.getItemsCount(); + if (!isValidItemIndex(index)) { + return viewAdapter.getEmptyItem(recycle.getEmptyItem(), itemsLayout); + } else { + while (index < 0) { + index = count + index; + } + } + + index %= count; + return viewAdapter.getItem(index, recycle.getItem(), itemsLayout); + } + + /** + * Stops scrolling + */ + public void stopScrolling() { + scroller.stopScrolling(); + } +} diff --git a/wheel/src/kankan/wheel/widget/adapters/AbstractWheelAdapter.java b/wheel/wheel/src/main/java/kankan/wheel/widget/adapters/AbstractWheelAdapter.java similarity index 100% rename from wheel/src/kankan/wheel/widget/adapters/AbstractWheelAdapter.java rename to wheel/wheel/src/main/java/kankan/wheel/widget/adapters/AbstractWheelAdapter.java index aa30f3e..600650b 100644 --- a/wheel/src/kankan/wheel/widget/adapters/AbstractWheelAdapter.java +++ b/wheel/wheel/src/main/java/kankan/wheel/widget/adapters/AbstractWheelAdapter.java @@ -16,13 +16,13 @@ package kankan.wheel.widget.adapters; -import java.util.LinkedList; -import java.util.List; - import android.database.DataSetObserver; import android.view.View; import android.view.ViewGroup; +import java.util.LinkedList; +import java.util.List; + /** * Abstract Wheel adapter. */ diff --git a/wheel/src/kankan/wheel/widget/adapters/AbstractWheelTextAdapter.java b/wheel/wheel/src/main/java/kankan/wheel/widget/adapters/AbstractWheelTextAdapter.java similarity index 100% rename from wheel/src/kankan/wheel/widget/adapters/AbstractWheelTextAdapter.java rename to wheel/wheel/src/main/java/kankan/wheel/widget/adapters/AbstractWheelTextAdapter.java diff --git a/wheel/src/kankan/wheel/widget/adapters/AdapterWheel.java b/wheel/wheel/src/main/java/kankan/wheel/widget/adapters/AdapterWheel.java similarity index 99% rename from wheel/src/kankan/wheel/widget/adapters/AdapterWheel.java rename to wheel/wheel/src/main/java/kankan/wheel/widget/adapters/AdapterWheel.java index ed5f275..3c80755 100644 --- a/wheel/src/kankan/wheel/widget/adapters/AdapterWheel.java +++ b/wheel/wheel/src/main/java/kankan/wheel/widget/adapters/AdapterWheel.java @@ -16,9 +16,10 @@ package kankan.wheel.widget.adapters; -import kankan.wheel.widget.WheelAdapter; import android.content.Context; +import kankan.wheel.widget.WheelAdapter; + /** * Adapter class for old wheel adapter (deprecated WheelAdapter class). * diff --git a/wheel/src/kankan/wheel/widget/adapters/ArrayWheelAdapter.java b/wheel/wheel/src/main/java/kankan/wheel/widget/adapters/ArrayWheelAdapter.java similarity index 100% rename from wheel/src/kankan/wheel/widget/adapters/ArrayWheelAdapter.java rename to wheel/wheel/src/main/java/kankan/wheel/widget/adapters/ArrayWheelAdapter.java diff --git a/wheel/src/kankan/wheel/widget/adapters/NumericWheelAdapter.java b/wheel/wheel/src/main/java/kankan/wheel/widget/adapters/NumericWheelAdapter.java similarity index 100% rename from wheel/src/kankan/wheel/widget/adapters/NumericWheelAdapter.java rename to wheel/wheel/src/main/java/kankan/wheel/widget/adapters/NumericWheelAdapter.java diff --git a/wheel/src/kankan/wheel/widget/adapters/WheelViewAdapter.java b/wheel/wheel/src/main/java/kankan/wheel/widget/adapters/WheelViewAdapter.java similarity index 97% rename from wheel/src/kankan/wheel/widget/adapters/WheelViewAdapter.java rename to wheel/wheel/src/main/java/kankan/wheel/widget/adapters/WheelViewAdapter.java index 6d9f7b3..88adb46 100644 --- a/wheel/src/kankan/wheel/widget/adapters/WheelViewAdapter.java +++ b/wheel/wheel/src/main/java/kankan/wheel/widget/adapters/WheelViewAdapter.java @@ -60,5 +60,5 @@ public interface WheelViewAdapter { * Unregister an observer that has previously been registered * @param observer the observer to be unregistered */ - void unregisterDataSetObserver (DataSetObserver observer); + void unregisterDataSetObserver(DataSetObserver observer); } diff --git a/wheel/res/drawable/wheel_bg.xml b/wheel/wheel/src/main/res/drawable/wheel_bg.xml similarity index 97% rename from wheel/res/drawable/wheel_bg.xml rename to wheel/wheel/src/main/res/drawable/wheel_bg.xml index c7956b4..5ecd6ad 100644 --- a/wheel/res/drawable/wheel_bg.xml +++ b/wheel/wheel/src/main/res/drawable/wheel_bg.xml @@ -1,42 +1,42 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/wheel/res/drawable/wheel_val.xml b/wheel/wheel/src/main/res/drawable/wheel_val.xml similarity index 97% rename from wheel/res/drawable/wheel_val.xml rename to wheel/wheel/src/main/res/drawable/wheel_val.xml index c284bfa..8e7538d 100644 --- a/wheel/res/drawable/wheel_val.xml +++ b/wheel/wheel/src/main/res/drawable/wheel_val.xml @@ -1,29 +1,29 @@ - - - - - - - - - + + + + + + + + + diff --git a/wheel/wheel/src/main/res/values/strings.xml b/wheel/wheel/src/main/res/values/strings.xml new file mode 100644 index 0000000..bf74f80 --- /dev/null +++ b/wheel/wheel/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + Android Wheel Widget + diff --git a/wheel/wheel/src/test/java/kankan/wheel/widget/ExampleUnitTest.java b/wheel/wheel/src/test/java/kankan/wheel/widget/ExampleUnitTest.java new file mode 100644 index 0000000..83fb235 --- /dev/null +++ b/wheel/wheel/src/test/java/kankan/wheel/widget/ExampleUnitTest.java @@ -0,0 +1,15 @@ +package kankan.wheel.widget; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * To work on unit tests, switch the Test Artifact in the Build Variants view. + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() throws Exception { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file