From 705006fe0c1187ace53ee6505f71ba98fe4b44e6 Mon Sep 17 00:00:00 2001 From: mac <user@users-MacBook-Pro.local> Date: 星期五, 26 四月 2024 18:27:45 +0800 Subject: [PATCH] 2024年04月26日18:26:42 --- wheelview/src/main/res/values/dimens.xml | 13 wheelview/src/main/java/com/contrarywind/timer/MessageHandler.java | 42 pickerview/src/main/java/com/bigkoo/pickerview/utils/ChinaDate.java | 352 +++ pickerview/src/main/java/com/bigkoo/pickerview/view/TimePickerView.java | 293 ++ wheelview/src/main/java/com/contrarywind/timer/SmoothScrollTimerTask.java | 64 wheelview/src/main/java/com/contrarywind/timer/InertiaTimerTask.java | 79 app/src/main/java/com/hdl/photovoltaic/utils/TimeUtils.java | 37 pickerview/src/main/java/com/bigkoo/pickerview/view/OptionsPickerView.java | 197 + pickerview/src/main/java/com/bigkoo/pickerview/adapter/ArrayWheelAdapter.java | 44 pickerview/src/main/java/com/bigkoo/pickerview/listener/OnTimeSelectListener.java | 14 pickerview/src/main/java/com/bigkoo/pickerview/view/WheelOptions.java | 428 ++++ pickerview/src/main/java/com/bigkoo/pickerview/view/WheelTime.java | 900 +++++++++ wheelview/src/androidTest/java/test/wheelview/ExampleInstrumentedTest.java | 26 pickerview/src/androidTest/java/com/bigkoo/pickerview/ApplicationTest.java | 13 pickerview/src/main/java/com/bigkoo/pickerview/listener/OnTimeSelectChangeListener.java | 12 app/src/main/res/drawable/time_selected_38c494.xml | 8 pickerview/src/main/java/com/bigkoo/pickerview/utils/LunarCalendar.java | 429 ++++ pickerview/src/main/res/drawable/selector_pickerview_btn.xml | 6 wheelview/src/main/java/com/contrarywind/listener/OnItemSelectedListener.java | 6 pickerview/src/main/res/layout/layout_basepickerview.xml | 16 app/build.gradle | 6 pickerview/src/main/res/values/dimens.xml | 13 third-zxing/build.gradle | 6 pickerview/src/main/java/com/bigkoo/pickerview/configure/PickerOptions.java | 114 + app/src/main/res/values/strings.xml | 9 wheelview/build.gradle | 47 wheelview/src/main/java/com/contrarywind/interfaces/IPickerViewData.java | 8 pickerview/src/main/res/anim/pickerview_slide_in_bottom.xml | 11 pickerview/src/main/java/com/bigkoo/pickerview/builder/TimePickerBuilder.java | 315 +++ pickerview/src/main/res/anim/pickerview_slide_out_bottom.xml | 11 pickerview/src/main/java/com/bigkoo/pickerview/listener/OnOptionsSelectListener.java | 13 pickerview/src/main/java/com/bigkoo/pickerview/builder/OptionsPickerBuilder.java | 292 ++ pickerview/src/main/java/com/bigkoo/pickerview/listener/CustomListener.java | 13 pickerview/src/main/res/values-en/strings.xml | 11 pickerview/src/main/java/com/bigkoo/pickerview/listener/ISelectTimeCallback.java | 10 wheelview/.gitignore | 12 app/src/main/res/values/themes.xml | 2 pickerview/proguard-rules.pro | 17 wheelview/src/main/res/values/colors.xml | 14 app/src/main/res/values/colors.xml | 1 pickerview/src/main/res/anim/pickerview_dialog_scale_in.xml | 19 pickerview/build.gradle | 49 wheelview/src/main/java/com/contrarywind/view/WheelView.java | 840 ++++++++ app/src/main/java/com/hdl/photovoltaic/ui/home/HomePageFragment.java | 250 ++ app/src/main/res/layout/fragment_home_page.xml | 53 pickerview/src/main/res/values/styles.xml | 31 wheelview/src/main/res/values/attrs.xml | 16 pickerview/src/main/java/com/bigkoo/pickerview/listener/OnOptionsSelectChangeListener.java | 11 pickerview/src/main/res/anim/pickerview_dialog_scale_out.xml | 18 pickerview/src/main/res/values/integers.xml | 5 pickerview/src/main/AndroidManifest.xml | 5 pickerview/src/main/res/layout/pickerview_options.xml | 46 settings.gradle | 2 app/src/main/res/layout/item_station.xml | 4 pickerview/.gitignore | 12 pickerview/src/main/res/layout/include_pickerview_topbar.xml | 44 pickerview/src/main/res/layout/pickerview_time.xml | 64 app/src/main/java/com/hdl/photovoltaic/HDLApp.java | 13 wheelview/src/main/res/values/strings.xml | 3 /dev/null | 3 pickerview/src/main/java/com/bigkoo/pickerview/view/BasePickerView.java | 361 +++ wheelview/src/main/java/com/contrarywind/listener/LoopViewGestureListener.java | 25 wheelview/proguard-rules.pro | 25 pickerview/src/main/java/com/bigkoo/pickerview/adapter/NumericWheelAdapter.java | 47 pickerview/src/main/java/com/bigkoo/pickerview/listener/OnDismissListener.java | 8 pickerview/src/main/res/values/strings.xml | 11 wheelview/src/main/AndroidManifest.xml | 4 wheelview/src/main/java/com/contrarywind/adapter/WheelAdapter.java | 25 pickerview/src/main/java/com/bigkoo/pickerview/utils/PickerViewAnimateUtil.java | 26 69 files changed, 5,823 insertions(+), 101 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 3422468..1271f2f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -121,6 +121,8 @@ implementation 'androidx.navigation:navigation-fragment:2.3.5' implementation 'androidx.navigation:navigation-ui:2.3.5' implementation 'androidx.legacy:legacy-support-v4:1.0.0' + //鏃堕棿搴� + implementation project(path: ':pickerview') //鍥捐〃搴� implementation project(path: ':aa_chart_core') //鍥藉鍒楄〃鍜屾墜鏈哄尯鍙峰簱 @@ -177,10 +179,6 @@ implementation 'cn.jiguang.sdk:jpush-google:5.2.2' //鍒嗘瀽鍜岀敤鎴锋爣绛剧瓑鍔熻兘(鍙�夛紝闆嗘垚鏋佸厜鍒嗘瀽SDK鍚庯紝鍗冲彲鏀寔琛屼负瑙﹀彂鎺ㄩ�佹秷鎭�佹帹閫佽浆鍖栫巼缁熻锛岀敤鎴疯涓哄垎) implementation 'cn.jiguang.sdk:joperate:2.0.2' - - //PickerView - implementation 'com.contrarywind:Android-PickerView:4.1.9' - diff --git a/app/src/main/java/com/hdl/photovoltaic/HDLApp.java b/app/src/main/java/com/hdl/photovoltaic/HDLApp.java index 592295c..f81c9d7 100644 --- a/app/src/main/java/com/hdl/photovoltaic/HDLApp.java +++ b/app/src/main/java/com/hdl/photovoltaic/HDLApp.java @@ -49,6 +49,7 @@ import cn.jpush.android.api.JPushInterface; import io.dcloud.common.util.RuningAcitvityUtil; +import me.jessyan.autosize.AutoSize; import me.jessyan.autosize.AutoSizeConfig; import me.jessyan.autosize.onAdaptListener; import me.jessyan.autosize.utils.ScreenUtils; @@ -73,6 +74,7 @@ @Override public void onCreate() { super.onCreate(); + // 鑾峰彇褰撳墠杩涚▼鐨凱ID Log.d("杩涚▼===", android.os.Process.myPid() + ""); mHDLApp = this; @@ -312,12 +314,14 @@ * 鏃嬭浆鍚庨珮鍙樺,鎸夋棆杞悗楂樺害閫傞厤,鎵�浠ュ搴︿笉鍐欐 */ private void initAutoSize() { + AutoSize.initCompatMultiProcess(this); boolean isBaseOnWidth = getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT; AutoSizeConfig.getInstance() - .setBaseOnWidth(isBaseOnWidth) + .setBaseOnWidth(true) + .setCustomFragment(true) + .setDesignWidthInDp(375) + .setDesignHeightInDp(812) .setUseDeviceSize(false) - .setDesignWidthInDp(isBaseOnWidth ? 375 : 812) - .setDesignHeightInDp(isBaseOnWidth ? 812 : 375) .setOnAdaptListener(new onAdaptListener() { @Override public void onAdaptBefore(Object target, Activity activity) { @@ -357,4 +361,7 @@ MultiDex.install(base); super.attachBaseContext(base); } + + + } diff --git a/app/src/main/java/com/hdl/photovoltaic/ui/home/HomePageFragment.java b/app/src/main/java/com/hdl/photovoltaic/ui/home/HomePageFragment.java index 283afbf..d0474e4 100644 --- a/app/src/main/java/com/hdl/photovoltaic/ui/home/HomePageFragment.java +++ b/app/src/main/java/com/hdl/photovoltaic/ui/home/HomePageFragment.java @@ -53,10 +53,13 @@ import android.content.Intent; import android.graphics.Color; import android.os.Bundle; +import android.provider.Settings; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.widget.Toast; + +import androidx.appcompat.content.res.AppCompatResources; import com.bigkoo.pickerview.builder.TimePickerBuilder; import com.bigkoo.pickerview.listener.OnTimeSelectListener; @@ -67,10 +70,13 @@ import com.github.AAChartModel.AAChartCore.AAChartEnum.AAChartType; import com.hdl.photovoltaic.R; import com.hdl.photovoltaic.base.CustomBaseFragment; +import com.hdl.photovoltaic.config.AppConfigManage; import com.hdl.photovoltaic.config.ConstantManage; +import com.hdl.photovoltaic.config.UserConfigManage; import com.hdl.photovoltaic.databinding.FragmentHomePageBinding; import com.hdl.photovoltaic.enums.HomepageTitleTabSwitch; import com.hdl.photovoltaic.other.HdlLogLogic; +import com.hdl.photovoltaic.utils.TimeUtils; import com.hdl.sdk.link.core.bean.eventbus.BaseEventBus; import org.greenrobot.eventbus.EventBus; @@ -90,12 +96,12 @@ FragmentHomePageBinding viewBinding; - AAChartView aaChartView1; + AAChartView aaChartView; - AAChartModel aaChartModel1; - AAChartView aaChartView2; + AAChartModel aaChartModel; - AAChartModel aaChartModel2; + + private TimeType timeType = TimeType.day;//鏃堕棿绫诲瀷(榛樿锛氬ぉ) @Override @@ -106,30 +112,169 @@ @Override public void onBindView(Bundle savedInstanceState) { - viewBinding.homePageStationDataTitleTv.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - setUpAAChartView(1); - } - }); - viewBinding.yearMonthDayTv.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - timeSelectedView(); - - } - }); - timeSelectedView(); -// viewBinding.test2.setOnClickListener(new View.OnClickListener() { -// @Override -// public void onClick(View v) { -// setUpAAChartView(2); -// } -// }); + //鍒濆鍖� + initView(); + //鍒濆鍖栫晫闈㈢洃鍚櫒 + initEvent(); } - private void timeSelectedView(){ + private void initEvent() { + //鏃堕棿閫夋嫨鍣� + viewBinding.yearMonthDayTv.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + selectedTimePickerBuilder(); + + } + }); + //鏃� + viewBinding.dayTv.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + timeType = TimeType.day; + + viewBinding.dayTv.setBackground(AppCompatResources.getDrawable(_mActivity, R.drawable.time_selected_38c494)); + viewBinding.dayTv.setTextColor(_mActivity.getColor(R.color.text_38C494)); + + viewBinding.monthTv.setBackground(AppCompatResources.getDrawable(_mActivity, R.color.text_00000000)); + viewBinding.monthTv.setTextColor(_mActivity.getColor(R.color.text_40000000)); + + viewBinding.yearTv.setBackground(AppCompatResources.getDrawable(_mActivity, R.color.text_00000000)); + viewBinding.yearTv.setTextColor(_mActivity.getColor(R.color.text_40000000)); + + viewBinding.lifeCycleTv.setBackground(AppCompatResources.getDrawable(_mActivity, R.color.text_00000000)); + viewBinding.lifeCycleTv.setTextColor(_mActivity.getColor(R.color.text_40000000)); + + viewBinding.v1.setVisibility(View.GONE); + viewBinding.v2.setVisibility(View.VISIBLE); + viewBinding.v3.setVisibility(View.VISIBLE); + viewBinding.homePageStationSelectTimeLl.setVisibility(View.VISIBLE); + + + setUpAAChartView(1); + + } + }); + //鏈� + viewBinding.monthTv.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + timeType = TimeType.month; + viewBinding.dayTv.setBackground(AppCompatResources.getDrawable(_mActivity, R.color.text_00000000)); + viewBinding.dayTv.setTextColor(_mActivity.getColor(R.color.text_40000000)); + + viewBinding.monthTv.setBackground(AppCompatResources.getDrawable(_mActivity, R.drawable.time_selected_38c494)); + viewBinding.monthTv.setTextColor(_mActivity.getColor(R.color.text_38C494)); + + viewBinding.yearTv.setBackground(AppCompatResources.getDrawable(_mActivity, R.color.text_00000000)); + viewBinding.yearTv.setTextColor(_mActivity.getColor(R.color.text_40000000)); + + viewBinding.lifeCycleTv.setBackground(AppCompatResources.getDrawable(_mActivity, R.color.text_00000000)); + viewBinding.lifeCycleTv.setTextColor(_mActivity.getColor(R.color.text_40000000)); + + viewBinding.v1.setVisibility(View.GONE); + viewBinding.v2.setVisibility(View.GONE); + viewBinding.v3.setVisibility(View.VISIBLE); + viewBinding.homePageStationSelectTimeLl.setVisibility(View.VISIBLE); + + setUpAAChartView(2); + + + } + }); + //骞� + viewBinding.yearTv.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + timeType = TimeType.year; + viewBinding.dayTv.setBackground(AppCompatResources.getDrawable(_mActivity, R.color.text_00000000)); + viewBinding.dayTv.setTextColor(_mActivity.getColor(R.color.text_40000000)); + + viewBinding.monthTv.setBackground(AppCompatResources.getDrawable(_mActivity, R.color.text_00000000)); + viewBinding.monthTv.setTextColor(_mActivity.getColor(R.color.text_40000000)); + + viewBinding.yearTv.setBackground(AppCompatResources.getDrawable(_mActivity, R.drawable.time_selected_38c494)); + viewBinding.yearTv.setTextColor(_mActivity.getColor(R.color.text_38C494)); + + viewBinding.lifeCycleTv.setBackground(AppCompatResources.getDrawable(_mActivity, R.color.text_00000000)); + viewBinding.lifeCycleTv.setTextColor(_mActivity.getColor(R.color.text_40000000)); + + viewBinding.v1.setVisibility(View.VISIBLE); + viewBinding.v2.setVisibility(View.GONE); + viewBinding.v3.setVisibility(View.GONE); + viewBinding.homePageStationSelectTimeLl.setVisibility(View.VISIBLE); + + setUpAAChartView(2); + } + }); + //鐢熷懡鏈� + viewBinding.lifeCycleTv.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + timeType = TimeType.lifecycle; + viewBinding.dayTv.setBackground(AppCompatResources.getDrawable(_mActivity, R.color.text_00000000)); + viewBinding.dayTv.setTextColor(_mActivity.getColor(R.color.text_40000000)); + + viewBinding.monthTv.setBackground(AppCompatResources.getDrawable(_mActivity, R.color.text_00000000)); + viewBinding.monthTv.setTextColor(_mActivity.getColor(R.color.text_40000000)); + + viewBinding.yearTv.setBackground(AppCompatResources.getDrawable(_mActivity, R.color.text_00000000)); + viewBinding.yearTv.setTextColor(_mActivity.getColor(R.color.text_40000000)); + + viewBinding.lifeCycleTv.setBackground(AppCompatResources.getDrawable(_mActivity, R.drawable.time_selected_38c494)); + viewBinding.lifeCycleTv.setTextColor(_mActivity.getColor(R.color.text_38C494)); + + viewBinding.v1.setVisibility(View.VISIBLE); + viewBinding.v2.setVisibility(View.VISIBLE); + viewBinding.v3.setVisibility(View.GONE); + viewBinding.homePageStationSelectTimeLl.setVisibility(View.GONE); + + setUpAAChartView(2); + + } + }); + //涓婁竴姝� + viewBinding.lastStepIv.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + } + }); + //涓嬩竴姝� + viewBinding.nextStepIv.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + } + }); + } + + private void initView() { + String dataStr = TimeUtils.getDateTimestamp(System.currentTimeMillis(), TimeUtils.zhDateFormat); + if (!UserConfigManage.getInstance().isZh()) { + dataStr = TimeUtils.getDateTimestamp(System.currentTimeMillis(), TimeUtils.enDateFormat); + } + viewBinding.yearMonthDayTv.setText(dataStr); + viewBinding.dayTv.setBackground(AppCompatResources.getDrawable(_mActivity, R.drawable.time_selected_38c494)); + viewBinding.dayTv.setTextColor(_mActivity.getColor(R.color.text_38C494)); + viewBinding.monthTv.setBackground(AppCompatResources.getDrawable(_mActivity, R.color.text_00000000)); + viewBinding.monthTv.setTextColor(_mActivity.getColor(R.color.text_40000000)); + viewBinding.yearTv.setBackground(AppCompatResources.getDrawable(_mActivity, R.color.text_00000000)); + viewBinding.yearTv.setTextColor(_mActivity.getColor(R.color.text_40000000)); + viewBinding.lifeCycleTv.setBackground(AppCompatResources.getDrawable(_mActivity, R.color.text_00000000)); + viewBinding.lifeCycleTv.setTextColor(_mActivity.getColor(R.color.text_40000000)); + viewBinding.v1.setVisibility(View.GONE); + viewBinding.v2.setVisibility(View.VISIBLE); + viewBinding.v3.setVisibility(View.VISIBLE); + viewBinding.homePageStationSelectTimeLl.setVisibility(View.VISIBLE); + } + + + /** + * 鏃堕棿閫夋嫨鍣� + */ + private void selectedTimePickerBuilder() { //鏃堕棿閫夋嫨鍣� Calendar selectedDate = Calendar.getInstance(); Calendar startDate = Calendar.getInstance(); @@ -147,12 +292,12 @@ // tvTime.setText(getTime(date)); } }) - .setType(new boolean[]{true, false, false, false, false, false})// 榛樿鍏ㄩ儴鏄剧ず - .setCancelText("鍙栨秷")//鍙栨秷鎸夐挳鏂囧瓧 - .setSubmitText("纭畾")//纭鎸夐挳鏂囧瓧 + .setType(new boolean[]{true, true, true, false, false, false})// 榛樿鍏ㄩ儴鏄剧ず + .setCancelText(_mActivity.getString(R.string.loading_cancel))//鍙栨秷鎸夐挳鏂囧瓧 + .setSubmitText(_mActivity.getString(R.string.loading_affirm))//纭鎸夐挳鏂囧瓧 .setContentTextSize(18)//婊氳疆鏂囧瓧澶у皬 .setTitleSize(18)//鏍囬鏂囧瓧澶у皬 - .setTitleText("鏃堕棿閫夋嫨")//鏍囬鏂囧瓧 + .setTitleText(_mActivity.getString(R.string.time_selectd))//鏍囬鏂囧瓧 .setOutSideCancelable(true)//鐐瑰嚮灞忓箷锛岀偣鍦ㄦ帶浠跺閮ㄨ寖鍥存椂锛屾槸鍚﹀彇娑堟樉绀� .isCyclic(false)//鏄惁寰幆婊氬姩 .setTitleColor(_mActivity.getColor(R.color.text_90000000))//鏍囬鏂囧瓧棰滆壊 @@ -163,54 +308,51 @@ .setTextColorCenter(_mActivity.getColor(R.color.text_90000000)) .setDate(selectedDate)// 濡傛灉涓嶈缃殑璇濓紝榛樿鏄郴缁熸椂闂�*/ .setRangDate(startDate, endDate)//璧峰缁堟骞存湀鏃ヨ瀹� - .setLabel("骞�", "鏈�", "鏃�", "鏃�", "鍒�", "绉�")//榛樿璁剧疆涓哄勾鏈堟棩鏃跺垎绉� + .setLabel(_mActivity.getString(R.string.year), _mActivity.getString(R.string.month), _mActivity.getString(R.string.day), _mActivity.getString(R.string.hour), _mActivity.getString(R.string.minute), _mActivity.getString(R.string.succeed))//榛樿璁剧疆涓哄勾鏈堟棩鏃跺垎绉� .isCenterLabel(false) //鏄惁鍙樉绀轰腑闂撮�変腑椤圭殑label鏂囧瓧锛宖alse鍒欐瘡椤筰tem鍏ㄩ儴閮藉甫鏈塴abel銆� .isDialog(false)//鏄惁鏄剧ず涓哄璇濇鏍峰紡 - .setItemVisibleCount(17)//瀵硅瘽妗嗛珮搴� + .setItemVisibleCount(7)//瀵硅瘽妗嗛珮搴� .setDividerColor(_mActivity.getColor(R.color.text_E1E1E1)) - .setDecorView(viewBinding.wwwwww) -// .setLineSpacingMultiplier(3f)// + .setLineSpacingMultiplier(3f)// .build(); pvTime.show(); } private void setUpAAChartView(int value) { if (value == 1) { - aaChartView1 = viewBinding.AAChartView; - aaChartView1.callBack = this; - aaChartModel1 = configureAAChartModel(); - aaChartView1.aa_drawChartWithChartModel(aaChartModel1); + aaChartView = viewBinding.AAChartView; + aaChartView.callBack = this; + aaChartModel = configureAAChartModel(); + aaChartView.aa_drawChartWithChartModel(aaChartModel); } else if (value == 2) { -// aaChartView2 = viewBinding.AAChartView2; - aaChartView2.callBack = this; - aaChartModel2 = configureColorfulColumnChart();// configureTheAAChartModel("colorfulColumnChart"); - aaChartView2.aa_drawChartWithChartModel(aaChartModel2); + aaChartView = viewBinding.AAChartView; + aaChartView.callBack = this; + aaChartModel = configureColorfulColumnChart();// configureTheAAChartModel("colorfulColumnChart"); + aaChartView.aa_drawChartWithChartModel(aaChartModel); } } private AAChartModel configureAAChartModel() { -// Intent intent = getIntent(); String chartType = AAChartType.Area; int position = 0; - aaChartModel1 = BasicChartComposer.configureAreaChart(); + aaChartModel = BasicChartComposer.configureAreaChart(); configureTheStyleForDifferentTypeChart(chartType, position); -// configureViewsVisibility(chartType); - return aaChartModel1; + return aaChartModel; } private void configureTheStyleForDifferentTypeChart(String chartType, int position) { if ((chartType.equals(AAChartType.Area) || chartType.equals(AAChartType.Line)) && (position == 4 || position == 5)) { - aaChartModel1 = BasicChartComposer.configureStepAreaChartAndStepLineChart(); + aaChartModel = BasicChartComposer.configureStepAreaChartAndStepLineChart(); } else if (chartType.equals(AAChartType.Column) || chartType.equals(AAChartType.Bar)) { - aaChartModel1 = BasicChartComposer.configureColumnChartAndBarChart(); + aaChartModel = BasicChartComposer.configureColumnChartAndBarChart(); } else if (chartType.equals(AAChartType.Area) || chartType.equals(AAChartType.Areaspline)) { - aaChartModel1 = BasicChartComposer.configureAreaChartAndAreasplineChartStyle(chartType); + aaChartModel = BasicChartComposer.configureAreaChartAndAreasplineChartStyle(chartType); } else if (chartType.equals(AAChartType.Line) || chartType.equals(AAChartType.Spline)) { - aaChartModel1 = BasicChartComposer.configureLineChartAndSplineChartStyle(chartType); + aaChartModel = BasicChartComposer.configureLineChartAndSplineChartStyle(chartType); } - aaChartModel1.chartType = chartType; + aaChartModel.chartType = chartType; } private AAChartModel configureTheAAChartModel(String chartType) { @@ -344,4 +486,12 @@ } } } + + + public enum TimeType { + day, + month, + year, + lifecycle + } } \ No newline at end of file diff --git a/app/src/main/java/com/hdl/photovoltaic/utils/TimeUtils.java b/app/src/main/java/com/hdl/photovoltaic/utils/TimeUtils.java index b7d267e..2e9aed4 100644 --- a/app/src/main/java/com/hdl/photovoltaic/utils/TimeUtils.java +++ b/app/src/main/java/com/hdl/photovoltaic/utils/TimeUtils.java @@ -16,6 +16,9 @@ */ public class TimeUtils { + public static final String zhDateFormat = "yyyy/MM/dd"; + public static final String enDateFormat = "dd/MM/yyyy"; + /** * 鑾峰彇鍒嗛挓 * @@ -36,12 +39,13 @@ /** * 鏃堕棿鎴宠浆鏃堕棿(鏍煎紡:yyyy-MM-dd) * - * @param timestamp 鏃堕棿鎴� + * @param timestamp 鏃堕棿鎴� + * @param date_format 鏃堕棿鏍煎紡(渚嬪"yyyy-MM-dd") * @return - */ - public static String getDateTimestamp(long timestamp) { + public static String getDateTimestamp(long timestamp, String date_format) { try { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd ", Locale.ENGLISH); + SimpleDateFormat dateFormat = new SimpleDateFormat(date_format, Locale.ENGLISH); Date date = new Date(timestamp); return dateFormat.format(date); } catch (Exception e) { @@ -95,4 +99,31 @@ return ""; } + /** + * 鍔犲ぉ鏁� + * + * @param date 鏃ュ巻 + * @param daysToAdd 澶╂暟 + * @return 鏃ュ巻 + */ + public static Calendar addDaysToDate(Calendar date, int daysToAdd) { + Calendar newDate = (Calendar) date.clone(); + newDate.add(Calendar.DAY_OF_MONTH, daysToAdd); + return newDate; + } + + /** + * 鍑忓ぉ鏁� + * + * @param date 鏃ュ巻 + * @param daysToSubtract 澶╂暟 + * @return 鏃ュ巻 + */ + public static Calendar subtractDaysFromDate(Calendar date, int daysToSubtract) { + Calendar newDate = (Calendar) date.clone(); + newDate.add(Calendar.DAY_OF_MONTH, -daysToSubtract); + return newDate; + } + + } diff --git a/app/src/main/res/drawable/time_selected_38c494.xml b/app/src/main/res/drawable/time_selected_38c494.xml new file mode 100644 index 0000000..4d80ef2 --- /dev/null +++ b/app/src/main/res/drawable/time_selected_38c494.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<shape xmlns:android="http://schemas.android.com/apk/res/android"> + <solid android:color="@color/text_1238C494" /> + <corners android:radius="@dimen/dp_6" /> + <stroke + android:width="@dimen/dp_1" + android:color="@color/text_38C494" /> +</shape> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home_page.xml b/app/src/main/res/layout/fragment_home_page.xml index 03310b3..dc4f322 100644 --- a/app/src/main/res/layout/fragment_home_page.xml +++ b/app/src/main/res/layout/fragment_home_page.xml @@ -45,7 +45,7 @@ <LinearLayout android:id="@+id/home_page_station_ll" - android:layout_width="0dp" + android:layout_width="375dp" android:layout_height="@dimen/dp_56" android:orientation="horizontal" app:layout_constraintEnd_toEndOf="parent" @@ -284,7 +284,7 @@ android:layout_width="86dp" android:layout_height="match_parent" android:gravity="center" - android:text="Day" /> + android:text="@string/day" /> <View android:id="@+id/v_1" @@ -298,7 +298,7 @@ android:layout_width="86dp" android:layout_height="match_parent" android:gravity="center" - android:text="Month" /> + android:text="@string/month" /> <View android:id="@+id/v_2" @@ -312,7 +312,7 @@ android:layout_width="86dp" android:layout_height="match_parent" android:gravity="center" - android:text="Year" /> + android:text="@string/year" /> <View android:id="@+id/v_3" @@ -326,7 +326,7 @@ android:layout_width="86dp" android:layout_height="match_parent" android:gravity="center" - android:text="LifeCycle" /> + android:text="@string/life_cycle" /> </LinearLayout> <!--鏃堕棿鍒囨崲鎺т欢--> @@ -461,27 +461,27 @@ <TextView android:id="@+id/social_contribution_data_1_tv" android:layout_width="wrap_content" - android:layout_height="13dp" + android:layout_height="22dp" android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_marginStart="@dimen/dp_10" android:layout_marginTop="@dimen/dp_16" android:text="13.14" android:textColor="@color/text_90000000" - android:textSize="@dimen/text_14" + android:textSize="@dimen/text_18" android:textStyle="bold" /> <TextView android:id="@+id/social_contribution_unit_1_tv" android:layout_width="wrap_content" - android:layout_height="9dp" + android:layout_height="15dp" android:layout_alignBottom="@+id/social_contribution_data_1_tv" android:layout_marginStart="@dimen/dp_2" android:layout_toEndOf="@+id/social_contribution_data_1_tv" android:text="(T)" android:textColor="@color/text_90000000" - android:textSize="@dimen/text_14" - android:textStyle="bold" + android:textSize="@dimen/text_12" + /> @@ -495,7 +495,7 @@ android:layout_marginTop="@dimen/dp_35" android:text="ssss" android:textColor="@color/text_40000000" - android:textSize="@dimen/text_14" /> + android:textSize="@dimen/text_12" /> </RelativeLayout> @@ -518,27 +518,26 @@ <TextView android:id="@+id/social_contribution_data_2_tv" android:layout_width="wrap_content" - android:layout_height="13dp" + android:layout_height="22dp" android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_marginStart="@dimen/dp_10" android:layout_marginTop="@dimen/dp_16" android:text="13.14" android:textColor="@color/text_90000000" - android:textSize="@dimen/text_14" + android:textSize="@dimen/text_18" android:textStyle="bold" /> <TextView android:id="@+id/social_contribution_unit_2_tv" android:layout_width="wrap_content" - android:layout_height="9dp" + android:layout_height="15dp" android:layout_alignBottom="@+id/social_contribution_data_2_tv" android:layout_marginStart="@dimen/dp_2" android:layout_toEndOf="@+id/social_contribution_data_2_tv" android:text="(T)" android:textColor="@color/text_90000000" - android:textSize="@dimen/text_14" - android:textStyle="bold" + android:textSize="@dimen/text_12" /> @@ -552,7 +551,7 @@ android:layout_marginTop="@dimen/dp_35" android:text="ssss" android:textColor="@color/text_40000000" - android:textSize="@dimen/text_14" /> + android:textSize="@dimen/text_12" /> </RelativeLayout> @@ -575,27 +574,25 @@ <TextView android:id="@+id/social_contribution_data_3_tv" android:layout_width="wrap_content" - android:layout_height="13dp" - android:layout_alignParentStart="true" + android:layout_height="22dp" android:layout_alignParentTop="true" android:layout_marginStart="@dimen/dp_10" android:layout_marginTop="@dimen/dp_16" android:text="13.14" android:textColor="@color/text_90000000" - android:textSize="@dimen/text_14" + android:textSize="@dimen/text_18" android:textStyle="bold" /> <TextView android:id="@+id/social_contribution_unit_3_tv" android:layout_width="wrap_content" - android:layout_height="9dp" + android:layout_height="15dp" android:layout_alignBottom="@+id/social_contribution_data_3_tv" android:layout_marginStart="@dimen/dp_2" android:layout_toEndOf="@+id/social_contribution_data_3_tv" android:text="(T)" android:textColor="@color/text_90000000" - android:textSize="@dimen/text_14" - android:textStyle="bold" + android:textSize="@dimen/text_12" /> @@ -609,22 +606,14 @@ android:layout_marginTop="@dimen/dp_35" android:text="ssss" android:textColor="@color/text_40000000" - android:textSize="@dimen/text_14" /> + android:textSize="@dimen/text_12" /> </RelativeLayout> </androidx.constraintlayout.widget.ConstraintLayout> - <LinearLayout - android:id="@+id/wwwwww" - android:layout_width="match_parent" - android:layout_height="323dp" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/home_page_station_statistics_cl"> - </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout> diff --git a/app/src/main/res/layout/item_station.xml b/app/src/main/res/layout/item_station.xml index 845f2c1..772a677 100644 --- a/app/src/main/res/layout/item_station.xml +++ b/app/src/main/res/layout/item_station.xml @@ -2,8 +2,8 @@ <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/station_status_cl" - android:layout_width="@dimen/dp_74" - android:layout_height="@dimen/dp_56" + android:layout_width="74dp" + android:layout_height="56dp" android:background="@drawable/station_status_no_ffffff"> <TextView diff --git a/app/src/main/res/values-w1240dp/dimens.xml b/app/src/main/res/values-w1240dp/dimens.xml deleted file mode 100644 index d73f4a3..0000000 --- a/app/src/main/res/values-w1240dp/dimens.xml +++ /dev/null @@ -1,3 +0,0 @@ -<resources> - <dimen name="fab_margin">200dp</dimen> -</resources> \ No newline at end of file diff --git a/app/src/main/res/values-w600dp/dimens.xml b/app/src/main/res/values-w600dp/dimens.xml deleted file mode 100644 index 22d7f00..0000000 --- a/app/src/main/res/values-w600dp/dimens.xml +++ /dev/null @@ -1,3 +0,0 @@ -<resources> - <dimen name="fab_margin">48dp</dimen> -</resources> \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 543e265..99a78bd 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -49,6 +49,7 @@ <color name="text_38C494">#38C494</color> <color name="text_C2EDDE">#C2EDDE</color> <color name="text_C1C1C1">#C1C1C1</color> + <color name="text_1238C494">#1238C494</color> </resources> \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5c8a221..43d90dd 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -247,4 +247,13 @@ <string name="port_conflict">搴旂敤鍐茬獊锛岄渶瑕佸叧闂璷npro鎴栬�呭叾瀹冪増鏈殑璋冭瘯杞欢鐒跺悗鍐嶉噸鏂板惎鍔ㄨ繖涓蒋浠惰瘯璇�</string> + <string name="time_selectd">鏃堕棿閫夋嫨</string> + <string name="life_cycle">鐢熷懡鏈�</string> + <string name="year">骞�</string> + <string name="month">鏈�</string> + <string name="day">鏃�</string> + <string name="hour">鏃�</string> + <string name="minutc">鍒�</string> + <string name="seconds">绉�</string> + </resources> \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index e7da647..0649322 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -11,13 +11,13 @@ <item name="colorOnSecondary">@color/black</item> <!-- Status bar color. --> <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item> - <!-- Customize your theme here. --> </style> <style name="Theme.PhotovoltaicDebug.NoActionBar"> <item name="windowActionBar">false</item> <item name="windowNoTitle">true</item> + </style> diff --git a/pickerview/.gitignore b/pickerview/.gitignore new file mode 100644 index 0000000..43cf153 --- /dev/null +++ b/pickerview/.gitignore @@ -0,0 +1,12 @@ +/build +*.idea +/.idea/libraries +/.idea/modules +/.idea/compiler.xml +/.idea/gradle.xml +/.idea/jarRepositories.xml +/.idea/misc.xml +/.idea/modules.xml +/.idea/vcs.xml +/.idea/workspace.xml +/release \ No newline at end of file diff --git a/pickerview/build.gradle b/pickerview/build.gradle new file mode 100644 index 0000000..338d980 --- /dev/null +++ b/pickerview/build.gradle @@ -0,0 +1,49 @@ +apply plugin: 'com.android.library' +//apply plugin: 'com.novoda.bintray-release'//娣诲姞JCenter鎻掍欢 + + + +android { + compileSdkVersion 31 + + defaultConfig { + minSdkVersion 23 + targetSdkVersion 31 + versionCode 34 + versionName "4.1.9" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + lintOptions { + abortOnError false + } +} + +//allprojects { +// tasks.withType(Javadoc) {//鍏煎涓枃瀛楃 +// options{ +// encoding "UTF-8" +// charSet 'UTF-8' +// links "http://docs.oracle.com/javase/7/docs/api" +// } +// } +//} +//publish { +// userOrg = 'contrarywind'//bintray.com 鐢ㄦ埛鍚�/缁勭粐鍚� user/org name +// groupId = 'com.contrarywind'//JCenter涓婃樉绀虹殑璺緞 path +// artifactId = 'Android-PickerView'//椤圭洰鍚嶇О project name +// publishVersion = '4.1.9'//鐗堟湰鍙� version code +// desc = 'this is a pickerview for android'//椤圭洰鎻忚堪 description +// website = 'https://github.com/Bigkoo/Android-PickerView' //椤圭洰缃戝潃閾炬帴 link +//} + +dependencies { +// compile fileTree(include: ['*.jar'], dir: 'libs') + api project(path: ':wheelview') +// implementation 'com.contrarywind:wheelview:4.1.0' + implementation 'com.android.support:support-annotations:28.0.0' +} \ No newline at end of file diff --git a/pickerview/proguard-rules.pro b/pickerview/proguard-rules.pro new file mode 100644 index 0000000..0cc5098 --- /dev/null +++ b/pickerview/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/Sai/Documents/software/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/pickerview/src/androidTest/java/com/bigkoo/pickerview/ApplicationTest.java b/pickerview/src/androidTest/java/com/bigkoo/pickerview/ApplicationTest.java new file mode 100644 index 0000000..e820eb1 --- /dev/null +++ b/pickerview/src/androidTest/java/com/bigkoo/pickerview/ApplicationTest.java @@ -0,0 +1,13 @@ +package com.bigkoo.pickerview; + +import android.app.Application; +import android.test.ApplicationTestCase; + +/** + * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a> + */ +public class ApplicationTest extends ApplicationTestCase<Application> { + public ApplicationTest() { + super(Application.class); + } +} \ No newline at end of file diff --git a/pickerview/src/main/AndroidManifest.xml b/pickerview/src/main/AndroidManifest.xml new file mode 100644 index 0000000..e2336d9 --- /dev/null +++ b/pickerview/src/main/AndroidManifest.xml @@ -0,0 +1,5 @@ +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.bigkoo.pickerview"> + + +</manifest> diff --git a/pickerview/src/main/java/com/bigkoo/pickerview/adapter/ArrayWheelAdapter.java b/pickerview/src/main/java/com/bigkoo/pickerview/adapter/ArrayWheelAdapter.java new file mode 100644 index 0000000..76f873e --- /dev/null +++ b/pickerview/src/main/java/com/bigkoo/pickerview/adapter/ArrayWheelAdapter.java @@ -0,0 +1,44 @@ +package com.bigkoo.pickerview.adapter; + +import com.contrarywind.adapter.WheelAdapter; + +import java.util.List; + +/** + * The simple Array wheel adapter + * @param <T> the element type + */ +public class ArrayWheelAdapter<T> implements WheelAdapter { + + + // items + private List<T> items; + + /** + * Constructor + * @param items the items + */ + public ArrayWheelAdapter(List<T> items) { + this.items = items; + + } + + @Override + public Object getItem(int index) { + if (index >= 0 && index < items.size()) { + return items.get(index); + } + return ""; + } + + @Override + public int getItemsCount() { + return items.size(); + } + + @Override + public int indexOf(Object o){ + return items.indexOf(o); + } + +} diff --git a/pickerview/src/main/java/com/bigkoo/pickerview/adapter/NumericWheelAdapter.java b/pickerview/src/main/java/com/bigkoo/pickerview/adapter/NumericWheelAdapter.java new file mode 100644 index 0000000..99a9721 --- /dev/null +++ b/pickerview/src/main/java/com/bigkoo/pickerview/adapter/NumericWheelAdapter.java @@ -0,0 +1,47 @@ +package com.bigkoo.pickerview.adapter; + + +import com.contrarywind.adapter.WheelAdapter; + +/** + * Numeric Wheel adapter. + */ +public class NumericWheelAdapter implements WheelAdapter { + + private int minValue; + private int maxValue; + + /** + * Constructor + * @param minValue the wheel min value + * @param maxValue the wheel max value + */ + public NumericWheelAdapter(int minValue, int maxValue) { + this.minValue = minValue; + this.maxValue = maxValue; + } + + @Override + public Object getItem(int index) { + if (index >= 0 && index < getItemsCount()) { + int value = minValue + index; + return value; + } + return 0; + } + + @Override + public int getItemsCount() { + return maxValue - minValue + 1; + } + + @Override + public int indexOf(Object o){ + try { + return (int)o - minValue; + } catch (Exception e) { + return -1; + } + + } +} diff --git a/pickerview/src/main/java/com/bigkoo/pickerview/builder/OptionsPickerBuilder.java b/pickerview/src/main/java/com/bigkoo/pickerview/builder/OptionsPickerBuilder.java new file mode 100644 index 0000000..5176fd7 --- /dev/null +++ b/pickerview/src/main/java/com/bigkoo/pickerview/builder/OptionsPickerBuilder.java @@ -0,0 +1,292 @@ +package com.bigkoo.pickerview.builder; + +import android.content.Context; +import android.graphics.Typeface; +import android.view.View; +import android.view.ViewGroup; + +import com.bigkoo.pickerview.configure.PickerOptions; +import com.bigkoo.pickerview.listener.CustomListener; +import com.bigkoo.pickerview.listener.OnOptionsSelectChangeListener; +import com.bigkoo.pickerview.listener.OnOptionsSelectListener; +import com.bigkoo.pickerview.view.OptionsPickerView; +import com.contrarywind.view.WheelView; + +import androidx.annotation.ColorInt; + +/** + * Created by xiaosongzeem on 2018/3/20. + */ + +public class OptionsPickerBuilder { + + //閰嶇疆绫� + private PickerOptions mPickerOptions; + + + //Required + public OptionsPickerBuilder(Context context, OnOptionsSelectListener listener) { + mPickerOptions = new PickerOptions(PickerOptions.TYPE_PICKER_OPTIONS); + mPickerOptions.context = context; + mPickerOptions.optionsSelectListener = listener; + } + + //Option + public OptionsPickerBuilder setSubmitText(String textContentConfirm) { + mPickerOptions.textContentConfirm = textContentConfirm; + return this; + } + + public OptionsPickerBuilder setCancelText(String textContentCancel) { + mPickerOptions.textContentCancel = textContentCancel; + return this; + } + + public OptionsPickerBuilder setTitleText(String textContentTitle) { + mPickerOptions.textContentTitle = textContentTitle; + return this; + } + + public OptionsPickerBuilder isDialog(boolean isDialog) { + mPickerOptions.isDialog = isDialog; + return this; + } + + public OptionsPickerBuilder addOnCancelClickListener(View.OnClickListener cancelListener) { + mPickerOptions.cancelListener = cancelListener; + return this; + } + + + public OptionsPickerBuilder setSubmitColor(int textColorConfirm) { + mPickerOptions.textColorConfirm = textColorConfirm; + return this; + } + + public OptionsPickerBuilder setCancelColor(int textColorCancel) { + mPickerOptions.textColorCancel = textColorCancel; + return this; + } + + + /** + * {@link #setOutSideColor} instead. + * + * @param backgroundId color resId. + */ + @Deprecated + public OptionsPickerBuilder setBackgroundId(int backgroundId) { + mPickerOptions.outSideColor = backgroundId; + return this; + } + + /** + * 鏄剧ず鏃剁殑澶栭儴鑳屾櫙鑹查鑹�,榛樿鏄伆鑹� + * + * @param outSideColor color resId. + * @return + */ + public OptionsPickerBuilder setOutSideColor(int outSideColor) { + mPickerOptions.outSideColor = outSideColor; + return this; + } + + /** + * ViewGroup 绫诲瀷 + * 璁剧疆PickerView鐨勬樉绀哄鍣� + * + * @param decorView Parent View. + * @return + */ + public OptionsPickerBuilder setDecorView(ViewGroup decorView) { + mPickerOptions.decorView = decorView; + return this; + } + + public OptionsPickerBuilder setLayoutRes(int res, CustomListener listener) { + mPickerOptions.layoutRes = res; + mPickerOptions.customListener = listener; + return this; + } + + public OptionsPickerBuilder setBgColor(int bgColorWheel) { + mPickerOptions.bgColorWheel = bgColorWheel; + return this; + } + + public OptionsPickerBuilder setTitleBgColor(int bgColorTitle) { + mPickerOptions.bgColorTitle = bgColorTitle; + return this; + } + + public OptionsPickerBuilder setTitleColor(int textColorTitle) { + mPickerOptions.textColorTitle = textColorTitle; + return this; + } + + public OptionsPickerBuilder setSubCalSize(int textSizeSubmitCancel) { + mPickerOptions.textSizeSubmitCancel = textSizeSubmitCancel; + return this; + } + + public OptionsPickerBuilder setTitleSize(int textSizeTitle) { + mPickerOptions.textSizeTitle = textSizeTitle; + return this; + } + + public OptionsPickerBuilder setContentTextSize(int textSizeContent) { + mPickerOptions.textSizeContent = textSizeContent; + return this; + } + + public OptionsPickerBuilder setOutSideCancelable(boolean cancelable) { + mPickerOptions.cancelable = cancelable; + return this; + } + + + public OptionsPickerBuilder setLabels(String label1, String label2, String label3) { + mPickerOptions.label1 = label1; + mPickerOptions.label2 = label2; + mPickerOptions.label3 = label3; + return this; + } + + /** + * 璁剧疆Item 鐨勯棿璺濆�嶆暟锛岀敤浜庢帶鍒� Item 楂樺害闂撮殧 + * + * @param lineSpacingMultiplier 娴偣鍨嬶紝1.0-4.0f 涔嬮棿鏈夋晥,瓒呰繃鍒欏彇鏋佸�笺�� + */ + public OptionsPickerBuilder setLineSpacingMultiplier(float lineSpacingMultiplier) { + mPickerOptions.lineSpacingMultiplier = lineSpacingMultiplier; + return this; + } + + /** + * Set item divider line type color. + * + * @param dividerColor color resId. + */ + public OptionsPickerBuilder setDividerColor(@ColorInt int dividerColor) { + mPickerOptions.dividerColor = dividerColor; + return this; + } + + /** + * Set item divider line type. + * + * @param dividerType enum Type {@link WheelView.DividerType} + */ + public OptionsPickerBuilder setDividerType(WheelView.DividerType dividerType) { + mPickerOptions.dividerType = dividerType; + return this; + } + + /** + * Set the textColor of selected item. + * + * @param textColorCenter color res. + */ + public OptionsPickerBuilder setTextColorCenter(int textColorCenter) { + mPickerOptions.textColorCenter = textColorCenter; + return this; + } + + /** + * Set the textColor of outside item. + * + * @param textColorOut color resId. + */ + public OptionsPickerBuilder setTextColorOut(@ColorInt int textColorOut) { + mPickerOptions.textColorOut = textColorOut; + return this; + } + + public OptionsPickerBuilder setTypeface(Typeface font) { + mPickerOptions.font = font; + return this; + } + + public OptionsPickerBuilder setCyclic(boolean cyclic1, boolean cyclic2, boolean cyclic3) { + mPickerOptions.cyclic1 = cyclic1; + mPickerOptions.cyclic2 = cyclic2; + mPickerOptions.cyclic3 = cyclic3; + return this; + } + + public OptionsPickerBuilder setSelectOptions(int option1) { + mPickerOptions.option1 = option1; + return this; + } + + public OptionsPickerBuilder setSelectOptions(int option1, int option2) { + mPickerOptions.option1 = option1; + mPickerOptions.option2 = option2; + return this; + } + + public OptionsPickerBuilder setSelectOptions(int option1, int option2, int option3) { + mPickerOptions.option1 = option1; + mPickerOptions.option2 = option2; + mPickerOptions.option3 = option3; + return this; + } + + public OptionsPickerBuilder setTextXOffset(int xoffset_one, int xoffset_two, int xoffset_three) { + mPickerOptions.x_offset_one = xoffset_one; + mPickerOptions.x_offset_two = xoffset_two; + mPickerOptions.x_offset_three = xoffset_three; + return this; + } + + public OptionsPickerBuilder isCenterLabel(boolean isCenterLabel) { + mPickerOptions.isCenterLabel = isCenterLabel; + return this; + } + + + /** + * 璁剧疆鏈�澶у彲瑙佹暟鐩� + * + * @param count 寤鸿璁剧疆涓� 3 ~ 9涔嬮棿銆� + */ + public OptionsPickerBuilder setItemVisibleCount(int count) { + mPickerOptions.itemsVisibleCount = count; + return this; + } + + /** + * 閫忔槑搴︽槸鍚︽笎鍙� + * + * @param isAlphaGradient true of false + */ + public OptionsPickerBuilder isAlphaGradient(boolean isAlphaGradient) { + mPickerOptions.isAlphaGradient = isAlphaGradient; + return this; + } + + /** + * 鍒囨崲閫夐」鏃讹紝鏄惁杩樺師绗竴椤� + * + * @param isRestoreItem true锛氳繕鍘燂紱 false: 淇濇寔涓婁竴涓�夐」 + * @return TimePickerBuilder + */ + public OptionsPickerBuilder isRestoreItem(boolean isRestoreItem) { + mPickerOptions.isRestoreItem = isRestoreItem; + return this; + } + + /** + * @param listener 鍒囨崲item椤规粴鍔ㄥ仠姝㈡椂锛屽疄鏃跺洖璋冪洃鍚�� + * @return + */ + public OptionsPickerBuilder setOptionsSelectChangeListener(OnOptionsSelectChangeListener listener) { + mPickerOptions.optionsSelectChangeListener = listener; + return this; + } + + + public <T> OptionsPickerView<T> build() { + return new OptionsPickerView<>(mPickerOptions); + } +} diff --git a/pickerview/src/main/java/com/bigkoo/pickerview/builder/TimePickerBuilder.java b/pickerview/src/main/java/com/bigkoo/pickerview/builder/TimePickerBuilder.java new file mode 100644 index 0000000..f001319 --- /dev/null +++ b/pickerview/src/main/java/com/bigkoo/pickerview/builder/TimePickerBuilder.java @@ -0,0 +1,315 @@ +package com.bigkoo.pickerview.builder; + +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; + +import com.bigkoo.pickerview.configure.PickerOptions; +import com.bigkoo.pickerview.listener.CustomListener; +import com.bigkoo.pickerview.listener.OnTimeSelectChangeListener; +import com.bigkoo.pickerview.listener.OnTimeSelectListener; +import com.bigkoo.pickerview.view.TimePickerView; +import com.contrarywind.view.WheelView; + +import java.util.Calendar; + +import androidx.annotation.ColorInt; + +/** + * Created by xiaosongzeem on 2018/3/20. + */ + +public class TimePickerBuilder { + + private PickerOptions mPickerOptions; + + //Required + public TimePickerBuilder(Context context, OnTimeSelectListener listener) { + mPickerOptions = new PickerOptions(PickerOptions.TYPE_PICKER_TIME); + mPickerOptions.context = context; + mPickerOptions.timeSelectListener = listener; + } + + //Option + public TimePickerBuilder setGravity(int gravity) { + mPickerOptions.textGravity = gravity; + return this; + } + + public TimePickerBuilder addOnCancelClickListener(View.OnClickListener cancelListener) { + mPickerOptions.cancelListener = cancelListener; + return this; + } + + /** + * new boolean[]{true, true, true, false, false, false} + * control the "year","month","day","hours","minutes","seconds " display or hide. + * 鍒嗗埆鎺у埗鈥滃勾鈥濃�滄湀鈥濃�滄棩鈥濃�滄椂鈥濃�滃垎鈥濃�滅鈥濈殑鏄剧ず鎴栭殣钘忋�� + * + * @param type 甯冨皵鍨嬫暟缁勶紝闀垮害闇�瑕佽缃负6銆� + * @return TimePickerBuilder + */ + public TimePickerBuilder setType(boolean[] type) { + mPickerOptions.type = type; + return this; + } + + public TimePickerBuilder setSubmitText(String textContentConfirm) { + mPickerOptions.textContentConfirm = textContentConfirm; + return this; + } + + public TimePickerBuilder isDialog(boolean isDialog) { + mPickerOptions.isDialog = isDialog; + return this; + } + + public TimePickerBuilder setCancelText(String textContentCancel) { + mPickerOptions.textContentCancel = textContentCancel; + return this; + } + + public TimePickerBuilder setTitleText(String textContentTitle) { + mPickerOptions.textContentTitle = textContentTitle; + return this; + } + + public TimePickerBuilder setSubmitColor(int textColorConfirm) { + mPickerOptions.textColorConfirm = textColorConfirm; + return this; + } + + public TimePickerBuilder setCancelColor(int textColorCancel) { + mPickerOptions.textColorCancel = textColorCancel; + return this; + } + + /** + * ViewGroup 绫诲瀷鐨勫鍣� + * + * @param decorView 閫夋嫨鍣ㄤ細琚坊鍔犲埌姝ゅ鍣ㄤ腑 + * @return TimePickerBuilder + */ + public TimePickerBuilder setDecorView(ViewGroup decorView) { + mPickerOptions.decorView = decorView; + return this; + } + + public TimePickerBuilder setBgColor(int bgColorWheel) { + mPickerOptions.bgColorWheel = bgColorWheel; + return this; + } + + public TimePickerBuilder setTitleBgColor(int bgColorTitle) { + mPickerOptions.bgColorTitle = bgColorTitle; + return this; + } + + public TimePickerBuilder setTitleColor(int textColorTitle) { + mPickerOptions.textColorTitle = textColorTitle; + return this; + } + + public TimePickerBuilder setSubCalSize(int textSizeSubmitCancel) { + mPickerOptions.textSizeSubmitCancel = textSizeSubmitCancel; + return this; + } + + public TimePickerBuilder setTitleSize(int textSizeTitle) { + mPickerOptions.textSizeTitle = textSizeTitle; + return this; + } + + public TimePickerBuilder setContentTextSize(int textSizeContent) { + mPickerOptions.textSizeContent = textSizeContent; + return this; + } + + /** + * 璁剧疆鏈�澶у彲瑙佹暟鐩� + * + * @param count suggest value: 3, 5, 7, 9 + */ + public TimePickerBuilder setItemVisibleCount(int count) { + mPickerOptions.itemsVisibleCount = count; + return this; + } + + /** + * 閫忔槑搴︽槸鍚︽笎鍙� + * + * @param isAlphaGradient true of false + */ + public TimePickerBuilder isAlphaGradient(boolean isAlphaGradient) { + mPickerOptions.isAlphaGradient = isAlphaGradient; + return this; + } + + /** + * 鍥犱负绯荤粺Calendar鐨勬湀浠芥槸浠�0-11鐨�,鎵�浠ュ鏋滄槸璋冪敤Calendar鐨剆et鏂规硶鏉ヨ缃椂闂�,鏈堜唤鐨勮寖鍥翠篃瑕佹槸浠�0-11 + * + * @param date + * @return TimePickerBuilder + */ + public TimePickerBuilder setDate(Calendar date) { + mPickerOptions.date = date; + return this; + } + + public TimePickerBuilder setLayoutRes(int res, CustomListener customListener) { + mPickerOptions.layoutRes = res; + mPickerOptions.customListener = customListener; + return this; + } + + + /** + * 璁剧疆璧峰鏃堕棿 + * 鍥犱负绯荤粺Calendar鐨勬湀浠芥槸浠�0-11鐨�,鎵�浠ュ鏋滄槸璋冪敤Calendar鐨剆et鏂规硶鏉ヨ缃椂闂�,鏈堜唤鐨勮寖鍥翠篃瑕佹槸浠�0-11 + */ + + public TimePickerBuilder setRangDate(Calendar startDate, Calendar endDate) { + mPickerOptions.startDate = startDate; + mPickerOptions.endDate = endDate; + return this; + } + + + /** + * 璁剧疆闂磋窛鍊嶆暟,浣嗘槸鍙兘鍦�1.0-4.0f涔嬮棿 + * + * @param lineSpacingMultiplier + */ + public TimePickerBuilder setLineSpacingMultiplier(float lineSpacingMultiplier) { + mPickerOptions.lineSpacingMultiplier = lineSpacingMultiplier; + return this; + } + + /** + * 璁剧疆鍒嗗壊绾跨殑棰滆壊 + * + * @param dividerColor + */ + + public TimePickerBuilder setDividerColor(@ColorInt int dividerColor) { + mPickerOptions.dividerColor = dividerColor; + return this; + } + + /** + * 璁剧疆鍒嗗壊绾跨殑绫诲瀷 + * + * @param dividerType + */ + public TimePickerBuilder setDividerType(WheelView.DividerType dividerType) { + mPickerOptions.dividerType = dividerType; + return this; + } + + /** + * {@link #setOutSideColor} instead. + * + * @param backgroundId color resId. + */ + @Deprecated + public TimePickerBuilder setBackgroundId(int backgroundId) { + mPickerOptions.outSideColor = backgroundId; + return this; + } + + /** + * 鏄剧ず鏃剁殑澶栭儴鑳屾櫙鑹查鑹�,榛樿鏄伆鑹� + * + * @param outSideColor + */ + public TimePickerBuilder setOutSideColor(@ColorInt int outSideColor) { + mPickerOptions.outSideColor = outSideColor; + return this; + } + + /** + * 璁剧疆鍒嗗壊绾夸箣闂寸殑鏂囧瓧鐨勯鑹� + * + * @param textColorCenter + */ + public TimePickerBuilder setTextColorCenter(@ColorInt int textColorCenter) { + mPickerOptions.textColorCenter = textColorCenter; + return this; + } + + /** + * 璁剧疆鍒嗗壊绾夸互澶栨枃瀛楃殑棰滆壊 + * + * @param textColorOut + */ + public TimePickerBuilder setTextColorOut(@ColorInt int textColorOut) { + mPickerOptions.textColorOut = textColorOut; + return this; + } + + public TimePickerBuilder isCyclic(boolean cyclic) { + mPickerOptions.cyclic = cyclic; + return this; + } + + public TimePickerBuilder setOutSideCancelable(boolean cancelable) { + mPickerOptions.cancelable = cancelable; + return this; + } + + public TimePickerBuilder setLunarCalendar(boolean lunarCalendar) { + mPickerOptions.isLunarCalendar = lunarCalendar; + return this; + } + + + public TimePickerBuilder setLabel(String label_year, String label_month, String label_day, String label_hours, String label_mins, String label_seconds) { + mPickerOptions.label_year = label_year; + mPickerOptions.label_month = label_month; + mPickerOptions.label_day = label_day; + mPickerOptions.label_hours = label_hours; + mPickerOptions.label_minutes = label_mins; + mPickerOptions.label_seconds = label_seconds; + return this; + } + + /** + * 璁剧疆X杞村�炬枩瑙掑害[ -90 , 90掳] + * + * @param x_offset_year 骞� + * @param x_offset_month 鏈� + * @param x_offset_day 鏃� + * @param x_offset_hours 鏃� + * @param x_offset_minutes 鍒� + * @param x_offset_seconds 绉� + * @return + */ + public TimePickerBuilder setTextXOffset(int x_offset_year, int x_offset_month, int x_offset_day, + int x_offset_hours, int x_offset_minutes, int x_offset_seconds) { + mPickerOptions.x_offset_year = x_offset_year; + mPickerOptions.x_offset_month = x_offset_month; + mPickerOptions.x_offset_day = x_offset_day; + mPickerOptions.x_offset_hours = x_offset_hours; + mPickerOptions.x_offset_minutes = x_offset_minutes; + mPickerOptions.x_offset_seconds = x_offset_seconds; + return this; + } + + public TimePickerBuilder isCenterLabel(boolean isCenterLabel) { + mPickerOptions.isCenterLabel = isCenterLabel; + return this; + } + + /** + * @param listener 鍒囨崲item椤规粴鍔ㄥ仠姝㈡椂锛屽疄鏃跺洖璋冪洃鍚�� + * @return + */ + public TimePickerBuilder setTimeSelectChangeListener(OnTimeSelectChangeListener listener) { + mPickerOptions.timeSelectChangeListener = listener; + return this; + } + + public TimePickerView build() { + return new TimePickerView(mPickerOptions); + } +} diff --git a/pickerview/src/main/java/com/bigkoo/pickerview/configure/PickerOptions.java b/pickerview/src/main/java/com/bigkoo/pickerview/configure/PickerOptions.java new file mode 100644 index 0000000..5a4d688 --- /dev/null +++ b/pickerview/src/main/java/com/bigkoo/pickerview/configure/PickerOptions.java @@ -0,0 +1,114 @@ +package com.bigkoo.pickerview.configure; + +import android.content.Context; +import android.graphics.Typeface; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; + +import com.bigkoo.pickerview.R; +import com.bigkoo.pickerview.listener.CustomListener; +import com.bigkoo.pickerview.listener.OnOptionsSelectChangeListener; +import com.bigkoo.pickerview.listener.OnOptionsSelectListener; +import com.bigkoo.pickerview.listener.OnTimeSelectChangeListener; +import com.bigkoo.pickerview.listener.OnTimeSelectListener; +import com.contrarywind.view.WheelView; + +import java.util.Calendar; + +/** + * Build Options + * Created by xiaosongzeem on 2018/3/8. + */ + +public class PickerOptions { + + //constant + private static final int PICKER_VIEW_BTN_COLOR_NORMAL = 0xFF057dff; + private static final int PICKER_VIEW_BG_COLOR_TITLE = 0xFFf5f5f5; + private static final int PICKER_VIEW_COLOR_TITLE = 0xFF000000; + private static final int PICKER_VIEW_BG_COLOR_DEFAULT = 0xFFFFFFFF; + + public static final int TYPE_PICKER_OPTIONS = 1; + public static final int TYPE_PICKER_TIME = 2; + + public OnOptionsSelectListener optionsSelectListener; + public OnTimeSelectListener timeSelectListener; + public View.OnClickListener cancelListener; + + public OnTimeSelectChangeListener timeSelectChangeListener; + public OnOptionsSelectChangeListener optionsSelectChangeListener; + public CustomListener customListener; + + //options picker + public String label1, label2, label3;//鍗曚綅瀛楃 + public int option1, option2, option3;//榛樿閫変腑椤� + public int x_offset_one, x_offset_two, x_offset_three;//x杞村亸绉婚噺 + + public boolean cyclic1 = false;//鏄惁寰幆锛岄粯璁ゅ惁 + public boolean cyclic2 = false; + public boolean cyclic3 = false; + + public boolean isRestoreItem = false; //鍒囨崲鏃讹紝杩樺師绗竴椤� + + + //time picker + public boolean[] type = new boolean[]{true, true, true, false, false, false};//鏄剧ず绫诲瀷锛岄粯璁ゆ樉绀猴細 骞存湀鏃� + + public Calendar date;//褰撳墠閫変腑鏃堕棿 + public Calendar startDate;//寮�濮嬫椂闂� + public Calendar endDate;//缁堟鏃堕棿 + public int startYear;//寮�濮嬪勾浠� + public int endYear;//缁撳熬骞翠唤 + + public boolean cyclic = false;//鏄惁寰幆 + public boolean isLunarCalendar = false;//鏄惁鏄剧ず鍐滃巻 + + public String label_year, label_month, label_day, label_hours, label_minutes, label_seconds;//鍗曚綅 + public int x_offset_year, x_offset_month, x_offset_day, x_offset_hours, x_offset_minutes, x_offset_seconds;//鍗曚綅 + + + public PickerOptions(int buildType) { + if (buildType == TYPE_PICKER_OPTIONS) { + layoutRes = R.layout.pickerview_options; + } else { + layoutRes = R.layout.pickerview_time; + } + } + + //******* general field ******// + public int layoutRes; + public ViewGroup decorView; + public int textGravity = Gravity.CENTER; + public Context context; + + public String textContentConfirm;//纭畾鎸夐挳鏂囧瓧 + public String textContentCancel;//鍙栨秷鎸夐挳鏂囧瓧 + public String textContentTitle;//鏍囬鏂囧瓧 + + public int textColorConfirm = PICKER_VIEW_BTN_COLOR_NORMAL;//纭畾鎸夐挳棰滆壊 + public int textColorCancel = PICKER_VIEW_BTN_COLOR_NORMAL;//鍙栨秷鎸夐挳棰滆壊 + public int textColorTitle = PICKER_VIEW_COLOR_TITLE;//鏍囬棰滆壊 + + public int bgColorWheel = PICKER_VIEW_BG_COLOR_DEFAULT;//婊氳疆鑳屾櫙棰滆壊 + public int bgColorTitle = PICKER_VIEW_BG_COLOR_DEFAULT;//鏍囬鑳屾櫙棰滆壊 + + public int textSizeSubmitCancel = 17;//纭畾鍙栨秷鎸夐挳澶у皬 + public int textSizeTitle = 18;//鏍囬鏂囧瓧澶у皬 + public int textSizeContent = 18;//鍐呭鏂囧瓧澶у皬 + + public int textColorOut = 0xFFa8a8a8; //鍒嗗壊绾夸互澶栫殑鏂囧瓧棰滆壊 + public int textColorCenter = 0xFF2a2a2a; //鍒嗗壊绾夸箣闂寸殑鏂囧瓧棰滆壊 + public int dividerColor = 0xFFd5d5d5; //鍒嗗壊绾跨殑棰滆壊 + public int outSideColor = -1; //鏄剧ず鏃剁殑澶栭儴鑳屾櫙鑹查鑹�,榛樿鏄伆鑹� + + public float lineSpacingMultiplier = 1.6f; // 鏉$洰闂磋窛鍊嶆暟 榛樿1.6 + public boolean isDialog;//鏄惁鏄璇濇妯″紡 + + public boolean cancelable = true;//鏄惁鑳藉彇娑� + public boolean isCenterLabel = false;//鏄惁鍙樉绀轰腑闂寸殑label,榛樿姣忎釜item閮芥樉绀� + public Typeface font = Typeface.MONOSPACE;//瀛椾綋鏍峰紡 + public WheelView.DividerType dividerType = WheelView.DividerType.FILL;//鍒嗛殧绾跨被鍨� + public int itemsVisibleCount = 9; //鏈�澶у彲瑙佹潯鐩暟 + public boolean isAlphaGradient = false; //閫忔槑搴︽笎鍙� +} diff --git a/pickerview/src/main/java/com/bigkoo/pickerview/listener/CustomListener.java b/pickerview/src/main/java/com/bigkoo/pickerview/listener/CustomListener.java new file mode 100644 index 0000000..26cfef1 --- /dev/null +++ b/pickerview/src/main/java/com/bigkoo/pickerview/listener/CustomListener.java @@ -0,0 +1,13 @@ +package com.bigkoo.pickerview.listener; + +import android.view.View; + +/** + * Created by KyuYi on 2017/3/2. + * E-Mail:kyu_yi@sina.com + * 鍔熻兘锛� + */ + +public interface CustomListener { + void customLayout(View v); +} diff --git a/pickerview/src/main/java/com/bigkoo/pickerview/listener/ISelectTimeCallback.java b/pickerview/src/main/java/com/bigkoo/pickerview/listener/ISelectTimeCallback.java new file mode 100644 index 0000000..775a114 --- /dev/null +++ b/pickerview/src/main/java/com/bigkoo/pickerview/listener/ISelectTimeCallback.java @@ -0,0 +1,10 @@ +package com.bigkoo.pickerview.listener; + +/** + * Created by zengsong on 2018/3/21. + */ + +public interface ISelectTimeCallback { + + public void onTimeSelectChanged(); +} diff --git a/pickerview/src/main/java/com/bigkoo/pickerview/listener/OnDismissListener.java b/pickerview/src/main/java/com/bigkoo/pickerview/listener/OnDismissListener.java new file mode 100644 index 0000000..d3aec7e --- /dev/null +++ b/pickerview/src/main/java/com/bigkoo/pickerview/listener/OnDismissListener.java @@ -0,0 +1,8 @@ +package com.bigkoo.pickerview.listener; + +/** + * Created by Sai on 15/8/9. + */ +public interface OnDismissListener { + public void onDismiss(Object o); +} diff --git a/pickerview/src/main/java/com/bigkoo/pickerview/listener/OnOptionsSelectChangeListener.java b/pickerview/src/main/java/com/bigkoo/pickerview/listener/OnOptionsSelectChangeListener.java new file mode 100644 index 0000000..f01e774 --- /dev/null +++ b/pickerview/src/main/java/com/bigkoo/pickerview/listener/OnOptionsSelectChangeListener.java @@ -0,0 +1,11 @@ +package com.bigkoo.pickerview.listener; + +/** + * Created by xiaosong on 2018/3/20. + */ + +public interface OnOptionsSelectChangeListener { + + void onOptionsSelectChanged(int options1, int options2, int options3); + +} diff --git a/pickerview/src/main/java/com/bigkoo/pickerview/listener/OnOptionsSelectListener.java b/pickerview/src/main/java/com/bigkoo/pickerview/listener/OnOptionsSelectListener.java new file mode 100644 index 0000000..34b6aab --- /dev/null +++ b/pickerview/src/main/java/com/bigkoo/pickerview/listener/OnOptionsSelectListener.java @@ -0,0 +1,13 @@ +package com.bigkoo.pickerview.listener; + +import android.view.View; + +/** + * Created by xiaosong on 2018/3/20. + */ + +public interface OnOptionsSelectListener { + + void onOptionsSelect(int options1, int options2, int options3, View v); + +} diff --git a/pickerview/src/main/java/com/bigkoo/pickerview/listener/OnTimeSelectChangeListener.java b/pickerview/src/main/java/com/bigkoo/pickerview/listener/OnTimeSelectChangeListener.java new file mode 100644 index 0000000..40109f2 --- /dev/null +++ b/pickerview/src/main/java/com/bigkoo/pickerview/listener/OnTimeSelectChangeListener.java @@ -0,0 +1,12 @@ +package com.bigkoo.pickerview.listener; + +import java.util.Date; + +/** + * Created by xiaosong on 2018/3/20. + */ + +public interface OnTimeSelectChangeListener { + + void onTimeSelectChanged(Date date); +} diff --git a/pickerview/src/main/java/com/bigkoo/pickerview/listener/OnTimeSelectListener.java b/pickerview/src/main/java/com/bigkoo/pickerview/listener/OnTimeSelectListener.java new file mode 100644 index 0000000..ab85075 --- /dev/null +++ b/pickerview/src/main/java/com/bigkoo/pickerview/listener/OnTimeSelectListener.java @@ -0,0 +1,14 @@ +package com.bigkoo.pickerview.listener; + +import android.view.View; + +import java.util.Date; + +/** + * Created by xiaosong on 2018/3/20. + */ + +public interface OnTimeSelectListener { + + void onTimeSelect(Date date, View v); +} diff --git a/pickerview/src/main/java/com/bigkoo/pickerview/utils/ChinaDate.java b/pickerview/src/main/java/com/bigkoo/pickerview/utils/ChinaDate.java new file mode 100644 index 0000000..74920c0 --- /dev/null +++ b/pickerview/src/main/java/com/bigkoo/pickerview/utils/ChinaDate.java @@ -0,0 +1,352 @@ +package com.bigkoo.pickerview.utils; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Locale; + +public class ChinaDate { + + /** + * <lunarInfo 鏁扮粍鍊肩殑璁$畻鍘熺悊> + * + * 0x浠h〃鍗佸叚杩涘埗锛屽悗闈㈢殑浜斾綅鏁版槸鍗佸叚杩涘埗鏁般�� + * 涓句釜渚嬪瓙: 1980骞寸殑鏁版嵁鏄� 0x095b0 + * 浜岃繘鍒�: 0000 1001 0101 1011 0000 + * 1-4: 琛ㄧず褰撳勾鏄惁涓洪棸骞达紝鏄殑璇濅负1锛屽惁鍒欎负0銆� + * 5-16: 涓洪櫎浜嗛棸鏈堝鐨勬甯告湀浠芥槸澶ф湀杩樻槸灏忔湀锛�1涓�30澶╋紝0涓�29澶┿�� + * 娉ㄦ剰: 浠�1鏈堝埌12鏈堝搴旂殑鏄16浣嶅埌绗�5浣嶃�� + * 17-20: 闈為棸骞翠负0锛屽ぇ浜�0琛ㄧず闂版湀鏈堜唤锛屼粎褰撳瓨鍦ㄩ棸鏈堢殑鎯呭喌涓嬫湁鎰忎箟銆� + */ + final private static long[] lunarInfo = new long[]{ + 0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2,//1900-1909 + 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977,//1910-1919 + 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970,//1920-1929 + 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950,//1930-1939 + 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557,//1940-1949 + 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0,//1950-1959 + 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0,//1960-1969 + 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6,//1970-1979 + 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570,//1980-1989 + 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0,//1990-1999 + 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5,//2000-2009 + 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930,//2010-2019 + 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530,//2020-2029 + 0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45,//2030-2039 + 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0,//2040-2049 + 0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0,//2050-2059 + 0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4,//2060-2069 + 0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0,//2070-2079 + 0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160,//2080-2089 + 0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252,//2090-2099 + 0x0d520};//2100 + + private final static String[] nStr1 = new String[]{"", "姝�", "浜�", "涓�", "鍥�", + "浜�", "鍏�", "涓�", "鍏�", "涔�", "鍗�", "鍐�", "鑵�"}; + private final static String[] Gan = new String[]{"鐢�", "涔�", "涓�", "涓�", "鎴�", + "宸�", "搴�", "杈�", "澹�", "鐧�"}; + private final static String[] Zhi = new String[]{"瀛�", "涓�", "瀵�", "鍗�", "杈�", + "宸�", "鍗�", "鏈�", "鐢�", "閰�", "鎴�", "浜�"}; + private final static String[] Animals = new String[]{"榧�", "鐗�", "铏�", "鍏�", + "榫�", "铔�", "椹�", "缇�", "鐚�", "楦�", "鐙�", "鐚�"}; + + /** + * 浼犲洖鍐滃巻 + * + * @param y 骞寸殑鎬诲ぉ鏁� + * @return 鍐滃巻 + */ + final private static int lYearDays(int y) { + int i, sum = 348; + for (i = 0x8000; i > 0x8; i >>= 1) { + if ((lunarInfo[y - 1900] & i) != 0) + sum += 1; + } + return (sum + leapDays(y)); + } + + /** + * 浼犲洖鍐滃巻 + * + * @param y 骞撮棸鏈堢殑澶╂暟 + * @return 鍐滃巻 + */ + final public static int leapDays(int y) { + if (leapMonth(y) != 0) { + if ((lunarInfo[y - 1900] & 0x10000) != 0) + return 30; + else + return 29; + } else + return 0; + } + + /** + * 浼犲洖鍐滃巻 + * + * @param y 骞撮棸鍝釜鏈� 1-12 , 娌¢棸浼犲洖 0 + * @return 鍐滃巻 + */ + final public static int leapMonth(int y) { + return (int) (lunarInfo[y - 1900] & 0xf); + } + + /** + * 浼犲洖鍐滃巻 y + * + * @param y y骞磎鏈堢殑鎬诲ぉ鏁� + * @param m y骞磎鏈堢殑鎬诲ぉ鏁� + * @return 鍐滃巻 + */ + final public static int monthDays(int y, int m) { + if ((lunarInfo[y - 1900] & (0x10000 >> m)) == 0) + return 29; + else + return 30; + } + + /** + * 浼犲洖鍐滃巻 + * + * @param y 骞寸殑鐢熻倴 + * @return + */ + final public static String AnimalsYear(int y) { + return Animals[(y - 4) % 12]; + } + + /** + * 浼犲叆 + * + * @param num 鏈堟棩鐨刼ffset 浼犲洖骞叉敮,0鏄敳瀛� + * @return 骞叉敮 + */ + final private static String cyclicalm(int num) { + return (Gan[num % 10] + Zhi[num % 12]); + } + + /** + * 浼犲叆 offset 浼犲洖骞叉敮 + * + * @param y 0鏄敳瀛� + * @return 骞叉敮 + */ + final public static String cyclical(int y) { + int num = y - 1900 + 36; + return (cyclicalm(num)); + } + + + /** + * 浼犲嚭y骞磎鏈坉鏃ュ搴旂殑鍐滃巻.year0 .month1 .day2 .yearCyl3 .monCyl4 .dayCyl5 .isLeap6 + * + * @param y 骞� + * @param m 鏈� + * @param d 鏃� + * @return y骞磎鏈坉鏃ュ搴旂殑鍐滃巻 + */ + final public static long[] calElement(int y, int m, int d) { + long[] nongDate = new long[7]; + int i = 0, temp = 0, leap = 0; + Date baseDate = new GregorianCalendar(0 + 1900, 0, 31).getTime(); + Date objDate = new GregorianCalendar(y, m - 1, d).getTime(); + long offset = (objDate.getTime() - baseDate.getTime()) / 86400000L; + nongDate[5] = offset + 40; + nongDate[4] = 14; + for (i = 1900; i < 2100 && offset > 0; i++) { + temp = lYearDays(i); + offset -= temp; + nongDate[4] += 12; + } + if (offset < 0) { + offset += temp; + i--; + nongDate[4] -= 12; + } + nongDate[0] = i; + nongDate[3] = i - 1864; + leap = leapMonth(i); // 闂板摢涓湀 + nongDate[6] = 0; + for (i = 1; i < 13 && offset > 0; i++) { + // 闂版湀 + if (leap > 0 && i == (leap + 1) && nongDate[6] == 0) { + --i; + nongDate[6] = 1; + temp = leapDays((int) nongDate[0]); + } else { + temp = monthDays((int) nongDate[0], i); + } + // 瑙i櫎闂版湀 + if (nongDate[6] == 1 && i == (leap + 1)) + nongDate[6] = 0; + offset -= temp; + if (nongDate[6] == 0) + nongDate[4]++; + } + if (offset == 0 && leap > 0 && i == leap + 1) { + if (nongDate[6] == 1) { + nongDate[6] = 0; + } else { + nongDate[6] = 1; + --i; + --nongDate[4]; + } + } + if (offset < 0) { + offset += temp; + --i; + --nongDate[4]; + } + nongDate[1] = i; + nongDate[2] = offset + 1; + return nongDate; + } + + public final static String getChinaDate(int day) { + String a = ""; + if (day == 10) + return "鍒濆崄"; + if (day == 20) + return "浜屽崄"; + if (day == 30) + return "涓夊崄"; + int two = (int) ((day) / 10); + if (two == 0) + a = "鍒�"; + if (two == 1) + a = "鍗�"; + if (two == 2) + a = "寤�"; + if (two == 3) + a = "涓�"; + int one = (int) (day % 10); + switch (one) { + case 1: + a += "涓�"; + break; + case 2: + a += "浜�"; + break; + case 3: + a += "涓�"; + break; + case 4: + a += "鍥�"; + break; + case 5: + a += "浜�"; + break; + case 6: + a += "鍏�"; + break; + case 7: + a += "涓�"; + break; + case 8: + a += "鍏�"; + break; + case 9: + a += "涔�"; + break; + } + return a; + } + + public static String getCurrentLunarDate() { + Calendar today = Calendar.getInstance(Locale.SIMPLIFIED_CHINESE); + int year = today.get(Calendar.YEAR); + int month = today.get(Calendar.MONTH) + 1; + int date = today.get(Calendar.DATE); + long[] l = calElement(year, month, date); + StringBuffer sToday = new StringBuffer(); + try { + sToday.append(sdf.format(today.getTime())); + sToday.append(" 鍐滃巻"); + sToday.append(cyclical(year)); + sToday.append('('); + sToday.append(AnimalsYear(year)); + sToday.append(")骞�"); + sToday.append(nStr1[(int) l[1]]); + sToday.append("鏈�"); + sToday.append(getChinaDate((int) (l[2]))); + return sToday.toString(); + } finally { + sToday = null; + } + } + + public static String oneDay(int year, int month, int day) { + // Calendar today = Calendar.getInstance(Locale.SIMPLIFIED_CHINESE); + long[] l = calElement(year, month, day); + StringBuffer sToday = new StringBuffer(); + try { + // sToday.append(sdf.format(today.getTime())); + sToday.append(" 鍐滃巻"); + sToday.append(cyclical(year)); + sToday.append('('); + sToday.append(AnimalsYear(year)); + sToday.append(")骞�"); + sToday.append(nStr1[(int) l[1]]); + sToday.append("鏈�"); + sToday.append(getChinaDate((int) (l[2]))); + return sToday.toString(); + } finally { + sToday = null; + } + } + + private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy骞碝鏈坉鏃� EEEEE"); + + + /** + * @param lunarYear 鍐滃巻骞翠唤 + * @return String of Ganzhi: 鐢插瓙骞� + * 鐢蹭箼涓欎竵鎴婂繁搴氳緵澹櫢 + * 瀛愪笐瀵呭嵂杈板烦鏃犱负鐢抽厜鎴屼亥 + */ + public static String getLunarYearText(int lunarYear) { + return Gan[(lunarYear - 4) % 10] + Zhi[(lunarYear - 4) % 12] + "骞�"; + } + + + public static ArrayList<String> getYears(int startYear, int endYear) { + ArrayList<String> years = new ArrayList<>(); + for (int i = startYear; i < endYear; i++) { + years.add(String.format("%s(%d)", getLunarYearText(i), i)); + } + return years; + } + + /** + * 鑾峰彇year骞寸殑鎵�鏈夋湀浠� + * + * @param year 骞� + * @return 鏈堜唤鍒楄〃 + */ + public static ArrayList<String> getMonths(int year) { + ArrayList<String> baseMonths = new ArrayList<>(); + for (int i = 1; i < nStr1.length; i++) { + baseMonths.add(nStr1[i] + "鏈�"); + } + if (leapMonth(year) != 0) { + baseMonths.add(leapMonth(year), "闂�" + nStr1[leapMonth(year)] + "鏈�"); + } + return baseMonths; + } + + /** + * 鑾峰彇姣忔湀鍐滃巻鏄剧ず鍚嶇О + * + * @param maxDay 澶� + * @return 鍚嶇О鍒楄〃 + */ + public static ArrayList<String> getLunarDays(int maxDay) { + ArrayList<String> days = new ArrayList<>(); + for (int i = 1; i <= maxDay; i++) { + days.add(getChinaDate(i)); + } + return days; + } +} diff --git a/pickerview/src/main/java/com/bigkoo/pickerview/utils/LunarCalendar.java b/pickerview/src/main/java/com/bigkoo/pickerview/utils/LunarCalendar.java new file mode 100644 index 0000000..7986c0d --- /dev/null +++ b/pickerview/src/main/java/com/bigkoo/pickerview/utils/LunarCalendar.java @@ -0,0 +1,429 @@ +package com.bigkoo.pickerview.utils; + +import android.util.Log; + +import java.util.Date; +import java.util.GregorianCalendar; + +/** + * author: Jerry on 2016/7/11 11:29. + * description:宸ュ叿绫伙紝瀹炵幇鍏啘鍘嗕簰杞� + */ +public class LunarCalendar { + + /** + * 鏀寔杞崲鐨勬渶灏忓啘鍘嗗勾浠� + */ + public static final int MIN_YEAR = 1900; + /** + * 鏀寔杞崲鐨勬渶澶у啘鍘嗗勾浠� + */ + public static final int MAX_YEAR = 2099; + + /** + * 鍏巻姣忔湀鍓嶇殑澶╂暟 + */ + private static final int DAYS_BEFORE_MONTH[] = {0, 31, 59, 90, 120, 151, 181, + 212, 243, 273, 304, 334, 365}; + + /** + * 鐢ㄦ潵琛ㄧず1900骞村埌2099骞撮棿鍐滃巻骞翠唤鐨勭浉鍏充俊鎭紝鍏�24浣峛it鐨�16杩涘埗琛ㄧず锛屽叾涓細 + * 1. 鍓�4浣嶈〃绀鸿骞撮棸鍝釜鏈堬紱 + * 2. 5-17浣嶈〃绀哄啘鍘嗗勾浠�13涓湀鐨勫ぇ灏忔湀鍒嗗竷锛�0琛ㄧず灏忥紝1琛ㄧず澶э紱 + * 3. 鏈�鍚�7浣嶈〃绀哄啘鍘嗗勾棣栵紙姝f湀鍒濅竴锛夊搴旂殑鍏巻鏃ユ湡銆� + * <p> + * 浠�2014骞寸殑鏁版嵁0x955ABF涓轰緥璇存槑锛� + * 1001 0101 0101 1010 1011 1111 + * 闂颁節鏈� 鍐滃巻姝f湀鍒濅竴瀵瑰簲鍏巻1鏈�31鍙� + */ + private static final int LUNAR_INFO[] = { + 0x84B6BF,/*1900*/ + 0x04AE53, 0x0A5748, 0x5526BD, 0x0D2650, 0x0D9544, 0x46AAB9, 0x056A4D, 0x09AD42, 0x24AEB6, 0x04AE4A,/*1901-1910*/ + 0x6A4DBE, 0x0A4D52, 0x0D2546, 0x5D52BA, 0x0B544E, 0x0D6A43, 0x296D37, 0x095B4B, 0x749BC1, 0x049754,/*1911-1920*/ + 0x0A4B48, 0x5B25BC, 0x06A550, 0x06D445, 0x4ADAB8, 0x02B64D, 0x095742, 0x2497B7, 0x04974A, 0x664B3E,/*1921-1930*/ + 0x0D4A51, 0x0EA546, 0x56D4BA, 0x05AD4E, 0x02B644, 0x393738, 0x092E4B, 0x7C96BF, 0x0C9553, 0x0D4A48,/*1931-1940*/ + 0x6DA53B, 0x0B554F, 0x056A45, 0x4AADB9, 0x025D4D, 0x092D42, 0x2C95B6, 0x0A954A, 0x7B4ABD, 0x06CA51,/*1941-1950*/ + 0x0B5546, 0x555ABB, 0x04DA4E, 0x0A5B43, 0x352BB8, 0x052B4C, 0x8A953F, 0x0E9552, 0x06AA48, 0x6AD53C,/*1951-1960*/ + 0x0AB54F, 0x04B645, 0x4A5739, 0x0A574D, 0x052642, 0x3E9335, 0x0D9549, 0x75AABE, 0x056A51, 0x096D46,/*1961-1970*/ + 0x54AEBB, 0x04AD4F, 0x0A4D43, 0x4D26B7, 0x0D254B, 0x8D52BF, 0x0B5452, 0x0B6A47, 0x696D3C, 0x095B50,/*1971-1980*/ + 0x049B45, 0x4A4BB9, 0x0A4B4D, 0xAB25C2, 0x06A554, 0x06D449, 0x6ADA3D, 0x0AB651, 0x095746, 0x5497BB,/*1981-1990*/ + 0x04974F, 0x064B44, 0x36A537, 0x0EA54A, 0x86B2BF, 0x05AC53, 0x0AB647, 0x5936BC, 0x092E50, 0x0C9645,/*1991-2000*/ + 0x4D4AB8, 0x0D4A4C, 0x0DA541, 0x25AAB6, 0x056A49, 0x7AADBD, 0x025D52, 0x092D47, 0x5C95BA, 0x0A954E,/*2001-2010*/ + 0x0B4A43, 0x4B5537, 0x0AD54A, 0x955ABF, 0x04BA53, 0x0A5B48, 0x652BBC, 0x052B50, 0x0A9345, 0x474AB9,/*2011-2020*/ + 0x06AA4C, 0x0AD541, 0x24DAB6, 0x04B64A, 0x6a573D, 0x0A4E51, 0x0D2646, 0x5E933A, 0x0D534D, 0x05AA43,/*2021-2030*/ + 0x36B537, 0x096D4B, 0xB4AEBF, 0x04AD53, 0x0A4D48, 0x6D25BC, 0x0D254F, 0x0D5244, 0x5DAA38, 0x0B5A4C,/*2031-2040*/ + 0x056D41, 0x24ADB6, 0x049B4A, 0x7A4BBE, 0x0A4B51, 0x0AA546, 0x5B52BA, 0x06D24E, 0x0ADA42, 0x355B37,/*2041-2050*/ + 0x09374B, 0x8497C1, 0x049753, 0x064B48, 0x66A53C, 0x0EA54F, 0x06AA44, 0x4AB638, 0x0AAE4C, 0x092E42,/*2051-2060*/ + 0x3C9735, 0x0C9649, 0x7D4ABD, 0x0D4A51, 0x0DA545, 0x55AABA, 0x056A4E, 0x0A6D43, 0x452EB7, 0x052D4B,/*2061-2070*/ + 0x8A95BF, 0x0A9553, 0x0B4A47, 0x6B553B, 0x0AD54F, 0x055A45, 0x4A5D38, 0x0A5B4C, 0x052B42, 0x3A93B6,/*2071-2080*/ + 0x069349, 0x7729BD, 0x06AA51, 0x0AD546, 0x54DABA, 0x04B64E, 0x0A5743, 0x452738, 0x0D264A, 0x8E933E,/*2081-2090*/ + 0x0D5252, 0x0DAA47, 0x66B53B, 0x056D4F, 0x04AE45, 0x4A4EB9, 0x0A4D4C, 0x0D1541, 0x2D92B5 /*2091-2099*/ + }; + private static int[] solar_1_1 = {1887, 0xec04c, 0xec23f, 0xec435, 0xec649, + 0xec83e, 0xeca51, 0xecc46, 0xece3a, 0xed04d, 0xed242, 0xed436, + 0xed64a, 0xed83f, 0xeda53, 0xedc48, 0xede3d, 0xee050, 0xee244, + 0xee439, 0xee64d, 0xee842, 0xeea36, 0xeec4a, 0xeee3e, 0xef052, + 0xef246, 0xef43a, 0xef64e, 0xef843, 0xefa37, 0xefc4b, 0xefe41, + 0xf0054, 0xf0248, 0xf043c, 0xf0650, 0xf0845, 0xf0a38, 0xf0c4d, + 0xf0e42, 0xf1037, 0xf124a, 0xf143e, 0xf1651, 0xf1846, 0xf1a3a, + 0xf1c4e, 0xf1e44, 0xf2038, 0xf224b, 0xf243f, 0xf2653, 0xf2848, + 0xf2a3b, 0xf2c4f, 0xf2e45, 0xf3039, 0xf324d, 0xf3442, 0xf3636, + 0xf384a, 0xf3a3d, 0xf3c51, 0xf3e46, 0xf403b, 0xf424e, 0xf4443, + 0xf4638, 0xf484c, 0xf4a3f, 0xf4c52, 0xf4e48, 0xf503c, 0xf524f, + 0xf5445, 0xf5639, 0xf584d, 0xf5a42, 0xf5c35, 0xf5e49, 0xf603e, + 0xf6251, 0xf6446, 0xf663b, 0xf684f, 0xf6a43, 0xf6c37, 0xf6e4b, + 0xf703f, 0xf7252, 0xf7447, 0xf763c, 0xf7850, 0xf7a45, 0xf7c39, + 0xf7e4d, 0xf8042, 0xf8254, 0xf8449, 0xf863d, 0xf8851, 0xf8a46, + 0xf8c3b, 0xf8e4f, 0xf9044, 0xf9237, 0xf944a, 0xf963f, 0xf9853, + 0xf9a47, 0xf9c3c, 0xf9e50, 0xfa045, 0xfa238, 0xfa44c, 0xfa641, + 0xfa836, 0xfaa49, 0xfac3d, 0xfae52, 0xfb047, 0xfb23a, 0xfb44e, + 0xfb643, 0xfb837, 0xfba4a, 0xfbc3f, 0xfbe53, 0xfc048, 0xfc23c, + 0xfc450, 0xfc645, 0xfc839, 0xfca4c, 0xfcc41, 0xfce36, 0xfd04a, + 0xfd23d, 0xfd451, 0xfd646, 0xfd83a, 0xfda4d, 0xfdc43, 0xfde37, + 0xfe04b, 0xfe23f, 0xfe453, 0xfe648, 0xfe83c, 0xfea4f, 0xfec44, + 0xfee38, 0xff04c, 0xff241, 0xff436, 0xff64a, 0xff83e, 0xffa51, + 0xffc46, 0xffe3a, 0x10004e, 0x100242, 0x100437, 0x10064b, 0x100841, + 0x100a53, 0x100c48, 0x100e3c, 0x10104f, 0x101244, 0x101438, + 0x10164c, 0x101842, 0x101a35, 0x101c49, 0x101e3d, 0x102051, + 0x102245, 0x10243a, 0x10264e, 0x102843, 0x102a37, 0x102c4b, + 0x102e3f, 0x103053, 0x103247, 0x10343b, 0x10364f, 0x103845, + 0x103a38, 0x103c4c, 0x103e42, 0x104036, 0x104249, 0x10443d, + 0x104651, 0x104846, 0x104a3a, 0x104c4e, 0x104e43, 0x105038, + 0x10524a, 0x10543e, 0x105652, 0x105847, 0x105a3b, 0x105c4f, + 0x105e45, 0x106039, 0x10624c, 0x106441, 0x106635, 0x106849, + 0x106a3d, 0x106c51, 0x106e47, 0x10703c, 0x10724f, 0x107444, + 0x107638, 0x10784c, 0x107a3f, 0x107c53, 0x107e48}; + private static int[] lunar_month_days = {1887, 0x1694, 0x16aa, 0x4ad5, + 0xab6, 0xc4b7, 0x4ae, 0xa56, 0xb52a, 0x1d2a, 0xd54, 0x75aa, 0x156a, + 0x1096d, 0x95c, 0x14ae, 0xaa4d, 0x1a4c, 0x1b2a, 0x8d55, 0xad4, + 0x135a, 0x495d, 0x95c, 0xd49b, 0x149a, 0x1a4a, 0xbaa5, 0x16a8, + 0x1ad4, 0x52da, 0x12b6, 0xe937, 0x92e, 0x1496, 0xb64b, 0xd4a, + 0xda8, 0x95b5, 0x56c, 0x12ae, 0x492f, 0x92e, 0xcc96, 0x1a94, + 0x1d4a, 0xada9, 0xb5a, 0x56c, 0x726e, 0x125c, 0xf92d, 0x192a, + 0x1a94, 0xdb4a, 0x16aa, 0xad4, 0x955b, 0x4ba, 0x125a, 0x592b, + 0x152a, 0xf695, 0xd94, 0x16aa, 0xaab5, 0x9b4, 0x14b6, 0x6a57, + 0xa56, 0x1152a, 0x1d2a, 0xd54, 0xd5aa, 0x156a, 0x96c, 0x94ae, + 0x14ae, 0xa4c, 0x7d26, 0x1b2a, 0xeb55, 0xad4, 0x12da, 0xa95d, + 0x95a, 0x149a, 0x9a4d, 0x1a4a, 0x11aa5, 0x16a8, 0x16d4, 0xd2da, + 0x12b6, 0x936, 0x9497, 0x1496, 0x1564b, 0xd4a, 0xda8, 0xd5b4, + 0x156c, 0x12ae, 0xa92f, 0x92e, 0xc96, 0x6d4a, 0x1d4a, 0x10d65, + 0xb58, 0x156c, 0xb26d, 0x125c, 0x192c, 0x9a95, 0x1a94, 0x1b4a, + 0x4b55, 0xad4, 0xf55b, 0x4ba, 0x125a, 0xb92b, 0x152a, 0x1694, + 0x96aa, 0x15aa, 0x12ab5, 0x974, 0x14b6, 0xca57, 0xa56, 0x1526, + 0x8e95, 0xd54, 0x15aa, 0x49b5, 0x96c, 0xd4ae, 0x149c, 0x1a4c, + 0xbd26, 0x1aa6, 0xb54, 0x6d6a, 0x12da, 0x1695d, 0x95a, 0x149a, + 0xda4b, 0x1a4a, 0x1aa4, 0xbb54, 0x16b4, 0xada, 0x495b, 0x936, + 0xf497, 0x1496, 0x154a, 0xb6a5, 0xda4, 0x15b4, 0x6ab6, 0x126e, + 0x1092f, 0x92e, 0xc96, 0xcd4a, 0x1d4a, 0xd64, 0x956c, 0x155c, + 0x125c, 0x792e, 0x192c, 0xfa95, 0x1a94, 0x1b4a, 0xab55, 0xad4, + 0x14da, 0x8a5d, 0xa5a, 0x1152b, 0x152a, 0x1694, 0xd6aa, 0x15aa, + 0xab4, 0x94ba, 0x14b6, 0xa56, 0x7527, 0xd26, 0xee53, 0xd54, 0x15aa, + 0xa9b5, 0x96c, 0x14ae, 0x8a4e, 0x1a4c, 0x11d26, 0x1aa4, 0x1b54, + 0xcd6a, 0xada, 0x95c, 0x949d, 0x149a, 0x1a2a, 0x5b25, 0x1aa4, + 0xfb52, 0x16b4, 0xaba, 0xa95b, 0x936, 0x1496, 0x9a4b, 0x154a, + 0x136a5, 0xda4, 0x15ac}; + + /** + * 灏嗗啘鍘嗘棩鏈熻浆鎹负鍏巻鏃ユ湡 + * + * @param year 鍐滃巻骞翠唤 + * @param month 鍐滃巻鏈� + * @param monthDay 鍐滃巻鏃� + * @param isLeapMonth 璇ユ湀鏄惁鏄棸鏈� + * @return 杩斿洖鍐滃巻鏃ユ湡瀵瑰簲鐨勫叕鍘嗘棩鏈燂紝year0, month1, day2. + */ + public static final int[] lunarToSolar(int year, int month, int monthDay, + boolean isLeapMonth) { + int dayOffset; + int leapMonth; + int i; + + if (year < MIN_YEAR || year > MAX_YEAR || month < 1 || month > 12 + || monthDay < 1 || monthDay > 30) { + throw new IllegalArgumentException( + "Illegal lunar date, must be like that:\n\t" + + "year : 1900~2099\n\t" + + "month : 1~12\n\t" + + "day : 1~30"); + } + + dayOffset = (LUNAR_INFO[year - MIN_YEAR] & 0x001F) - 1; + + if (((LUNAR_INFO[year - MIN_YEAR] & 0x0060) >> 5) == 2) + dayOffset += 31; + + for (i = 1; i < month; i++) { + if ((LUNAR_INFO[year - MIN_YEAR] & (0x80000 >> (i - 1))) == 0) + dayOffset += 29; + else + dayOffset += 30; + } + + dayOffset += monthDay; + leapMonth = (LUNAR_INFO[year - MIN_YEAR] & 0xf00000) >> 20; + + // 杩欎竴骞存湁闂版湀 + if (leapMonth != 0) { + if (month > leapMonth || (month == leapMonth && isLeapMonth)) { + if ((LUNAR_INFO[year - MIN_YEAR] & (0x80000 >> (month - 1))) == 0) + dayOffset += 29; + else + dayOffset += 30; + } + } + + if (dayOffset > 366 || (year % 4 != 0 && dayOffset > 365)) { + year += 1; + if (year % 4 == 1) + dayOffset -= 366; + else + dayOffset -= 365; + } + + int[] solarInfo = new int[3]; + for (i = 1; i < 13; i++) { + int iPos = DAYS_BEFORE_MONTH[i]; + if (year % 4 == 0 && i > 2) { + iPos += 1; + } + + if (year % 4 == 0 && i == 2 && iPos + 1 == dayOffset) { + solarInfo[1] = i; + solarInfo[2] = dayOffset - 31; + break; + } + + if (iPos >= dayOffset) { + solarInfo[1] = i; + iPos = DAYS_BEFORE_MONTH[i - 1]; + if (year % 4 == 0 && i > 2) { + iPos += 1; + } + if (dayOffset > iPos) + solarInfo[2] = dayOffset - iPos; + else if (dayOffset == iPos) { + if (year % 4 == 0 && i == 2) + solarInfo[2] = DAYS_BEFORE_MONTH[i] - DAYS_BEFORE_MONTH[i - 1] + 1; + else + solarInfo[2] = DAYS_BEFORE_MONTH[i] - DAYS_BEFORE_MONTH[i - 1]; + + } else + solarInfo[2] = dayOffset; + break; + } + } + solarInfo[0] = year; + + return solarInfo; + } + + public static final int[] solarToLunar(int year, int month, int monthDay) { + int[] lunarDate = new int[4]; + + int index = year - solar_1_1[0]; + int data = (year << 9) | (month << 5) + | (monthDay); + int solar11 = 0; + if (solar_1_1[index] > data) { + index--; + } + solar11 = solar_1_1[index]; + int y = getBitInt(solar11, 12, 9); + int m = getBitInt(solar11, 4, 5); + int d = getBitInt(solar11, 5, 0); + long offset = solarToInt(year, month, + monthDay) - solarToInt(y, m, d); + + int days = lunar_month_days[index]; + int leap = getBitInt(days, 4, 13); + + int lunarY = index + solar_1_1[0]; + int lunarM = 1; + int lunarD = 1; + offset += 1; + + for (int i = 0; i < 13; i++) { + int dm = getBitInt(days, 1, 12 - i) == 1 ? 30 : 29; + if (offset > dm) { + lunarM++; + offset -= dm; + } else { + break; + } + } + lunarD = (int) (offset); + lunarDate[0] = lunarY; + lunarDate[1] = lunarM; + boolean isLeap = false; + if (leap != 0 && lunarM > leap) { + lunarDate[1] = lunarM - 1; + if (lunarM == leap + 1) { + isLeap = true; + } + } + + lunarDate[2] = lunarD; + lunarDate[3] = isLeap ? 1 : 0; + //Log.i("----------->",year+"-"+month+"-"+monthDay+"====>"+lunarDate[0]+"-"+lunarDate[1]+"-"+lunarDate[2]+"-"+lunarDate[3]); + return lunarDate; + } + + + /** + * 灏嗗叕鍘嗘棩鏈熻浆鎹负鍐滃巻鏃ユ湡锛屼笖鏍囪瘑鏄惁鏄棸鏈� + * + * @param year + * @param month + * @param monthDay + * @return 杩斿洖鍏巻鏃ユ湡瀵瑰簲鐨勫啘鍘嗘棩鏈燂紝year0锛宮onth1锛宒ay2锛宭eap3 + * @deprecated 涓嶅噯纭� + */ + @Deprecated + public static final int[] solarToLunarDeprecated(int year, int month, int monthDay) { + int[] lunarDate = new int[4]; + Date baseDate = new GregorianCalendar(1900, 0, 31).getTime(); + Date objDate = new GregorianCalendar(year, month - 1, monthDay).getTime(); + int offset = (int) ((objDate.getTime() - baseDate.getTime()) / 86400000L); + + // 鐢╫ffset鍑忓幓姣忓啘鍘嗗勾鐨勫ぉ鏁拌绠楀綋澶╂槸鍐滃巻绗嚑澶� + // iYear鏈�缁堢粨鏋滄槸鍐滃巻鐨勫勾浠�, offset鏄綋骞寸殑绗嚑澶� + int iYear, daysOfYear = 0; + for (iYear = MIN_YEAR; iYear <= MAX_YEAR && offset > 0; iYear++) { + daysOfYear = daysInLunarYear(iYear); + offset -= daysOfYear; + } + if (offset < 0) { + offset += daysOfYear; + iYear--; + } + + // 鍐滃巻骞翠唤 + lunarDate[0] = iYear; + + int leapMonth = leapMonth(iYear); // 闂板摢涓湀,1-12 + boolean isLeap = false; + // 鐢ㄥ綋骞寸殑澶╂暟offset,閫愪釜鍑忓幓姣忔湀锛堝啘鍘嗭級鐨勫ぉ鏁帮紝姹傚嚭褰撳ぉ鏄湰鏈堢殑绗嚑澶� + int iMonth, daysOfMonth = 0; + for (iMonth = 1; iMonth <= 13 && offset > 0; iMonth++) { + daysOfMonth = daysInLunarMonth(iYear, iMonth); + offset -= daysOfMonth; + } + // 褰撳墠鏈堣秴杩囬棸鏈堬紝瑕佹牎姝� + if (leapMonth != 0 && iMonth > leapMonth) { + --iMonth; + Log.i("----------->", year + "-" + month + "-" + monthDay + "====>" + iMonth + "-" + leapMonth); + if (iMonth == leapMonth) { + isLeap = true; + } + } + // offset灏忎簬0鏃讹紝涔熻鏍℃ + if (offset < 0) { + offset += daysOfMonth; + --iMonth; + } + + lunarDate[1] = iMonth; + lunarDate[2] = offset + 1; + lunarDate[3] = isLeap ? 1 : 0; + + //Log.i("----------->",year+"-"+month+"-"+monthDay+"====>"+lunarDate[0]+"-"+lunarDate[1]+"-"+lunarDate[2]+"-"+lunarDate[3]); + return lunarDate; + } + + /** + * 浼犲洖鍐滃巻year骞磎onth鏈堢殑鎬诲ぉ鏁� + * + * @param year 瑕佽绠楃殑骞翠唤 + * @param month 瑕佽绠楃殑鏈� + * @return 浼犲洖澶╂暟 + */ + final public static int daysInMonth(int year, int month) { + return daysInMonth(year, month, false); + } + + /** + * 浼犲洖鍐滃巻year骞磎onth鏈堢殑鎬诲ぉ鏁� + * + * @param year 瑕佽绠楃殑骞翠唤 + * @param month 瑕佽绠楃殑鏈� + * @param leap 褰撴湀鏄惁鏄棸鏈� + * @return 浼犲洖澶╂暟锛屽鏋滈棸鏈堟槸閿欒鐨勶紝杩斿洖0. + */ + public static final int daysInMonth(int year, int month, boolean leap) { + int leapMonth = leapMonth(year); + int offset = 0; + + // 濡傛灉鏈勾鏈夐棸鏈堜笖month澶т簬闂版湀鏃讹紝闇�瑕佹牎姝� + if (leapMonth != 0 && month > leapMonth) { + offset = 1; + } + + // 涓嶈�冭檻闂版湀 + if (!leap) { + return daysInLunarMonth(year, month + offset); + } else { + // 浼犲叆鐨勯棸鏈堟槸姝g‘鐨勬湀浠� + if (leapMonth != 0 && leapMonth == month) { + return daysInLunarMonth(year, month + 1); + } + } + + return 0; + } + + /** + * 浼犲洖鍐滃巻 year骞寸殑鎬诲ぉ鏁� + * + * @param year 灏嗚璁$畻鐨勫勾浠� + * @return 杩斿洖浼犲叆骞翠唤鐨勬�诲ぉ鏁� + */ + private static int daysInLunarYear(int year) { + int i, sum = 348; + if (leapMonth(year) != 0) { + sum = 377; + } + int monthInfo = LUNAR_INFO[year - MIN_YEAR] & 0x0FFF80; + for (i = 0x80000; i > 0x7; i >>= 1) { + if ((monthInfo & i) != 0) + sum += 1; + } + return sum; + } + + /** + * 浼犲洖鍐滃巻 year骞磎onth鏈堢殑鎬诲ぉ鏁帮紝鎬诲叡鏈�13涓湀鍖呮嫭闂版湀 + * + * @param year 灏嗚璁$畻鐨勫勾浠� + * @param month 灏嗚璁$畻鐨勬湀浠� + * @return 浼犲洖鍐滃巻 year骞磎onth鏈堢殑鎬诲ぉ鏁� + */ + private static int daysInLunarMonth(int year, int month) { + if ((LUNAR_INFO[year - MIN_YEAR] & (0x100000 >> month)) == 0) + return 29; + else + return 30; + } + + /** + * 浼犲洖鍐滃巻 year骞撮棸鍝釜鏈� 1-12 , 娌¢棸浼犲洖 0 + * + * @param year 灏嗚璁$畻鐨勫勾浠� + * @return 浼犲洖鍐滃巻 year骞撮棸鍝釜鏈�1-12, 娌¢棸浼犲洖 0 + */ + public static int leapMonth(int year) { + return (int) ((LUNAR_INFO[year - MIN_YEAR] & 0xF00000)) >> 20; + } + + + private static int getBitInt(int data, int length, int shift) { + return (data & (((1 << length) - 1) << shift)) >> shift; + } + + private static long solarToInt(int y, int m, int d) { + m = (m + 9) % 12; + y = y - m / 10; + return 365 * y + y / 4 - y / 100 + y / 400 + (m * 306 + 5) / 10 + + (d - 1); + } + +} diff --git a/pickerview/src/main/java/com/bigkoo/pickerview/utils/PickerViewAnimateUtil.java b/pickerview/src/main/java/com/bigkoo/pickerview/utils/PickerViewAnimateUtil.java new file mode 100644 index 0000000..3e4a9f6 --- /dev/null +++ b/pickerview/src/main/java/com/bigkoo/pickerview/utils/PickerViewAnimateUtil.java @@ -0,0 +1,26 @@ +package com.bigkoo.pickerview.utils; + +import android.view.Gravity; + +import com.bigkoo.pickerview.R; + +/** + * Created by Sai on 15/8/9. + */ +public class PickerViewAnimateUtil { + private static final int INVALID = -1; + /** + * Get default animation resource when not defined by the user + * + * @param gravity the animGravity of the dialog + * @param isInAnimation determine if is in or out animation. true when is is + * @return the id of the animation resource + */ + public static int getAnimationResource(int gravity, boolean isInAnimation) { + switch (gravity) { + case Gravity.BOTTOM: + return isInAnimation ? R.anim.pickerview_slide_in_bottom : R.anim.pickerview_slide_out_bottom; + } + return INVALID; + } +} diff --git a/pickerview/src/main/java/com/bigkoo/pickerview/view/BasePickerView.java b/pickerview/src/main/java/com/bigkoo/pickerview/view/BasePickerView.java new file mode 100644 index 0000000..6ddddc5 --- /dev/null +++ b/pickerview/src/main/java/com/bigkoo/pickerview/view/BasePickerView.java @@ -0,0 +1,361 @@ +package com.bigkoo.pickerview.view; + +import android.app.Activity; +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.graphics.Color; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.widget.FrameLayout; + +import com.bigkoo.pickerview.R; +import com.bigkoo.pickerview.configure.PickerOptions; +import com.bigkoo.pickerview.listener.OnDismissListener; +import com.bigkoo.pickerview.utils.PickerViewAnimateUtil; + +/** + * Created by Sai on 15/11/22. + * 绮句豢iOSPickerViewController鎺т欢 + */ +public class BasePickerView { + + private Context context; + protected ViewGroup contentContainer; + private ViewGroup rootView;//闄勫姞View 鐨� 鏍筕iew + private ViewGroup dialogView;//闄勫姞Dialog 鐨� 鏍筕iew + + protected PickerOptions mPickerOptions; + private OnDismissListener onDismissListener; + private boolean dismissing; + + private Animation outAnim; + private Animation inAnim; + private boolean isShowing; + + protected int animGravity = Gravity.BOTTOM; + + private Dialog mDialog; + protected View clickView;//鏄�氳繃鍝釜View寮瑰嚭鐨� + private boolean isAnim = true; + + public BasePickerView(Context context) { + this.context = context; + } + + + protected void initViews() { + + FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.BOTTOM); + + LayoutInflater layoutInflater = LayoutInflater.from(context); + if (isDialog()) { + //濡傛灉鏄璇濇妯″紡 + dialogView = (ViewGroup) layoutInflater.inflate(R.layout.layout_basepickerview, null, false); + //璁剧疆鐣岄潰鐨勮儗鏅负閫忔槑 + dialogView.setBackgroundColor(Color.TRANSPARENT); + //杩欎釜鏄湡姝h鍔犺浇閫夋嫨鍣ㄧ殑鐖跺竷灞� + contentContainer = (ViewGroup) dialogView.findViewById(R.id.content_container); + //璁剧疆瀵硅瘽妗� 榛樿宸﹀彸闂磋窛灞忓箷30 + params.leftMargin = 30; + params.rightMargin = 30; + contentContainer.setLayoutParams(params); + //鍒涘缓瀵硅瘽妗� + createDialog(); + //缁欒儗鏅缃偣鍑讳簨浠�,杩欐牱褰撶偣鍑诲唴瀹逛互澶栫殑鍦版柟浼氬叧闂晫闈� + dialogView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + dismiss(); + } + }); + } else { + //濡傛灉鍙槸瑕佹樉绀哄湪灞忓箷鐨勪笅鏂� + //decorView鏄痑ctivity鐨勬牴View,鍖呭惈 contentView 鍜� titleView + if (mPickerOptions.decorView == null) { + mPickerOptions.decorView = (ViewGroup) ((Activity) context).getWindow().getDecorView(); + } + //灏嗘帶浠舵坊鍔犲埌decorView涓� + rootView = (ViewGroup) layoutInflater.inflate(R.layout.layout_basepickerview, mPickerOptions.decorView, false); + rootView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); + if (mPickerOptions.outSideColor != -1) { + rootView.setBackgroundColor(mPickerOptions.outSideColor); + } + //杩欎釜鏄湡姝h鍔犺浇鏃堕棿閫夊彇鍣ㄧ殑鐖跺竷灞� + contentContainer = (ViewGroup) rootView.findViewById(R.id.content_container); + contentContainer.setLayoutParams(params); + } + setKeyBackCancelable(true); + } + + protected void initAnim() { + inAnim = getInAnimation(); + outAnim = getOutAnimation(); + } + + protected void initEvents() { + } + + + /** + * @param v (鏄�氳繃鍝釜View寮瑰嚭鐨�) + * @param isAnim 鏄惁鏄剧ず鍔ㄧ敾鏁堟灉 + */ + public void show(View v, boolean isAnim) { + this.clickView = v; + this.isAnim = isAnim; + show(); + } + + public void show(boolean isAnim) { + show(null, isAnim); + } + + public void show(View v) { + this.clickView = v; + show(); + } + + + /** + * 娣诲姞View鍒版牴瑙嗗浘 + */ + public void show() { + if (isDialog()) { + showDialog(); + } else { + if (isShowing()) { + return; + } + isShowing = true; + onAttached(rootView); + rootView.requestFocus(); + } + } + + + /** + * show鐨勬椂鍊欒皟鐢� + * + * @param view 杩欎釜View + */ + private void onAttached(View view) { + mPickerOptions.decorView.addView(view); + if (isAnim) { + contentContainer.startAnimation(inAnim); + } + } + + + /** + * 妫�娴嬭View鏄笉鏄凡缁忔坊鍔犲埌鏍硅鍥� + * + * @return 濡傛灉瑙嗗浘宸茬粡瀛樺湪璇iew杩斿洖true + */ + public boolean isShowing() { + if (isDialog()) { + return false; + } else { + return rootView.getParent() != null || isShowing; + } + + } + + public void dismiss() { + if (isDialog()) { + dismissDialog(); + } else { + if (dismissing) { + return; + } + + if (isAnim) { + //娑堝け鍔ㄧ敾 + outAnim.setAnimationListener(new Animation.AnimationListener() { + @Override + public void onAnimationStart(Animation animation) { + + } + + @Override + public void onAnimationEnd(Animation animation) { + dismissImmediately(); + } + + @Override + public void onAnimationRepeat(Animation animation) { + + } + }); + contentContainer.startAnimation(outAnim); + } else { + dismissImmediately(); + } + dismissing = true; + } + + + } + + public void dismissImmediately() { + + mPickerOptions.decorView.post(new Runnable() { + @Override + public void run() { + //浠庢牴瑙嗗浘绉婚櫎 + mPickerOptions.decorView.removeView(rootView); + isShowing = false; + dismissing = false; + if (onDismissListener != null) { + onDismissListener.onDismiss(BasePickerView.this); + } + } + }); + + + } + + private Animation getInAnimation() { + int res = PickerViewAnimateUtil.getAnimationResource(this.animGravity, true); + return AnimationUtils.loadAnimation(context, res); + } + + private Animation getOutAnimation() { + int res = PickerViewAnimateUtil.getAnimationResource(this.animGravity, false); + return AnimationUtils.loadAnimation(context, res); + } + + public BasePickerView setOnDismissListener(OnDismissListener onDismissListener) { + this.onDismissListener = onDismissListener; + return this; + } + + public void setKeyBackCancelable(boolean isCancelable) { + + ViewGroup View; + if (isDialog()) { + View = dialogView; + } else { + View = rootView; + } + + View.setFocusable(isCancelable); + View.setFocusableInTouchMode(isCancelable); + if (isCancelable) { + View.setOnKeyListener(onKeyBackListener); + } else { + View.setOnKeyListener(null); + } + } + + private View.OnKeyListener onKeyBackListener = new View.OnKeyListener() { + @Override + public boolean onKey(View v, int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == MotionEvent.ACTION_DOWN && isShowing()) { + dismiss(); + return true; + } + return false; + } + }; + + protected BasePickerView setOutSideCancelable(boolean isCancelable) { + + if (rootView != null) { + View view = rootView.findViewById(R.id.outmost_container); + + if (isCancelable) { + view.setOnTouchListener(onCancelableTouchListener); + } else { + view.setOnTouchListener(null); + } + } + + return this; + } + + /** + * 璁剧疆瀵硅瘽妗嗘ā寮忔槸鍚﹀彲浠ョ偣鍑诲閮ㄥ彇娑� + */ + public void setDialogOutSideCancelable() { + if (mDialog != null) { + mDialog.setCancelable(mPickerOptions.cancelable); + } + } + + + /** + * Called when the user touch on black overlay, in order to dismiss the dialog. + */ + private final View.OnTouchListener onCancelableTouchListener = new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + dismiss(); + } + return false; + } + }; + + public View findViewById(int id) { + return contentContainer.findViewById(id); + } + + public void createDialog() { + if (dialogView != null) { + mDialog = new Dialog(context, R.style.custom_dialog2); + mDialog.setCancelable(mPickerOptions.cancelable);//涓嶈兘鐐瑰闈㈠彇娑�,涔熶笉鑳界偣back鍙栨秷 + mDialog.setContentView(dialogView); + + Window dialogWindow = mDialog.getWindow(); + if (dialogWindow != null) { + dialogWindow.setWindowAnimations(R.style.picker_view_scale_anim); + dialogWindow.setGravity(Gravity.CENTER);//鍙互鏀规垚Bottom + } + + mDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + if (onDismissListener != null) { + onDismissListener.onDismiss(BasePickerView.this); + } + } + }); + } + } + + private void showDialog() { + if (mDialog != null) { + mDialog.show(); + } + } + + private void dismissDialog() { + if (mDialog != null) { + mDialog.dismiss(); + } + } + + public ViewGroup getDialogContainerLayout() { + return contentContainer; + } + + + public Dialog getDialog() { + return mDialog; + } + + + public boolean isDialog() { + return false; + } + +} diff --git a/pickerview/src/main/java/com/bigkoo/pickerview/view/OptionsPickerView.java b/pickerview/src/main/java/com/bigkoo/pickerview/view/OptionsPickerView.java new file mode 100644 index 0000000..a9333f5 --- /dev/null +++ b/pickerview/src/main/java/com/bigkoo/pickerview/view/OptionsPickerView.java @@ -0,0 +1,197 @@ +package com.bigkoo.pickerview.view; + +import android.content.Context; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import com.bigkoo.pickerview.R; +import com.bigkoo.pickerview.configure.PickerOptions; + +import java.util.List; + +/** + * 鏉′欢閫夋嫨鍣� + * Created by Sai on 15/11/22. + */ +public class OptionsPickerView<T> extends BasePickerView implements View.OnClickListener { + + private WheelOptions<T> wheelOptions; + + private static final String TAG_SUBMIT = "submit"; + private static final String TAG_CANCEL = "cancel"; + + + public OptionsPickerView(PickerOptions pickerOptions) { + super(pickerOptions.context); + mPickerOptions = pickerOptions; + initView(pickerOptions.context); + } + + private void initView(Context context) { + setDialogOutSideCancelable(); + initViews(); + initAnim(); + initEvents(); + if (mPickerOptions.customListener == null) { + LayoutInflater.from(context).inflate(mPickerOptions.layoutRes, contentContainer); + + //椤堕儴鏍囬 + TextView tvTitle = (TextView) findViewById(R.id.tvTitle); + RelativeLayout rv_top_bar = (RelativeLayout) findViewById(R.id.rv_topbar); + + //纭畾鍜屽彇娑堟寜閽� + Button btnSubmit = (Button) findViewById(R.id.btnSubmit); + Button btnCancel = (Button) findViewById(R.id.btnCancel); + + btnSubmit.setTag(TAG_SUBMIT); + btnCancel.setTag(TAG_CANCEL); + btnSubmit.setOnClickListener(this); + btnCancel.setOnClickListener(this); + + //璁剧疆鏂囧瓧 + btnSubmit.setText(TextUtils.isEmpty(mPickerOptions.textContentConfirm) ? context.getResources().getString(R.string.pickerview_submit) : mPickerOptions.textContentConfirm); + btnCancel.setText(TextUtils.isEmpty(mPickerOptions.textContentCancel) ? context.getResources().getString(R.string.pickerview_cancel) : mPickerOptions.textContentCancel); + tvTitle.setText(TextUtils.isEmpty(mPickerOptions.textContentTitle) ? "" : mPickerOptions.textContentTitle);//榛樿涓虹┖ + + //璁剧疆color + btnSubmit.setTextColor(mPickerOptions.textColorConfirm); + btnCancel.setTextColor(mPickerOptions.textColorCancel); + tvTitle.setTextColor(mPickerOptions.textColorTitle); + rv_top_bar.setBackgroundColor(mPickerOptions.bgColorTitle); + + //璁剧疆鏂囧瓧澶у皬 + btnSubmit.setTextSize(mPickerOptions.textSizeSubmitCancel); + btnCancel.setTextSize(mPickerOptions.textSizeSubmitCancel); + tvTitle.setTextSize(mPickerOptions.textSizeTitle); + } else { + mPickerOptions.customListener.customLayout(LayoutInflater.from(context).inflate(mPickerOptions.layoutRes, contentContainer)); + } + + // ----婊氳疆甯冨眬 + final LinearLayout optionsPicker = (LinearLayout) findViewById(R.id.optionspicker); + optionsPicker.setBackgroundColor(mPickerOptions.bgColorWheel); + + wheelOptions = new WheelOptions<>(optionsPicker, mPickerOptions.isRestoreItem); + if (mPickerOptions.optionsSelectChangeListener != null) { + wheelOptions.setOptionsSelectChangeListener(mPickerOptions.optionsSelectChangeListener); + } + + wheelOptions.setTextContentSize(mPickerOptions.textSizeContent); + wheelOptions.setItemsVisible(mPickerOptions.itemsVisibleCount); + wheelOptions.setAlphaGradient(mPickerOptions.isAlphaGradient); + wheelOptions.setLabels(mPickerOptions.label1, mPickerOptions.label2, mPickerOptions.label3); + wheelOptions.setTextXOffset(mPickerOptions.x_offset_one, mPickerOptions.x_offset_two, mPickerOptions.x_offset_three); + wheelOptions.setCyclic(mPickerOptions.cyclic1, mPickerOptions.cyclic2, mPickerOptions.cyclic3); + wheelOptions.setTypeface(mPickerOptions.font); + + setOutSideCancelable(mPickerOptions.cancelable); + + wheelOptions.setDividerColor(mPickerOptions.dividerColor); + wheelOptions.setDividerType(mPickerOptions.dividerType); + wheelOptions.setLineSpacingMultiplier(mPickerOptions.lineSpacingMultiplier); + wheelOptions.setTextColorOut(mPickerOptions.textColorOut); + wheelOptions.setTextColorCenter(mPickerOptions.textColorCenter); + wheelOptions.isCenterLabel(mPickerOptions.isCenterLabel); + } + + /** + * 鍔ㄦ�佽缃爣棰� + * + * @param text 鏍囬鏂囨湰鍐呭 + */ + public void setTitleText(String text) { + TextView tvTitle = (TextView) findViewById(R.id.tvTitle); + if (tvTitle != null) { + tvTitle.setText(text); + } + } + + /** + * 璁剧疆榛樿閫変腑椤� + * + * @param option1 + */ + public void setSelectOptions(int option1) { + mPickerOptions.option1 = option1; + reSetCurrentItems(); + } + + + public void setSelectOptions(int option1, int option2) { + mPickerOptions.option1 = option1; + mPickerOptions.option2 = option2; + reSetCurrentItems(); + } + + public void setSelectOptions(int option1, int option2, int option3) { + mPickerOptions.option1 = option1; + mPickerOptions.option2 = option2; + mPickerOptions.option3 = option3; + reSetCurrentItems(); + } + + private void reSetCurrentItems() { + if (wheelOptions != null) { + wheelOptions.setCurrentItems(mPickerOptions.option1, mPickerOptions.option2, mPickerOptions.option3); + } + } + + public void setPicker(List<T> optionsItems) { + this.setPicker(optionsItems, null, null); + } + + public void setPicker(List<T> options1Items, List<List<T>> options2Items) { + this.setPicker(options1Items, options2Items, null); + } + + public void setPicker(List<T> options1Items, + List<List<T>> options2Items, + List<List<List<T>>> options3Items) { + + wheelOptions.setPicker(options1Items, options2Items, options3Items); + reSetCurrentItems(); + } + + + //涓嶈仈鍔ㄦ儏鍐典笅璋冪敤 + public void setNPicker(List<T> options1Items, + List<T> options2Items, + List<T> options3Items) { + + wheelOptions.setLinkage(false); + wheelOptions.setNPicker(options1Items, options2Items, options3Items); + reSetCurrentItems(); + } + + @Override + public void onClick(View v) { + String tag = (String) v.getTag(); + if (tag.equals(TAG_SUBMIT)) { + returnData(); + } else if (tag.equals(TAG_CANCEL)) { + if (mPickerOptions.cancelListener != null) { + mPickerOptions.cancelListener.onClick(v); + } + } + dismiss(); + } + + //鎶界鎺ュ彛鍥炶皟鐨勬柟娉� + public void returnData() { + if (mPickerOptions.optionsSelectListener != null) { + int[] optionsCurrentItems = wheelOptions.getCurrentItems(); + mPickerOptions.optionsSelectListener.onOptionsSelect(optionsCurrentItems[0], optionsCurrentItems[1], optionsCurrentItems[2], clickView); + } + } + + + @Override + public boolean isDialog() { + return mPickerOptions.isDialog; + } +} diff --git a/pickerview/src/main/java/com/bigkoo/pickerview/view/TimePickerView.java b/pickerview/src/main/java/com/bigkoo/pickerview/view/TimePickerView.java new file mode 100644 index 0000000..0381294 --- /dev/null +++ b/pickerview/src/main/java/com/bigkoo/pickerview/view/TimePickerView.java @@ -0,0 +1,293 @@ +package com.bigkoo.pickerview.view; + +import android.content.Context; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import com.bigkoo.pickerview.R; +import com.bigkoo.pickerview.configure.PickerOptions; +import com.bigkoo.pickerview.listener.ISelectTimeCallback; + +import java.text.ParseException; +import java.util.Calendar; +import java.util.Date; + +/** + * 鏃堕棿閫夋嫨鍣� + * Created by Sai on 15/11/22. + * Updated by XiaoSong on 2017-2-22. + */ +public class TimePickerView extends BasePickerView implements View.OnClickListener { + + private WheelTime wheelTime; //鑷畾涔夋帶浠� + private static final String TAG_SUBMIT = "submit"; + private static final String TAG_CANCEL = "cancel"; + + public TimePickerView(PickerOptions pickerOptions) { + super(pickerOptions.context); + mPickerOptions = pickerOptions; + initView(pickerOptions.context); + } + + private void initView(Context context) { + setDialogOutSideCancelable(); + initViews(); + initAnim(); + + if (mPickerOptions.customListener == null) { + LayoutInflater.from(context).inflate(R.layout.pickerview_time, contentContainer); + + //椤堕儴鏍囬 + TextView tvTitle = (TextView) findViewById(R.id.tvTitle); + RelativeLayout rv_top_bar = (RelativeLayout) findViewById(R.id.rv_topbar); + + //纭畾鍜屽彇娑堟寜閽� + Button btnSubmit = (Button) findViewById(R.id.btnSubmit); + Button btnCancel = (Button) findViewById(R.id.btnCancel); + //杩欐牱鍋氬彲浠ラ樆姝㈠瓙鎺т欢鐨勭偣鍑讳簨浠剁┛閫忓埌鐖舵帶浠朵笂锛屼粠鑰屼娇寰楃埗鎺т欢鍝嶅簲鐐瑰嚮浜嬩欢銆� + tvTitle.setClickable(true); + tvTitle.setFocusable(true); + + + btnSubmit.setTag(TAG_SUBMIT); + btnCancel.setTag(TAG_CANCEL); + + btnSubmit.setOnClickListener(this); + btnCancel.setOnClickListener(this); + + //璁剧疆鏂囧瓧 + btnSubmit.setText(TextUtils.isEmpty(mPickerOptions.textContentConfirm) ? context.getResources().getString(R.string.pickerview_submit) : mPickerOptions.textContentConfirm); + btnCancel.setText(TextUtils.isEmpty(mPickerOptions.textContentCancel) ? context.getResources().getString(R.string.pickerview_cancel) : mPickerOptions.textContentCancel); + tvTitle.setText(TextUtils.isEmpty(mPickerOptions.textContentTitle) ? "" : mPickerOptions.textContentTitle);//榛樿涓虹┖ + + //璁剧疆color + btnSubmit.setTextColor(mPickerOptions.textColorConfirm); + btnCancel.setTextColor(mPickerOptions.textColorCancel); + tvTitle.setTextColor(mPickerOptions.textColorTitle); + rv_top_bar.setBackgroundColor(mPickerOptions.bgColorTitle); + + //璁剧疆鏂囧瓧澶у皬 + btnSubmit.setTextSize(mPickerOptions.textSizeSubmitCancel); + btnCancel.setTextSize(mPickerOptions.textSizeSubmitCancel); + tvTitle.setTextSize(mPickerOptions.textSizeTitle); + + } else { + mPickerOptions.customListener.customLayout(LayoutInflater.from(context).inflate(mPickerOptions.layoutRes, contentContainer)); + } + // 鏃堕棿杞疆 鑷畾涔夋帶浠� + LinearLayout timePickerView = (LinearLayout) findViewById(R.id.timepicker); + timePickerView.setBackgroundColor(mPickerOptions.bgColorWheel); + + initWheelTime(timePickerView); + } + + private void initWheelTime(LinearLayout timePickerView) { + wheelTime = new WheelTime(timePickerView, mPickerOptions.type, mPickerOptions.textGravity, mPickerOptions.textSizeContent); + if (mPickerOptions.timeSelectChangeListener != null) { + wheelTime.setSelectChangeCallback(new ISelectTimeCallback() { + @Override + public void onTimeSelectChanged() { + try { + Date date = WheelTime.dateFormat.parse(wheelTime.getTime()); + mPickerOptions.timeSelectChangeListener.onTimeSelectChanged(date); + } catch (ParseException e) { + e.printStackTrace(); + } + } + }); + } + + wheelTime.setLunarMode(mPickerOptions.isLunarCalendar); + + if (mPickerOptions.startYear != 0 && mPickerOptions.endYear != 0 + && mPickerOptions.startYear <= mPickerOptions.endYear) { + setRange(); + } + + //鑻ユ墜鍔ㄨ缃簡鏃堕棿鑼冨洿闄愬埗 + if (mPickerOptions.startDate != null && mPickerOptions.endDate != null) { + if (mPickerOptions.startDate.getTimeInMillis() > mPickerOptions.endDate.getTimeInMillis()) { + throw new IllegalArgumentException("startDate can't be later than endDate"); + } else { + setRangDate(); + } + } else if (mPickerOptions.startDate != null) { + if (mPickerOptions.startDate.get(Calendar.YEAR) < 1900) { + throw new IllegalArgumentException("The startDate can not as early as 1900"); + } else { + setRangDate(); + } + } else if (mPickerOptions.endDate != null) { + if (mPickerOptions.endDate.get(Calendar.YEAR) > 2100) { + throw new IllegalArgumentException("The endDate should not be later than 2100"); + } else { + setRangDate(); + } + } else {//娌℃湁璁剧疆鏃堕棿鑼冨洿闄愬埗锛屽垯浼氫娇鐢ㄩ粯璁よ寖鍥淬�� + setRangDate(); + } + + setTime(); + wheelTime.setLabels(mPickerOptions.label_year, mPickerOptions.label_month, mPickerOptions.label_day + , mPickerOptions.label_hours, mPickerOptions.label_minutes, mPickerOptions.label_seconds); + wheelTime.setTextXOffset(mPickerOptions.x_offset_year, mPickerOptions.x_offset_month, mPickerOptions.x_offset_day, + mPickerOptions.x_offset_hours, mPickerOptions.x_offset_minutes, mPickerOptions.x_offset_seconds); + wheelTime.setItemsVisible(mPickerOptions.itemsVisibleCount); + wheelTime.setAlphaGradient(mPickerOptions.isAlphaGradient); + setOutSideCancelable(mPickerOptions.cancelable); + wheelTime.setCyclic(mPickerOptions.cyclic); + wheelTime.setDividerColor(mPickerOptions.dividerColor); + wheelTime.setDividerType(mPickerOptions.dividerType); + wheelTime.setLineSpacingMultiplier(mPickerOptions.lineSpacingMultiplier); + wheelTime.setTextColorOut(mPickerOptions.textColorOut); + wheelTime.setTextColorCenter(mPickerOptions.textColorCenter); + wheelTime.isCenterLabel(mPickerOptions.isCenterLabel); + } + + + /** + * 璁剧疆榛樿鏃堕棿 + */ + public void setDate(Calendar date) { + mPickerOptions.date = date; + setTime(); + } + + /** + * 璁剧疆鍙互閫夋嫨鐨勬椂闂磋寖鍥�, 瑕佸湪setTime涔嬪墠璋冪敤鎵嶆湁鏁堟灉 + */ + private void setRange() { + wheelTime.setStartYear(mPickerOptions.startYear); + wheelTime.setEndYear(mPickerOptions.endYear); + + } + + /** + * 璁剧疆鍙互閫夋嫨鐨勬椂闂磋寖鍥�, 瑕佸湪setTime涔嬪墠璋冪敤鎵嶆湁鏁堟灉 + */ + private void setRangDate() { + wheelTime.setRangDate(mPickerOptions.startDate, mPickerOptions.endDate); + initDefaultSelectedDate(); + } + + private void initDefaultSelectedDate() { + //濡傛灉鎵嬪姩璁剧疆浜嗘椂闂磋寖鍥� + if (mPickerOptions.startDate != null && mPickerOptions.endDate != null) { + //鑻ラ粯璁ゆ椂闂存湭璁剧疆锛屾垨鑰呰缃殑榛樿鏃堕棿瓒婄晫浜嗭紝鍒欒缃粯璁ら�変腑鏃堕棿涓哄紑濮嬫椂闂淬�� + if (mPickerOptions.date == null || mPickerOptions.date.getTimeInMillis() < mPickerOptions.startDate.getTimeInMillis() + || mPickerOptions.date.getTimeInMillis() > mPickerOptions.endDate.getTimeInMillis()) { + mPickerOptions.date = mPickerOptions.startDate; + } + } else if (mPickerOptions.startDate != null) { + //娌℃湁璁剧疆榛樿閫変腑鏃堕棿,閭e氨鎷垮紑濮嬫椂闂村綋榛樿鏃堕棿 + mPickerOptions.date = mPickerOptions.startDate; + } else if (mPickerOptions.endDate != null) { + mPickerOptions.date = mPickerOptions.endDate; + } + } + + /** + * 璁剧疆閫変腑鏃堕棿,榛樿閫変腑褰撳墠鏃堕棿 + */ + private void setTime() { + int year, month, day, hours, minute, seconds; + Calendar calendar = Calendar.getInstance(); + + if (mPickerOptions.date == null) { + calendar.setTimeInMillis(System.currentTimeMillis()); + year = calendar.get(Calendar.YEAR); + month = calendar.get(Calendar.MONTH); + day = calendar.get(Calendar.DAY_OF_MONTH); + hours = calendar.get(Calendar.HOUR_OF_DAY); + minute = calendar.get(Calendar.MINUTE); + seconds = calendar.get(Calendar.SECOND); + } else { + year = mPickerOptions.date.get(Calendar.YEAR); + month = mPickerOptions.date.get(Calendar.MONTH); + day = mPickerOptions.date.get(Calendar.DAY_OF_MONTH); + hours = mPickerOptions.date.get(Calendar.HOUR_OF_DAY); + minute = mPickerOptions.date.get(Calendar.MINUTE); + seconds = mPickerOptions.date.get(Calendar.SECOND); + } + + wheelTime.setPicker(year, month, day, hours, minute, seconds); + } + + + @Override + public void onClick(View v) { + String tag = (String) v.getTag(); + if (tag.equals(TAG_SUBMIT)) { + returnData(); + } else if (tag.equals(TAG_CANCEL)) { + if (mPickerOptions.cancelListener != null) { + mPickerOptions.cancelListener.onClick(v); + } + } + dismiss(); + } + + public void returnData() { + if (mPickerOptions.timeSelectListener != null) { + try { + Date date = WheelTime.dateFormat.parse(wheelTime.getTime()); + mPickerOptions.timeSelectListener.onTimeSelect(date, clickView); + } catch (ParseException e) { + e.printStackTrace(); + } + } + } + + /** + * 鍔ㄦ�佽缃爣棰� + * + * @param text 鏍囬鏂囨湰鍐呭 + */ + public void setTitleText(String text) { + TextView tvTitle = (TextView) findViewById(R.id.tvTitle); + if (tvTitle != null) { + tvTitle.setText(text); + } + } + + /** + * 鐩墠鏆傛椂鍙敮鎸佽缃�1900 - 2100骞� + * + * @param lunar 鍐滃巻鐨勫紑鍏� + */ + public void setLunarCalendar(boolean lunar) { + try { + int year, month, day, hours, minute, seconds; + Calendar calendar = Calendar.getInstance(); + calendar.setTime(WheelTime.dateFormat.parse(wheelTime.getTime())); + year = calendar.get(Calendar.YEAR); + month = calendar.get(Calendar.MONTH); + day = calendar.get(Calendar.DAY_OF_MONTH); + hours = calendar.get(Calendar.HOUR_OF_DAY); + minute = calendar.get(Calendar.MINUTE); + seconds = calendar.get(Calendar.SECOND); + + wheelTime.setLunarMode(lunar); + wheelTime.setLabels(mPickerOptions.label_year, mPickerOptions.label_month, mPickerOptions.label_day, + mPickerOptions.label_hours, mPickerOptions.label_minutes, mPickerOptions.label_seconds); + wheelTime.setPicker(year, month, day, hours, minute, seconds); + } catch (ParseException e) { + e.printStackTrace(); + } + } + + public boolean isLunarCalendar() { + return wheelTime.isLunarMode(); + } + + + @Override + public boolean isDialog() { + return mPickerOptions.isDialog; + } +} diff --git a/pickerview/src/main/java/com/bigkoo/pickerview/view/WheelOptions.java b/pickerview/src/main/java/com/bigkoo/pickerview/view/WheelOptions.java new file mode 100644 index 0000000..ca36475 --- /dev/null +++ b/pickerview/src/main/java/com/bigkoo/pickerview/view/WheelOptions.java @@ -0,0 +1,428 @@ +package com.bigkoo.pickerview.view; + +import android.graphics.Typeface; +import android.view.View; + +import com.bigkoo.pickerview.R; +import com.bigkoo.pickerview.adapter.ArrayWheelAdapter; +import com.bigkoo.pickerview.listener.OnOptionsSelectChangeListener; +import com.contrarywind.listener.OnItemSelectedListener; +import com.contrarywind.view.WheelView; + +import java.util.List; + +public class WheelOptions<T> { + private View view; + private WheelView wv_option1; + private WheelView wv_option2; + private WheelView wv_option3; + + private List<T> mOptions1Items; + private List<List<T>> mOptions2Items; + private List<List<List<T>>> mOptions3Items; + + private boolean linkage = true;//榛樿鑱斿姩 + private boolean isRestoreItem; //鍒囨崲鏃讹紝杩樺師绗竴椤� + private OnItemSelectedListener wheelListener_option1; + private OnItemSelectedListener wheelListener_option2; + + private OnOptionsSelectChangeListener optionsSelectChangeListener; + + public View getView() { + return view; + } + + public void setView(View view) { + this.view = view; + } + + public WheelOptions(View view, boolean isRestoreItem) { + super(); + this.isRestoreItem = isRestoreItem; + this.view = view; + wv_option1 = (WheelView) view.findViewById(R.id.options1);// 鍒濆鍖栨椂鏄剧ず鐨勬暟鎹� + wv_option2 = (WheelView) view.findViewById(R.id.options2); + wv_option3 = (WheelView) view.findViewById(R.id.options3); + } + + + public void setPicker(List<T> options1Items, + List<List<T>> options2Items, + List<List<List<T>>> options3Items) { + this.mOptions1Items = options1Items; + this.mOptions2Items = options2Items; + this.mOptions3Items = options3Items; + + // 閫夐」1 + wv_option1.setAdapter(new ArrayWheelAdapter(mOptions1Items));// 璁剧疆鏄剧ず鏁版嵁 + wv_option1.setCurrentItem(0);// 鍒濆鍖栨椂鏄剧ず鐨勬暟鎹� + // 閫夐」2 + if (mOptions2Items != null) { + wv_option2.setAdapter(new ArrayWheelAdapter(mOptions2Items.get(0)));// 璁剧疆鏄剧ず鏁版嵁 + } + wv_option2.setCurrentItem(wv_option2.getCurrentItem());// 鍒濆鍖栨椂鏄剧ず鐨勬暟鎹� + // 閫夐」3 + if (mOptions3Items != null) { + wv_option3.setAdapter(new ArrayWheelAdapter(mOptions3Items.get(0).get(0)));// 璁剧疆鏄剧ず鏁版嵁 + } + wv_option3.setCurrentItem(wv_option3.getCurrentItem()); + wv_option1.setIsOptions(true); + wv_option2.setIsOptions(true); + wv_option3.setIsOptions(true); + + if (this.mOptions2Items == null) { + wv_option2.setVisibility(View.GONE); + } else { + wv_option2.setVisibility(View.VISIBLE); + } + if (this.mOptions3Items == null) { + wv_option3.setVisibility(View.GONE); + } else { + wv_option3.setVisibility(View.VISIBLE); + } + + // 鑱斿姩鐩戝惉鍣� + wheelListener_option1 = new OnItemSelectedListener() { + + @Override + public void onItemSelected(int index) { + int opt2Select = 0; + if (mOptions2Items == null) {//鍙湁1绾ц仈鍔ㄦ暟鎹� + if (optionsSelectChangeListener != null) { + optionsSelectChangeListener.onOptionsSelectChanged(wv_option1.getCurrentItem(), 0, 0); + } + } else { + if (!isRestoreItem) { + opt2Select = wv_option2.getCurrentItem();//涓婁竴涓猳pt2鐨勯�変腑浣嶇疆 + //鏂皁pt2鐨勪綅缃紝鍒ゆ柇濡傛灉鏃т綅缃病鏈夎秴杩囨暟鎹寖鍥达紝鍒欐部鐢ㄦ棫浣嶇疆锛屽惁鍒欓�変腑鏈�鍚庝竴椤� + opt2Select = opt2Select >= mOptions2Items.get(index).size() - 1 ? mOptions2Items.get(index).size() - 1 : opt2Select; + } + wv_option2.setAdapter(new ArrayWheelAdapter(mOptions2Items.get(index))); + wv_option2.setCurrentItem(opt2Select); + + if (mOptions3Items != null) { + wheelListener_option2.onItemSelected(opt2Select); + } else {//鍙湁2绾ц仈鍔ㄦ暟鎹紝婊戝姩绗�1椤瑰洖璋� + if (optionsSelectChangeListener != null) { + optionsSelectChangeListener.onOptionsSelectChanged(index, opt2Select, 0); + } + } + } + } + }; + + wheelListener_option2 = new OnItemSelectedListener() { + + @Override + public void onItemSelected(int index) { + if (mOptions3Items != null) { + int opt1Select = wv_option1.getCurrentItem(); + opt1Select = opt1Select >= mOptions3Items.size() - 1 ? mOptions3Items.size() - 1 : opt1Select; + index = index >= mOptions2Items.get(opt1Select).size() - 1 ? mOptions2Items.get(opt1Select).size() - 1 : index; + int opt3 = 0; + if (!isRestoreItem) { + // wv_option3.getCurrentItem() 涓婁竴涓猳pt3鐨勯�変腑浣嶇疆 + //鏂皁pt3鐨勪綅缃紝鍒ゆ柇濡傛灉鏃т綅缃病鏈夎秴杩囨暟鎹寖鍥达紝鍒欐部鐢ㄦ棫浣嶇疆锛屽惁鍒欓�変腑鏈�鍚庝竴椤� + opt3 = wv_option3.getCurrentItem() >= mOptions3Items.get(opt1Select).get(index).size() - 1 ? + mOptions3Items.get(opt1Select).get(index).size() - 1 : wv_option3.getCurrentItem(); + } + wv_option3.setAdapter(new ArrayWheelAdapter(mOptions3Items.get(wv_option1.getCurrentItem()).get(index))); + wv_option3.setCurrentItem(opt3); + + //3绾ц仈鍔ㄦ暟鎹疄鏃跺洖璋� + if (optionsSelectChangeListener != null) { + optionsSelectChangeListener.onOptionsSelectChanged(wv_option1.getCurrentItem(), index, opt3); + } + } else {//鍙湁2绾ц仈鍔ㄦ暟鎹紝婊戝姩绗�2椤瑰洖璋� + if (optionsSelectChangeListener != null) { + optionsSelectChangeListener.onOptionsSelectChanged(wv_option1.getCurrentItem(), index, 0); + } + } + } + }; + // 娣诲姞鑱斿姩鐩戝惉 + if (options1Items != null && linkage) { + wv_option1.setOnItemSelectedListener(wheelListener_option1); + } + if (options2Items != null && linkage) { + wv_option2.setOnItemSelectedListener(wheelListener_option2); + } + if (options3Items != null && linkage && optionsSelectChangeListener != null) { + wv_option3.setOnItemSelectedListener(new OnItemSelectedListener() { + @Override + public void onItemSelected(int index) { + optionsSelectChangeListener.onOptionsSelectChanged(wv_option1.getCurrentItem(), wv_option2.getCurrentItem(), index); + } + }); + } + } + + + //涓嶈仈鍔ㄦ儏鍐典笅 + public void setNPicker(List<T> options1Items, List<T> options2Items, List<T> options3Items) { + + // 閫夐」1 + wv_option1.setAdapter(new ArrayWheelAdapter<>(options1Items));// 璁剧疆鏄剧ず鏁版嵁 + wv_option1.setCurrentItem(0);// 鍒濆鍖栨椂鏄剧ず鐨勬暟鎹� + // 閫夐」2 + if (options2Items != null) { + wv_option2.setAdapter(new ArrayWheelAdapter<>(options2Items));// 璁剧疆鏄剧ず鏁版嵁 + } + wv_option2.setCurrentItem(wv_option2.getCurrentItem());// 鍒濆鍖栨椂鏄剧ず鐨勬暟鎹� + // 閫夐」3 + if (options3Items != null) { + wv_option3.setAdapter(new ArrayWheelAdapter<>(options3Items));// 璁剧疆鏄剧ず鏁版嵁 + } + wv_option3.setCurrentItem(wv_option3.getCurrentItem()); + wv_option1.setIsOptions(true); + wv_option2.setIsOptions(true); + wv_option3.setIsOptions(true); + + if (optionsSelectChangeListener != null) { + wv_option1.setOnItemSelectedListener(new OnItemSelectedListener() { + @Override + public void onItemSelected(int index) { + optionsSelectChangeListener.onOptionsSelectChanged(index, wv_option2.getCurrentItem(), wv_option3.getCurrentItem()); + } + }); + } + + if (options2Items == null) { + wv_option2.setVisibility(View.GONE); + } else { + wv_option2.setVisibility(View.VISIBLE); + if (optionsSelectChangeListener != null) { + wv_option2.setOnItemSelectedListener(new OnItemSelectedListener() { + @Override + public void onItemSelected(int index) { + optionsSelectChangeListener.onOptionsSelectChanged(wv_option1.getCurrentItem(), index, wv_option3.getCurrentItem()); + } + }); + } + } + if (options3Items == null) { + wv_option3.setVisibility(View.GONE); + } else { + wv_option3.setVisibility(View.VISIBLE); + if (optionsSelectChangeListener != null) { + wv_option3.setOnItemSelectedListener(new OnItemSelectedListener() { + @Override + public void onItemSelected(int index) { + optionsSelectChangeListener.onOptionsSelectChanged(wv_option1.getCurrentItem(), wv_option2.getCurrentItem(), index); + } + }); + } + } + } + + public void setTextContentSize(int textSize) { + wv_option1.setTextSize(textSize); + wv_option2.setTextSize(textSize); + wv_option3.setTextSize(textSize); + } + + private void setLineSpacingMultiplier() { + + } + + /** + * 璁剧疆閫夐」鐨勫崟浣� + * + * @param label1 鍗曚綅 + * @param label2 鍗曚綅 + * @param label3 鍗曚綅 + */ + public void setLabels(String label1, String label2, String label3) { + if (label1 != null) { + wv_option1.setLabel(label1); + } + if (label2 != null) { + wv_option2.setLabel(label2); + } + if (label3 != null) { + wv_option3.setLabel(label3); + } + } + + /** + * 璁剧疆x杞村亸绉婚噺 + */ + public void setTextXOffset(int x_offset_one, int x_offset_two, int x_offset_three) { + wv_option1.setTextXOffset(x_offset_one); + wv_option2.setTextXOffset(x_offset_two); + wv_option3.setTextXOffset(x_offset_three); + } + + /** + * 璁剧疆鏄惁寰幆婊氬姩 + * + * @param cyclic 鏄惁寰幆 + */ + public void setCyclic(boolean cyclic) { + wv_option1.setCyclic(cyclic); + wv_option2.setCyclic(cyclic); + wv_option3.setCyclic(cyclic); + } + + /** + * 璁剧疆瀛椾綋鏍峰紡 + * + * @param font 绯荤粺鎻愪緵鐨勫嚑绉嶆牱寮� + */ + public void setTypeface(Typeface font) { + wv_option1.setTypeface(font); + wv_option2.setTypeface(font); + wv_option3.setTypeface(font); + } + + /** + * 鍒嗗埆璁剧疆绗竴浜屼笁绾ф槸鍚﹀惊鐜粴鍔� + * + * @param cyclic1,cyclic2,cyclic3 鏄惁寰幆 + */ + public void setCyclic(boolean cyclic1, boolean cyclic2, boolean cyclic3) { + wv_option1.setCyclic(cyclic1); + wv_option2.setCyclic(cyclic2); + wv_option3.setCyclic(cyclic3); + } + + /** + * 杩斿洖褰撳墠閫変腑鐨勭粨鏋滃搴旂殑浣嶇疆鏁扮粍 鍥犱负鏀寔涓夌骇鑱斿姩鏁堟灉锛屽垎涓変釜绾у埆绱㈠紩锛�0锛�1锛�2銆� + * 鍦ㄥ揩閫熸粦鍔ㄦ湭鍋滄鏃讹紝鐐瑰嚮纭畾鎸夐挳锛屼細杩涜鍒ゆ柇锛屽鏋滃尮閰嶆暟鎹秺鐣岋紝鍒欒涓�0锛岄槻姝ndex鍑洪敊瀵艰嚧宕╂簝銆� + * + * @return 绱㈠紩鏁扮粍 + */ + public int[] getCurrentItems() { + int[] currentItems = new int[3]; + currentItems[0] = wv_option1.getCurrentItem(); + + if (mOptions2Items != null && mOptions2Items.size() > 0) {//闈炵┖鍒ゆ柇 + currentItems[1] = wv_option2.getCurrentItem() > (mOptions2Items.get(currentItems[0]).size() - 1) ? 0 : wv_option2.getCurrentItem(); + } else { + currentItems[1] = wv_option2.getCurrentItem(); + } + + if (mOptions3Items != null && mOptions3Items.size() > 0) {//闈炵┖鍒ゆ柇 + currentItems[2] = wv_option3.getCurrentItem() > (mOptions3Items.get(currentItems[0]).get(currentItems[1]).size() - 1) ? 0 : wv_option3.getCurrentItem(); + } else { + currentItems[2] = wv_option3.getCurrentItem(); + } + + return currentItems; + } + + public void setCurrentItems(int option1, int option2, int option3) { + if (linkage) { + itemSelected(option1, option2, option3); + } else { + wv_option1.setCurrentItem(option1); + wv_option2.setCurrentItem(option2); + wv_option3.setCurrentItem(option3); + } + } + + private void itemSelected(int opt1Select, int opt2Select, int opt3Select) { + if (mOptions1Items != null) { + wv_option1.setCurrentItem(opt1Select); + } + if (mOptions2Items != null) { + wv_option2.setAdapter(new ArrayWheelAdapter(mOptions2Items.get(opt1Select))); + wv_option2.setCurrentItem(opt2Select); + } + if (mOptions3Items != null) { + wv_option3.setAdapter(new ArrayWheelAdapter(mOptions3Items.get(opt1Select).get(opt2Select))); + wv_option3.setCurrentItem(opt3Select); + } + } + + /** + * 璁剧疆闂磋窛鍊嶆暟,浣嗘槸鍙兘鍦�1.2-4.0f涔嬮棿 + * + * @param lineSpacingMultiplier + */ + public void setLineSpacingMultiplier(float lineSpacingMultiplier) { + wv_option1.setLineSpacingMultiplier(lineSpacingMultiplier); + wv_option2.setLineSpacingMultiplier(lineSpacingMultiplier); + wv_option3.setLineSpacingMultiplier(lineSpacingMultiplier); + } + + /** + * 璁剧疆鍒嗗壊绾跨殑棰滆壊 + * + * @param dividerColor + */ + public void setDividerColor(int dividerColor) { + wv_option1.setDividerColor(dividerColor); + wv_option2.setDividerColor(dividerColor); + wv_option3.setDividerColor(dividerColor); + } + + /** + * 璁剧疆鍒嗗壊绾跨殑绫诲瀷 + * + * @param dividerType + */ + public void setDividerType(WheelView.DividerType dividerType) { + wv_option1.setDividerType(dividerType); + wv_option2.setDividerType(dividerType); + wv_option3.setDividerType(dividerType); + } + + /** + * 璁剧疆鍒嗗壊绾夸箣闂寸殑鏂囧瓧鐨勯鑹� + * + * @param textColorCenter + */ + public void setTextColorCenter(int textColorCenter) { + wv_option1.setTextColorCenter(textColorCenter); + wv_option2.setTextColorCenter(textColorCenter); + wv_option3.setTextColorCenter(textColorCenter); + } + + /** + * 璁剧疆鍒嗗壊绾夸互澶栨枃瀛楃殑棰滆壊 + * + * @param textColorOut + */ + public void setTextColorOut(int textColorOut) { + wv_option1.setTextColorOut(textColorOut); + wv_option2.setTextColorOut(textColorOut); + wv_option3.setTextColorOut(textColorOut); + } + + /** + * Label 鏄惁鍙樉绀轰腑闂撮�変腑椤圭殑 + * + * @param isCenterLabel + */ + public void isCenterLabel(boolean isCenterLabel) { + wv_option1.isCenterLabel(isCenterLabel); + wv_option2.isCenterLabel(isCenterLabel); + wv_option3.isCenterLabel(isCenterLabel); + } + + public void setOptionsSelectChangeListener(OnOptionsSelectChangeListener optionsSelectChangeListener) { + this.optionsSelectChangeListener = optionsSelectChangeListener; + } + + public void setLinkage(boolean linkage) { + this.linkage = linkage; + } + + /** + * 璁剧疆鏈�澶у彲瑙佹暟鐩� + * + * @param itemsVisible 寤鸿璁剧疆涓� 3 ~ 9涔嬮棿銆� + */ + public void setItemsVisible(int itemsVisible) { + wv_option1.setItemsVisibleCount(itemsVisible); + wv_option2.setItemsVisibleCount(itemsVisible); + wv_option3.setItemsVisibleCount(itemsVisible); + } + + public void setAlphaGradient(boolean isAlphaGradient) { + wv_option1.setAlphaGradient(isAlphaGradient); + wv_option2.setAlphaGradient(isAlphaGradient); + wv_option3.setAlphaGradient(isAlphaGradient); + } +} diff --git a/pickerview/src/main/java/com/bigkoo/pickerview/view/WheelTime.java b/pickerview/src/main/java/com/bigkoo/pickerview/view/WheelTime.java new file mode 100644 index 0000000..d7023bd --- /dev/null +++ b/pickerview/src/main/java/com/bigkoo/pickerview/view/WheelTime.java @@ -0,0 +1,900 @@ +package com.bigkoo.pickerview.view; + +import android.view.View; + +import com.bigkoo.pickerview.R; +import com.bigkoo.pickerview.adapter.ArrayWheelAdapter; +import com.bigkoo.pickerview.adapter.NumericWheelAdapter; +import com.bigkoo.pickerview.listener.ISelectTimeCallback; +import com.bigkoo.pickerview.utils.ChinaDate; +import com.bigkoo.pickerview.utils.LunarCalendar; +import com.contrarywind.listener.OnItemSelectedListener; +import com.contrarywind.view.WheelView; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Calendar; +import java.util.List; + + +public class WheelTime { + public static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + private View view; + private WheelView wv_year; + private WheelView wv_month; + private WheelView wv_day; + private WheelView wv_hours; + private WheelView wv_minutes; + private WheelView wv_seconds; + private int gravity; + + private boolean[] type; + private static final int DEFAULT_START_YEAR = 1900; + private static final int DEFAULT_END_YEAR = 2100; + private static final int DEFAULT_START_MONTH = 1; + private static final int DEFAULT_END_MONTH = 12; + private static final int DEFAULT_START_DAY = 1; + private static final int DEFAULT_END_DAY = 31; + + private int startYear = DEFAULT_START_YEAR; + private int endYear = DEFAULT_END_YEAR; + private int startMonth = DEFAULT_START_MONTH; + private int endMonth = DEFAULT_END_MONTH; + private int startDay = DEFAULT_START_DAY; + private int endDay = DEFAULT_END_DAY; //琛ㄧず31澶╃殑 + private int currentYear; + + private int textSize; + + private boolean isLunarCalendar = false; + private ISelectTimeCallback mSelectChangeCallback; + + public WheelTime(View view, boolean[] type, int gravity, int textSize) { + super(); + this.view = view; + this.type = type; + this.gravity = gravity; + this.textSize = textSize; + } + + public void setLunarMode(boolean isLunarCalendar) { + this.isLunarCalendar = isLunarCalendar; + } + + public boolean isLunarMode() { + return isLunarCalendar; + } + + public void setPicker(int year, int month, int day) { + this.setPicker(year, month, day, 0, 0, 0); + } + + public void setPicker(int year, final int month, int day, int h, int m, int s) { + if (isLunarCalendar) { + int[] lunar = LunarCalendar.solarToLunar(year, month + 1, day); + setLunar(lunar[0], lunar[1] - 1, lunar[2], lunar[3] == 1, h, m, s); + } else { + setSolar(year, month, day, h, m, s); + } + } + + /** + * 璁剧疆鍐滃巻 + * + * @param year + * @param month + * @param day + * @param h + * @param m + * @param s + */ + private void setLunar(int year, final int month, int day, boolean isLeap, int h, int m, int s) { + // 骞� + wv_year = (WheelView) view.findViewById(R.id.year); + wv_year.setAdapter(new ArrayWheelAdapter(ChinaDate.getYears(startYear, endYear)));// 璁剧疆"骞�"鐨勬樉绀烘暟鎹� + wv_year.setLabel("");// 娣诲姞鏂囧瓧 + wv_year.setCurrentItem(year - startYear);// 鍒濆鍖栨椂鏄剧ず鐨勬暟鎹� + wv_year.setGravity(gravity); + + // 鏈� + wv_month = (WheelView) view.findViewById(R.id.month); + wv_month.setAdapter(new ArrayWheelAdapter(ChinaDate.getMonths(year))); + wv_month.setLabel(""); + + int leapMonth = ChinaDate.leapMonth(year); + if (leapMonth != 0 && (month > leapMonth - 1 || isLeap)) { //閫変腑鏈堟槸闂版湀鎴栧ぇ浜庨棸鏈� + wv_month.setCurrentItem(month + 1); + } else { + wv_month.setCurrentItem(month); + } + + wv_month.setGravity(gravity); + + // 鏃� + wv_day = (WheelView) view.findViewById(R.id.day); + // 鍒ゆ柇澶у皬鏈堝強鏄惁闂板勾,鐢ㄦ潵纭畾"鏃�"鐨勬暟鎹� + if (ChinaDate.leapMonth(year) == 0) { + wv_day.setAdapter(new ArrayWheelAdapter(ChinaDate.getLunarDays(ChinaDate.monthDays(year, month)))); + } else { + wv_day.setAdapter(new ArrayWheelAdapter(ChinaDate.getLunarDays(ChinaDate.leapDays(year)))); + } + wv_day.setLabel(""); + wv_day.setCurrentItem(day - 1); + wv_day.setGravity(gravity); + + wv_hours = (WheelView) view.findViewById(R.id.hour); + wv_hours.setAdapter(new NumericWheelAdapter(0, 23)); + //wv_hours.setLabel(context.getString(R.string.pickerview_hours));// 娣诲姞鏂囧瓧 + wv_hours.setCurrentItem(h); + wv_hours.setGravity(gravity); + + wv_minutes = (WheelView) view.findViewById(R.id.min); + wv_minutes.setAdapter(new NumericWheelAdapter(0, 59)); + //wv_minutes.setLabel(context.getString(R.string.pickerview_minutes));// 娣诲姞鏂囧瓧 + wv_minutes.setCurrentItem(m); + wv_minutes.setGravity(gravity); + + wv_seconds = (WheelView) view.findViewById(R.id.second); + wv_seconds.setAdapter(new NumericWheelAdapter(0, 59)); + //wv_seconds.setLabel(context.getString(R.string.pickerview_minutes));// 娣诲姞鏂囧瓧 + wv_seconds.setCurrentItem(m); + wv_seconds.setGravity(gravity); + + // 娣诲姞"骞�"鐩戝惉 + wv_year.setOnItemSelectedListener(new OnItemSelectedListener() { + @Override + public void onItemSelected(int index) { + int year_num = index + startYear; + // 鍒ゆ柇鏄笉鏄棸骞�,鏉ョ‘瀹氭湀鍜屾棩鐨勯�夋嫨 + wv_month.setAdapter(new ArrayWheelAdapter(ChinaDate.getMonths(year_num))); + if (ChinaDate.leapMonth(year_num) != 0 && wv_month.getCurrentItem() > ChinaDate.leapMonth(year_num) - 1) { + wv_month.setCurrentItem(wv_month.getCurrentItem() + 1); + } else { + wv_month.setCurrentItem(wv_month.getCurrentItem()); + } + + int currentIndex = wv_day.getCurrentItem(); + int maxItem = 29; + if (ChinaDate.leapMonth(year_num) != 0 && wv_month.getCurrentItem() > ChinaDate.leapMonth(year_num) - 1) { + if (wv_month.getCurrentItem() == ChinaDate.leapMonth(year_num) + 1) { + wv_day.setAdapter(new ArrayWheelAdapter(ChinaDate.getLunarDays(ChinaDate.leapDays(year_num)))); + maxItem = ChinaDate.leapDays(year_num); + } else { + wv_day.setAdapter(new ArrayWheelAdapter(ChinaDate.getLunarDays(ChinaDate.monthDays(year_num, wv_month.getCurrentItem())))); + maxItem = ChinaDate.monthDays(year_num, wv_month.getCurrentItem()); + } + } else { + wv_day.setAdapter(new ArrayWheelAdapter(ChinaDate.getLunarDays(ChinaDate.monthDays(year_num, wv_month.getCurrentItem() + 1)))); + maxItem = ChinaDate.monthDays(year_num, wv_month.getCurrentItem() + 1); + } + + if (currentIndex > maxItem - 1) { + wv_day.setCurrentItem(maxItem - 1); + } + + if (mSelectChangeCallback != null) { + mSelectChangeCallback.onTimeSelectChanged(); + } + } + }); + + // 娣诲姞"鏈�"鐩戝惉 + wv_month.setOnItemSelectedListener(new OnItemSelectedListener() { + @Override + public void onItemSelected(int index) { + int month_num = index; + int year_num = wv_year.getCurrentItem() + startYear; + int currentIndex = wv_day.getCurrentItem(); + int maxItem = 29; + if (ChinaDate.leapMonth(year_num) != 0 && month_num > ChinaDate.leapMonth(year_num) - 1) { + if (wv_month.getCurrentItem() == ChinaDate.leapMonth(year_num) + 1) { + wv_day.setAdapter(new ArrayWheelAdapter(ChinaDate.getLunarDays(ChinaDate.leapDays(year_num)))); + maxItem = ChinaDate.leapDays(year_num); + } else { + wv_day.setAdapter(new ArrayWheelAdapter(ChinaDate.getLunarDays(ChinaDate.monthDays(year_num, month_num)))); + maxItem = ChinaDate.monthDays(year_num, month_num); + } + } else { + wv_day.setAdapter(new ArrayWheelAdapter(ChinaDate.getLunarDays(ChinaDate.monthDays(year_num, month_num + 1)))); + maxItem = ChinaDate.monthDays(year_num, month_num + 1); + } + + if (currentIndex > maxItem - 1) { + wv_day.setCurrentItem(maxItem - 1); + } + + if (mSelectChangeCallback != null) { + mSelectChangeCallback.onTimeSelectChanged(); + } + } + }); + + setChangedListener(wv_day); + setChangedListener(wv_hours); + setChangedListener(wv_minutes); + setChangedListener(wv_seconds); + + if (type.length != 6) { + throw new RuntimeException("type[] length is not 6"); + } + wv_year.setVisibility(type[0] ? View.VISIBLE : View.GONE); + wv_month.setVisibility(type[1] ? View.VISIBLE : View.GONE); + wv_day.setVisibility(type[2] ? View.VISIBLE : View.GONE); + wv_hours.setVisibility(type[3] ? View.VISIBLE : View.GONE); + wv_minutes.setVisibility(type[4] ? View.VISIBLE : View.GONE); + wv_seconds.setVisibility(type[5] ? View.VISIBLE : View.GONE); + setContentTextSize(); + } + + /** + * 璁剧疆鍏巻 + * + * @param year + * @param month + * @param day + * @param h + * @param m + * @param s + */ + private void setSolar(int year, final int month, int day, int h, int m, int s) { + // 娣诲姞澶у皬鏈堟湀浠藉苟灏嗗叾杞崲涓簂ist,鏂逛究涔嬪悗鐨勫垽鏂� + String[] months_big = {"1", "3", "5", "7", "8", "10", "12"}; + String[] months_little = {"4", "6", "9", "11"}; + + final List<String> list_big = Arrays.asList(months_big); + final List<String> list_little = Arrays.asList(months_little); + + currentYear = year; + // 骞� + wv_year = (WheelView) view.findViewById(R.id.year); + wv_year.setAdapter(new NumericWheelAdapter(startYear, endYear));// 璁剧疆"骞�"鐨勬樉绀烘暟鎹� + + + wv_year.setCurrentItem(year - startYear);// 鍒濆鍖栨椂鏄剧ず鐨勬暟鎹� + wv_year.setGravity(gravity); + // 鏈� + wv_month = (WheelView) view.findViewById(R.id.month); + if (startYear == endYear) {//寮�濮嬪勾绛変簬缁堟骞� + wv_month.setAdapter(new NumericWheelAdapter(startMonth, endMonth)); + wv_month.setCurrentItem(month + 1 - startMonth); + } else if (year == startYear) { + //璧峰鏃ユ湡鐨勬湀浠芥帶鍒� + wv_month.setAdapter(new NumericWheelAdapter(startMonth, 12)); + wv_month.setCurrentItem(month + 1 - startMonth); + } else if (year == endYear) { + //缁堟鏃ユ湡鐨勬湀浠芥帶鍒� + wv_month.setAdapter(new NumericWheelAdapter(1, endMonth)); + wv_month.setCurrentItem(month); + } else { + wv_month.setAdapter(new NumericWheelAdapter(1, 12)); + wv_month.setCurrentItem(month); + } + wv_month.setGravity(gravity); + // 鏃� + wv_day = (WheelView) view.findViewById(R.id.day); + + boolean leapYear = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0; + if (startYear == endYear && startMonth == endMonth) { + if (list_big.contains(String.valueOf(month + 1))) { + if (endDay > 31) { + endDay = 31; + } + wv_day.setAdapter(new NumericWheelAdapter(startDay, endDay)); + } else if (list_little.contains(String.valueOf(month + 1))) { + if (endDay > 30) { + endDay = 30; + } + wv_day.setAdapter(new NumericWheelAdapter(startDay, endDay)); + } else { + // 闂板勾 + if (leapYear) { + if (endDay > 29) { + endDay = 29; + } + wv_day.setAdapter(new NumericWheelAdapter(startDay, endDay)); + } else { + if (endDay > 28) { + endDay = 28; + } + wv_day.setAdapter(new NumericWheelAdapter(startDay, endDay)); + } + } + wv_day.setCurrentItem(day - startDay); + } else if (year == startYear && month + 1 == startMonth) { + // 璧峰鏃ユ湡鐨勫ぉ鏁版帶鍒� + if (list_big.contains(String.valueOf(month + 1))) { + + wv_day.setAdapter(new NumericWheelAdapter(startDay, 31)); + } else if (list_little.contains(String.valueOf(month + 1))) { + + wv_day.setAdapter(new NumericWheelAdapter(startDay, 30)); + } else { + // 闂板勾 29锛屽钩骞� 28 + wv_day.setAdapter(new NumericWheelAdapter(startDay, leapYear ? 29 : 28)); + } + wv_day.setCurrentItem(day - startDay); + } else if (year == endYear && month + 1 == endMonth) { + // 缁堟鏃ユ湡鐨勫ぉ鏁版帶鍒� + if (list_big.contains(String.valueOf(month + 1))) { + if (endDay > 31) { + endDay = 31; + } + wv_day.setAdapter(new NumericWheelAdapter(1, endDay)); + } else if (list_little.contains(String.valueOf(month + 1))) { + if (endDay > 30) { + endDay = 30; + } + wv_day.setAdapter(new NumericWheelAdapter(1, endDay)); + } else { + // 闂板勾 + if (leapYear) { + if (endDay > 29) { + endDay = 29; + } + wv_day.setAdapter(new NumericWheelAdapter(1, endDay)); + } else { + if (endDay > 28) { + endDay = 28; + } + wv_day.setAdapter(new NumericWheelAdapter(1, endDay)); + } + } + wv_day.setCurrentItem(day - 1); + } else { + // 鍒ゆ柇澶у皬鏈堝強鏄惁闂板勾,鐢ㄦ潵纭畾"鏃�"鐨勬暟鎹� + if (list_big.contains(String.valueOf(month + 1))) { + wv_day.setAdapter(new NumericWheelAdapter(1, 31)); + } else if (list_little.contains(String.valueOf(month + 1))) { + wv_day.setAdapter(new NumericWheelAdapter(1, 30)); + } else { + // 闂板勾 29锛屽钩骞� 28 + wv_day.setAdapter(new NumericWheelAdapter(startDay, leapYear ? 29 : 28)); + } + wv_day.setCurrentItem(day - 1); + } + + wv_day.setGravity(gravity); + //鏃� + wv_hours = (WheelView) view.findViewById(R.id.hour); + wv_hours.setAdapter(new NumericWheelAdapter(0, 23)); + + wv_hours.setCurrentItem(h); + wv_hours.setGravity(gravity); + //鍒� + wv_minutes = (WheelView) view.findViewById(R.id.min); + wv_minutes.setAdapter(new NumericWheelAdapter(0, 59)); + + wv_minutes.setCurrentItem(m); + wv_minutes.setGravity(gravity); + //绉� + wv_seconds = (WheelView) view.findViewById(R.id.second); + wv_seconds.setAdapter(new NumericWheelAdapter(0, 59)); + + wv_seconds.setCurrentItem(s); + wv_seconds.setGravity(gravity); + + // 娣诲姞"骞�"鐩戝惉 + wv_year.setOnItemSelectedListener(new OnItemSelectedListener() { + @Override + public void onItemSelected(int index) { + int year_num = index + startYear; + currentYear = year_num; + int currentMonthItem = wv_month.getCurrentItem();//璁板綍涓婁竴娆$殑item浣嶇疆 + // 鍒ゆ柇澶у皬鏈堝強鏄惁闂板勾,鐢ㄦ潵纭畾"鏃�"鐨勬暟鎹� + if (startYear == endYear) { + //閲嶆柊璁剧疆鏈堜唤 + wv_month.setAdapter(new NumericWheelAdapter(startMonth, endMonth)); + + if (currentMonthItem > wv_month.getAdapter().getItemsCount() - 1) { + currentMonthItem = wv_month.getAdapter().getItemsCount() - 1; + wv_month.setCurrentItem(currentMonthItem); + } + + int monthNum = currentMonthItem + startMonth; + + if (startMonth == endMonth) { + //閲嶆柊璁剧疆鏃� + setReDay(year_num, monthNum, startDay, endDay, list_big, list_little); + } else if (monthNum == startMonth) { + //閲嶆柊璁剧疆鏃� + setReDay(year_num, monthNum, startDay, 31, list_big, list_little); + } else if (monthNum == endMonth) { + setReDay(year_num, monthNum, 1, endDay, list_big, list_little); + } else {//閲嶆柊璁剧疆鏃� + setReDay(year_num, monthNum, 1, 31, list_big, list_little); + } + } else if (year_num == startYear) {//绛変簬寮�濮嬬殑骞� + //閲嶆柊璁剧疆鏈堜唤 + wv_month.setAdapter(new NumericWheelAdapter(startMonth, 12)); + + if (currentMonthItem > wv_month.getAdapter().getItemsCount() - 1) { + currentMonthItem = wv_month.getAdapter().getItemsCount() - 1; + wv_month.setCurrentItem(currentMonthItem); + } + + int month = currentMonthItem + startMonth; + if (month == startMonth) { + //閲嶆柊璁剧疆鏃� + setReDay(year_num, month, startDay, 31, list_big, list_little); + } else { + //閲嶆柊璁剧疆鏃� + setReDay(year_num, month, 1, 31, list_big, list_little); + } + + } else if (year_num == endYear) { + //閲嶆柊璁剧疆鏈堜唤 + wv_month.setAdapter(new NumericWheelAdapter(1, endMonth)); + if (currentMonthItem > wv_month.getAdapter().getItemsCount() - 1) { + currentMonthItem = wv_month.getAdapter().getItemsCount() - 1; + wv_month.setCurrentItem(currentMonthItem); + } + int monthNum = currentMonthItem + 1; + + if (monthNum == endMonth) { + //閲嶆柊璁剧疆鏃� + setReDay(year_num, monthNum, 1, endDay, list_big, list_little); + } else { + //閲嶆柊璁剧疆鏃� + setReDay(year_num, monthNum, 1, 31, list_big, list_little); + } + + } else { + //閲嶆柊璁剧疆鏈堜唤 + wv_month.setAdapter(new NumericWheelAdapter(1, 12)); + //閲嶆柊璁剧疆鏃� + setReDay(year_num, wv_month.getCurrentItem() + 1, 1, 31, list_big, list_little); + } + + if (mSelectChangeCallback != null) { + mSelectChangeCallback.onTimeSelectChanged(); + } + } + }); + + + // 娣诲姞"鏈�"鐩戝惉 + wv_month.setOnItemSelectedListener(new OnItemSelectedListener() { + @Override + public void onItemSelected(int index) { + int month_num = index + 1; + + if (startYear == endYear) { + month_num = month_num + startMonth - 1; + if (startMonth == endMonth) { + //閲嶆柊璁剧疆鏃� + setReDay(currentYear, month_num, startDay, endDay, list_big, list_little); + } else if (startMonth == month_num) { + + //閲嶆柊璁剧疆鏃� + setReDay(currentYear, month_num, startDay, 31, list_big, list_little); + } else if (endMonth == month_num) { + setReDay(currentYear, month_num, 1, endDay, list_big, list_little); + } else { + setReDay(currentYear, month_num, 1, 31, list_big, list_little); + } + } else if (currentYear == startYear) { + month_num = month_num + startMonth - 1; + if (month_num == startMonth) { + //閲嶆柊璁剧疆鏃� + setReDay(currentYear, month_num, startDay, 31, list_big, list_little); + } else { + //閲嶆柊璁剧疆鏃� + setReDay(currentYear, month_num, 1, 31, list_big, list_little); + } + + } else if (currentYear == endYear) { + if (month_num == endMonth) { + //閲嶆柊璁剧疆鏃� + setReDay(currentYear, wv_month.getCurrentItem() + 1, 1, endDay, list_big, list_little); + } else { + setReDay(currentYear, wv_month.getCurrentItem() + 1, 1, 31, list_big, list_little); + } + + } else { + //閲嶆柊璁剧疆鏃� + setReDay(currentYear, month_num, 1, 31, list_big, list_little); + } + + if (mSelectChangeCallback != null) { + mSelectChangeCallback.onTimeSelectChanged(); + } + } + }); + + setChangedListener(wv_day); + setChangedListener(wv_hours); + setChangedListener(wv_minutes); + setChangedListener(wv_seconds); + + if (type.length != 6) { + throw new IllegalArgumentException("type[] length is not 6"); + } + wv_year.setVisibility(type[0] ? View.VISIBLE : View.GONE); + wv_month.setVisibility(type[1] ? View.VISIBLE : View.GONE); + wv_day.setVisibility(type[2] ? View.VISIBLE : View.GONE); + wv_hours.setVisibility(type[3] ? View.VISIBLE : View.GONE); + wv_minutes.setVisibility(type[4] ? View.VISIBLE : View.GONE); + wv_seconds.setVisibility(type[5] ? View.VISIBLE : View.GONE); + setContentTextSize(); + } + + private void setChangedListener(WheelView wheelView) { + if (mSelectChangeCallback != null) { + wheelView.setOnItemSelectedListener(new OnItemSelectedListener() { + @Override + public void onItemSelected(int index) { + mSelectChangeCallback.onTimeSelectChanged(); + } + }); + } + + } + + + private void setReDay(int year_num, int monthNum, int startD, int endD, List<String> list_big, List<String> list_little) { + int currentItem = wv_day.getCurrentItem(); + +// int maxItem; + if (list_big.contains(String.valueOf(monthNum))) { + if (endD > 31) { + endD = 31; + } + wv_day.setAdapter(new NumericWheelAdapter(startD, endD)); +// maxItem = endD; + } else if (list_little.contains(String.valueOf(monthNum))) { + if (endD > 30) { + endD = 30; + } + wv_day.setAdapter(new NumericWheelAdapter(startD, endD)); +// maxItem = endD; + } else { + if ((year_num % 4 == 0 && year_num % 100 != 0) + || year_num % 400 == 0) { + if (endD > 29) { + endD = 29; + } + wv_day.setAdapter(new NumericWheelAdapter(startD, endD)); +// maxItem = endD; + } else { + if (endD > 28) { + endD = 28; + } + wv_day.setAdapter(new NumericWheelAdapter(startD, endD)); +// maxItem = endD; + } + } + + if (currentItem > wv_day.getAdapter().getItemsCount() - 1) { + currentItem = wv_day.getAdapter().getItemsCount() - 1; + wv_day.setCurrentItem(currentItem); + } + } + + + private void setContentTextSize() { + wv_day.setTextSize(textSize); + wv_month.setTextSize(textSize); + wv_year.setTextSize(textSize); + wv_hours.setTextSize(textSize); + wv_minutes.setTextSize(textSize); + wv_seconds.setTextSize(textSize); + } + + + public void setLabels(String label_year, String label_month, String label_day, String label_hours, String label_mins, String label_seconds) { + if (isLunarCalendar) { + return; + } + + if (label_year != null) { + wv_year.setLabel(label_year); + } else { + wv_year.setLabel(view.getContext().getString(R.string.pickerview_year)); + } + if (label_month != null) { + wv_month.setLabel(label_month); + } else { + wv_month.setLabel(view.getContext().getString(R.string.pickerview_month)); + } + if (label_day != null) { + wv_day.setLabel(label_day); + } else { + wv_day.setLabel(view.getContext().getString(R.string.pickerview_day)); + } + if (label_hours != null) { + wv_hours.setLabel(label_hours); + } else { + wv_hours.setLabel(view.getContext().getString(R.string.pickerview_hours)); + } + if (label_mins != null) { + wv_minutes.setLabel(label_mins); + } else { + wv_minutes.setLabel(view.getContext().getString(R.string.pickerview_minutes)); + } + if (label_seconds != null) { + wv_seconds.setLabel(label_seconds); + } else { + wv_seconds.setLabel(view.getContext().getString(R.string.pickerview_seconds)); + } + + } + + public void setTextXOffset(int x_offset_year, int x_offset_month, int x_offset_day, + int x_offset_hours, int x_offset_minutes, int x_offset_seconds) { + wv_year.setTextXOffset(x_offset_year); + wv_month.setTextXOffset(x_offset_month); + wv_day.setTextXOffset(x_offset_day); + wv_hours.setTextXOffset(x_offset_hours); + wv_minutes.setTextXOffset(x_offset_minutes); + wv_seconds.setTextXOffset(x_offset_seconds); + } + + /** + * 璁剧疆鏄惁寰幆婊氬姩 + * + * @param cyclic + */ + public void setCyclic(boolean cyclic) { + wv_year.setCyclic(cyclic); + wv_month.setCyclic(cyclic); + wv_day.setCyclic(cyclic); + wv_hours.setCyclic(cyclic); + wv_minutes.setCyclic(cyclic); + wv_seconds.setCyclic(cyclic); + } + + public String getTime() { + if (isLunarCalendar) { + //濡傛灉鏄啘鍘� 杩斿洖瀵瑰簲鐨勫叕鍘嗘椂闂� + return getLunarTime(); + } + StringBuilder sb = new StringBuilder(); + if (currentYear == startYear) { + /* int i = wv_month.getCurrentItem() + startMonth; + System.out.println("i:" + i);*/ + if ((wv_month.getCurrentItem() + startMonth) == startMonth) { + sb.append((wv_year.getCurrentItem() + startYear)).append("-") + .append((wv_month.getCurrentItem() + startMonth)).append("-") + .append((wv_day.getCurrentItem() + startDay)).append(" ") + .append(wv_hours.getCurrentItem()).append(":") + .append(wv_minutes.getCurrentItem()).append(":") + .append(wv_seconds.getCurrentItem()); + } else { + sb.append((wv_year.getCurrentItem() + startYear)).append("-") + .append((wv_month.getCurrentItem() + startMonth)).append("-") + .append((wv_day.getCurrentItem() + 1)).append(" ") + .append(wv_hours.getCurrentItem()).append(":") + .append(wv_minutes.getCurrentItem()).append(":") + .append(wv_seconds.getCurrentItem()); + } + + } else { + sb.append((wv_year.getCurrentItem() + startYear)).append("-") + .append((wv_month.getCurrentItem() + 1)).append("-") + .append((wv_day.getCurrentItem() + 1)).append(" ") + .append(wv_hours.getCurrentItem()).append(":") + .append(wv_minutes.getCurrentItem()).append(":") + .append(wv_seconds.getCurrentItem()); + } + + return sb.toString(); + } + + + /** + * 鍐滃巻杩斿洖瀵瑰簲鐨勫叕鍘嗘椂闂� + * + * @return + */ + private String getLunarTime() { + StringBuilder sb = new StringBuilder(); + int year = wv_year.getCurrentItem() + startYear; + int month = 1; + boolean isLeapMonth = false; + if (ChinaDate.leapMonth(year) == 0) { + month = wv_month.getCurrentItem() + 1; + } else { + if ((wv_month.getCurrentItem() + 1) - ChinaDate.leapMonth(year) <= 0) { + month = wv_month.getCurrentItem() + 1; + } else if ((wv_month.getCurrentItem() + 1) - ChinaDate.leapMonth(year) == 1) { + month = wv_month.getCurrentItem(); + isLeapMonth = true; + } else { + month = wv_month.getCurrentItem(); + } + } + int day = wv_day.getCurrentItem() + 1; + int[] solar = LunarCalendar.lunarToSolar(year, month, day, isLeapMonth); + + sb.append(solar[0]).append("-") + .append(solar[1]).append("-") + .append(solar[2]).append(" ") + .append(wv_hours.getCurrentItem()).append(":") + .append(wv_minutes.getCurrentItem()).append(":") + .append(wv_seconds.getCurrentItem()); + return sb.toString(); + } + + public View getView() { + return view; + } + + public int getStartYear() { + return startYear; + } + + public void setStartYear(int startYear) { + this.startYear = startYear; + } + + public int getEndYear() { + return endYear; + } + + public void setEndYear(int endYear) { + this.endYear = endYear; + } + + + public void setRangDate(Calendar startDate, Calendar endDate) { + + if (startDate == null && endDate != null) { + int year = endDate.get(Calendar.YEAR); + int month = endDate.get(Calendar.MONTH) + 1; + int day = endDate.get(Calendar.DAY_OF_MONTH); + if (year > startYear) { + this.endYear = year; + this.endMonth = month; + this.endDay = day; + } else if (year == startYear) { + if (month > startMonth) { + this.endYear = year; + this.endMonth = month; + this.endDay = day; + } else if (month == startMonth) { + if (day > startDay) { + this.endYear = year; + this.endMonth = month; + this.endDay = day; + } + } + } + + } else if (startDate != null && endDate == null) { + int year = startDate.get(Calendar.YEAR); + int month = startDate.get(Calendar.MONTH) + 1; + int day = startDate.get(Calendar.DAY_OF_MONTH); + if (year < endYear) { + this.startMonth = month; + this.startDay = day; + this.startYear = year; + } else if (year == endYear) { + if (month < endMonth) { + this.startMonth = month; + this.startDay = day; + this.startYear = year; + } else if (month == endMonth) { + if (day < endDay) { + this.startMonth = month; + this.startDay = day; + this.startYear = year; + } + } + } + + } else if (startDate != null && endDate != null) { + this.startYear = startDate.get(Calendar.YEAR); + this.endYear = endDate.get(Calendar.YEAR); + this.startMonth = startDate.get(Calendar.MONTH) + 1; + this.endMonth = endDate.get(Calendar.MONTH) + 1; + this.startDay = startDate.get(Calendar.DAY_OF_MONTH); + this.endDay = endDate.get(Calendar.DAY_OF_MONTH); + } + + } + + /** + * 璁剧疆闂磋窛鍊嶆暟,浣嗘槸鍙兘鍦�1.0-4.0f涔嬮棿 + * + * @param lineSpacingMultiplier + */ + public void setLineSpacingMultiplier(float lineSpacingMultiplier) { + wv_day.setLineSpacingMultiplier(lineSpacingMultiplier); + wv_month.setLineSpacingMultiplier(lineSpacingMultiplier); + wv_year.setLineSpacingMultiplier(lineSpacingMultiplier); + wv_hours.setLineSpacingMultiplier(lineSpacingMultiplier); + wv_minutes.setLineSpacingMultiplier(lineSpacingMultiplier); + wv_seconds.setLineSpacingMultiplier(lineSpacingMultiplier); + } + + /** + * 璁剧疆鍒嗗壊绾跨殑棰滆壊 + * + * @param dividerColor + */ + public void setDividerColor(int dividerColor) { + wv_day.setDividerColor(dividerColor); + wv_month.setDividerColor(dividerColor); + wv_year.setDividerColor(dividerColor); + wv_hours.setDividerColor(dividerColor); + wv_minutes.setDividerColor(dividerColor); + wv_seconds.setDividerColor(dividerColor); + } + + /** + * 璁剧疆鍒嗗壊绾跨殑绫诲瀷 + * + * @param dividerType + */ + public void setDividerType(WheelView.DividerType dividerType) { + wv_day.setDividerType(dividerType); + wv_month.setDividerType(dividerType); + wv_year.setDividerType(dividerType); + wv_hours.setDividerType(dividerType); + wv_minutes.setDividerType(dividerType); + wv_seconds.setDividerType(dividerType); + } + + /** + * 璁剧疆鍒嗗壊绾夸箣闂寸殑鏂囧瓧鐨勯鑹� + * + * @param textColorCenter + */ + public void setTextColorCenter(int textColorCenter) { + wv_day.setTextColorCenter(textColorCenter); + wv_month.setTextColorCenter(textColorCenter); + wv_year.setTextColorCenter(textColorCenter); + wv_hours.setTextColorCenter(textColorCenter); + wv_minutes.setTextColorCenter(textColorCenter); + wv_seconds.setTextColorCenter(textColorCenter); + } + + /** + * 璁剧疆鍒嗗壊绾夸互澶栨枃瀛楃殑棰滆壊 + * + * @param textColorOut + */ + public void setTextColorOut(int textColorOut) { + wv_day.setTextColorOut(textColorOut); + wv_month.setTextColorOut(textColorOut); + wv_year.setTextColorOut(textColorOut); + wv_hours.setTextColorOut(textColorOut); + wv_minutes.setTextColorOut(textColorOut); + wv_seconds.setTextColorOut(textColorOut); + } + + /** + * @param isCenterLabel 鏄惁鍙樉绀轰腑闂撮�変腑椤圭殑 + */ + public void isCenterLabel(boolean isCenterLabel) { + wv_day.isCenterLabel(isCenterLabel); + wv_month.isCenterLabel(isCenterLabel); + wv_year.isCenterLabel(isCenterLabel); + wv_hours.isCenterLabel(isCenterLabel); + wv_minutes.isCenterLabel(isCenterLabel); + wv_seconds.isCenterLabel(isCenterLabel); + } + + public void setSelectChangeCallback(ISelectTimeCallback mSelectChangeCallback) { + this.mSelectChangeCallback = mSelectChangeCallback; + } + + public void setItemsVisible(int itemsVisibleCount) { + wv_day.setItemsVisibleCount(itemsVisibleCount); + wv_month.setItemsVisibleCount(itemsVisibleCount); + wv_year.setItemsVisibleCount(itemsVisibleCount); + wv_hours.setItemsVisibleCount(itemsVisibleCount); + wv_minutes.setItemsVisibleCount(itemsVisibleCount); + wv_seconds.setItemsVisibleCount(itemsVisibleCount); + } + + public void setAlphaGradient(boolean isAlphaGradient) { + wv_day.setAlphaGradient(isAlphaGradient); + wv_month.setAlphaGradient(isAlphaGradient); + wv_year.setAlphaGradient(isAlphaGradient); + wv_hours.setAlphaGradient(isAlphaGradient); + wv_minutes.setAlphaGradient(isAlphaGradient); + wv_seconds.setAlphaGradient(isAlphaGradient); + } +} diff --git a/pickerview/src/main/res/anim/pickerview_dialog_scale_in.xml b/pickerview/src/main/res/anim/pickerview_dialog_scale_in.xml new file mode 100644 index 0000000..d374b90 --- /dev/null +++ b/pickerview/src/main/res/anim/pickerview_dialog_scale_in.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<set xmlns:android="http://schemas.android.com/apk/res/android"> + + + <alpha + android:duration="@integer/animation_default_duration" + android:fromAlpha="0.0" + android:toAlpha="1.0" /> + + <scale + android:duration="@integer/animation_default_duration" + android:fromXScale="0.0" + android:toXScale="1.0" + android:fromYScale="0.0" + android:toYScale="1.0" + android:pivotX="50%" + android:pivotY="50%"/> + +</set> \ No newline at end of file diff --git a/pickerview/src/main/res/anim/pickerview_dialog_scale_out.xml b/pickerview/src/main/res/anim/pickerview_dialog_scale_out.xml new file mode 100644 index 0000000..64acb59 --- /dev/null +++ b/pickerview/src/main/res/anim/pickerview_dialog_scale_out.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<set xmlns:android="http://schemas.android.com/apk/res/android"> + + + <alpha + android:duration="@integer/animation_default_duration" + android:fromAlpha="1.0" + android:toAlpha="0.3" /> + + <scale + android:duration="@integer/animation_default_duration" + android:fromXScale="1.0" + android:toXScale="0.0" + android:fromYScale="1.0" + android:toYScale="0.0" + android:pivotX="50%" + android:pivotY="50%"/> +</set> \ No newline at end of file diff --git a/pickerview/src/main/res/anim/pickerview_slide_in_bottom.xml b/pickerview/src/main/res/anim/pickerview_slide_in_bottom.xml new file mode 100644 index 0000000..58fd94b --- /dev/null +++ b/pickerview/src/main/res/anim/pickerview_slide_in_bottom.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:shareInterpolator="false"> + + <translate + android:duration="@integer/animation_default_duration" + android:fromXDelta="0%" + android:toXDelta="0%" + android:fromYDelta="100%" + android:toYDelta="0%"/> +</set> \ No newline at end of file diff --git a/pickerview/src/main/res/anim/pickerview_slide_out_bottom.xml b/pickerview/src/main/res/anim/pickerview_slide_out_bottom.xml new file mode 100644 index 0000000..6a45af3 --- /dev/null +++ b/pickerview/src/main/res/anim/pickerview_slide_out_bottom.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:shareInterpolator="false"> + + <translate + android:duration="@integer/animation_default_duration" + android:fromXDelta="0%" + android:toXDelta="0%" + android:fromYDelta="0%" + android:toYDelta="100%"/> +</set> \ No newline at end of file diff --git a/pickerview/src/main/res/drawable/selector_pickerview_btn.xml b/pickerview/src/main/res/drawable/selector_pickerview_btn.xml new file mode 100644 index 0000000..fd6ad35 --- /dev/null +++ b/pickerview/src/main/res/drawable/selector_pickerview_btn.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<selector + xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_pressed="true" android:color="@color/pickerview_timebtn_pre" /> + <item android:color="@color/pickerview_timebtn_nor" /> +</selector> diff --git a/pickerview/src/main/res/layout/include_pickerview_topbar.xml b/pickerview/src/main/res/layout/include_pickerview_topbar.xml new file mode 100644 index 0000000..f7d4812 --- /dev/null +++ b/pickerview/src/main/res/layout/include_pickerview_topbar.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/rv_topbar" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/pickerview_bgColor_default"> + + <Button + android:id="@+id/btnCancel" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:background="@android:color/transparent" + android:gravity="left|center_vertical" + android:paddingLeft="@dimen/pickerview_topbar_padding" + android:text="@string/pickerview_cancel" + android:textAllCaps="false" + android:textColor="@drawable/selector_pickerview_btn" + android:textSize="@dimen/pickerview_topbar_btn_textsize" /> + + <TextView + android:id="@+id/tvTitle" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_centerVertical="true" + android:layout_toLeftOf="@+id/btnSubmit" + android:layout_toRightOf="@+id/btnCancel" + android:gravity="center" + android:textColor="@color/pickerview_topbar_title" + android:textSize="@dimen/pickerview_topbar_title_textsize" + /> + + <Button + android:id="@id/btnSubmit" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_alignParentRight="true" + android:background="@android:color/transparent" + android:gravity="right|center_vertical" + android:paddingRight="@dimen/pickerview_topbar_padding" + android:text="@string/pickerview_submit" + android:textAllCaps="false" + android:textColor="@drawable/selector_pickerview_btn" + android:textSize="@dimen/pickerview_topbar_btn_textsize" /> +</RelativeLayout> diff --git a/pickerview/src/main/res/layout/layout_basepickerview.xml b/pickerview/src/main/res/layout/layout_basepickerview.xml new file mode 100644 index 0000000..091ff8d --- /dev/null +++ b/pickerview/src/main/res/layout/layout_basepickerview.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> +<FrameLayout + android:id="@+id/outmost_container" + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:clickable="true" + android:background="@color/pickerview_bgColor_overlay"> + + <FrameLayout + android:id="@+id/content_container" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + </FrameLayout> + +</FrameLayout> \ No newline at end of file diff --git a/pickerview/src/main/res/layout/pickerview_options.xml b/pickerview/src/main/res/layout/pickerview_options.xml new file mode 100644 index 0000000..a5e3378 --- /dev/null +++ b/pickerview/src/main/res/layout/pickerview_options.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <include + layout="@layout/include_pickerview_topbar" + android:layout_width="match_parent" + android:layout_height="50dp" /> + + <View + android:layout_width="match_parent" + android:layout_height="0.5dp" + android:background="#E1E1E1" /> + + <LinearLayout + android:id="@+id/optionspicker" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@android:color/white" + android:gravity="center" + android:minHeight="180dp" + android:orientation="horizontal"> + + <com.contrarywind.view.WheelView + android:id="@+id/options1" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" /> + + <com.contrarywind.view.WheelView + android:id="@+id/options2" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" /> + + <com.contrarywind.view.WheelView + android:id="@+id/options3" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" /> + </LinearLayout> + + +</LinearLayout> \ No newline at end of file diff --git a/pickerview/src/main/res/layout/pickerview_time.xml b/pickerview/src/main/res/layout/pickerview_time.xml new file mode 100644 index 0000000..8ea76e0 --- /dev/null +++ b/pickerview/src/main/res/layout/pickerview_time.xml @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <include + layout="@layout/include_pickerview_topbar" + android:layout_width="match_parent" + android:layout_height="@dimen/pickerview_topbar_height" /> + + <View + android:layout_width="match_parent" + android:layout_height="0.5dp" + android:background="#E1E1E1" /> + + <LinearLayout + android:id="@+id/timepicker" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@android:color/white" + android:gravity="center" + android:minHeight="150dp" + android:orientation="horizontal"> + + <com.contrarywind.view.WheelView + android:id="@+id/year" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="0.96" /> + + <com.contrarywind.view.WheelView + android:id="@+id/month" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" /> + + <com.contrarywind.view.WheelView + android:id="@+id/day" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" /> + + <com.contrarywind.view.WheelView + android:id="@+id/hour" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" /> + + <com.contrarywind.view.WheelView + android:id="@+id/min" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" /> + + <com.contrarywind.view.WheelView + android:id="@+id/second" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" /> + </LinearLayout> + + +</LinearLayout> \ No newline at end of file diff --git a/pickerview/src/main/res/values-en/strings.xml b/pickerview/src/main/res/values-en/strings.xml new file mode 100644 index 0000000..6ba3260 --- /dev/null +++ b/pickerview/src/main/res/values-en/strings.xml @@ -0,0 +1,11 @@ +<resources> + + <string name="pickerview_cancel">Cancel</string> + <string name="pickerview_submit">Confirm</string> + <string name="pickerview_year"> </string> + <string name="pickerview_month"> </string> + <string name="pickerview_day"> </string> + <string name="pickerview_hours"> </string> + <string name="pickerview_minutes"> </string> + <string name="pickerview_seconds"> </string> +</resources> diff --git a/pickerview/src/main/res/values/dimens.xml b/pickerview/src/main/res/values/dimens.xml new file mode 100644 index 0000000..9ea5247 --- /dev/null +++ b/pickerview/src/main/res/values/dimens.xml @@ -0,0 +1,13 @@ +<resources> + <!-- 椤堕儴鎸夐挳鏍忛珮搴� --> + <dimen name="pickerview_topbar_height">52dp</dimen> + + <!-- 椤堕儴鎸夐挳padding --> + <dimen name="pickerview_topbar_padding">20dp</dimen> + + <!-- 椤堕儴鎸夐挳鏂囧瓧澶у皬 --> + <dimen name="pickerview_topbar_btn_textsize">17sp</dimen> + <dimen name="pickerview_topbar_title_textsize">18sp</dimen> + <!-- 閫夐」鏂囧瓧澶у皬 --> + <dimen name="pickerview_textsize">20sp</dimen> +</resources> diff --git a/pickerview/src/main/res/values/integers.xml b/pickerview/src/main/res/values/integers.xml new file mode 100644 index 0000000..d3fb3c1 --- /dev/null +++ b/pickerview/src/main/res/values/integers.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + + <integer name="animation_default_duration">300</integer> +</resources> \ No newline at end of file diff --git a/pickerview/src/main/res/values/strings.xml b/pickerview/src/main/res/values/strings.xml new file mode 100644 index 0000000..3c7f01a --- /dev/null +++ b/pickerview/src/main/res/values/strings.xml @@ -0,0 +1,11 @@ +<resources> + + <string name="pickerview_cancel">鍙栨秷</string> + <string name="pickerview_submit">纭畾</string> + <string name="pickerview_year">骞�</string> + <string name="pickerview_month">鏈�</string> + <string name="pickerview_day">鏃�</string> + <string name="pickerview_hours">鏃�</string> + <string name="pickerview_minutes">鍒�</string> + <string name="pickerview_seconds">绉�</string> +</resources> diff --git a/pickerview/src/main/res/values/styles.xml b/pickerview/src/main/res/values/styles.xml new file mode 100644 index 0000000..29a356b --- /dev/null +++ b/pickerview/src/main/res/values/styles.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <style name="custom_dialog2" parent="@android:style/Theme.Dialog"> + <item name="android:windowFrame">@null</item> + <!-- Dialog鐨剋indowFrame妗嗕负鏃� --> + <item name="android:windowIsFloating">true</item> + <!-- 鏄惁婕傜幇鍦╝ctivity涓� --> + <item name="android:windowIsTranslucent">true</item> + <!-- 鏄惁鍗婇�忔槑 --> + <item name="android:windowNoTitle">true</item> + <item name="android:background">@null</item> + <item name="android:windowBackground">@android:color/transparent</item> + <item name="android:windowContentOverlay">@null</item> + <!-- 鍘婚櫎榛戣壊杈规鐨勫叧閿缃」 --> + <item name="android:backgroundDimEnabled">true</item> + <!-- 灞忓箷鑳屾櫙鏄惁鍙樻殫 --> + <item name="android:backgroundDimAmount">0.3</item> + </style> + + <style name="picker_view_scale_anim" mce_bogus="1" parent="android:Animation"> + <item name="android:windowEnterAnimation">@anim/pickerview_dialog_scale_in</item> + <item name="android:windowExitAnimation">@anim/pickerview_dialog_scale_out</item> + </style> + + + <style name="picker_view_slide_anim" mce_bogus="1" parent="android:Animation"> + <item name="android:windowEnterAnimation">@anim/pickerview_slide_in_bottom</item> + <item name="android:windowExitAnimation">@anim/pickerview_slide_out_bottom</item> + </style> + +</resources> diff --git a/settings.gradle b/settings.gradle index ff82e42..f42f856 100644 --- a/settings.gradle +++ b/settings.gradle @@ -3,3 +3,5 @@ include ':third-zxing' include ':countrypicker' include ':aa_chart_core' +include ':pickerview' +include ':wheelview' \ No newline at end of file diff --git a/third-zxing/build.gradle b/third-zxing/build.gradle index 2961ed2..c39f127 100644 --- a/third-zxing/build.gradle +++ b/third-zxing/build.gradle @@ -2,12 +2,12 @@ android { - compileSdkVersion 29 + compileSdkVersion 30 buildToolsVersion "29.0.1" defaultConfig { - minSdkVersion 21 - targetSdkVersion 26 + minSdkVersion 23 + targetSdkVersion 30 versionCode 1 versionName "1.0" diff --git a/wheelview/.gitignore b/wheelview/.gitignore new file mode 100644 index 0000000..43cf153 --- /dev/null +++ b/wheelview/.gitignore @@ -0,0 +1,12 @@ +/build +*.idea +/.idea/libraries +/.idea/modules +/.idea/compiler.xml +/.idea/gradle.xml +/.idea/jarRepositories.xml +/.idea/misc.xml +/.idea/modules.xml +/.idea/vcs.xml +/.idea/workspace.xml +/release \ No newline at end of file diff --git a/wheelview/build.gradle b/wheelview/build.gradle new file mode 100644 index 0000000..6bd966b --- /dev/null +++ b/wheelview/build.gradle @@ -0,0 +1,47 @@ +apply plugin: 'com.android.library' +//apply plugin: 'com.novoda.bintray-release'//娣诲姞鎻掍欢 + + + +android { + compileSdkVersion 31 + + defaultConfig { + minSdkVersion 23 + targetSdkVersion 31 + versionCode 31 + versionName "4.1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + lintOptions { + abortOnError false + } +} + +//allprojects { +// tasks.withType(Javadoc) {//鍏煎涓枃瀛楃 +// options{ +// encoding "UTF-8" +// charSet 'UTF-8' +// links "http://docs.oracle.com/javase/7/docs/api" +// } +// } +//} +//publish { +// userOrg = 'contrarywind'//bintray.com 鐢ㄦ埛鍚�/缁勭粐鍚� user/org name +// groupId = 'com.contrarywind'//JCenter涓婃樉绀虹殑璺緞 path +// artifactId = 'wheelview'//椤圭洰鍚嶇О project name +// publishVersion = '4.1.0'//鐗堟湰鍙� version code +// desc = 'this is a wheelview for android'//椤圭洰鎻忚堪 description +// website = 'https://github.com/Bigkoo/Android-PickerView' //椤圭洰缃戝潃閾炬帴 link +//} + +dependencies { +// compile fileTree(include: ['*.jar'], dir: 'libs') + implementation 'com.android.support:support-annotations:28.0.0' +} \ No newline at end of file diff --git a/wheelview/proguard-rules.pro b/wheelview/proguard-rules.pro new file mode 100644 index 0000000..8b26010 --- /dev/null +++ b/wheelview/proguard-rules.pro @@ -0,0 +1,25 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in C:\Users\song\AppData\Local\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 *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/wheelview/src/androidTest/java/test/wheelview/ExampleInstrumentedTest.java b/wheelview/src/androidTest/java/test/wheelview/ExampleInstrumentedTest.java new file mode 100644 index 0000000..b5aa002 --- /dev/null +++ b/wheelview/src/androidTest/java/test/wheelview/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package test.wheelview; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumentation test, which will execute on an Android device. + * + * @see <a href="http://d.android.com/tools/testing">Testing documentation</a> + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() throws Exception { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("test.wheelview.test", appContext.getPackageName()); + } +} diff --git a/wheelview/src/main/AndroidManifest.xml b/wheelview/src/main/AndroidManifest.xml new file mode 100644 index 0000000..88cabec --- /dev/null +++ b/wheelview/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.contrarywind.view"> + +</manifest> diff --git a/wheelview/src/main/java/com/contrarywind/adapter/WheelAdapter.java b/wheelview/src/main/java/com/contrarywind/adapter/WheelAdapter.java new file mode 100644 index 0000000..5e53b7b --- /dev/null +++ b/wheelview/src/main/java/com/contrarywind/adapter/WheelAdapter.java @@ -0,0 +1,25 @@ +package com.contrarywind.adapter; + + +public interface WheelAdapter<T> { + /** + * Gets items count + * @return the count of wheel items + */ + int getItemsCount(); + + /** + * Gets a wheel item by index. + * @param index the item index + * @return the wheel item text or null + */ + T 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. + * @param o the item object + * @return the maximum item length or -1 + */ + int indexOf(T o); +} diff --git a/wheelview/src/main/java/com/contrarywind/interfaces/IPickerViewData.java b/wheelview/src/main/java/com/contrarywind/interfaces/IPickerViewData.java new file mode 100644 index 0000000..33c4956 --- /dev/null +++ b/wheelview/src/main/java/com/contrarywind/interfaces/IPickerViewData.java @@ -0,0 +1,8 @@ +package com.contrarywind.interfaces; + +/** + * Created by Sai on 2016/7/13. + */ +public interface IPickerViewData { + String getPickerViewText(); +} diff --git a/wheelview/src/main/java/com/contrarywind/listener/LoopViewGestureListener.java b/wheelview/src/main/java/com/contrarywind/listener/LoopViewGestureListener.java new file mode 100644 index 0000000..da8266c --- /dev/null +++ b/wheelview/src/main/java/com/contrarywind/listener/LoopViewGestureListener.java @@ -0,0 +1,25 @@ +package com.contrarywind.listener; + +import android.view.MotionEvent; + +import com.contrarywind.view.WheelView; + + +/** + * 鎵嬪娍鐩戝惉 + */ +public final class LoopViewGestureListener extends android.view.GestureDetector.SimpleOnGestureListener { + + private final WheelView wheelView; + + + public LoopViewGestureListener(WheelView wheelView) { + this.wheelView = wheelView; + } + + @Override + public final boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { + wheelView.scrollBy(velocityY); + return true; + } +} diff --git a/wheelview/src/main/java/com/contrarywind/listener/OnItemSelectedListener.java b/wheelview/src/main/java/com/contrarywind/listener/OnItemSelectedListener.java new file mode 100644 index 0000000..953841a --- /dev/null +++ b/wheelview/src/main/java/com/contrarywind/listener/OnItemSelectedListener.java @@ -0,0 +1,6 @@ +package com.contrarywind.listener; + + +public interface OnItemSelectedListener { + void onItemSelected(int index); +} diff --git a/wheelview/src/main/java/com/contrarywind/timer/InertiaTimerTask.java b/wheelview/src/main/java/com/contrarywind/timer/InertiaTimerTask.java new file mode 100644 index 0000000..2e5f061 --- /dev/null +++ b/wheelview/src/main/java/com/contrarywind/timer/InertiaTimerTask.java @@ -0,0 +1,79 @@ +package com.contrarywind.timer; + +import com.contrarywind.view.WheelView; + +import java.util.TimerTask; + +/** + * 婊氬姩鎯�х殑瀹炵幇 + * + * @author 灏忓旦 + * date: 2017-12-23 23:20:44 + */ +public final class InertiaTimerTask extends TimerTask { + + private float mCurrentVelocityY; //褰撳墠婊戝姩閫熷害 + private final float mFirstVelocityY;//鎵嬫寚绂诲紑灞忓箷鏃剁殑鍒濆閫熷害 + private final WheelView mWheelView; + + /** + * @param wheelView 婊氳疆瀵硅薄 + * @param velocityY Y杞存粦琛岄�熷害 + */ + public InertiaTimerTask(WheelView wheelView, float velocityY) { + super(); + this.mWheelView = wheelView; + this.mFirstVelocityY = velocityY; + mCurrentVelocityY = Integer.MAX_VALUE; + } + + @Override + public final void run() { + + //闃叉闂姩锛屽閫熷害鍋氫竴涓檺鍒躲�� + if (mCurrentVelocityY == Integer.MAX_VALUE) { + if (Math.abs(mFirstVelocityY) > 2000F) { + mCurrentVelocityY = mFirstVelocityY > 0 ? 2000F : -2000F; + } else { + mCurrentVelocityY = mFirstVelocityY; + } + } + + //鍙戦�乭andler娑堟伅 澶勭悊骞抽『鍋滄婊氬姩閫昏緫 + if (Math.abs(mCurrentVelocityY) >= 0.0F && Math.abs(mCurrentVelocityY) <= 20F) { + mWheelView.cancelFuture(); + mWheelView.getHandler().sendEmptyMessage(MessageHandler.WHAT_SMOOTH_SCROLL); + return; + } + + int dy = (int) (mCurrentVelocityY / 100F); + mWheelView.setTotalScrollY(mWheelView.getTotalScrollY() - dy); + if (!mWheelView.isLoop()) { + float itemHeight = mWheelView.getItemHeight(); + float top = (-mWheelView.getInitPosition()) * itemHeight; + float bottom = (mWheelView.getItemsCount() - 1 - mWheelView.getInitPosition()) * itemHeight; + if (mWheelView.getTotalScrollY() - itemHeight * 0.25 < top) { + top = mWheelView.getTotalScrollY() + dy; + } else if (mWheelView.getTotalScrollY() + itemHeight * 0.25 > bottom) { + bottom = mWheelView.getTotalScrollY() + dy; + } + + if (mWheelView.getTotalScrollY() <= top) { + mCurrentVelocityY = 40F; + mWheelView.setTotalScrollY((int) top); + } else if (mWheelView.getTotalScrollY() >= bottom) { + mWheelView.setTotalScrollY((int) bottom); + mCurrentVelocityY = -40F; + } + } + + if (mCurrentVelocityY < 0.0F) { + mCurrentVelocityY = mCurrentVelocityY + 20F; + } else { + mCurrentVelocityY = mCurrentVelocityY - 20F; + } + + //鍒锋柊UI + mWheelView.getHandler().sendEmptyMessage(MessageHandler.WHAT_INVALIDATE_LOOP_VIEW); + } +} diff --git a/wheelview/src/main/java/com/contrarywind/timer/MessageHandler.java b/wheelview/src/main/java/com/contrarywind/timer/MessageHandler.java new file mode 100644 index 0000000..34a4856 --- /dev/null +++ b/wheelview/src/main/java/com/contrarywind/timer/MessageHandler.java @@ -0,0 +1,42 @@ +package com.contrarywind.timer; + +import android.os.Handler; +import android.os.Message; + +import com.contrarywind.view.WheelView; + +/** + * Handler 娑堟伅绫� + * + * @author 灏忓旦 + * date: 2017-12-23 23:20:44 + */ +public final class MessageHandler extends Handler { + public static final int WHAT_INVALIDATE_LOOP_VIEW = 1000; + public static final int WHAT_SMOOTH_SCROLL = 2000; + public static final int WHAT_ITEM_SELECTED = 3000; + + private final WheelView wheelView; + + public MessageHandler(WheelView wheelView) { + this.wheelView = wheelView; + } + + @Override + public final void handleMessage(Message msg) { + switch (msg.what) { + case WHAT_INVALIDATE_LOOP_VIEW: + wheelView.invalidate(); + break; + + case WHAT_SMOOTH_SCROLL: + wheelView.smoothScroll(WheelView.ACTION.FLING); + break; + + case WHAT_ITEM_SELECTED: + wheelView.onItemSelected(); + break; + } + } + +} diff --git a/wheelview/src/main/java/com/contrarywind/timer/SmoothScrollTimerTask.java b/wheelview/src/main/java/com/contrarywind/timer/SmoothScrollTimerTask.java new file mode 100644 index 0000000..403b68a --- /dev/null +++ b/wheelview/src/main/java/com/contrarywind/timer/SmoothScrollTimerTask.java @@ -0,0 +1,64 @@ +package com.contrarywind.timer; + +import com.contrarywind.view.WheelView; + +import java.util.TimerTask; + +/** + * 骞虫粦婊氬姩鐨勫疄鐜� + * + * @author 灏忓旦 + */ +public final class SmoothScrollTimerTask extends TimerTask { + + private int realTotalOffset; + private int realOffset; + private int offset; + private final WheelView wheelView; + + public SmoothScrollTimerTask(WheelView wheelView, int offset) { + this.wheelView = wheelView; + this.offset = offset; + realTotalOffset = Integer.MAX_VALUE; + realOffset = 0; + } + + @Override + public final void run() { + if (realTotalOffset == Integer.MAX_VALUE) { + realTotalOffset = offset; + } + //鎶婅婊氬姩鐨勮寖鍥寸粏鍒嗘垚10灏忎唤锛屾寜10灏忎唤鍗曚綅鏉ラ噸缁� + realOffset = (int) ((float) realTotalOffset * 0.1F); + + if (realOffset == 0) { + if (realTotalOffset < 0) { + realOffset = -1; + } else { + realOffset = 1; + } + } + + if (Math.abs(realTotalOffset) <= 1) { + wheelView.cancelFuture(); + wheelView.getHandler().sendEmptyMessage(MessageHandler.WHAT_ITEM_SELECTED); + } else { + wheelView.setTotalScrollY(wheelView.getTotalScrollY() + realOffset); + + //杩欓噷濡傛灉涓嶆槸寰幆妯″紡锛屽垯鐐瑰嚮绌虹櫧浣嶇疆闇�瑕佸洖婊氾紝涓嶇劧灏变細鍑虹幇閫夊埌锛�1 item鐨� 鎯呭喌 + if (!wheelView.isLoop()) { + float itemHeight = wheelView.getItemHeight(); + float top = (float) (-wheelView.getInitPosition()) * itemHeight; + float bottom = (float) (wheelView.getItemsCount() - 1 - wheelView.getInitPosition()) * itemHeight; + if (wheelView.getTotalScrollY() <= top || wheelView.getTotalScrollY() >= bottom) { + wheelView.setTotalScrollY(wheelView.getTotalScrollY() - realOffset); + wheelView.cancelFuture(); + wheelView.getHandler().sendEmptyMessage(MessageHandler.WHAT_ITEM_SELECTED); + return; + } + } + wheelView.getHandler().sendEmptyMessage(MessageHandler.WHAT_INVALIDATE_LOOP_VIEW); + realTotalOffset = realTotalOffset - realOffset; + } + } +} diff --git a/wheelview/src/main/java/com/contrarywind/view/WheelView.java b/wheelview/src/main/java/com/contrarywind/view/WheelView.java new file mode 100644 index 0000000..45f114a --- /dev/null +++ b/wheelview/src/main/java/com/contrarywind/view/WheelView.java @@ -0,0 +1,840 @@ +package com.contrarywind.view; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Rect; +import android.graphics.Typeface; +import android.os.Handler; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.util.Log; +import android.view.GestureDetector; +import android.view.Gravity; +import android.view.MotionEvent; +import android.view.View; + +import com.contrarywind.adapter.WheelAdapter; +import com.contrarywind.interfaces.IPickerViewData; +import com.contrarywind.listener.LoopViewGestureListener; +import com.contrarywind.listener.OnItemSelectedListener; +import com.contrarywind.timer.InertiaTimerTask; +import com.contrarywind.timer.MessageHandler; +import com.contrarywind.timer.SmoothScrollTimerTask; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +/** + * 3d婊氳疆鎺т欢 + */ +public class WheelView extends View { + + public enum ACTION { // 鐐瑰嚮锛屾粦缈�(婊戝埌灏藉ご)锛屾嫋鎷戒簨浠� + CLICK, FLING, DAGGLE + } + + public enum DividerType { // 鍒嗛殧绾跨被鍨� + FILL, WRAP, CIRCLE + } + + private static final String[] TIME_NUM = {"00", "01", "02", "03", "04", "05", "06", "07", "08", "09"}; + + private DividerType dividerType;//鍒嗛殧绾跨被鍨� + + private Context context; + private Handler handler; + private GestureDetector gestureDetector; + private OnItemSelectedListener onItemSelectedListener; + + private boolean isOptions = false; + private boolean isCenterLabel = true; + + // Timer mTimer; + private ScheduledExecutorService mExecutor = Executors.newSingleThreadScheduledExecutor(); + private ScheduledFuture<?> mFuture; + + private Paint paintOuterText; + private Paint paintCenterText; + private Paint paintIndicator; + + private WheelAdapter adapter; + + private String label;//闄勫姞鍗曚綅 + private int textSize;//閫夐」鐨勬枃瀛楀ぇ灏� + private int maxTextWidth; + private int maxTextHeight; + private int textXOffset; + private float itemHeight;//姣忚楂樺害 + + + private Typeface typeface = Typeface.MONOSPACE;//瀛椾綋鏍峰紡锛岄粯璁ゆ槸绛夊瀛椾綋 + private int textColorOut; + private int textColorCenter; + private int dividerColor; + private int dividerWidth; + + // 鏉$洰闂磋窛鍊嶆暟 + private float lineSpacingMultiplier = 1.6F; + private boolean isLoop; + + // 绗竴鏉$嚎Y鍧愭爣鍊� + private float firstLineY; + //绗簩鏉$嚎Y鍧愭爣 + private float secondLineY; + //涓棿label缁樺埗鐨刌鍧愭爣 + private float centerY; + + //褰撳墠婊氬姩鎬婚珮搴鍊� + private float totalScrollY; + + //鍒濆鍖栭粯璁ら�変腑椤� + private int initPosition; + + //閫変腑鐨処tem鏄鍑犱釜 + private int selectedItem; + private int preCurrentIndex; + + // 缁樺埗鍑犱釜鏉$洰锛屽疄闄呬笂绗竴椤瑰拰鏈�鍚庝竴椤筜杞村帇缂╂垚0%浜嗭紝鎵�浠ュ彲瑙佺殑鏁扮洰瀹為檯涓�9 + private int itemsVisible = 11; + + private int measuredHeight;// WheelView 鎺т欢楂樺害 + private int measuredWidth;// WheelView 鎺т欢瀹藉害 + + // 鍗婂緞 + private int radius; + + private int mOffset = 0; + private float previousY = 0; + private long startTime = 0; + + // 淇敼杩欎釜鍊煎彲浠ユ敼鍙樻粦琛岄�熷害 + private static final int VELOCITY_FLING = 5; + private int widthMeasureSpec; + + private int mGravity = Gravity.CENTER; + private int drawCenterContentStart = 0;//涓棿閫変腑鏂囧瓧寮�濮嬬粯鍒朵綅缃� + private int drawOutContentStart = 0;//闈炰腑闂存枃瀛楀紑濮嬬粯鍒朵綅缃� + private static final float SCALE_CONTENT = 0.8F;//闈炰腑闂存枃瀛楀垯鐢ㄦ鎺у埗楂樺害锛屽帇鎵佸舰鎴�3d閿欒 + private float CENTER_CONTENT_OFFSET;//鍋忕Щ閲� + + private boolean isAlphaGradient = false; //閫忔槑搴︽笎鍙� + + public WheelView(Context context) { + this(context, null); + } + + public WheelView(Context context, AttributeSet attrs) { + super(context, attrs); + + textSize = getResources().getDimensionPixelSize(R.dimen.pickerview_textsize);//榛樿澶у皬 + + DisplayMetrics dm = getResources().getDisplayMetrics(); + float density = dm.density; // 灞忓箷瀵嗗害姣旓紙0.75/1.0/1.5/2.0/3.0锛� + + if (density < 1) {//鏍规嵁瀵嗗害涓嶅悓杩涜閫傞厤 + CENTER_CONTENT_OFFSET = 2.4F; + } else if (1 <= density && density < 2) { + CENTER_CONTENT_OFFSET = 4.0F; + } else if (2 <= density && density < 3) { + CENTER_CONTENT_OFFSET = 6.0F; + } else if (density >= 3) { + CENTER_CONTENT_OFFSET = density * 2.5F; + } + + if (attrs != null) { + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.pickerview, 0, 0); + mGravity = a.getInt(R.styleable.pickerview_wheelview_gravity, Gravity.CENTER); + textColorOut = a.getColor(R.styleable.pickerview_wheelview_textColorOut, 0xFFa8a8a8); + textColorCenter = a.getColor(R.styleable.pickerview_wheelview_textColorCenter, 0xFF2a2a2a); + dividerColor = a.getColor(R.styleable.pickerview_wheelview_dividerColor, 0xFFd5d5d5); + dividerWidth = a.getDimensionPixelSize(R.styleable.pickerview_wheelview_dividerWidth, 2); + textSize = a.getDimensionPixelOffset(R.styleable.pickerview_wheelview_textSize, textSize); + lineSpacingMultiplier = a.getFloat(R.styleable.pickerview_wheelview_lineSpacingMultiplier, lineSpacingMultiplier); + a.recycle();//鍥炴敹鍐呭瓨 + } + + judgeLineSpace(); + initLoopView(context); + } + + /** + * 鍒ゆ柇闂磋窛鏄惁鍦�1.0-4.0涔嬮棿 + */ + private void judgeLineSpace() { + if (lineSpacingMultiplier < 1.0f) { + lineSpacingMultiplier = 1.0f; + } else if (lineSpacingMultiplier > 4.0f) { + lineSpacingMultiplier = 4.0f; + } + } + + private void initLoopView(Context context) { + this.context = context; + handler = new MessageHandler(this); + gestureDetector = new GestureDetector(context, new LoopViewGestureListener(this)); + gestureDetector.setIsLongpressEnabled(false); + isLoop = true; + + totalScrollY = 0; + initPosition = -1; + initPaints(); + } + + private void initPaints() { + paintOuterText = new Paint(); + paintOuterText.setColor(textColorOut); + paintOuterText.setAntiAlias(true); + paintOuterText.setTypeface(typeface); + paintOuterText.setTextSize(textSize); + + paintCenterText = new Paint(); + paintCenterText.setColor(textColorCenter); + paintCenterText.setAntiAlias(true); + paintCenterText.setTextScaleX(1.1F); + paintCenterText.setTypeface(typeface); + paintCenterText.setTextSize(textSize); + + paintIndicator = new Paint(); + paintIndicator.setColor(dividerColor); + paintIndicator.setAntiAlias(true); + + setLayerType(LAYER_TYPE_SOFTWARE, null); + } + + private void reMeasure() {//閲嶆柊娴嬮噺 + if (adapter == null) { + return; + } + + measureTextWidthHeight(); + + //鍗婂渾鐨勫懆闀� = item楂樺害涔樹互item鏁扮洰-1 + int halfCircumference = (int) (itemHeight * (itemsVisible - 1)); + //鏁翠釜鍦嗙殑鍛ㄩ暱闄や互PI寰楀埌鐩村緞锛岃繖涓洿寰勭敤浣滄帶浠剁殑鎬婚珮搴� + measuredHeight = (int) ((halfCircumference * 2) / Math.PI); + //姹傚嚭鍗婂緞 + radius = (int) (halfCircumference / Math.PI); + //鎺т欢瀹藉害锛岃繖閲屾敮鎸亀eight + measuredWidth = MeasureSpec.getSize(widthMeasureSpec); + //璁$畻涓ゆ潯妯嚎 鍜� 閫変腑椤圭敾绗旂殑鍩虹嚎Y浣嶇疆 + firstLineY = (measuredHeight - itemHeight) / 2.0F; + secondLineY = (measuredHeight + itemHeight) / 2.0F; + centerY = secondLineY - (itemHeight - maxTextHeight) / 2.0f - CENTER_CONTENT_OFFSET; + + //鍒濆鍖栨樉绀虹殑item鐨刾osition + if (initPosition == -1) { + if (isLoop) { + initPosition = (adapter.getItemsCount() + 1) / 2; + } else { + initPosition = 0; + } + } + preCurrentIndex = initPosition; + } + + /** + * 璁$畻鏈�澶ength鐨凾ext鐨勫楂樺害 + */ + private void measureTextWidthHeight() { + Rect rect = new Rect(); + for (int i = 0; i < adapter.getItemsCount(); i++) { + String s1 = getContentText(adapter.getItem(i)); + paintCenterText.getTextBounds(s1, 0, s1.length(), rect); + + int textWidth = rect.width(); + if (textWidth > maxTextWidth) { + maxTextWidth = textWidth; + } + } + paintCenterText.getTextBounds("\u661F\u671F", 0, 2, rect); // 鏄熸湡鐨勫瓧绗︾紪鐮侊紙浠ュ畠涓烘爣鍑嗛珮搴︼級 + maxTextHeight = rect.height() + 2; + itemHeight = lineSpacingMultiplier * maxTextHeight; + } + + public void smoothScroll(ACTION action) {//骞虫粦婊氬姩鐨勫疄鐜� + cancelFuture(); + if (action == ACTION.FLING || action == ACTION.DAGGLE) { + mOffset = (int) ((totalScrollY % itemHeight + itemHeight) % itemHeight); + if ((float) mOffset > itemHeight / 2.0F) {//濡傛灉瓒呰繃Item楂樺害鐨勪竴鍗婏紝婊氬姩鍒颁笅涓�涓狪tem鍘� + mOffset = (int) (itemHeight - (float) mOffset); + } else { + mOffset = -mOffset; + } + } + //鍋滄鐨勬椂鍊欙紝浣嶇疆鏈夊亸绉伙紝涓嶆槸鍏ㄩ儴閮借兘姝g‘鍋滄鍒颁腑闂翠綅缃殑锛岃繖閲屾妸鏂囧瓧浣嶇疆鎸洖涓棿鍘� + mFuture = mExecutor.scheduleWithFixedDelay(new SmoothScrollTimerTask(this, mOffset), 0, 10, TimeUnit.MILLISECONDS); + } + + public final void scrollBy(float velocityY) {//婊氬姩鎯�х殑瀹炵幇 + cancelFuture(); + mFuture = mExecutor.scheduleWithFixedDelay(new InertiaTimerTask(this, velocityY), 0, VELOCITY_FLING, TimeUnit.MILLISECONDS); + } + + public void cancelFuture() { + if (mFuture != null && !mFuture.isCancelled()) { + mFuture.cancel(true); + mFuture = null; + } + } + + /** + * 璁剧疆鏄惁寰幆婊氬姩 + * + * @param cyclic 鏄惁寰幆 + */ + public final void setCyclic(boolean cyclic) { + isLoop = cyclic; + } + + public final void setTypeface(Typeface font) { + typeface = font; + paintOuterText.setTypeface(typeface); + paintCenterText.setTypeface(typeface); + } + + public final void setTextSize(float size) { + if (size > 0.0F) { + textSize = (int) (context.getResources().getDisplayMetrics().density * size); + paintOuterText.setTextSize(textSize); + paintCenterText.setTextSize(textSize); + } + } + + public final void setCurrentItem(int currentItem) { + //涓嶆坊鍔犺繖鍙�,褰撹繖涓獁heelView涓嶅彲瑙佹椂,榛樿閮芥槸0,浼氬鑷磋幏鍙栧埌鐨勬椂闂撮敊璇� + this.selectedItem = currentItem; + this.initPosition = currentItem; + totalScrollY = 0;//鍥炲綊椤堕儴锛屼笉鐒堕噸璁緎etCurrentItem鐨勮瘽浣嶇疆浼氬亸绉荤殑锛屽氨浼氭樉绀哄嚭涓嶅浣嶇疆鐨勬暟鎹� + invalidate(); + } + + public final void setOnItemSelectedListener(OnItemSelectedListener OnItemSelectedListener) { + this.onItemSelectedListener = OnItemSelectedListener; + } + + public final void setAdapter(WheelAdapter adapter) { + this.adapter = adapter; + reMeasure(); + invalidate(); + } + + public void setItemsVisibleCount(int visibleCount) { + if (visibleCount % 2 == 0) { + visibleCount += 1; + } + this.itemsVisible = visibleCount + 2; //绗竴鏉″拰鏈�鍚庝竴鏉� + } + + public void setAlphaGradient(boolean alphaGradient) { + isAlphaGradient = alphaGradient; + } + + public final WheelAdapter getAdapter() { + return adapter; + } + + public final int getCurrentItem() { + // return selectedItem; + if (adapter == null) { + return 0; + } + if (isLoop && (selectedItem < 0 || selectedItem >= adapter.getItemsCount())) { + return Math.max(0, Math.min(Math.abs(Math.abs(selectedItem) - adapter.getItemsCount()), adapter.getItemsCount() - 1)); + } + return Math.max(0, Math.min(selectedItem, adapter.getItemsCount() - 1)); + } + + public final void onItemSelected() { + if (onItemSelectedListener != null) { + postDelayed(new Runnable() { + @Override + public void run() { + onItemSelectedListener.onItemSelected(getCurrentItem()); + } + }, 200L); + } + } + + @Override + protected void onDraw(Canvas canvas) { + if (adapter == null) { + return; + } + //initPosition瓒婄晫浼氶�犳垚preCurrentIndex鐨勫�间笉姝g‘ + initPosition = Math.min(Math.max(0, initPosition), adapter.getItemsCount() - 1); + + //婊氬姩鐨刌鍊奸珮搴﹂櫎鍘绘瘡琛孖tem鐨勯珮搴︼紝寰楀埌婊氬姩浜嗗灏戜釜item锛屽嵆change鏁� + //婊氬姩鍋忕Щ鍊�,鐢ㄤ簬璁板綍婊氬姩浜嗗灏戜釜item + int change = (int) (totalScrollY / itemHeight); + // Log.d("change", "" + change); + + try { + //婊氬姩涓疄闄呯殑棰勯�変腑鐨刬tem(鍗崇粡杩囦簡涓棿浣嶇疆鐨刬tem) 锛� 婊戝姩鍓嶇殑浣嶇疆 锛� 婊戝姩鐩稿浣嶇疆 + preCurrentIndex = initPosition + change % adapter.getItemsCount(); + + } catch (ArithmeticException e) { + Log.e("WheelView", "鍑洪敊浜嗭紒adapter.getItemsCount() == 0锛岃仈鍔ㄦ暟鎹笉鍖归厤"); + } + if (!isLoop) {//涓嶅惊鐜殑鎯呭喌 + if (preCurrentIndex < 0) { + preCurrentIndex = 0; + } + if (preCurrentIndex > adapter.getItemsCount() - 1) { + preCurrentIndex = adapter.getItemsCount() - 1; + } + } else {//寰幆 + if (preCurrentIndex < 0) {//涓句釜渚嬪瓙锛氬鏋滄�绘暟鏄�5锛宲reCurrentIndex 锛� 锛�1锛岄偅涔坧reCurrentIndex鎸夊惊鐜潵璇达紝鍏跺疄鏄�0鐨勪笂闈紝涔熷氨鏄�4鐨勪綅缃� + preCurrentIndex = adapter.getItemsCount() + preCurrentIndex; + } + if (preCurrentIndex > adapter.getItemsCount() - 1) {//鍚岀悊涓婇潰,鑷繁鑴戣ˉ涓�涓� + preCurrentIndex = preCurrentIndex - adapter.getItemsCount(); + } + } + //璺熸粴鍔ㄦ祦鐣呭害鏈夊叧锛屾�绘粦鍔ㄨ窛绂讳笌姣忎釜item楂樺害鍙栦綑锛屽嵆骞朵笉鏄竴鏍兼牸鐨勬粴鍔紝姣忎釜item涓嶄竴瀹氭粴鍒板搴擱ect閲岀殑锛岃繖涓猧tem瀵瑰簲鏍煎瓙鐨勫亸绉诲�� + float itemHeightOffset = (totalScrollY % itemHeight); + + + //缁樺埗涓棿涓ゆ潯妯嚎 + if (dividerType == DividerType.WRAP) {//妯嚎闀垮害浠呭寘瑁瑰唴瀹� + float startX; + float endX; + + if (TextUtils.isEmpty(label)) {//闅愯棌Label鐨勬儏鍐� + startX = (measuredWidth - maxTextWidth) / 2 - 12; + } else { + startX = (measuredWidth - maxTextWidth) / 4 - 12; + } + + if (startX <= 0) {//濡傛灉瓒呰繃浜哤heelView鐨勮竟缂� + startX = 10; + } + endX = measuredWidth - startX; + canvas.drawLine(startX, firstLineY, endX, firstLineY, paintIndicator); + canvas.drawLine(startX, secondLineY, endX, secondLineY, paintIndicator); + } else if (dividerType == DividerType.CIRCLE) { + //鍒嗗壊绾夸负鍦嗗湀褰㈢姸 + paintIndicator.setStyle(Paint.Style.STROKE); + paintIndicator.setStrokeWidth(dividerWidth); + float startX; + float endX; + if (TextUtils.isEmpty(label)) {//闅愯棌Label鐨勬儏鍐� + startX = (measuredWidth - maxTextWidth) / 2f - 12; + } else { + startX = (measuredWidth - maxTextWidth) / 4f - 12; + } + if (startX <= 0) {//濡傛灉瓒呰繃浜哤heelView鐨勮竟缂� + startX = 10; + } + endX = measuredWidth - startX; + //鍗婂緞濮嬬粓浠ュ楂樹腑鏈�澶х殑鏉ョ畻 + float radius = Math.max((endX - startX), itemHeight) / 1.8f; + canvas.drawCircle(measuredWidth / 2f, measuredHeight / 2f, radius, paintIndicator); + } else { + canvas.drawLine(0.0F, firstLineY, measuredWidth, firstLineY, paintIndicator); + canvas.drawLine(0.0F, secondLineY, measuredWidth, secondLineY, paintIndicator); + } + + //鍙樉绀洪�変腑椤筁abel鏂囧瓧鐨勬ā寮忥紝骞朵笖Label鏂囧瓧涓嶄负绌猴紝鍒欒繘琛岀粯鍒� + if (!TextUtils.isEmpty(label) && isCenterLabel) { + //缁樺埗鏂囧瓧锛岄潬鍙冲苟鐣欏嚭绌洪殭 + int drawRightContentStart = measuredWidth - getTextWidth(paintCenterText, label); + canvas.drawText(label, drawRightContentStart - CENTER_CONTENT_OFFSET, centerY, paintCenterText); + } + + // 璁剧疆鏁扮粍涓瘡涓厓绱犵殑鍊� + int counter = 0; + while (counter < itemsVisible) { + Object showText; + int index = preCurrentIndex - (itemsVisible / 2 - counter);//绱㈠紩鍊硷紝鍗冲綋鍓嶅湪鎺т欢涓棿鐨刬tem鐪嬩綔鏁版嵁婧愮殑涓棿锛岃绠楀嚭鐩稿婧愭暟鎹簮鐨刬ndex鍊� + + //鍒ゆ柇鏄惁寰幆锛屽鏋滄槸寰幆鏁版嵁婧愪篃浣跨敤鐩稿寰幆鐨刾osition鑾峰彇瀵瑰簲鐨刬tem鍊硷紝濡傛灉涓嶆槸寰幆鍒欒秴鍑烘暟鎹簮鑼冨洿浣跨敤""绌虹櫧瀛楃涓插~鍏咃紝鍦ㄧ晫闈笂褰㈡垚绌虹櫧鏃犳暟鎹殑item椤� + if (isLoop) { + index = getLoopMappingIndex(index); + showText = adapter.getItem(index); + } else if (index < 0) { + showText = ""; + } else if (index > adapter.getItemsCount() - 1) { + showText = ""; + } else { + showText = adapter.getItem(index); + } + + canvas.save(); + // 寮ч暱 L = itemHeight * counter - itemHeightOffset + // 姹傚姬搴� 伪 = L / r (寮ч暱/鍗婂緞) [0,蟺] + double radian = ((itemHeight * counter - itemHeightOffset)) / radius; + // 寮у害杞崲鎴愯搴�(鎶婂崐鍦嗕互Y杞翠负杞村績鍚戝彸杞�90搴︼紝浣垮叾澶勪簬绗竴璞¢檺鍙婄鍥涜薄闄� + // angle [-90掳,90掳] + float angle = (float) (90D - (radian / Math.PI) * 180D);//item绗竴椤�,浠�90搴﹀紑濮嬶紝閫愭笎閫掑噺鍒� -90搴� + + // 璁$畻鍙栧�煎彲鑳芥湁缁嗗井鍋忓樊锛屼繚璇佽礋90掳鍒�90掳浠ュ鐨勪笉缁樺埗 + if (angle > 90F || angle < -90F) { + canvas.restore(); + } else { + //鑾峰彇鍐呭鏂囧瓧 + String contentText; + + //濡傛灉鏄痩abel姣忛」閮芥樉绀虹殑妯″紡锛屽苟涓攊tem鍐呭涓嶄负绌恒�乴abel 涔熶笉涓虹┖ + if (!isCenterLabel && !TextUtils.isEmpty(label) && !TextUtils.isEmpty(getContentText(showText))) { + contentText = getContentText(showText) + label; + } else { + contentText = getContentText(showText); + } + // 鏍规嵁褰撳墠瑙掑害璁$畻鍑哄亸宸郴鏁帮紝鐢ㄤ互鍦ㄧ粯鍒舵椂鎺у埗鏂囧瓧鐨� 姘村钩绉诲姩 閫忔槑搴� 鍊炬枩绋嬪害. + float offsetCoefficient = (float) Math.pow(Math.abs(angle) / 90f, 2.2); + + reMeasureTextSize(contentText); + //璁$畻寮�濮嬬粯鍒剁殑浣嶇疆 + measuredCenterContentStart(contentText); + measuredOutContentStart(contentText); + float translateY = (float) (radius - Math.cos(radian) * radius - (Math.sin(radian) * maxTextHeight) / 2D); + //鏍规嵁Math.sin(radian)鏉ユ洿鏀筩anvas鍧愭爣绯诲師鐐癸紝鐒跺悗缂╂斁鐢诲竷锛屼娇寰楁枃瀛楅珮搴﹁繘琛岀缉鏀撅紝褰㈡垚寮у舰3d瑙嗚宸� + canvas.translate(0.0F, translateY); + if (translateY <= firstLineY && maxTextHeight + translateY >= firstLineY) { + // 鏉$洰缁忚繃绗竴鏉$嚎 + canvas.save(); + canvas.clipRect(0, 0, measuredWidth, firstLineY - translateY); + canvas.scale(1.0F, (float) Math.sin(radian) * SCALE_CONTENT); + setOutPaintStyle(offsetCoefficient, angle); + canvas.drawText(contentText, drawOutContentStart, maxTextHeight, paintOuterText); + canvas.restore(); + canvas.save(); + canvas.clipRect(0, firstLineY - translateY, measuredWidth, (int) (itemHeight)); + canvas.scale(1.0F, (float) Math.sin(radian) * 1.0F); + canvas.drawText(contentText, drawCenterContentStart, maxTextHeight - CENTER_CONTENT_OFFSET, paintCenterText); + canvas.restore(); + } else if (translateY <= secondLineY && maxTextHeight + translateY >= secondLineY) { + // 鏉$洰缁忚繃绗簩鏉$嚎 + canvas.save(); + canvas.clipRect(0, 0, measuredWidth, secondLineY - translateY); + canvas.scale(1.0F, (float) Math.sin(radian) * 1.0F); + canvas.drawText(contentText, drawCenterContentStart, maxTextHeight - CENTER_CONTENT_OFFSET, paintCenterText); + canvas.restore(); + canvas.save(); + canvas.clipRect(0, secondLineY - translateY, measuredWidth, (int) (itemHeight)); + canvas.scale(1.0F, (float) Math.sin(radian) * SCALE_CONTENT); + setOutPaintStyle(offsetCoefficient, angle); + canvas.drawText(contentText, drawOutContentStart, maxTextHeight, paintOuterText); + canvas.restore(); + } else if (translateY >= firstLineY && maxTextHeight + translateY <= secondLineY) { + // 涓棿鏉$洰 + // canvas.clipRect(0, 0, measuredWidth, maxTextHeight); + //璁╂枃瀛楀眳涓� + float Y = maxTextHeight - CENTER_CONTENT_OFFSET;//鍥犱负鍦嗗姬瑙掓崲绠楃殑鍚戜笅鍙栧�硷紝瀵艰嚧瑙掑害绋嶅井鏈夌偣鍋忓樊锛屽姞涓婄敾绗旂殑鍩虹嚎浼氬亸涓婏紝鍥犳闇�瑕佸亸绉婚噺淇涓�涓� + canvas.drawText(contentText, drawCenterContentStart, Y, paintCenterText); + //璁剧疆閫変腑椤� + selectedItem = preCurrentIndex - (itemsVisible / 2 - counter); + } else { + // 鍏朵粬鏉$洰 + canvas.save(); + canvas.clipRect(0, 0, measuredWidth, (int) (itemHeight)); + canvas.scale(1.0F, (float) Math.sin(radian) * SCALE_CONTENT); + setOutPaintStyle(offsetCoefficient, angle); + // 鎺у埗鏂囧瓧姘村钩鍋忕Щ璺濈 + canvas.drawText(contentText, drawOutContentStart + textXOffset * offsetCoefficient, maxTextHeight, paintOuterText); + canvas.restore(); + } + canvas.restore(); + paintCenterText.setTextSize(textSize); + } + counter++; + } + } + + //璁剧疆鏂囧瓧鍊炬枩瑙掑害锛岄�忔槑搴� + private void setOutPaintStyle(float offsetCoefficient, float angle) { + // 鎺у埗鏂囧瓧鍊炬枩瑙掑害 + float DEFAULT_TEXT_TARGET_SKEW_X = 0.5f; + int multiplier = 0; + if (textXOffset > 0) { + multiplier = 1; + } else if (textXOffset < 0) { + multiplier = -1; + } + paintOuterText.setTextSkewX(multiplier * (angle > 0 ? -1 : 1) * DEFAULT_TEXT_TARGET_SKEW_X * offsetCoefficient); + + // 鎺у埗閫忔槑搴� + int alpha = isAlphaGradient ? (int) ((90F - Math.abs(angle)) / 90f * 255) : 255; + // Log.d("WheelView", "alpha:" + alpha); + paintOuterText.setAlpha(alpha); + } + + /** + * reset the size of the text Let it can fully display + * + * @param contentText item text content. + */ + private void reMeasureTextSize(String contentText) { + Rect rect = new Rect(); + paintCenterText.getTextBounds(contentText, 0, contentText.length(), rect); + int width = rect.width(); + int size = textSize; + while (width > measuredWidth) { + size--; + //璁剧疆2鏉℃í绾夸腑闂寸殑鏂囧瓧澶у皬 + paintCenterText.setTextSize(size); + paintCenterText.getTextBounds(contentText, 0, contentText.length(), rect); + width = rect.width(); + } + //璁剧疆2鏉℃í绾垮闈㈢殑鏂囧瓧澶у皬 + paintOuterText.setTextSize(size); + } + + + //閫掑綊璁$畻鍑哄搴旂殑index + private int getLoopMappingIndex(int index) { + if (index < 0) { + index = index + adapter.getItemsCount(); + index = getLoopMappingIndex(index); + } else if (index > adapter.getItemsCount() - 1) { + index = index - adapter.getItemsCount(); + index = getLoopMappingIndex(index); + } + return index; + } + + /** + * 鑾峰彇鎵�鏄剧ず鐨勬暟鎹簮 + * + * @param item data resource + * @return 瀵瑰簲鏄剧ず鐨勫瓧绗︿覆 + */ + private String getContentText(Object item) { + if (item == null) { + return ""; + } else if (item instanceof IPickerViewData) { + return ((IPickerViewData) item).getPickerViewText(); + } else if (item instanceof Integer) { + //濡傛灉涓烘暣褰㈠垯鏈�灏戜繚鐣欎袱浣嶆暟. + return getFixNum((int) item); + } + return item.toString(); + } + + private String getFixNum(int timeNum) { + return timeNum >= 0 && timeNum < 10 ? TIME_NUM[timeNum] : String.valueOf(timeNum); + } + + private void measuredCenterContentStart(String content) { + Rect rect = new Rect(); + paintCenterText.getTextBounds(content, 0, content.length(), rect); + switch (mGravity) { + case Gravity.CENTER://鏄剧ず鍐呭灞呬腑 + if (isOptions || label == null || label.equals("") || !isCenterLabel) { + drawCenterContentStart = (int) ((measuredWidth - rect.width()) * 0.5); + } else {//鍙樉绀轰腑闂磍abel鏃讹紝鏃堕棿閫夋嫨鍣ㄥ唴瀹瑰亸宸︿竴鐐癸紝鐣欏嚭绌洪棿缁樺埗鍗曚綅鏍囩 + drawCenterContentStart = (int) ((measuredWidth - rect.width()) * 0.25); + } + break; + case Gravity.LEFT: + drawCenterContentStart = 0; + break; + case Gravity.RIGHT://娣诲姞鍋忕Щ閲� + drawCenterContentStart = measuredWidth - rect.width() - (int) CENTER_CONTENT_OFFSET; + break; + } + } + + private void measuredOutContentStart(String content) { + Rect rect = new Rect(); + paintOuterText.getTextBounds(content, 0, content.length(), rect); + switch (mGravity) { + case Gravity.CENTER: + if (isOptions || label == null || label.equals("") || !isCenterLabel) { + drawOutContentStart = (int) ((measuredWidth - rect.width()) * 0.5); + } else {//鍙樉绀轰腑闂磍abel鏃讹紝鏃堕棿閫夋嫨鍣ㄥ唴瀹瑰亸宸︿竴鐐癸紝鐣欏嚭绌洪棿缁樺埗鍗曚綅鏍囩 + drawOutContentStart = (int) ((measuredWidth - rect.width()) * 0.25); + } + break; + case Gravity.LEFT: + drawOutContentStart = 0; + break; + case Gravity.RIGHT: + drawOutContentStart = measuredWidth - rect.width() - (int) CENTER_CONTENT_OFFSET; + break; + } + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + this.widthMeasureSpec = widthMeasureSpec; + reMeasure(); + setMeasuredDimension(measuredWidth, measuredHeight); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + boolean eventConsumed = gestureDetector.onTouchEvent(event); + boolean isIgnore = false;//瓒呰繃杈圭晫婊戝姩鏃讹紝涓嶅啀缁樺埗UI銆� + + float top = -initPosition * itemHeight; + float bottom = (adapter.getItemsCount() - 1 - initPosition) * itemHeight; + float ratio = 0.25f; + + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + startTime = System.currentTimeMillis(); + cancelFuture(); + previousY = event.getRawY(); + break; + + case MotionEvent.ACTION_MOVE: + float dy = previousY - event.getRawY(); + previousY = event.getRawY(); + totalScrollY = totalScrollY + dy; + + // normal mode銆� + if (!isLoop) { + if ((totalScrollY - itemHeight * ratio < top && dy < 0) + || (totalScrollY + itemHeight * ratio > bottom && dy > 0)) { + //蹇粦鍔ㄥ埌杈圭晫浜嗭紝璁剧疆宸叉粦鍔ㄥ埌杈圭晫鐨勬爣蹇� + totalScrollY -= dy; + isIgnore = true; + } else { + isIgnore = false; + } + } + break; + + case MotionEvent.ACTION_UP: + default: + if (!eventConsumed) {//鏈秷璐规帀浜嬩欢 + + /** + *@describe <鍏充簬寮ч暱鐨勮绠�> + * + * 寮ч暱鍏紡锛� L = 伪*R + * 鍙嶄綑寮﹀叕寮忥細arccos(cos伪) = 伪 + * 鐢变簬涔嬪墠鏄湁椤烘椂閽堝亸绉�90搴︼紝 + * 鎵�浠ュ疄闄呭姬搴﹁寖鍥次�2鐨勫�� 锛毼�2 = 蟺/2-伪 锛埼�=[0,蟺] 伪2 = [-蟺/2,蟺/2]锛� + * 鏍规嵁姝e鸡浣欏鸡杞崲鍏紡 cos伪 = sin(蟺/2-伪) + * 浠e叆锛屽緱锛� cos伪 = sin(蟺/2-伪) = sin伪2 = (R - y) / R + * 鎵�浠ュ姬闀� L = arccos(cos伪)*R = arccos((R - y) / R)*R + */ + + float y = event.getY(); + double L = Math.acos((radius - y) / radius) * radius; + //item0 鏈変竴鍗婃槸鍦ㄤ笉鍙鍖哄煙锛屾墍浠ラ渶瑕佸姞涓� itemHeight / 2 + int circlePosition = (int) ((L + itemHeight / 2) / itemHeight); + float extraOffset = (totalScrollY % itemHeight + itemHeight) % itemHeight; + //宸叉粦鍔ㄧ殑寮ч暱鍊� + mOffset = (int) ((circlePosition - itemsVisible / 2) * itemHeight - extraOffset); + + if ((System.currentTimeMillis() - startTime) > 120) { + // 澶勭悊鎷栨嫿浜嬩欢 + smoothScroll(ACTION.DAGGLE); + } else { + // 澶勭悊鏉$洰鐐瑰嚮浜嬩欢 + smoothScroll(ACTION.CLICK); + } + } + break; + } + if (!isIgnore && event.getAction() != MotionEvent.ACTION_DOWN) { + invalidate(); + } + return true; + } + + public int getItemsCount() { + return adapter != null ? adapter.getItemsCount() : 0; + } + + public void setLabel(String label) { + this.label = label; + } + + public void isCenterLabel(boolean isCenterLabel) { + this.isCenterLabel = isCenterLabel; + } + + public void setGravity(int gravity) { + this.mGravity = gravity; + } + + public int getTextWidth(Paint paint, String str) { //calculate text width + int iRet = 0; + if (str != null && str.length() > 0) { + int len = str.length(); + float[] widths = new float[len]; + paint.getTextWidths(str, widths); + for (int j = 0; j < len; j++) { + iRet += (int) Math.ceil(widths[j]); + } + } + return iRet; + } + + public void setIsOptions(boolean options) { + isOptions = options; + } + + public void setTextColorOut(int textColorOut) { + + this.textColorOut = textColorOut; + paintOuterText.setColor(this.textColorOut); + } + + public void setTextColorCenter(int textColorCenter) { + this.textColorCenter = textColorCenter; + paintCenterText.setColor(this.textColorCenter); + } + + public void setTextXOffset(int textXOffset) { + this.textXOffset = textXOffset; + if (textXOffset != 0) { + paintCenterText.setTextScaleX(1.0f); + } + } + + public void setDividerWidth(int dividerWidth) { + this.dividerWidth = dividerWidth; + paintIndicator.setStrokeWidth(dividerWidth); + } + + public void setDividerColor(int dividerColor) { + this.dividerColor = dividerColor; + paintIndicator.setColor(dividerColor); + } + + public void setDividerType(DividerType dividerType) { + this.dividerType = dividerType; + } + + public void setLineSpacingMultiplier(float lineSpacingMultiplier) { + if (lineSpacingMultiplier != 0) { + this.lineSpacingMultiplier = lineSpacingMultiplier; + judgeLineSpace(); + } + } + + public boolean isLoop() { + return isLoop; + } + + public float getTotalScrollY() { + return totalScrollY; + } + + public void setTotalScrollY(float totalScrollY) { + this.totalScrollY = totalScrollY; + } + + public float getItemHeight() { + return itemHeight; + } + + public int getInitPosition() { + return initPosition; + } + + @Override + public Handler getHandler() { + return handler; + } +} \ No newline at end of file diff --git a/wheelview/src/main/res/values/attrs.xml b/wheelview/src/main/res/values/attrs.xml new file mode 100644 index 0000000..d6343aa --- /dev/null +++ b/wheelview/src/main/res/values/attrs.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <declare-styleable name="pickerview"> + <attr name="wheelview_gravity"> + <enum name="center" value="17"/> + <enum name="left" value="3"/> + <enum name="right" value="5"/> + </attr> + <attr name="wheelview_textSize" format="dimension"/> + <attr name="wheelview_textColorOut" format="color"/> + <attr name="wheelview_textColorCenter" format="color"/> + <attr name="wheelview_dividerColor" format="color"/> + <attr name="wheelview_dividerWidth" format="dimension"/> + <attr name="wheelview_lineSpacingMultiplier" format="float"/> + </declare-styleable> +</resources> \ No newline at end of file diff --git a/wheelview/src/main/res/values/colors.xml b/wheelview/src/main/res/values/colors.xml new file mode 100644 index 0000000..f95f8f3 --- /dev/null +++ b/wheelview/src/main/res/values/colors.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <color name="pickerview_timebtn_nor">#057dff</color> + <color name="pickerview_timebtn_pre">#c2daf5</color> + <color name="pickerview_bg_topbar">#f5f5f5</color> + + <color name="pickerview_topbar_title">#000000</color> + <color name="pickerview_wheelview_textcolor_out">#a8a8a8</color> + <color name="pickerview_wheelview_textcolor_center">#2a2a2a</color> + <color name="pickerview_wheelview_textcolor_divider">#d5d5d5</color> + <color name="pickerview_bgColor_overlay">#60000000</color> + <color name="pickerview_bgColor_default">#FFFFFFFF</color> + +</resources> diff --git a/wheelview/src/main/res/values/dimens.xml b/wheelview/src/main/res/values/dimens.xml new file mode 100644 index 0000000..ddfb5ab --- /dev/null +++ b/wheelview/src/main/res/values/dimens.xml @@ -0,0 +1,13 @@ +<resources> + <!-- 椤堕儴鎸夐挳鏍忛珮搴� --> + <dimen name="pickerview_topbar_height">44dp</dimen> + + <!-- 椤堕儴鎸夐挳padding --> + <dimen name="pickerview_topbar_padding">20dp</dimen> + + <!-- 椤堕儴鎸夐挳鏂囧瓧澶у皬 --> + <dimen name="pickerview_topbar_btn_textsize">17sp</dimen> + <dimen name="pickerview_topbar_title_textsize">18sp</dimen> + <!-- 閫夐」鏂囧瓧澶у皬 --> + <dimen name="pickerview_textsize">20sp</dimen> +</resources> diff --git a/wheelview/src/main/res/values/strings.xml b/wheelview/src/main/res/values/strings.xml new file mode 100644 index 0000000..0a65b07 --- /dev/null +++ b/wheelview/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ +<resources> + <string name="app_name">wheelview</string> +</resources> -- Gitblit v1.8.0