সময়, দিন, মাস, বছর এবং দিনের পরিসীমা বাছাই করার জন্য কিভাবে PickerDialog
ব্যবহার করা যায় তা নিয়ে আজকে আমরা কথা বলব।
অ্যান্ড্রয়েডে কাজ করতে গিয়ে প্রায়ই বিভিন্ন কাজে সময় বাছাই করা প্রয়োজন হয়। যেমন, অ্যালার্ম সেট করতে একটি নির্দিষ্ট সময় দেয়া লাগে, রিমাইন্ডার দিতে হলে একটি সময়ের সাথে দিনও বাছাই করতে হয়। আবার ফিটনেস অ্যাপগুলোতে নির্দিষ্ট সময়ের তথ্য দেখার জন্য মাস বা বছর সিলেক্ট করা প্রয়োজন হতে পারে। হোটেল বা ফ্লাইট বুকিং করার জন্য একটি নির্দিষ্ট দিনের পরিসীমা সিলেক্ট করে দিতে হয়। এছাড়াও বিভিন্ন কাজে এমন বিভিন্ন ধরণের সময় নির্বাচন করা দরকার হতে পারে। এজন্যই আমরা আজকে এদের Picker-গুলো দেখব।
PickerExamples অ্যাপ
Picker-গুলো দেখানোর জন্য একটি সোজাসাপ্টা অ্যান্ড্রয়েড অ্যাপ বানানো হয়েছে। অ্যাপ্লিকেশনের একমাত্র পেজে সবার উপরে একটি TextView
রাখা হয়েছে। Picker-গুলোর মাধ্যমে আমরা যে সময়/দিন/মাস/বছর/দিনের পরিসীমা বাছাই করব তা আমরা এই TextView-তে দেখতে পাব। TextView-তে প্রাথমিকভাবে বর্তমান দিনের তথ্য দেখানো হচ্ছে। TextView-এর নিচে পাঁচটি TextButton
আছে যেগুলো ক্লিক করে আমরা যথাক্রমে সময়, দিন, মাস, বছর এবং দিনের পরিসীমার PickerDialog
ওপেন করব।
বিভিন্ন তথ্যগুলো নির্দিষ্ট ফরম্যাটে দেখানোর জন্য কিছু SimpleDateFormat
নেয়া হয়েছে। যেহেতু বছর মূলত একটি সংখ্যা তাই বছরের জন্য কোন ফরম্যাট প্রয়োজন হয়নি। আর দিনের পরিসীমাতে দুইটি দিন আছে বলে এটা ম্যানুয়ালি দেখানো হয়েছে।
SimpleDateFormat timeFormat, dateFormat, monthFormat;
timeFormat = new SimpleDateFormat("hh:mm a", Locale.getDefault());
dateFormat = new SimpleDateFormat("dd MMM, yyyy", Locale.getDefault());
monthFormat = new SimpleDateFormat("MMM, yyyy", Locale.getDefault());
অ্যাপ্লিকেশনের কাজের পদ্ধতি বোঝার জন্য যা যা দেখা প্রয়োজন সেসব আমরা দেখলাম। এবার আমরা Picker-গুলো একটি একটি করে দেখে নেবো।
TimePicker
TimePicker
-এর মাধ্যমে আমরা দিনের একটি নির্দিষ্ট সময় বাছাই করতে পারি। timePicker
বাটনটি ক্লিক করলে প্রথমে একটি Calendar
অবজেক্ট তৈরি করছি এবং এর ঘণ্টা ও মিনিট সেভ করে রাখছি প্যারামিটারে পাঠানোর জন্য। এরপর একটি TimePickerDialog
তৈরি করছি। এই ডায়লগে পাঁচটি প্যারামিটার লাগে। প্রথমে Context
হিসেবে এই Activity
-র রেফারেন্স দিচ্ছি। এরপরের প্যারামিটারে TimePicker-এর OnTimeSetListener
পাঠাতে হবে যেখানে onTimeSet
ফাংশনটি ওভাররাইড করে বলে দিতে হবে যে সময় বাছাই করা হলে কি করা হবে। এই ফাংশনের তিনটি প্যারামিটারের দ্বিতীয় এবং তৃতীয়টিতে বাছাইকৃত ঘণ্টা এবং মিনিট থাকবে। আমরা আমাদের calendar-এর ঘণ্টা এবং মিনিট হিসেবে এই দুটি মান সেট করব। এরপর calendar-এর পরিবর্তিত সময়কে timeFormat
-এর মাধ্যমে ফরম্যাট করে TextView-তে দেখাব।
new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker timePicker, int selectedHour, int selectedMinute) {
calendar.set(Calendar.HOUR_OF_DAY, selectedHour);
calendar.set(Calendar.MINUTE, selectedMinute);
time = timeFormat.format(calendar.getTime());
timeText.setText(time);
}
}
তৃতীয় এবং চতুর্থ প্যারামিটারে হিসেবে ঘণ্টা এবং মিনিট পাঠাতে হবে যা ডায়লগ ওপেন করলে দেখানো হবে। আমরা আমাদের calendar-এর ঘণ্টা এবং মিনিটকেই এখানে পাঠাব। শেষের প্যারামিটারে একটি boolean
পাঠাতে হবে, true
পাঠালে ডায়লগটি ২৪ ঘণ্টা ভিউতে থাকবে এবং false
পাঠালে ডায়লগটি ১২ ঘণ্টা ভিউতে AM/PM সহ থাকবে। আমরা ডায়লগটি ১২ ঘণ্টা ভিউতে দেখতে চাই তাই true পাঠিয়েছি। এবার ডায়লগের show()
মেথডটি কল করলে ডায়লগটি দেখাবে। সম্পূর্ণ কোডটি নিচে দেয়া হল।
Button timePicker = findViewById(R.id.timePicker);
timePicker.setOnClickListener(new View.OnClickListener() {
Calendar calendar = Calendar.getInstance();
int hour = calendar.get(Calendar.HOUR);
int minute = calendar.get(Calendar.MINUTE);
@Override
public void onClick(View view) {
new TimePickerDialog(MainActivity.this, new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker timePicker, int selectedHour, int selectedMinute) {
calendar.set(Calendar.HOUR_OF_DAY, selectedHour);
calendar.set(Calendar.MINUTE, selectedMinute);
time = timeFormat.format(calendar.getTime());
timeText.setText(time);
}
}, hour, minute, false).show();
}
});
show() মেথড কল করার আগে PickerDialog-এর বিভিন্ন বৈশিষ্ট্য সেট করার জন্য অন্যান্য মেথড কল করা যায়।
setTitle();
setMessage();
setIcon();
DatePicker
একটি নির্দিষ্ট দিন বাছাই করার জন্য datePicker
বাটন ক্লিক করলে আমরা আগের মত আগে একটি Calendar
অবজেক্ট তৈরি করে এর বছর, মাস এবং দিন সেভ করে রাখছি। এরপর আমরা একটি DatePickerDialog
ওপেন করছি। এই ডায়লগেও আমরা পাঁচটি প্যারামিটারে পাঠাচ্ছি যার প্রথমটি Context এবং দ্বিতীয়টি onDateSetListener
যার onDateSet
ফাংশনটি আমরা ওভাররাইড করব। আগের মতই এখানেও আমরা প্যারামিটারে দেয়া বছর, মাস এবং দিনের মান আমাদের calendar-এ সেট করে dateFormat
-এর মাধেমে ফরম্যাট করে TextView-তে দেখাচ্ছি। তৃতীয়, চতুর্থ এবং পঞ্চম প্যারামিটারে বছর, মাস এবং দিন পাঠাতে হবে যেখানে আমরা আমাদের calendar থেকে সেভ করা তথ্য পাঠাব। এখানে লক্ষ করি যে ডায়লগটিকে dialog
ভ্যারিয়েবলের মধ্যে রাখা হয়েছে। এরপর getDatePicker()
-এর মাধ্যমে সর্বোচ্চ দিন হিসেবে বর্তমান সময়কে সেট করা হয়েছে।
dialog.getDatePicker().setMaxDate(calendar.getTimeInMillis());
এভাবে getDatePicker()
-এর মাধ্যমে আরও বিভিন্ন মান সেট করা যায়।
setMinDate();
setFirstDayOfTheWeek();
setBackground();
setBackgroundColor();
এভাবে সব মান সেট করার পর dialog.show()
মেথড কল করে ডায়লগটি দেখাব। পুরো কোডটি একবার দেখে নেই।
Button datePicker = findViewById(R.id.datePicker);
datePicker.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
final Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DAY_OF_MONTH);
DatePickerDialog dialog = new DatePickerDialog(MainActivity.this, new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker datePicker, int selectedYear, int selectedMonth, int selectedDay) {
calendar.set(Calendar.YEAR, selectedYear);
calendar.set(Calendar.MONTH, selectedMonth);
calendar.set(Calendar.DAY_OF_MONTH, selectedDay);
time = dateFormat.format(calendar.getTime());
timeText.setText(time);
}
}, year, month, day);
dialog.getDatePicker().setMaxDate(calendar.getTimeInMillis());
dialog.show();
}
});
MonthPicker
এবার আসি MonthPickerDialog
-এ। মাস বাছাইয়ের জন্য কোন ডিফল্ট ডায়লগ না থাকায় আমরা এর জন্য একটি ওপেনসোর্স লাইব্রেরি ব্যবহার করছি। লাইব্রেরিটি হল premkumarroyal/MonthAndYearPicker। এই লাইব্রেরিটি ব্যবহার করার জন্য প্রথমে অ্যাপ্লিকেশনের অ্যাপ লেভেলের build.gradle
-এ এই লাইব্রেরির ডিপেন্ডেন্সি যোগ করতে হবে।
dependencies {
...
implementation 'com.whiteelephant:monthandyearpicker:1.3.0'
}
এবার আমরা monthPicker
বাটন ক্লিক করে একটি MonthPickerDialog.Builder
ওপেন করব। এর onDateSetListener
-এর onDateSet
ফাংশনটি ওভাররাইড করে প্যারামিটারে দেয়া মাস এবং বছর calendar-এ সেট করে নিচ্ছি। এরপর monthFormat
-এর মাধ্যমে TextView-তে দেখাচ্ছি। আমরা একটি Builder
নিয়েছি তাই show() মেথডের আগে build()
মেথড কল করতে হবে।
Button monthPicker = findViewById(R.id.monthPicker);
monthPicker.setOnClickListener(new View.OnClickListener() {
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
@Override
public void onClick(View view) {
new MonthPickerDialog.Builder(MainActivity.this, new MonthPickerDialog.OnDateSetListener() {
@Override
public void onDateSet(int selectedMonth, int selectedYear) {
calendar.set(Calendar.YEAR, selectedYear);
calendar.set(Calendar.MONTH, selectedMonth);
time = monthFormat.format(calendar.getTime());
timeText.setText(time);
}
}, year, month)
.build()
.show();
}
});
আগের ডায়লগগুলোর মত এখানেও বিভিন্ন মেথড কল করে মান সেট করা যায়, কিন্তু কল করতে হবে build() কল করার আগে।
setTitle();
setMinMonth();
setMaxMonth();
setMinYear();
setMaxYear();
setMonthRange();
setYearRange();
showMonthOnly();
YearPicker
YearPickerDialog
-এর জন্য আমরা আগের লাইব্রেরিটাই ব্যবহার করব। পার্থক্য একটাই, build() কল করার আগে showYearOnly()
মেথডটি কল করব যেন ডায়লগে শুধু বছর দেখায়। যেহেতু একই লাইব্রেরি ব্যবহার করা হচ্ছে, সুতরাং, আগের মেথডগুলো আমরা এখানেও ব্যবহার করতে পারব।
Button yearPicker = findViewById(R.id.yearPicker);
yearPicker.setOnClickListener(new View.OnClickListener() {
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
@Override
public void onClick(View view) {
new MonthPickerDialog.Builder(MainActivity.this, new MonthPickerDialog.OnDateSetListener() {
@Override
public void onDateSet(int selectedMonth, int selectedYear) {
calendar.set(Calendar.YEAR, selectedYear);
time = String.valueOf(calendar.get(Calendar.YEAR));
timeText.setText(time);
}
}, year, month)
.showYearOnly()
.build()
.show();
}
});
DateRangePicker
এবার আমরা DateRangePickerDialog
নিয়ে কাজ করব যার মাধ্যমে আমরা একটি নির্দিষ্ট দিন থেকে শুরু করে আরেকটি দিন পর্যন্ত পরিসীমা বাছাই করতে পারি। কোন ডিফল্ট না থাকায় এর জন্য আমরা আরেকটি লাইব্রেরি ব্যবহার করব। আমরা যে ওপেনসোর্স লাইব্রেরিটি এখানে ব্যবহার করছি সেটি হল ArchitShah248/CalendarDateRangePicker। আগের মত এই লাইব্রেরির ডিপেন্ডেন্সি আমরা যোগ করে নেই।
dependencies {
...
implementation 'com.archit.calendar:awesome-calendar:1.1.4'
}
অন্যান্য Picker-গুলোর মত এটি একটি ডায়লগ নয়, বরং একটি ভিউ। তাই একে ডায়লগ হিসেবে ব্যবহার করার জন্য আমরা আগে একটি লে-আউটে একে বসিয়ে নেব। এরপর ডিফল্ট AlertDialog.Builder
-এর ভিউ হিসেবে ওই লে-আউটটিকে সেট করে দিব। তাহলে শুরু করা যাক।
প্রথমে একটি সাধারণ লে-আউট বানাই, যার নাম আমরা দিচ্ছি layout_date_range_picker.xml
। এখানে LinearLayout
এর মধ্যে DateRangeCalendarView
বসাই। লে-আউটের কাজ এতটুকুই।
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.archit.calendardaterangepicker.customviews.DateRangeCalendarView
android:id="@+id/date_picker_dialog"
custom:enable_past_date="true"
custom:range_color="@color/colorPrimaryLight"
custom:selected_date_circle_color="@color/colorPrimaryDark"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
rangePicker
বাটন ক্লিক করে আমরা এই Picker-টি ডায়লগে ওপেন করতে চাই। এজন্য আমরা প্রথমে আমাদের লে-আউটটি inflate
করে pickerLayout
-এ সেভ করি। লে-আউটের প্রথম এবং একমাত্র child
হল DateRangeCalendarView
যাকে আমরা datePicker
-এ রাখছি। এবার এর setCalendarListener
-এর দুটি মেথড ওভাররাইট করতে হবে। আমরা onFirstDateSelected
মেথড কল হয় যখন প্রথম দিন বাছাই করা হয়, এখানে আমরা প্রথম দিনের ফরম্যাট সেভ করে রাখছি। onDateRangeSelected
মেথড কল হয় যখন প্রথম এবং শেষ দিন দুটিই বাছাই করা হয়। এখানে আমরা প্রথম দিন এবং শেষ দিনের ফরম্যাট যুক্ত করে সেভ করে রাখছি।
এরপর আমরা একটি AlertDialog.Builder
নিয়ে একটি মেসেজ সেট করে দিয়েছি। এর ভিউ হিসেবে আমাদের pickerLayout কে সেট করি। এর setCancelable()
-কে true
করে দিয়েছি অর্থাৎ ডায়লগের বাইরে ক্লিক করলে ডায়লগটি ডিসমিস হয়ে যাবে। এবার setPositiveButton()
-এ আমরা সেভ করা পরিসীমার ফরম্যাট দেখাচ্ছি। setNegativeButton()
-টি ও কল করছি যেন Cancel
বাটনে ক্লিক করলে ডায়লগটি ডিসমিস হয়ে যায়। সবশেষে ডায়লগটি দেখাচ্ছি।
Button rangePicker = findViewById(R.id.rangePicker);
rangePicker.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
LinearLayout pickerLayout = (LinearLayout) getLayoutInflater().inflate(R.layout.layout_date_range_picker, null, false);
DateRangeCalendarView datePicker = (DateRangeCalendarView) pickerLayout.getChildAt(0);
datePicker.setCalendarListener(new DateRangeCalendarView.CalendarListener() {
@Override
public void onFirstDateSelected(Calendar start) {
time = dateFormat.format(start.getTime());
}
@Override
public void onDateRangeSelected(Calendar start, Calendar end) {
time = dateFormat.format(start.getTime()).concat(" - ").concat(dateFormat.format(end.getTime()));
}
});
new AlertDialog.Builder(MainActivity.this)
.setMessage("শুরুর দিন এবং শেষ দিনে ক্লিক করে দিনের পরিসীমা সিলেক্ট করুন")
.setView(pickerLayout)
.setCancelable(true)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
timeText.setText(time);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
})
.show();
}
});
যে অ্যাপ্লিকেশনটি বানিয়ে আমরা এই কাজগুলো করলাম তার পুরো কোড ams-hasan/PickerExamples-এই রিপোসিটোরিতে আছে। আশা করি এরপর প্রয়োজনে সহজেই দরকারি ডায়লগটি ব্যবহার করতে পারব।