问题
I am looking for a CalendarView that can be used in a dialog something like this:
I plan to use android.widget.CalendarView
but it is available from API level 11. That's an issue considering there are still lot of users, using android 2.3.3 (but not a major one can let go those set of user).
Which of these options should I use?
1) libraries that are available and use them accordingly.
2) customize the android.widget.CalendarView
?
If #2, then are there any examples for it?
回答1:
Hi visit all given links, hope will help you
1.https://github.com/inteist/android-better-time-picker
2.https://github.com/derekbrameyer/android-betterpickers
3.http://www.androiddevelopersolutions.com/2013/05/android-calendar-sync.html
4.http://www.androidviews.net/2013/04/extendedcalendarview/
5.http://abinashandroid.wordpress.com/2013/07/21/how-to-create-custom-calendar-in-android/
6.http://w2davids.wordpress.com/android-simple-calendar/
7.https://github.com/roomorama/Caldroid
8.https://github.com/flavienlaurent/datetimepicker
when you will visit
https://github.com/derekbrameyer/android-betterpickers
For a working implementation of this project see the sample/ folder.
Implement the appropriate Handler callbacks:
public class MyActivity extends Activity implements DatePickerDialogFragment.DatePickerDialogHandler {
@Override
public void onCreate(Bundle savedInstanceState) {
// ...
}
@Override
public void onDialogDateSet(int year, int monthOfYear, int dayOfMonth) {
// Do something with your date!
}
}
Use one of the Builder classes to create a PickerDialog with a theme:
DatePickerBuilder dpb = new DatePickerBuilder()
.setFragmentManager(getSupportFragmentManager())
.setStyleResId(R.style.BetterPickersDialogFragment);
dpb.show();
also for an another example you can visit
https://github.com/roomorama/Caldroid
and use as follows
To embed the caldroid fragment in your activity, use below code:
CaldroidFragment caldroidFragment = new CaldroidFragment();
Bundle args = new Bundle();
Calendar cal = Calendar.getInstance();
args.putInt(CaldroidFragment.MONTH, cal.get(Calendar.MONTH) + 1);
args.putInt(CaldroidFragment.YEAR, cal.get(Calendar.YEAR));
caldroidFragment.setArguments(args);
FragmentTransaction t = getSupportFragmentManager().beginTransaction();
t.replace(R.id.calendar1, caldroidFragment);
t.commit();
回答2:
hope this help you this is all editable custom calendar you can edit in your way
take fragment
public class fragmentCalender extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
ArrayList<calenderModelCustom> itemsArrayList = new ArrayList<>(); // calls function to get items list
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
private View mView;
private Context mContext;
private GridView mGridView;
private int temp = 1;
private calenderModelCustom mCalenderModelCustom;
private ImageButton mPreviousButton, mForwardButton;
private int mPageCount = 0;
private TextView mYearLable;
private int mYear;
private Calendar mCalender;
private int mCurrentDay, mCurrentMonth, mCurrentYear;
private ArrayList<calenderModelCustom> list;
private String mFirstDate;
public fragmentCalender() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment fragmentCalender.
*/
// TODO: Rename and change types and number of parameters
public static fragmentCalender newInstance(String param1, String param2) {
fragmentCalender fragment = new fragmentCalender();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
mView = inflater.inflate(R.layout.fragment_fragment_calender2, container, false);
mContext = this.getActivity();
Util.CAL_CUR_DATE_CNST = "0";
mCalender = Calendar.getInstance();
list = new ArrayList<>();
//initialize xml element object
initializeView();
//current things
setCurrentEnv(mCalender.get(Calendar.MONTH));
//current date
getDateTime();
//actions
initializeViewAction();
//set adapter
initializeViewAdapter(mPageCount, Util.CAL_CUR_DATE_CNST);
return mView;
}
/*
* setting first date,day of current month
* */
private void setCurrentEnv(int mCurrentMonth){
Log.i("<<>>Cal",String.valueOf(mCurrentMonth));
Date date = new Date();
date.setDate(1);
date.setMonth(mCurrentMonth);
date.setYear(mCurrentYear);
mFirstDate = getDay(date);
Log.i("<<>>Cal",mFirstDate);
if (mFirstDate.contains("Fri")) {
mPageCount = 4;
initializeViewAction();
initializeViewAdapter(mPageCount, Util.CAL_CUR_DATE_CNST);
} else if (mFirstDate.contains("Sat")) {
mPageCount = 5;
initializeViewAction();
initializeViewAdapter(mPageCount, Util.CAL_CUR_DATE_CNST);
} else if (mFirstDate.contains("Sunday")) {
mPageCount = 6;
initializeViewAction();
initializeViewAdapter(mPageCount, Util.CAL_CUR_DATE_CNST);
} else if (mFirstDate.contains("Mon")) {
mPageCount = 0;
initializeViewAction();
initializeViewAdapter(mPageCount, Util.CAL_CUR_DATE_CNST);
} else if (mFirstDate.contains("Tue")) {
mPageCount = 1;
initializeViewAction();
initializeViewAdapter(mPageCount, Util.CAL_CUR_DATE_CNST);
} else if (mFirstDate.contains("Wed")) {
mPageCount = 2;
initializeViewAction();
initializeViewAdapter(mPageCount, Util.CAL_CUR_DATE_CNST);
} else if (mFirstDate.contains("Thu")) {
mPageCount = 3;
initializeViewAction();
initializeViewAdapter(mPageCount, Util.CAL_CUR_DATE_CNST);
}
}
private void initializeViewAction() {
if (mCurrentMonth == 1) {
mYearLable.setText("Jan " + String.valueOf(mCurrentYear));
} else if (mCurrentMonth == 2) {
mYearLable.setText("Feb " + String.valueOf(mCurrentYear));
} else if (mCurrentMonth == 3) {
mYearLable.setText("Mar " + String.valueOf(mCurrentYear));
} else if (mCurrentMonth == 4) {
mYearLable.setText("Apr " + String.valueOf(mCurrentYear));
} else if (mCurrentMonth == 5) {
mYearLable.setText("May " + String.valueOf(mCurrentYear));
} else if (mCurrentMonth == 6) {
mYearLable.setText("Jun " + String.valueOf(mCurrentYear));
} else if (mCurrentMonth == 7) {
mYearLable.setText("Jul " + String.valueOf(mCurrentYear));
} else if (mCurrentMonth == 8) {
mYearLable.setText("Aug " + String.valueOf(mCurrentYear));
} else if (mCurrentMonth == 9) {
mYearLable.setText("Sep " + String.valueOf(mCurrentYear));
} else if (mCurrentMonth == 10) {
mYearLable.setText("Oct " + String.valueOf(mCurrentYear));
} else if (mCurrentMonth == 11) {
mYearLable.setText("Nov " + String.valueOf(mCurrentYear));
} else if (mCurrentMonth == 12) {
mYearLable.setText("Dec " + String.valueOf(mCurrentYear));
} else {
mYearLable.setText("" + String.valueOf(mCurrentYear));
}
mForwardButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//increment current month by one
mCurrentMonth++;
//if current month >= 13 then start from first month
if (mCurrentMonth >= 13) {
mCurrentMonth = 1;
mCurrentYear ++;
}
setIfBackOrForwardToCurrentMonth();
setCurrentEnv(mCurrentMonth);
}
});
mPreviousButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//increment current month by one
mCurrentMonth--;
//if current month >= 13 then start from first month
if (mCurrentMonth < 1) {
mCurrentMonth = 12;
mCurrentYear --;
}
setIfBackOrForwardToCurrentMonth();
setCurrentEnv(mCurrentMonth);
}
});
mGridView.setOnTouchListener(new OnSwipeTouchListener(mContext) {
public void onSwipeTop() {
Log.i("top","");
}
public void onSwipeRight() {
//increment current month by one
mCurrentMonth++;
//if current month >= 13 then start from first month
if (mCurrentMonth >= 13) {
mCurrentMonth = 1;
mCurrentYear ++;
}
setIfBackOrForwardToCurrentMonth();
setCurrentEnv(mCurrentMonth);
}
public void onSwipeLeft() {
//increment current month by one
mCurrentMonth--;
//if current month >= 13 then start from first month
if (mCurrentMonth < 1) {
mCurrentMonth = 12;
mCurrentYear --;
}
setIfBackOrForwardToCurrentMonth();
setCurrentEnv(mCurrentMonth);
}
public void onSwipeBottom() {
Log.i("bottom","");
}
});
}
/*
* parameter to set current date marker on calender
* */
private void setIfBackOrForwardToCurrentMonth() {
Log.i("<<>>Cal<>",mCurrentMonth+" "+Util.CURRENT_DATE);
if (mCurrentMonth==mCalender.get(Calendar.MONTH)+1){
Util.CAL_CUR_DATE_CNST = "0";
} if (mCurrentMonth!=mCalender.get(Calendar.MONTH)+1){
Util.CAL_CUR_DATE_CNST = "1";
}
}
/*method to get current date and store it separetely in variable*/
private String getDateTime() {
DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
Date date = new Date();
mCurrentDay = mCalender.get(Calendar.DATE);
mCurrentMonth = mCalender.get(Calendar.MONTH)+1;
Util.CURRENT_DATE = String.valueOf(mCalender.get(Calendar.DATE));
Log.i("<<>>Cal<>",Util.CURRENT_DATE);
mCurrentYear = mCalender.get(Calendar.YEAR);
return dateFormat.format(date);
}
/*
* current day to print in text format
* */
public static String getDay(Date date) {
SimpleDateFormat simpleDateformat = new SimpleDateFormat("EEEE"); // the day of the week spelled out completely
System.out.println(simpleDateformat.format(date));
return simpleDateformat.format(date);
}
private void initializeViewAdapter(int temp , String mVisibility) {
CalenderAdapterView mCalenderAd = new CalenderAdapterView(mContext, generateItemsList(temp),Util.CURRENT_DATE,mVisibility);
mGridView.setAdapter(mCalenderAd);
}
private ArrayList<calenderModelCustom> generateItemsList(int temp) {
list.clear();
String itemNames[] = getResources().getStringArray(R.array.items_name);
for (int i = 0; i < temp; i++) {
list.add(new calenderModelCustom("", ""));
}
for (int i = 0; i < itemNames.length; i++) {
list.add(new calenderModelCustom(itemNames[i], itemNames[i]));
}
return list;
}
private void initializeView() {
mYearLable = (TextView) mView.findViewById(R.id.currentDateLabel);
mForwardButton = (ImageButton) mView.findViewById(R.id.btn_forward);
mPreviousButton = (ImageButton) mView.findViewById(R.id.btn_previous);
mGridView = (GridView) mView.findViewById(R.id.cal_grid_view);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
define grid view in 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"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/marginRight"
>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<android.support.constraint.ConstraintLayout
android:id="@+id/calendarHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageButton
android:id="@+id/btn_previous"
style="@style/Widget.AppCompat.Button.Borderless.Colored"
android:layout_width="85dp"
android:layout_height="0dp"
android:src="@drawable/ic_action_date_back"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="@+id/btn_forward"
style="@style/Widget.AppCompat.Button.Borderless.Colored"
android:layout_width="85dp"
android:layout_height="0dp"
android:src="@drawable/ic_action_date_next"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/currentDateLabel"
android:layout_width="0dp"
android:layout_height="56dp"
android:gravity="center"
android:text=""
android:textSize="18sp"
app:layout_constraintLeft_toRightOf="@id/btn_previous"
app:layout_constraintRight_toLeftOf="@id/btn_forward"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
<!-- eventDays header -->
<LinearLayout
android:id="@+id/calendar_header"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_below="@id/calendarHeader"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/mondayLabel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_horizontal"
android:text="@string/monday"
android:textColor="@color/daysLabelColor" />
<TextView
android:id="@+id/tuesdayLabel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_horizontal"
android:text="@string/tuesday"
android:textColor="@color/daysLabelColor" />
<TextView
android:id="@+id/wednesdayLabel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_horizontal"
android:text="@string/wednesday"
android:textColor="@color/daysLabelColor" />
<TextView
android:id="@+id/thursdayLabel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_horizontal"
android:text="@string/thursday"
android:textColor="@color/daysLabelColor" />
<TextView
android:id="@+id/fridayLabel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_horizontal"
android:text="@string/friday"
android:textColor="@color/daysLabelColor" />
<TextView
android:id="@+id/saturdayLabel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_horizontal"
android:text="@string/saturday"
android:textColor="@color/daysLabelColor" />
<TextView
android:id="@+id/sundayLabel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_horizontal"
android:text="@string/sunday"
android:textColor="@color/daysLabelColor" />
</LinearLayout>
<GridView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:numColumns="7"
android:gravity="center_vertical"
android:layout_below="@id/calendar_header"
android:id="@+id/cal_grid_view">
</GridView>
</RelativeLayout>
</android.support.v7.widget.CardView>
create Util.class and write constants
public static String CAL_CUR_DATE_CNST ;
public static String CURRENT_DATE ;
create Adapter for grid view
public class CalenderAdapterView extends BaseAdapter {
Calendar mCalender = Calendar.getInstance();
private Context context; //context
private ArrayList<calenderModelCustom> items; //data source of the list adapter
private String mCurrentDate;
private String mVisibility;
//public constructor
public CalenderAdapterView(Context context, ArrayList<calenderModelCustom> items, String currentDate, String mVisibility) {
this.context = context;
this.items = items;
this.mCurrentDate = currentDate;
this.mVisibility = mVisibility;
}
@Override
public int getCount() {
//returns total of items in the list
return items.size();
}
@Override
public Object getItem(int position) {
//returns list item at the specified position
return items.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// inflate the layout for each list row
if (convertView == null) {
convertView = LayoutInflater.from(context).
inflate(R.layout.calendar_item, parent, false);
}
// get current item to be displayed
calenderModelCustom currentItem = (calenderModelCustom) getItem(position);
// get the TextView for item name and item description
TextView textViewItemName = (TextView)
convertView.findViewById(R.id.text_view_item_name);
ImageView mImageBaground = (ImageView)
convertView.findViewById(R.id.img_baground);
//sets the text for item name and item description from the current item object
textViewItemName.setText(currentItem.getmNoOfDays());
if (mVisibility.equals("0")) {
if (String.valueOf(mCalender.get(Calendar.DATE)).equals(currentItem.getmNoOfDays())) {
mImageBaground.setImageResource(R.drawable.circle_cur_date);
}
}
// returns the view for the current row
return convertView;
}
}
create xml file
<?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">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:id="@+id/img_baground"/>
<TextView
android:id="@+id/text_view_item_name"
android:layout_width="match_parent"
android:layout_centerHorizontal="true"
android:gravity="center_horizontal"
android:layout_centerVertical="true"
android:text="1"
android:layout_height="wrap_content" />
</RelativeLayout>
<TextView
android:id="@+id/text_view_item_description"
android:layout_width="match_parent"
android:gravity="center_horizontal"
android:layout_height="wrap_content" />
</LinearLayout>
and one drawable file
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<size
android:width="30dp"
android:height="30dp"
/>
<stroke android:width="0.5dp"
android:color="@color/monsoon"/>
</shape>
and create class
public class calenderModelCustom {
private String mStartPos;
public String getmStartPos() {
return mStartPos;
}
public void setmStartPos(String mStartPos) {
this.mStartPos = mStartPos;
}
public String getmNoOfDays() {
return mNoOfDays;
}
public void setmNoOfDays(String mNoOfDays) {
this.mNoOfDays = mNoOfDays;
}
private String mNoOfDays;
public calenderModelCustom (String mStartPos,String mNoOfDays){
this.mStartPos = mStartPos;
this.mNoOfDays = mNoOfDays;
}
}
add in string.xml
<string name="monday">M</string>
<string name="tuesday">T</string>
<string name="wednesday">W</string>
<string name="thursday">T</string>
<string name="friday">F</string>
<string name="saturday">S</string>
<string name="sunday">S</string>
//calender
<string-array name="items_name">
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
<item>6</item>
<item>7</item>
<item>8</item>
<item>9</item>
<item>10</item>
<item>11</item>
<item>12</item>
<item>13</item>
<item>14</item>
<item>15</item>
<item>16</item>
<item>17</item>
<item>18</item>
<item>19</item>
<item>20</item>
<item>21</item>
<item>22</item>
<item>23</item>
<item>24</item>
<item>25</item>
<item>26</item>
<item>27</item>
<item>28</item>
<item>29</item>
<item>30</item>
<item>31</item>
</string-array>
add dependency for card
compile 'com.android.support:cardview-v7:26.1.0'
write down the scope of implementation guys
来源:https://stackoverflow.com/questions/21873472/custom-android-calendarview