Android ViewPager左右滑動月曆
阿新 • • 發佈:2019-02-01
先上圖:左右滑動顯示上個月和下個月,點選左上角日期區域出現時間選擇器,設定顯示時間
使用ViewPager左右滑動,在每頁動態新增GridView,GridView顯示當前月的日期,具體看程式碼中的註釋。
MainActivity:
package com.example.calendardemo; import java.util.Calendar; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.annotation.SuppressLint; import android.app.Activity; import android.app.AlertDialog; import android.app.DatePickerDialog; import android.app.DatePickerDialog.OnDateSetListener; import android.app.Dialog; import android.content.Context; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.os.Bundle; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.view.View.OnClickListener; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.DatePicker; import android.widget.GridView; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.RelativeLayout.LayoutParams; @SuppressLint("InlinedApi") public class MainActivity extends Activity implements OnClickListener { // 基本變數 private GridView title_gView; private Calendar calStartDate = Calendar.getInstance();// 當前顯示的日曆 private Calendar calSelectDate = Calendar.getInstance();// 當前選擇的日曆 private LinearLayout mCalendarLayout; private ImageView mPreImg; private ImageView mNextImg; private TextView mSelectedMonthTx; private TextView mYearTx; private TextView mMonthTx; private TextView mDayTx; private TextView mWeekTx; // ------------------------------------------------------------------------- public MyViewPager viewPager = null; public MyPagerAdapter pagerAdapter = null; // private GridView gView; // private CalendarGridViewAdapter gAdapter; private int currPager = 500; private CalendarGridViewAdapter adapter = null; private GridView currentView = null; // ------------------------------------------------------------------------- @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } /** * 初始化View */ private void initView() { viewPager = (MyViewPager) findViewById(R.id.stc_calendar_viewpager); mYearTx = (TextView) findViewById(R.id.stc_year_tx); mMonthTx = (TextView) findViewById(R.id.stc_month_tx); mWeekTx = (TextView) findViewById(R.id.stc_week_tx); mDayTx = (TextView) findViewById(R.id.stc_day_tx); mYearTx.getPaint().setFakeBoldText(true); mMonthTx.getPaint().setFakeBoldText(true); mWeekTx.getPaint().setFakeBoldText(true); mDayTx.getPaint().setFakeBoldText(true); mDayTx.setOnClickListener(this); mWeekTx.setOnClickListener(this); mMonthTx.setOnClickListener(this); mCalendarLayout = (LinearLayout) findViewById(R.id.stc_calendar_layout); mPreImg = (ImageView) findViewById(R.id.stc_pre_month_img); mPreImg.setOnClickListener(this); mNextImg = (ImageView) findViewById(R.id.stc_next_month_img); mNextImg.setOnClickListener(this); mSelectedMonthTx = (TextView) findViewById(R.id.stc_select_month_tx); setTitleGirdView(); LinearLayout.LayoutParams params_cal_title = new LinearLayout.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); mCalendarLayout.addView(title_gView, params_cal_title); } @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.stc_pre_month_img: showPreMonth(); break; case R.id.stc_next_month_img: showNextMonth(); break; case R.id.stc_day_tx: case R.id.stc_month_tx: case R.id.stc_week_tx:// 點選時間出現時間選擇器 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(this, AlertDialog.THEME_HOLO_LIGHT, setDateCallBack, year, month, day); dialog.show(); // dialogTitleLineColor(dialog, 0xffff6d4b); break; default: break; } } /** * 時間選擇器titleDivider的顏色 */ public final void dialogTitleLineColor(Dialog dialog, int color) { Context context = dialog.getContext(); int divierId = context.getResources().getIdentifier("android:id/titleDivider", null, null); View divider = dialog.findViewById(divierId); divider.setBackgroundColor(color); } /** * 回撥函式,int year, int monthOfYear, int dayOfMonth三個引數為日期對話方塊設定的日期 */ private OnDateSetListener setDateCallBack = new OnDateSetListener() { public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { calStartDate.set(year, monthOfYear, dayOfMonth); initData(); } }; /** * 初始化資料 */ private void initData() { setDateUI(calStartDate); initCalendar(); } /** * 更新頂部的日期控制元件資料 */ private void setDateUI(Calendar cal) { mSelectedMonthTx.setText(JTimeUtils.getShowTimeTx(this, cal.get(Calendar.MONTH) + 1)); mYearTx.setText(String.valueOf(cal.get(Calendar.YEAR))); mMonthTx.setText(JTimeUtils.getMonthAbbreviation(cal.get(Calendar.MONTH) + 1)); mDayTx.setText(cal.get(Calendar.DAY_OF_MONTH) < 10 ? "0" + cal.get(Calendar.DAY_OF_MONTH) : "" + cal.get(Calendar.DAY_OF_MONTH)); mWeekTx.setText(JTimeUtils.getWeekAbbreviation(cal.get(Calendar.DAY_OF_WEEK) - 1)); } @Override public void onResume() { super.onResume(); calStartDate = Calendar.getInstance(); initData(); } @Override public void onPause() { super.onPause(); // calSelectDate.setTime(calStartDate.getTime()); } private GridView setGirdView() { LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); GridView gridView = new GridView(this); gridView.setLayoutParams(params); gridView.setNumColumns(7);// 設定每行列數 gridView.setGravity(Gravity.CENTER_VERTICAL);// 位置居中 gridView.setVerticalSpacing(1);// 垂直間隔 gridView.setHorizontalSpacing(1);// 水平間隔 gridView.setBackgroundColor(Color.TRANSPARENT); gridView.setSelector(new ColorDrawable(Color.TRANSPARENT)); return gridView; } private void setTitleGirdView() { title_gView = setGirdView(); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); title_gView.setLayoutParams(params); title_gView.setVerticalSpacing(1);// 垂直間隔 title_gView.setHorizontalSpacing(1);// 水平間隔 TitleGridAdapter titleAdapter = new TitleGridAdapter(this); title_gView.setAdapter(titleAdapter);// 設定選單Adapter } public class TitleGridAdapter extends BaseAdapter { int[] titles = new int[] { R.string.sunday, R.string.monday, R.string.tuesday, R.string.wednesday, R.string.thursday, R.string.friday, R.string.saturday }; private Activity activity; // construct public TitleGridAdapter(Activity a) { activity = a; } @Override public int getCount() { return titles.length; } @Override public Object getItem(int position) { return titles[position]; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { LinearLayout iv = new LinearLayout(activity); TextView txtDay = new TextView(activity); txtDay.setFocusable(false); txtDay.setBackgroundColor(Color.TRANSPARENT); iv.setOrientation(LinearLayout.HORIZONTAL); txtDay.setGravity(Gravity.CENTER); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); txtDay.setTextColor(0xff999999); txtDay.setText((Integer) getItem(position)); iv.addView(txtDay, lp); return iv; } } /** * 初始化滑動控制元件ViewPager */ private void initCalendar() { pagerAdapter = new MyPagerAdapter(); viewPager.setAdapter(pagerAdapter); viewPager.setCurrentItem(500);// 設定當前頁位置為500 viewPager.setPageMargin(0); viewPager.setOnPageChangeListener(new OnPageChangeListener() { public void onPageScrollStateChanged(int arg0) { if (arg0 == 1) { } if (arg0 == 0) { currentView = (GridView) viewPager.findViewById(currPager); if (currentView != null) { adapter = (CalendarGridViewAdapter) currentView.getAdapter(); } } } public void onPageScrolled(int arg0, float arg1, int arg2) { } public void onPageSelected(int position) { // 滑動到某頁後更新資料、UI Calendar tempSelected = Calendar.getInstance(); // 臨時 tempSelected.setTime(calStartDate.getTime()); int count = position - 500; tempSelected.add(Calendar.MONTH, count); int month = tempSelected.get(Calendar.MONTH) + 1; mSelectedMonthTx.setText(JTimeUtils.getShowTimeTx(MainActivity.this, month)); setDateUI(tempSelected); currPager = position; calSelectDate.set(tempSelected.get(Calendar.YEAR), tempSelected.get(Calendar.MONTH), tempSelected.get(Calendar.DAY_OF_MONTH)); } }); } /** * ViewPager的介面卡,從第500頁開始,最多支援0-1000頁 */ private class MyPagerAdapter extends PagerAdapter { @Override public void setPrimaryItem(ViewGroup container, int position, Object object) { } @Override public int getCount() { return 1000; } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); } @Override public Object instantiateItem(ViewGroup container, int position) { GridView gv = initCalendarView(position); gv.setId(position); container.addView(gv); return gv; } } /** * 動態生成GridView */ private GridView initCalendarView(int position) { int count = position - 500; Calendar tempSelected = Calendar.getInstance(); // 臨時 /*if (position == 500) { int month = tempSelected.get(Calendar.MONTH) + 1; mSelectedMonthTx.setText(TimeUtils.getShowTimeTx(this, month)); }*/ tempSelected.setTime(calStartDate.getTime()); GridView gView = new CalendarGridView(this); tempSelected.add(Calendar.MONTH, count); final CalendarGridViewAdapter gAdapter = new CalendarGridViewAdapter(this, tempSelected, position); gView.setAdapter(gAdapter);// 設定選單Adapter gView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // item點選事件 // do somethings } }); return gView; } /** * 滑動到上一頁 */ private void showPreMonth() { viewPager.setCurrentItem(--currPager, true); } /** * 滑動到下一頁 */ private void showNextMonth() { viewPager.setCurrentItem(++currPager, true); } }
CalendarGridViewAdapter:
activity_main.xmlpackage com.example.calendardemo; import android.app.Activity; import android.content.res.Resources; import android.view.Display; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.GridView; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.LinearLayout.LayoutParams; import android.widget.RelativeLayout; import android.widget.TextView; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; public class CalendarGridViewAdapter extends BaseAdapter { private Calendar calStartDate = Calendar.getInstance();// 當前顯示的日曆 private Calendar calDate = Calendar.getInstance(); private LayoutInflater mInflater; private int mDisplayWidth = 0; private int mGridWidth = 0; private List<Date> mListData = new ArrayList<Date>(); private Activity activity; Resources resources; private int iMonthViewCurrentMonth = 0; // 當前檢視月 public CalendarGridViewAdapter(Activity a, Calendar cal, int pos) { activity = a; resources = activity.getResources(); calStartDate = cal; calDate.setTime(cal.getTime()); getDates(); mInflater = LayoutInflater.from(a); getGridWidth(); } /** * 根據改變的日期更新日曆,填充日曆控制元件用 */ private void UpdateStartDateForMonth() { calStartDate.set(Calendar.DATE, 1); // 設定成當月第一天 iMonthViewCurrentMonth = calStartDate.get(Calendar.MONTH);// 得到當前日曆顯示的月 // 星期一是2 星期天是1 填充剩餘天數 int iDay = 0; int iFirstDayOfWeek = Calendar.SUNDAY; int iStartDay = iFirstDayOfWeek; if (iStartDay == Calendar.MONDAY) { iDay = calStartDate.get(Calendar.DAY_OF_WEEK) - Calendar.MONDAY; if (iDay < 0) iDay = 6; } if (iStartDay == Calendar.SUNDAY) { iDay = calStartDate.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY; if (iDay < 0) iDay = 6; } calStartDate.add(Calendar.DAY_OF_WEEK, -iDay); } private void getDates() { UpdateStartDateForMonth(); for (int i = 1; i <= 42; i++) { mListData.add(calStartDate.getTime()); calStartDate.add(Calendar.DAY_OF_MONTH, 1); } } @SuppressWarnings("deprecation") private void getGridWidth() { Display display = activity.getWindowManager().getDefaultDisplay(); mDisplayWidth = display.getWidth(); float scale = activity.getResources().getDisplayMetrics().density; mGridWidth = (mDisplayWidth - (int) (46 * scale)) / 7;// 46dp位距離兩邊的margin } @Override public int getCount() { return mListData.size(); } @Override public Object getItem(int position) { return mListData.get(position); } @Override public long getItemId(int position) { return position; } @SuppressWarnings("deprecation") @Override public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { convertView = mInflater.inflate( R.layout.calendar_grid_view_item, null); holder = new ViewHolder(); holder.itemPic = (ImageView) convertView .findViewById(R.id.stc_cal_grid_item_pic); holder.itemPicMask = (ImageView) convertView .findViewById(R.id.stc_cal_grid_item_pic_mask); holder.itemDay = (TextView) convertView .findViewById(R.id.stc_cal_grid_item_day); holder.itemLayout = (RelativeLayout) convertView .findViewById(R.id.stc_cal_grid_item_layout); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } final Date myDate = (Date) getItem(position); Calendar calCalendar = Calendar.getInstance(); calCalendar.setTime(myDate); final int iMonth = calCalendar.get(Calendar.MONTH); // final int iDay = calCalendar.get(Calendar.DAY_OF_WEEK); int day = myDate.getDate(); // 日期 holder.itemDay.setText(String.valueOf(day)); holder.itemPic.setVisibility(View.GONE); holder.itemPicMask.setVisibility(View.GONE); if (equalsDate(calDate.getTime(), myDate)) { // 當前日期 holder.itemLayout .setBackgroundResource(R.drawable.stc_calendar_item_select_bg); holder.itemDay.setTextColor(0xFFFFFFFF); } else { holder.itemLayout .setBackgroundResource(R.drawable.stc_calendar_item_normal_bg); holder.itemDay.setTextColor(0xFF8F8F8F); } // 判斷是否是當前月,不是當前月不顯示 if (iMonth == iMonthViewCurrentMonth) { holder.itemLayout.setVisibility(View.VISIBLE); } else { holder.itemLayout.setVisibility(View.GONE); } LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( mGridWidth, mGridWidth); holder.itemLayout.setLayoutParams(params); /** * convertView設定了setLayoutParams後,如果在此函式中設定某個控制元件的click事件,會出現第一格點選沒有響應的情況, * 解決方法是設定GridView的onItemClick事件 */ convertView.setLayoutParams(new GridView.LayoutParams( LayoutParams.WRAP_CONTENT, mGridWidth)); return convertView; } @Override public void notifyDataSetChanged() { super.notifyDataSetChanged(); } /** * 比較時間 * */ private Boolean equalsDate(Date date1, Date date2) { Calendar cal1 = Calendar.getInstance(); cal1.setTimeInMillis(date1.getTime()); Calendar cal2 = Calendar.getInstance(); cal2.setTimeInMillis(date2.getTime()); int day1 = cal1.get(Calendar.DAY_OF_MONTH); int day2 = cal2.get(Calendar.DAY_OF_MONTH); if (day2 == day1) { return true; } return false; } private class ViewHolder { public ImageView itemPic; public ImageView itemPicMask; public TextView itemDay; public RelativeLayout itemLayout; } }
calendar_grid_view_item.xml<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/stc_layout_bg" android:orientation="vertical" > <RelativeLayout android:id="@+id/stc_info_layout" android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/stc_day_tx" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginLeft="23dp" android:layout_marginTop="37dp" android:background="@null" android:gravity="top" android:textColor="#ff6d4b" android:textSize="40sp" android:textStyle="bold" /> <TextView android:id="@+id/stc_month_tx" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_marginLeft="4dp" android:layout_marginTop="40dp" android:layout_toRightOf="@id/stc_day_tx" android:textColor="#ff6d4b" android:textSize="18sp" android:textStyle="bold" /> <TextView android:id="@+id/stc_week_tx" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/stc_month_tx" android:layout_marginLeft="4dp" android:layout_toRightOf="@id/stc_day_tx" android:textColor="#ff6d4b" android:textSize="18sp" android:textStyle="bold" /> <RelativeLayout android:id="@+id/stc_info_layout_1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_marginLeft="23dp" android:layout_marginRight="23dp" android:layout_centerVertical="true" > <TextView android:id="@+id/stc_year_tx" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:textColor="#8f8f8f" android:textStyle="bold" android:textSize="24sp" /> </RelativeLayout> <View android:layout_width="match_parent" android:layout_height="0.5dp" android:layout_below="@id/stc_week_tx" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:layout_marginTop="20dp" android:background="#8f8f8f" /> </RelativeLayout> <RelativeLayout android:id="@+id/stc_pre_next_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/stc_info_layout" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:layout_marginTop="10dp" > <ImageView android:id="@+id/stc_pre_month_img" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:contentDescription="@string/app_name" android:paddingLeft="3dp" android:paddingRight="12dp" android:paddingBottom="12dp" android:paddingTop="16dp" android:src="@drawable/stc_pre_icon" /> <ImageView android:id="@+id/stc_next_month_img" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:contentDescription="@string/app_name" android:paddingLeft="12dp" android:paddingRight="3dp" android:paddingBottom="12dp" android:paddingTop="16dp" android:src="@drawable/stc_next_icon" /> <TextView android:id="@+id/stc_select_month_tx" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:textColor="#8f8f8f" android:textSize="14sp" /> </RelativeLayout> <LinearLayout android:id="@+id/stc_calendar_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/stc_pre_next_layout" android:layout_marginLeft="23dp" android:layout_marginRight="23dp" android:orientation="vertical" > </LinearLayout> <com.example.calendardemo.MyViewPager android:id="@+id/stc_calendar_viewpager" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_below="@id/stc_calendar_layout" android:background="@android:color/transparent" android:scrollbars="none" android:layout_marginLeft="23dp" android:layout_marginRight="23dp" android:visibility="visible" > </com.example.calendardemo.MyViewPager> </RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="@+id/stc_cal_grid_item_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/stc_cal_grid_item_pic"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:visibility="gone"
android:contentDescription="@string/app_name"
/>
<ImageView
android:id="@+id/stc_cal_grid_item_pic_mask"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="@drawable/stc_calendar_item_pic_mask"
android:visibility="gone"
android:contentDescription="@string/app_name"
/>
<TextView
android:id="@+id/stc_cal_grid_item_day"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textSize="14sp"
android:textColor="#8f8f8f"/>
</RelativeLayout>
</LinearLayout>
下載Demo