版权声明:版权声明@忆痕惜dxh | https://blog.csdn.net/qq_38717971/article/details/83581325
努力不一定立刻会有好的结果,但一定是朝着好的方向 ——李尚龙 《你所谓的稳定,不过是在浪费生命》
开发中遇到一个日期选择器的需求,就是界面中有两段文本显示日期,点击之后从底部弹出日期选择器。查阅了很多资料后发现官方有一个DatePicker日期选择器,但是它只有一个日期,而且排版动画也不符合我们得要求,所以废了好的的功夫,把两个DatePicker自定义布局,嵌到Dialog控件里,实现由底弹出的动画效果。
废话不多说,一步一步放出代码(提前说明代码为Kotlin,读者根据所需自行调整):
项目源码打包在此:点击下载
目录
2、新建我们自定义的布局文件date_picker.xml代码:
4、新建自定义DateDialog类文件,DateDialog.kt 代码:
1、首先放出activity_main.xml代码:
//////////////////////////////activity_main.xml/////////////////////////////////////////
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.feds.datepickerdialog.MainActivity">
<LinearLayout
android:id="@+id/date_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" >
<TextView
android:id="@+id/start_date_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="****-**-**"
android:textSize="25sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" ------- "
android:textSize="25sp"/>
<TextView
android:id="@+id/end_date_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="****-**-**"
android:textSize="25sp" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
2、新建我们自定义的布局文件date_picker.xml代码:
//////////////////////////////////date_picker.xml////////////////////////////////////////
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffffff"
android:layout_gravity="bottom"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="From"
android:layout_gravity="center" />
<DatePicker
android:id="@+id/date_picker1"
android:theme="@android:style/Theme.Holo.Light.NoActionBar"
android:layout_width="match_parent"
android:layout_height="150dp"
android:calendarViewShown="false"
android:datePickerMode="spinner" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="To"
android:layout_gravity="center"/>
<DatePicker
android:id="@+id/date_picker2"
android:theme="@android:style/Theme.Holo.Light.NoActionBar"
android:layout_width="match_parent"
android:layout_height="150dp"
android:calendarViewShown="false"
android:datePickerMode="spinner" />
</LinearLayout>
3、添加由底向上弹出的样式文件styles.xml代码:
/////////////////////////////////////styles.xml////////////////////////////////////////////
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="ActionSheetDialogStyle" parent="@android:style/Theme.Dialog">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowFrame">@null</item>
<item name="android:backgroundDimEnabled">true</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowAnimationStyle">@style/ActionSheetDialogAnimation</item>
</style>
<style name="ActionSheetDialogAnimation" parent="@android:style/Animation.Dialog">
<item name="android:windowEnterAnimation">@anim/actionsheet_dialog_in</item>
<item name="android:windowExitAnimation">@anim/actionsheet_dialog_out</item>
</style>
</resources>
4、新建自定义DateDialog类文件,DateDialog.kt 代码:
//////////////////////////////////DateDialog.kt//////////////////////////////////////////
class DateDialog(context: Context?, theme:Int) : Dialog(context,theme) {
private var dateString1: String=""
private var dateString2: String=""
@SuppressLint("NewApi", "InflateParams")
@RequiresApi(Build.VERSION_CODES.N)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val dialogWindow = this.window
val lp: WindowManager.LayoutParams = dialogWindow.attributes
val inflate = LayoutInflater.from(context).inflate(R.layout.date_picker, null)
this.setContentView(inflate)
dialogWindow.setGravity(Gravity.BOTTOM)
lp.width = android.view.ViewGroup.LayoutParams.MATCH_PARENT
dialogWindow.attributes = lp
date_picker1.descendantFocusability = DatePicker.FOCUS_BLOCK_DESCENDANTS
date_picker2.descendantFocusability = DatePicker.FOCUS_BLOCK_DESCENDANTS
val calendar: Calendar = Calendar.getInstance()
val year = calendar.get(Calendar.YEAR)
val mindate = (year-1).toString() +"-"+ "12" +"-"+ "31"
date_picker1.minDate = getStringToDate(mindate,"yyyy-MM-dd")
date_picker1.maxDate = System.currentTimeMillis()
date_picker2.minDate = getStringToDate(mindate,"yyyy-MM-dd")
date_picker2.maxDate = System.currentTimeMillis()
date_picker1.setOnDateChangedListener { _, _:Int, _:Int, _:Int ->
dateString1 = date_picker1.year.toString() +"-"+ (date_picker1.month+1).toString() +"-"+
date_picker1.dayOfMonth.toString()
val dateLong1 = getStringToDate(dateString1,"yyyy-MM-dd")
dateString2 = date_picker2.year.toString() +"-"+ (date_picker2.month+1).toString() +"-"+
date_picker2.dayOfMonth.toString()
val dateLong2 = getStringToDate(dateString2,"yyyy-MM-dd")
if (dateLong1 > dateLong2){
date_picker1.updateDate(date_picker2.year,date_picker2.month,date_picker2.dayOfMonth)
}
}
date_picker2.setOnDateChangedListener { _, _: Int, _: Int, _: Int ->
dateString1 = date_picker1.year.toString() +"-"+ (date_picker1.month+1).toString() +"-"+
date_picker1.dayOfMonth.toString()
val dateLong1 = getStringToDate(dateString1,"yyyy-MM-dd")
dateString2 = date_picker2.year.toString() +"-"+ (date_picker2.month+1).toString() +"-"+
date_picker2.dayOfMonth.toString()
val dateLong2 = getStringToDate(dateString2,"yyyy-MM-dd")
if (dateLong2 < dateLong1){
date_picker1.updateDate(date_picker2.year,date_picker2.month,date_picker2.dayOfMonth)
}
}
}
fun startDate(): String {
return dateString1
}
fun endDate(): String {
return dateString2
}
@RequiresApi(Build.VERSION_CODES.N)
private fun getStringToDate(dateString: String, pattern: String): Long {
val dateFormat = SimpleDateFormat(pattern)
var date = Date()
try {
date = dateFormat.parse(dateString)
} catch (e: ParseException) {
e.printStackTrace()
}
return date.time
}
}
5、最后MainActivity.kt代码:
////////////////////////////////////MainActivity.kt//////////////////////////////////////
class MainActivity : AppCompatActivity(), View.OnClickListener {
private lateinit var datedialog: DateDialog
private lateinit var startDate: String
private lateinit var endDate: String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val calendar: Calendar = Calendar.getInstance()
val year = calendar.get(Calendar.YEAR).toString()
val month = (calendar.get(Calendar.MONTH) + 1).toString()
val day = calendar.get(Calendar.DAY_OF_MONTH).toString()
startDate = "$year-$month-$day"
endDate = "$year-$month-$day"
}
override fun onResume() {
super.onResume()
datedialog = DateDialog(this,R.style.ActionSheetDialogStyle)
date_view.setOnClickListener(this)
start_date_text.text = startDate
end_date_text.text = endDate
datedialog.setOnDismissListener {
if (datedialog.startDate() != "") {
start_date_text.text = datedialog.startDate()
}
if (datedialog.endDate() != "") {
end_date_text.text = datedialog.endDate()
}
}
}
override fun onClick(v: View?) {
when(v?.id){
R.id.date_view ->{
datedialog.show()
}
}
}
}