您好,登錄后才能下訂單哦!
怎么在Android中實現一個日歷控件?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
public class SelectDateDialog { private static final String TAG = "SelectDateDialog"; private Dialog dialog; private TextView dateText; private int selectYear, selectMonth; private AppCompatActivity mContext; private DateAdapter adapter; private List<String> selWeekList = new ArrayList<>(); private List<DateBean> list = new ArrayList<>(); public SelectDateDialog builder(AppCompatActivity mContext, int year, int month) { this.mContext = mContext; this.selectYear = year; this.selectMonth = month; // 獲取Dialog布局 View view = LayoutInflater.from(mContext).inflate(R.layout.dialog_date, null); // 定義Dialog布局和參數 dialog = new Dialog(mContext, R.style.AlertDialogStyle); dialog.setCanceledOnTouchOutside(false);//點擊外部是否取消 dialog.setCancelable(false); dialog.setContentView(view); Window window = dialog.getWindow(); WindowManager.LayoutParams params = window.getAttributes(); params.width = (ScreenUtils.getScreenWidth(mContext)); // params.height = (int) (ScreenUtils.getScreenHeight(mContext) * 0.5); window.setAttributes(params); window.setGravity(Gravity.BOTTOM); RecyclerView recycler = view.findViewById(R.id.recycler_select_date); dateText = view.findViewById(R.id.date_text); dateText.setText(year + "年" + month + "月"); //下個月 view.findViewById(R.id.next_month).setOnClickListener(view13 -> { if (selectMonth > 11) { selectYear = selectYear + 1; selectMonth = 1; } else { selectMonth++; } showNewData(selectYear, selectMonth); }); //上個月 view.findViewById(R.id.last_month).setOnClickListener(view14 -> { if (selectMonth < 2) { selectYear = selectYear - 1; selectMonth = 12; } else { selectMonth--; } showNewData(selectYear, selectMonth); }); list = DataUtils.getCalendar(year, month); adapter = new DateAdapter(mContext, list); GridLayoutManager manager = new GridLayoutManager(mContext, 7); recycler.setLayoutManager(manager); recycler.setAdapter(adapter); //取消 view.findViewById(R.id.middle_cancel).setOnClickListener(view1 -> { dialog.dismiss(); }); //確定 view.findViewById(R.id.middle_determine).setOnClickListener(view1 -> { initSelect(); }); //設置選中當天 adapter.setNowDay(year, month, DataUtils.getLastMonth(year, month)); return this; } private void showNewData(int year, int month) { list = DataUtils.getCalendar(year, month); //更新月數據 adapter.setList(list); adapter.setNowDay(year , month, DataUtils.getLastMonth(year, month)); dateText.setText(year + "年" + month + "月"); } /** * 獲取選中的日期 */ private void initSelect() { selWeekList.clear(); for (int i = 0; i < list.size(); i++) { if (list.get(i).isFlag()) { //記錄數量 selWeekList.add(selectYear + "-" + selectMonth + "-" + list.get(i).getWeek()); } } Log.e(TAG, "initSelect: "+ list.size()); Log.e(TAG, "initSelect: "+ selWeekList.size()); if (selWeekList.size() == 0) { Toast.makeText(mContext, "未選則日期", Toast.LENGTH_SHORT).show(); return; } dialog.dismiss(); listener.date(DataUtils.returnList(selWeekList)); Log.e(TAG, "initSelect: " + DataUtils.returnList(selWeekList)); } public void show() { if (dialog != null && (!dialog.isShowing())) { dialog.show(); } } private OnDateListener listener; public SelectDateDialog setListener(OnDateListener listener) { this.listener = listener; return this; } public interface OnDateListener { void date(String selectDate); } }
ScreenUtils:
public class ScreenUtils { public static int getScreenWidth(Context context) { DisplayMetrics localDisplayMetrics = new DisplayMetrics(); ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(localDisplayMetrics); return localDisplayMetrics.widthPixels; } }
DateBean:
public class DateBean { private int week; private boolean sign; //0 上月 1本月 2下月 private int month; private boolean isFlag; public boolean isFlag() { return isFlag; } public void setFlag(boolean flag) { isFlag = flag; } public int getWeek() { return week; } public void setWeek(int week) { this.week = week; } public boolean isSign() { return sign; } public void setSign(boolean sign) { this.sign = sign; } public int getMonth() { return month; } public void setMonth(int month) { this.month = month; } public DateBean(int week, boolean sign, int month) { this.week = week; this.sign = sign; this.month = month; } }
適配器:DateAdapter
public class DateAdapter extends CommonRecyclerAdapter<DateBean> { private static final String TAG = "DateAdapter"; private Integer nowDay; private int year; private int month; public DateAdapter(Context context, List<DateBean> list) { super(context, R.layout.item_date, list); } public void setNowDay(int year, int month, int nowDay) { this.nowDay = nowDay; this.year = year; this.month = month; notifyDataSetChanged(); } @Override public void convert(RecyclerHolder holder, DateBean item, int position) { TextView number = holder.getView(R.id.item_number); number.setText(item.getWeek() + ""); //當前年月等于切換年月時才選中當天 if (position == nowDay) { String date = year + "-" + month; if (date.equals(DataUtils.timeInMillsTrasToDate(1))) { number.setBackgroundResource(R.drawable.date_unsel_shape); number.setTextColor(Color.WHITE); }else { number.setTextColor(Color.parseColor("#333333")); } } else { number.setBackgroundResource(0); number.setTextColor(Color.parseColor("#333333")); if (item.getMonth() == 0 || item.getMonth() == 2) { number.setTextColor(Color.parseColor("#CDCDCD")); } else { number.setTextColor(Color.parseColor("#333333")); } } //點擊事件 number.setOnClickListener(view -> { //本月可以點擊 int nowYear = Integer.parseInt(DataUtils.timeInMillsTrasToDate(2)); int nowMonth = Integer.parseInt(DataUtils.timeInMillsTrasToDate(3)); //只有在今天之后的日期才可以選中 if (year == nowYear) { if (item.getMonth() == 1 && month == nowMonth && position > nowDay) { onClick(item, number); } else if (month > nowMonth) { onClick(item, number); } } else if (year > nowYear) { onClick(item, number); } }); } private void onClick(DateBean item, TextView number) { if (item.isFlag()) { item.setFlag(false); number.setBackgroundResource(0); number.setTextColor(Color.parseColor("#333333")); } else { item.setFlag(true); number.setBackgroundResource(R.drawable.date_sel_shape); number.setTextColor(Color.WHITE); } } }
注意:CommonRecyclerAdapter之前寫過,這里不再重復
數據源:DataUtils
public class DataUtils { private static final String TAG = "DataUtils"; /** * 日歷 */ public static List<DateBean> getCalendar(int currentYear, int currentMonth) { //實例化集合 List<DateBean> list = new ArrayList<>(); Calendar c = Calendar.getInstance(); c.clear(); /** * 處理上個月月末 */ if (currentMonth - 1 == 0) { c.set(Calendar.YEAR, currentYear - 1); c.set(Calendar.MONTH, 11); } else { c.set(Calendar.YEAR, currentYear); c.set(Calendar.MONTH, (currentMonth - 2)); } int last_sumDays = c.getActualMaximum(Calendar.DAY_OF_MONTH); c.set(Calendar.DATE, last_sumDays); //得到一號星期幾 int weekDay = c.get(Calendar.DAY_OF_WEEK); if (weekDay < 7) { for (int i = weekDay - 1; i >= 0; i--) { Integer date = new Integer(last_sumDays - i); list.add(new DateBean(date, true, 0)); } } /** * 處理當前月 */ c.clear(); c.set(Calendar.YEAR, currentYear); c.set(Calendar.MONTH, currentMonth - 1); int currentsumDays = c.getActualMaximum(Calendar.DAY_OF_MONTH); for (int i = 1; i <= currentsumDays; i++) { Integer date = new Integer(i); list.add(new DateBean(date, true, 1)); } /** * 處理下個月月初 */ c.clear(); if (currentMonth == 12) { c.set(Calendar.YEAR, currentYear + 1); c.set(Calendar.MONTH, 0); } else { c.set(Calendar.YEAR, currentYear); c.set(Calendar.MONTH, currentMonth); } c.set(Calendar.DATE, 1); int currentWeekDay = c.get(Calendar.DAY_OF_WEEK); if (currentWeekDay > 2 && currentWeekDay < 8) { for (int i = 1; i <= 8 - currentWeekDay; i++) { list.add(new DateBean(i, true, 2)); } } return list; } /** * 獲取上個月大小 */ public static Integer getLastMonth(int currentYear, int currentMonth) { //實例化集合 List<Integer> list = new ArrayList<>(); Calendar c = Calendar.getInstance(); c.clear(); /** * 處理上個月月末 */ if (currentMonth - 1 == 0) { c.set(Calendar.YEAR, currentYear - 1); c.set(Calendar.MONTH, 11); } else { c.set(Calendar.YEAR, currentYear); c.set(Calendar.MONTH, (currentMonth - 2)); } int last_sumDays = c.getActualMaximum(Calendar.DAY_OF_MONTH); c.set(Calendar.DATE, last_sumDays); //得到一號星期幾 int weekDay = c.get(Calendar.DAY_OF_WEEK); if (weekDay < 7) { for (int i = weekDay - 1; i >= 0; i--) { list.add(i); } } Log.e(TAG, "getLastMonth: " + Integer.parseInt(timeInMillsTrasToDate(0))); return list.size() + Integer.parseInt(timeInMillsTrasToDate(0)) - 1; } /** * list轉string字符串 */ public static String returnList(List<String> list) { if (null == list && list.size() == 0) { return ""; } else { //去除空格 String str = String.valueOf(list).replaceAll(" ", ""); return str.substring(1, str.length() - 1); } } /** * 時間轉換 */ @TargetApi(Build.VERSION_CODES.N) public static String timeInMillsTrasToDate(int formatType) { DateFormat formatter = null; switch (formatType) { case 0: formatter = new SimpleDateFormat("dd"); break; case 1: formatter = new SimpleDateFormat("yyyy-MM"); break; case 2: formatter = new SimpleDateFormat("yyyy"); break; case 3: formatter = new SimpleDateFormat("MM"); break; } Calendar calendar = Calendar.getInstance(); return formatter.format(calendar.getTime()); } }
使用:DateActivity
public class DateActivity extends AppCompatActivity { private Button openDate; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_date); openDate = this.findViewById(R.id.open_date); openDate.setOnClickListener(view -> { showDateDialog(); }); } private void showDateDialog() { int year = Integer.parseInt(DataUtils.timeInMillsTrasToDate(2)); int month = Integer.parseInt(DataUtils.timeInMillsTrasToDate(3)); new SelectDateDialog().builder(this, year, month) .setListener(selectDate -> openDate.setText(selectDate)).show(); } }
對應布局:activity_date
<?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="match_parent" android:orientation="vertical"> <Button android:id="@+id/open_date" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="打開日歷" /> </LinearLayout>
2、資源文件:
date_sel_shape.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" android:useLevel="false"> <solid android:color="@color/colorAccent" /> <!--<stroke android:width="1dp" android:color="@color/white"/>--> <size android:width="30dp" android:height="30dp" /> </shape>
date_unsel_shape.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" android:useLevel="false"> <solid android:color="@color/colorPrimary" /> <!--<stroke android:width="1dp" android:color="@color/white"/>--> <size android:width="30dp" android:height="30dp" /> </shape>
dialog_shape.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <corners android:radius="5dp" /> <solid android:color="#ffffff" /> </shape>
item_date.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:gravity="center" android:padding="5dp"> <TextView android:id="@+id/item_number" android:layout_width="35dp" android:layout_height="35dp" android:gravity="center" android:text="10" android:textSize="15sp" /> </LinearLayout>
顏色:
<color name="colorPrimary">#008577</color> <color name="colorPrimaryDark">#00574B</color> <color name="colorAccent">#D81B60</color>
樣式:
<style name="AlertDialogStyle" 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> </style>
看完上述內容,你們掌握怎么在Android中實現一個日歷控件的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。