├── app ├── .gitignore ├── src │ └── main │ │ ├── res │ │ ├── values │ │ │ ├── strings.xml │ │ │ ├── colors.xml │ │ │ ├── dimens.xml │ │ │ └── styles.xml │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ │ └── dimens.xml │ │ └── layout │ │ │ └── activity_main.xml │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── jhonnyx │ │ └── horizontalpickerexample │ │ └── MainActivity.java ├── build.gradle └── proguard-rules.pro ├── settings.gradle ├── appDemoDebug.apk ├── Screenshot_custom.png ├── Screenshot_palette.png ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── horizontal-picker ├── .gitignore ├── src │ └── main │ │ ├── res │ │ ├── values │ │ │ ├── strings.xml │ │ │ └── colors.xml │ │ ├── drawable │ │ │ ├── background_day_hover.xml │ │ │ ├── background_day_selected.xml │ │ │ └── background_day_today.xml │ │ └── layout │ │ │ ├── item_day.xml │ │ │ └── horizontal_picker.xml │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── github │ │ └── jhonnyx2012 │ │ └── horizontalpicker │ │ ├── DatePickerListener.java │ │ ├── OnItemClickedListener.java │ │ ├── HorizontalPickerListener.java │ │ ├── Day.java │ │ ├── HorizontalPickerAdapter.java │ │ ├── HorizontalPickerRecyclerView.java │ │ └── HorizontalPicker.java ├── proguard-rules.pro ├── build.gradle ├── public_key_sender.asc └── private_key_sender.asc ├── .gitignore ├── gradle.properties ├── gradlew.bat ├── README.md └── gradlew /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':horizontal-picker' 2 | -------------------------------------------------------------------------------- /appDemoDebug.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhonnyx2012/HorizontalPicker/HEAD/appDemoDebug.apk -------------------------------------------------------------------------------- /Screenshot_custom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhonnyx2012/HorizontalPicker/HEAD/Screenshot_custom.png -------------------------------------------------------------------------------- /Screenshot_palette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhonnyx2012/HorizontalPicker/HEAD/Screenshot_palette.png -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | HorizontalPickerExample 3 | 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhonnyx2012/HorizontalPicker/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /horizontal-picker/.gitignore: -------------------------------------------------------------------------------- 1 | /build/docs 2 | /build/generated 3 | /build/intermediates 4 | /build/libs 5 | /build/outputs 6 | /build/tmp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhonnyx2012/HorizontalPicker/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhonnyx2012/HorizontalPicker/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhonnyx2012/HorizontalPicker/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhonnyx2012/HorizontalPicker/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhonnyx2012/HorizontalPicker/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /horizontal-picker/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Horizontal Picker 3 | Today 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #37474f 4 | #2b3a41 5 | #e19a00 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /horizontal-picker/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Mar 07 09:02:42 BOT 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip 7 | -------------------------------------------------------------------------------- /horizontal-picker/src/main/java/com/github/jhonnyx2012/horizontalpicker/DatePickerListener.java: -------------------------------------------------------------------------------- 1 | package com.github.jhonnyx2012.horizontalpicker; 2 | 3 | import org.joda.time.DateTime; 4 | 5 | /** 6 | * Created by jhonn on 02/03/2017. 7 | */ 8 | public interface DatePickerListener { 9 | void onDateSelected(DateTime dateSelected); 10 | } -------------------------------------------------------------------------------- /horizontal-picker/src/main/java/com/github/jhonnyx2012/horizontalpicker/OnItemClickedListener.java: -------------------------------------------------------------------------------- 1 | package com.github.jhonnyx2012.horizontalpicker; 2 | 3 | import android.view.View; 4 | 5 | /** 6 | * Created by jhonn on 02/03/2017. 7 | */ 8 | public interface OnItemClickedListener { 9 | void onClickView(View v, int adapterPosition); 10 | } -------------------------------------------------------------------------------- /horizontal-picker/src/main/java/com/github/jhonnyx2012/horizontalpicker/HorizontalPickerListener.java: -------------------------------------------------------------------------------- 1 | package com.github.jhonnyx2012.horizontalpicker; 2 | 3 | /** 4 | * Created by jhonn on 02/03/2017. 5 | */ 6 | public interface HorizontalPickerListener { 7 | void onStopDraggingPicker(); 8 | void onDraggingPicker(); 9 | void onDateSelected(Day item); 10 | } -------------------------------------------------------------------------------- /horizontal-picker/src/main/res/drawable/background_day_hover.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /horizontal-picker/src/main/res/drawable/background_day_selected.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /horizontal-picker/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #e4e4e4 4 | #85f7f7f7 5 | #37474f 6 | #757575 7 | #4d4d4d 8 | #30818181 9 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /horizontal-picker/src/main/res/drawable/background_day_today.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "25.0.2" 6 | defaultConfig { 7 | applicationId "com.jhonnyx.horizontalpickerexample" 8 | minSdkVersion 16 9 | targetSdkVersion 25 10 | versionCode 1 11 | versionName "1.0" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | compile project(':horizontal-picker') 23 | compile 'com.android.support:appcompat-v7:25.1.1' 24 | } 25 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Users\jhonn\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /horizontal-picker/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Users\jhonn\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /horizontal-picker/src/main/res/layout/item_day.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 21 | 22 | 37 | 38 | -------------------------------------------------------------------------------- /horizontal-picker/src/main/java/com/github/jhonnyx2012/horizontalpicker/Day.java: -------------------------------------------------------------------------------- 1 | package com.github.jhonnyx2012.horizontalpicker; 2 | 3 | import org.joda.time.DateTime; 4 | 5 | import java.text.SimpleDateFormat; 6 | import java.util.Date; 7 | import java.util.Locale; 8 | 9 | /** 10 | * Created by jhonn on 28/02/2017. 11 | */ 12 | public class Day { 13 | private DateTime date; 14 | private boolean selected; 15 | private String monthPattern = "MMMM YYYY"; 16 | 17 | public Day(DateTime date) { 18 | this.date = date; 19 | } 20 | 21 | public String getDay() { 22 | return String.valueOf(date.getDayOfMonth()); 23 | } 24 | 25 | public String getWeekDay() { 26 | return date.toString("EEE", Locale.getDefault()).toUpperCase(); 27 | } 28 | 29 | public String getMonth() { return getMonth(""); } 30 | 31 | public String getMonth(String pattern) { 32 | if (!pattern.isEmpty()) 33 | this.monthPattern = pattern; 34 | 35 | return date.toString(monthPattern, Locale.getDefault()); 36 | } 37 | 38 | public DateTime getDate() { 39 | return date.withTime(0,0,0,0); 40 | } 41 | 42 | public boolean isToday() { 43 | DateTime today=new DateTime().withTime(0,0,0,0); 44 | return getDate().getMillis()==today.getMillis(); 45 | } 46 | 47 | public void setSelected(boolean selected) { 48 | this.selected = selected; 49 | } 50 | 51 | public boolean isSelected() { 52 | return selected; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /horizontal-picker/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | ext { 4 | bintrayRepo = 'HorizontalPicker' 5 | bintrayName = 'HorizontalPicker' 6 | 7 | publishedGroupId = 'com.github.jhonnyx2012' 8 | libraryName = 'HorizontalPicker' 9 | artifact = 'horizontal-picker' 10 | 11 | libraryDescription = 'Horizontal datepicker with smooth selection by day' 12 | 13 | siteUrl = 'https://github.com/jhonnyx2012/HorizontalPicker' 14 | gitUrl = 'https://github.com/jhonnyx2012/HorizontalPicker.git' 15 | 16 | libraryVersion = '1.0.6' 17 | 18 | developerId = 'jhonnyx2012' 19 | developerName = 'Jhonny Barrios' 20 | developerEmail = 'jhonnyx2012@gmail.com' 21 | 22 | licenseName = 'The Apache Software License, Version 2.0' 23 | licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt' 24 | allLicenses = ["Apache-2.0"] 25 | } 26 | 27 | android { 28 | compileSdkVersion 25 29 | buildToolsVersion "25.0.2" 30 | 31 | defaultConfig { 32 | minSdkVersion 16 33 | targetSdkVersion 25 34 | versionCode 1 35 | versionName "1.0.6" 36 | } 37 | buildTypes { 38 | release { 39 | minifyEnabled false 40 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 41 | } 42 | } 43 | } 44 | 45 | dependencies { 46 | compile 'com.android.support:recyclerview-v7:25.1.1' 47 | compile 'joda-time:joda-time:2.9.7' 48 | } 49 | 50 | apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle' 51 | apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle' -------------------------------------------------------------------------------- /horizontal-picker/public_key_sender.asc: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP PUBLIC KEY BLOCK----- 2 | Version: GnuPG v2 3 | 4 | mQENBFi/HdEBCADmP0mqYYJWLXdjkKAgeQVyyQHUqWLabItXH2Zml9Sw3ApEGNJK 5 | JRvvnSoJRtN1q+2pASoCU+h9iLklJhZSYJmZ04bmHqJq4ZBrb4M/IxllGotwZLiY 6 | Tb8xC8hLbrwHsgMnxi0xrpmN6e5Jp0t1kDD10148y3ztYCzJviRvSFsfacbgAokQ 7 | JKnWY1KSoLz6zSFtWWt+IdbBe/3/+1HKeMc+l0gU/7615ZrFc8QzSqXH6IJTuosI 8 | 6veZucAbWhWm4wbJibWAY5lw1XDgIR4rpkrlDR8zjeF+CVeSdc7Nz52ghcl39ZET 9 | 2nMZcHREo4bBCf5sP/Xh67iBnFQcqB6twYpvABEBAAG0LUpob25ueSBCYXJyaW9z 10 | IChuYWRhKSA8amhvbm55eDIwMTJAZ21haWwuY29tPokBOQQTAQgAIwUCWL8d0QIb 11 | AwcLCQgHAwIBBhUIAgkKCwQWAgMBAh4BAheAAAoJEB0sfxSmlJ/RBuUH/3DAaVeE 12 | 6vZX8sOqZea+lDz/Gi9YMy+HK+tG7HBW/jqJg2gFSHKw2Ww0qdAyyzJq5gULqxUY 13 | 3k1ibvVAOtuWhKAdCw8FaCzybPcglxrUU69pgwZnqZpmK/w5LboeZaaXZlhIqKIP 14 | eHwOfM0R82SDV1otNRPxbw0PAnpNDbM1iQFJAw8UWCeQqwH+rsELaQEgzvKnKqmH 15 | nCV1U8oTwNG/syju44EARZa02J7XXjzwPFvICnxIva029DIhL1w+BCvkLhHRU5kR 16 | 55Q/OOvVqrFaEkrByECBzWv47gxaHsx9kW+sR3qZbQffvquUDT/ecCHu7cH6lhBW 17 | hsyU9swg9vb6fQK5AQ0EWL8d0QEIALJa/hjqeBCxiex2g/fZ/yXODCnaI55uDA17 18 | qulmB8f8LO4RVIGd0fv3ckjD56f0QbiLf9KN0JF0yb/G3h9xlqL2NTELMbFgBvwj 19 | VjKjE6l1Fd5qxM3DtuTiTED4TMVsEUquL64K5YSkAMYK1HJ4nK1cVqNxrRNiLGjn 20 | l1rvHRBUiBSOofCcWaLXHELURHKWtgjB70FhAbxv0SHIxve8pFot+LIH0loIiLSz 21 | 7ivfdERbva/l94gkx5PpxGwHADpKqHL++rGcMErZsG0Dt3sdr1EYjyKN+c0dsCCY 22 | HGUSQPEeUPoemA0o5plna5U2nB7YvA2sG4vxO2qetRNWe7Moc5sAEQEAAYkBHwQY 23 | AQgACQUCWL8d0QIbDAAKCRAdLH8UppSf0QqvCADfgX7b3BprKP8EnhzI/fmGsh0W 24 | C4vW3KN1eZ8/p2sXWF/QrNFDE5DbkvIzOauxcCOHQCzCHFjTZKGieitWWaZARq8n 25 | 52WGkNsB9E1rXeWtfRnkvfBGleT/MthLm3pdyvxoHBgI4vnP9bIKOlmO+0k+A9e/ 26 | N/ILWSdvrVzoX4KXcE3lxP1jK4fKzQs3MGNoRj9cw8bMQmvbh3jYW0kRWyu4qs5W 27 | pFZrjd+gMe3sJWXzwcuEMJkpfcidjrHG3kjp4uF+qyXDDaxTDrHD3+OPtHg7iZOI 28 | LXQ8wFfffiv0wsPIRIjmduGLm160YRrkcF3opINzxjRWqfPsqEtJVDfdmMo4 29 | =agHB 30 | -----END PGP PUBLIC KEY BLOCK----- 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/jhonnyx/horizontalpickerexample/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.jhonnyx.horizontalpickerexample; 2 | 3 | import android.graphics.Color; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.util.Log; 7 | import com.github.jhonnyx2012.horizontalpicker.DatePickerListener; 8 | import com.github.jhonnyx2012.horizontalpicker.HorizontalPicker; 9 | 10 | import org.joda.time.DateTime; 11 | 12 | public class MainActivity extends AppCompatActivity implements DatePickerListener { 13 | 14 | @Override 15 | protected void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | setContentView(R.layout.activity_main); 18 | HorizontalPicker picker= (HorizontalPicker) findViewById(R.id.datePicker); 19 | picker.setListener(this) 20 | .setDays(120) 21 | .setOffset(7) 22 | .setDateSelectedColor(Color.DKGRAY) 23 | .setDateSelectedTextColor(Color.WHITE) 24 | .setMonthAndYearTextColor(Color.DKGRAY) 25 | .setTodayButtonTextColor(getResources().getColor(R.color.colorPrimary)) 26 | .setTodayDateTextColor(getResources().getColor(R.color.colorPrimary)) 27 | .setTodayDateBackgroundColor(Color.GRAY) 28 | .setUnselectedDayTextColor(Color.DKGRAY) 29 | .setDayOfWeekTextColor(Color.DKGRAY ) 30 | .setUnselectedDayTextColor(getResources().getColor(R.color.primaryTextColor)) 31 | .showTodayButton(false) 32 | .init(); 33 | picker.setBackgroundColor(Color.LTGRAY); 34 | picker.setDate(new DateTime()); 35 | } 36 | 37 | @Override 38 | public void onDateSelected(DateTime dateSelected) { 39 | Log.i("HorizontalPicker","Fecha seleccionada="+dateSelected.toString()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /horizontal-picker/src/main/res/layout/horizontal_picker.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 12 | 25 | 32 | 33 | 34 | 37 | 38 | 42 | 43 | 48 | 49 | 53 | 60 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /horizontal-picker/private_key_sender.asc: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP PRIVATE KEY BLOCK----- 2 | Version: GnuPG v2 3 | 4 | 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 58 | =trXM 59 | -----END PGP PRIVATE KEY BLOCK----- 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Horizontal Picker 2 | ================= 3 | 4 | What is this? 5 | ------------- 6 | HorizontalPicker is a custom-build Android View used for choosing dates (similar to the native date picker) but draws horizontally into a vertically narrow container. It allows easy day picking using the horizontal pan gesture. 7 | 8 | Too see it in action, [download the demo app](https://github.com/jhonnyx2012/HorizontalPicker/blob/master/appDemoDebug.apk?raw=true) to try it out. 9 | 10 | This is what it looks like. 11 | 12 | ![Screenshot_1](https://raw.githubusercontent.com/jhonnyx2012/HorizontalPicker/master/Screenshot_custom.png) 13 | ![Screenshot_2](https://raw.githubusercontent.com/jhonnyx2012/HorizontalPicker/master/Screenshot_palette.png) 14 | 15 | Features 16 | -------- 17 | 18 | * Date selection using a smooth swipe gesture 19 | * Date selection by clicking on a day slot 20 | * Date selection from code using the HorizontalPicker java object 21 | * Month and year view 22 | * _Today_ button to jump to the current day 23 | * Localized day and month names 24 | * Configurable number of generated days (default: 120) 25 | * Configurable number of offset generated days before the current date (default: 7) 26 | * Customizable set of colors, or themed through the app theming engine 27 | 28 | **Note**: This library uses the [JodaTime](https://github.com/JodaOrg/joda-time) library to work with days. 29 | 30 | Requirements 31 | ------------ 32 | - Android 4.1 or later (Minimum SDK level 16) 33 | - Android Studio (to compile and use) 34 | - **Eclipse is not supported** 35 | 36 | Getting Started 37 | --------------- 38 | 39 | In your app module's Gradle config file, add the following dependency: 40 | ```groovy 41 | dependencies { 42 | compile 'com.github.jhonnyx2012:horizontal-picker:1.0.6' 43 | } 44 | ``` 45 | 46 | Then to include it into your layout, add the following: 47 | ```xml 48 | 52 | ``` 53 | 54 | In your activity, you need to initialize it and set a listener, like this: 55 | ```java 56 | public class MainActivity extends AppCompatActivity implements DatePickerListener { 57 | @Override 58 | protected void onCreate(@Nullable final Bundle savedInstanceState) { 59 | // setup activity 60 | super.onCreate(savedInstanceState); 61 | setContentView(R.layout.activity_main); 62 | 63 | // find the picker 64 | HorizontalPicker picker = (HorizontalPicker) findViewById(R.id.datePicker); 65 | 66 | // initialize it and attach a listener 67 | picker 68 | .setListener(this) 69 | .init(); 70 | } 71 | 72 | @Override 73 | public void onDateSelected(@NonNull final DateTime dateSelected) { 74 | // log it for demo 75 | Log.i("HorizontalPicker", "Selected date is " + dateSelected.toString()); 76 | } 77 | } 78 | ``` 79 | 80 | Finally, you can also configure the number of days to show, the date offset, or set a date directly to the picker. For all options, see the full configuration below. 81 | 82 | 83 | ```java 84 | // at init time 85 | picker 86 | .setListener(listner) 87 | .setDays(20) 88 | .setOffset(10) 89 | .setDateSelectedColor(Color.DKGRAY) 90 | .setDateSelectedTextColor(Color.WHITE) 91 | .setMonthAndYearTextColor(Color.DKGRAY) 92 | .setTodayButtonTextColor(getColor(R.color.colorPrimary)) 93 | .setTodayDateTextColor(getColor(R.color.colorPrimary)) 94 | .setTodayDateBackgroundColor(Color.GRAY) 95 | .setUnselectedDayTextColor(Color.DKGRAY) 96 | .setDayOfWeekTextColor(Color.DKGRAY) 97 | .setUnselectedDayTextColor(getColor(R.color.textColor)) 98 | .showTodayButton(false) 99 | .init(); 100 | 101 | // or on the View directly after init was completed 102 | picker.setBackgroundColor(Color.LTGRAY); 103 | picker.setDate(new DateTime().plusDays(4)); 104 | ``` 105 | 106 | ```text 107 | Copyright 2017 Jhonny Barrios 108 | 109 | Licensed under the Apache License, Version 2.0 (the "License"); 110 | you may not use this file except in compliance with the License. 111 | You may obtain a copy of the License at 112 | 113 | http://www.apache.org/licenses/LICENSE-2.0 114 | 115 | 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. 116 | ``` 117 | -------------------------------------------------------------------------------- /horizontal-picker/src/main/java/com/github/jhonnyx2012/horizontalpicker/HorizontalPickerAdapter.java: -------------------------------------------------------------------------------- 1 | package com.github.jhonnyx2012.horizontalpicker; 2 | 3 | 4 | import android.app.AlarmManager; 5 | import android.content.Context; 6 | import android.graphics.Color; 7 | import android.graphics.drawable.Drawable; 8 | import android.support.v4.graphics.drawable.DrawableCompat; 9 | import android.support.v7.widget.RecyclerView; 10 | import android.util.Log; 11 | import android.view.LayoutInflater; 12 | import android.view.View; 13 | import android.view.ViewGroup; 14 | import android.widget.TextView; 15 | 16 | import org.joda.time.DateTime; 17 | 18 | import java.util.ArrayList; 19 | import java.util.Date; 20 | 21 | /** 22 | * Created by jhonn on 22/02/2017. 23 | */ 24 | 25 | public class HorizontalPickerAdapter extends RecyclerView.Adapter { 26 | 27 | private static final long DAY_MILLIS = AlarmManager.INTERVAL_DAY; 28 | private final int mBackgroundColor; 29 | private final int mDateSelectedTextColor; 30 | private final int mDateSelectedColor; 31 | private final int mTodayDateTextColor; 32 | private final int mTodayDateBackgroundColor; 33 | private final int mDayOfWeekTextColor; 34 | private final int mUnselectedDayTextColor; 35 | private int itemWidth; 36 | private final OnItemClickedListener listener; 37 | private ArrayList items; 38 | 39 | public HorizontalPickerAdapter(int itemWidth, OnItemClickedListener listener, Context context, int daysToCreate, int offset, int mBackgroundColor, int mDateSelectedColor, int mDateSelectedTextColor, int mTodayDateTextColor, int mTodayDateBackgroundColor, int mDayOfWeekTextColor, int mUnselectedDayTextColor) { 40 | items=new ArrayList<>(); 41 | this.itemWidth=itemWidth; 42 | this.listener=listener; 43 | generateDays(daysToCreate,new DateTime().minusDays(offset).getMillis(),false); 44 | this.mBackgroundColor=mBackgroundColor; 45 | this.mDateSelectedTextColor=mDateSelectedTextColor; 46 | this.mDateSelectedColor=mDateSelectedColor; 47 | this.mTodayDateTextColor=mTodayDateTextColor; 48 | this.mTodayDateBackgroundColor=mTodayDateBackgroundColor; 49 | this.mDayOfWeekTextColor=mDayOfWeekTextColor; 50 | this.mUnselectedDayTextColor=mUnselectedDayTextColor; 51 | } 52 | 53 | public void generateDays(int n, long initialDate, boolean cleanArray) { 54 | if(cleanArray) 55 | items.clear(); 56 | int i=0; 57 | while(i \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /horizontal-picker/src/main/java/com/github/jhonnyx2012/horizontalpicker/HorizontalPickerRecyclerView.java: -------------------------------------------------------------------------------- 1 | package com.github.jhonnyx2012.horizontalpicker; 2 | 3 | import android.app.AlarmManager; 4 | import android.content.Context; 5 | import android.graphics.Color; 6 | import android.support.annotation.Nullable; 7 | import android.support.v7.widget.LinearLayoutManager; 8 | import android.support.v7.widget.LinearSmoothScroller; 9 | import android.support.v7.widget.LinearSnapHelper; 10 | import android.support.v7.widget.RecyclerView; 11 | import android.util.AttributeSet; 12 | import android.util.Log; 13 | import android.view.View; 14 | 15 | import org.joda.time.DateTime; 16 | import org.joda.time.Days; 17 | 18 | /** 19 | * Created by Jhonny Barrios on 22/02/2017. 20 | * 21 | */ 22 | 23 | public class HorizontalPickerRecyclerView extends RecyclerView implements OnItemClickedListener, View.OnClickListener { 24 | 25 | private HorizontalPickerAdapter adapter; 26 | private int lastPosition; 27 | private LinearLayoutManager layoutManager; 28 | private float itemWidth; 29 | private HorizontalPickerListener listener; 30 | private int offset; 31 | 32 | public HorizontalPickerRecyclerView(Context context) { 33 | super(context); 34 | } 35 | 36 | public HorizontalPickerRecyclerView(Context context, @Nullable AttributeSet attrs) { 37 | super(context, attrs); 38 | } 39 | 40 | public HorizontalPickerRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) { 41 | super(context, attrs, defStyle); 42 | } 43 | 44 | public void init(Context context, final int daysToPlus, final int initialOffset, final int mBackgroundColor, final int mDateSelectedColor, final int mDateSelectedTextColor, final int mTodayDateTextColor, final int mTodayDateBackgroundColor, final int mDayOfWeekTextColor, final int mUnselectedDayTextColor) { 45 | this.offset=initialOffset; 46 | layoutManager=new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false); 47 | setLayoutManager(layoutManager); 48 | post(new Runnable() { 49 | @Override 50 | public void run() { 51 | itemWidth=getMeasuredWidth()/7; 52 | adapter=new HorizontalPickerAdapter((int) itemWidth,HorizontalPickerRecyclerView.this, getContext(),daysToPlus,initialOffset,mBackgroundColor,mDateSelectedColor,mDateSelectedTextColor,mTodayDateTextColor, 53 | mTodayDateBackgroundColor, 54 | mDayOfWeekTextColor, 55 | mUnselectedDayTextColor); 56 | setAdapter(adapter); 57 | LinearSnapHelper snapHelper=new LinearSnapHelper(); 58 | snapHelper.attachToRecyclerView(HorizontalPickerRecyclerView.this); 59 | removeOnScrollListener(onScrollListener); 60 | addOnScrollListener(onScrollListener); 61 | } 62 | }); 63 | } 64 | 65 | private OnScrollListener onScrollListener=new OnScrollListener() { 66 | @Override 67 | public void onScrollStateChanged(RecyclerView recyclerView, int newState) { 68 | super.onScrollStateChanged(recyclerView, newState); 69 | switch (newState){ 70 | case RecyclerView.SCROLL_STATE_IDLE: 71 | listener.onStopDraggingPicker(); 72 | int position = (int) ((computeHorizontalScrollOffset()/itemWidth)+3.5); 73 | if(position!=-1&&position!=lastPosition) 74 | { 75 | selectItem(true,position); 76 | selectItem(false,lastPosition); 77 | lastPosition=position; 78 | } 79 | break; 80 | case SCROLL_STATE_DRAGGING: 81 | listener.onDraggingPicker(); 82 | break; 83 | } 84 | } 85 | 86 | @Override 87 | public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 88 | super.onScrolled(recyclerView, dx, dy); 89 | } 90 | }; 91 | 92 | private void selectItem(boolean isSelected,int position) { 93 | adapter.getItem(position).setSelected(isSelected); 94 | adapter.notifyItemChanged(position); 95 | if(isSelected) 96 | { 97 | listener.onDateSelected(adapter.getItem(position)); 98 | } 99 | } 100 | 101 | public void setListener(HorizontalPickerListener listener) { 102 | this.listener = listener; 103 | } 104 | 105 | @Override 106 | public void onClickView(View v, int adapterPosition) { 107 | if(adapterPosition!=lastPosition) 108 | { 109 | selectItem(true,adapterPosition); 110 | selectItem(false,lastPosition); 111 | lastPosition=adapterPosition; 112 | } 113 | } 114 | 115 | @Override 116 | public void onClick(View v) { 117 | setDate(new DateTime()); 118 | } 119 | 120 | @Override 121 | public void smoothScrollToPosition(int position) { 122 | final RecyclerView.SmoothScroller smoothScroller = new CenterSmoothScroller(getContext()); 123 | smoothScroller.setTargetPosition(position); 124 | post(new Runnable() { 125 | @Override 126 | public void run() { 127 | layoutManager.startSmoothScroll(smoothScroller); 128 | } 129 | }); 130 | } 131 | 132 | public void setDate(DateTime date) { 133 | DateTime today = new DateTime().withTime(0,0,0,0); 134 | int difference = Days.daysBetween(date,today).getDays() * (date.getYear() < today.getMillis() ? -1 : 1); 135 | smoothScrollToPosition(offset+difference); 136 | } 137 | 138 | private static class CenterSmoothScroller extends LinearSmoothScroller { 139 | 140 | CenterSmoothScroller(Context context) { 141 | super(context); 142 | } 143 | 144 | @Override 145 | public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) { 146 | return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2); 147 | } 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /horizontal-picker/src/main/java/com/github/jhonnyx2012/horizontalpicker/HorizontalPicker.java: -------------------------------------------------------------------------------- 1 | package com.github.jhonnyx2012.horizontalpicker; 2 | 3 | import android.content.Context; 4 | import android.graphics.Color; 5 | import android.graphics.drawable.ColorDrawable; 6 | import android.graphics.drawable.Drawable; 7 | import android.support.annotation.ColorInt; 8 | import android.support.annotation.Nullable; 9 | import android.util.AttributeSet; 10 | import android.view.View; 11 | import android.widget.LinearLayout; 12 | import android.widget.TextView; 13 | 14 | import org.joda.time.DateTime; 15 | 16 | /** 17 | * Created by Jhonny Barrios on 22/02/2017. 18 | */ 19 | 20 | public class HorizontalPicker extends LinearLayout implements HorizontalPickerListener { 21 | 22 | private static final int NO_SETTED = -1; 23 | private View vHover; 24 | private TextView tvMonth; 25 | private TextView tvToday; 26 | private DatePickerListener listener; 27 | private OnTouchListener monthListener; 28 | private HorizontalPickerRecyclerView rvDays; 29 | private int days; 30 | private int offset; 31 | private int mDateSelectedColor = -1; 32 | private int mDateSelectedTextColor = -1; 33 | private int mMonthAndYearTextColor = -1; 34 | private int mTodayButtonTextColor = -1; 35 | private boolean showTodayButton = true; 36 | private String mMonthPattern = ""; 37 | private int mTodayDateTextColor = -1; 38 | private int mTodayDateBackgroundColor = -1; 39 | private int mDayOfWeekTextColor = -1; 40 | private int mUnselectedDayTextColor = -1; 41 | 42 | public HorizontalPicker(Context context) { 43 | super(context); 44 | internInit(); 45 | } 46 | 47 | public HorizontalPicker(Context context, @Nullable AttributeSet attrs) { 48 | super(context, attrs); 49 | internInit(); 50 | 51 | } 52 | 53 | public HorizontalPicker(Context context, @Nullable AttributeSet attrs, int defStyle) { 54 | super(context, attrs, defStyle); 55 | internInit(); 56 | } 57 | 58 | private void internInit() { 59 | this.days = NO_SETTED; 60 | this.offset = NO_SETTED; 61 | } 62 | 63 | public HorizontalPicker setListener(DatePickerListener listener) { 64 | this.listener = listener; 65 | return this; 66 | } 67 | 68 | public HorizontalPicker setMonthListener(OnTouchListener listener) { 69 | this.monthListener = listener; 70 | return this; 71 | } 72 | 73 | public void setDate(final DateTime date) { 74 | rvDays.post(new Runnable() { 75 | @Override 76 | public void run() { 77 | rvDays.setDate(date); 78 | } 79 | }); 80 | } 81 | 82 | public void init() { 83 | inflate(getContext(), R.layout.horizontal_picker, this); 84 | rvDays = (HorizontalPickerRecyclerView) findViewById(R.id.rvDays); 85 | int DEFAULT_DAYS_TO_PLUS = 120; 86 | int finalDays = days == NO_SETTED ? DEFAULT_DAYS_TO_PLUS : days; 87 | int DEFAULT_INITIAL_OFFSET = 7; 88 | int finalOffset = offset == NO_SETTED ? DEFAULT_INITIAL_OFFSET : offset; 89 | vHover = findViewById(R.id.vHover); 90 | 91 | tvMonth = (TextView) findViewById(R.id.tvMonth); 92 | if (monthListener != null) { 93 | tvMonth.setClickable(true); 94 | tvMonth.setOnTouchListener(monthListener); 95 | } 96 | 97 | 98 | tvToday = (TextView) findViewById(R.id.tvToday); 99 | rvDays.setListener(this); 100 | tvToday.setOnClickListener(rvDays); 101 | tvMonth.setTextColor(mMonthAndYearTextColor != -1 ? mMonthAndYearTextColor : getColor(R.color.primaryTextColor)); 102 | tvToday.setVisibility(showTodayButton ? VISIBLE : INVISIBLE); 103 | tvToday.setTextColor(mTodayButtonTextColor != -1 ? mTodayButtonTextColor : getColor(R.color.colorPrimary)); 104 | int mBackgroundColor = getBackgroundColor(); 105 | setBackgroundColor(mBackgroundColor != Color.TRANSPARENT ? mBackgroundColor : Color.WHITE); 106 | mDateSelectedColor = mDateSelectedColor == -1 ? getColor(R.color.colorPrimary) : mDateSelectedColor; 107 | mDateSelectedTextColor = mDateSelectedTextColor == -1 ? Color.WHITE : mDateSelectedTextColor; 108 | mTodayDateTextColor = mTodayDateTextColor == -1 ? getColor(R.color.primaryTextColor) : mTodayDateTextColor; 109 | mDayOfWeekTextColor = mDayOfWeekTextColor == -1 ? getColor(R.color.secundaryTextColor) : mDayOfWeekTextColor; 110 | mUnselectedDayTextColor = mUnselectedDayTextColor == -1 ? getColor(R.color.primaryTextColor) : mUnselectedDayTextColor; 111 | rvDays.init( 112 | getContext(), 113 | finalDays, 114 | finalOffset, 115 | mBackgroundColor, 116 | mDateSelectedColor, 117 | mDateSelectedTextColor, 118 | mTodayDateTextColor, 119 | mTodayDateBackgroundColor, 120 | mDayOfWeekTextColor, 121 | mUnselectedDayTextColor); 122 | } 123 | 124 | private int getColor(int colorId) { 125 | return getResources().getColor(colorId); 126 | } 127 | 128 | public int getBackgroundColor() { 129 | int color = Color.TRANSPARENT; 130 | Drawable background = getBackground(); 131 | if (background instanceof ColorDrawable) 132 | color = ((ColorDrawable) background).getColor(); 133 | return color; 134 | } 135 | 136 | @Override 137 | public boolean post(Runnable action) { 138 | return rvDays.post(action); 139 | } 140 | 141 | @Override 142 | public void onStopDraggingPicker() { 143 | if (vHover.getVisibility() == VISIBLE) 144 | vHover.setVisibility(INVISIBLE); 145 | } 146 | 147 | @Override 148 | public void onDraggingPicker() { 149 | if (vHover.getVisibility() == INVISIBLE) 150 | vHover.setVisibility(VISIBLE); 151 | } 152 | 153 | @Override 154 | public void onDateSelected(Day item) { 155 | tvMonth.setText(item.getMonth(mMonthPattern)); 156 | if (showTodayButton) 157 | tvToday.setVisibility(item.isToday() ? INVISIBLE : VISIBLE); 158 | if (listener != null) { 159 | listener.onDateSelected(item.getDate()); 160 | } 161 | } 162 | 163 | public HorizontalPicker setDays(int days) { 164 | this.days = days; 165 | return this; 166 | } 167 | 168 | public int getDays() { 169 | return days; 170 | } 171 | 172 | public HorizontalPicker setOffset(int offset) { 173 | this.offset = offset; 174 | return this; 175 | } 176 | 177 | public int getOffset() { 178 | return offset; 179 | } 180 | 181 | public HorizontalPicker setDateSelectedColor(@ColorInt int color) { 182 | mDateSelectedColor = color; 183 | return this; 184 | } 185 | 186 | public HorizontalPicker setDateSelectedTextColor(@ColorInt int color) { 187 | mDateSelectedTextColor = color; 188 | return this; 189 | } 190 | 191 | public HorizontalPicker setMonthAndYearTextColor(@ColorInt int color) { 192 | mMonthAndYearTextColor = color; 193 | return this; 194 | } 195 | 196 | public HorizontalPicker setTodayButtonTextColor(@ColorInt int color) { 197 | mTodayButtonTextColor = color; 198 | return this; 199 | } 200 | 201 | public HorizontalPicker showTodayButton(boolean show) { 202 | showTodayButton = show; 203 | return this; 204 | } 205 | 206 | public HorizontalPicker setTodayDateTextColor(int color) { 207 | mTodayDateTextColor = color; 208 | return this; 209 | } 210 | 211 | public HorizontalPicker setTodayDateBackgroundColor(@ColorInt int color) { 212 | mTodayDateBackgroundColor = color; 213 | return this; 214 | } 215 | 216 | public HorizontalPicker setDayOfWeekTextColor(@ColorInt int color) { 217 | mDayOfWeekTextColor = color; 218 | return this; 219 | } 220 | 221 | public HorizontalPicker setUnselectedDayTextColor(@ColorInt int color) { 222 | mUnselectedDayTextColor = color; 223 | return this; 224 | } 225 | 226 | public HorizontalPicker setMonthPattern(String pattern) { 227 | mMonthPattern = pattern; 228 | return this; 229 | } 230 | } --------------------------------------------------------------------------------