使用GridLayout繪製自定義日曆控件

轉載請標註:https://my.oschina.net/FlyinTang/blog/751731

效果圖

思路:就是先設置Gridlayout的行列數,而後往裏面放置必定數目的自定義日曆按鈕控件,最後實現日曆邏輯就能夠了。java

步驟:android

第一步:自定義日曆控件(初步)app

第二步:實現自定義單個日期按鈕控件ide

第三步:將第二步獲得的控件動態添加到第一步的佈局中,並實現日期邏輯佈局

第四步:編寫單個日期點擊監聽器接口this

第一步:自定義日曆控件(初步)spa

<?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" >

   <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="55dp"
            android:orientation="vertical"
            android:background="@color/lightGreen" >

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent" >

                <TextView
                    android:id="@+id/textView1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerHorizontal="true"
                    android:layout_centerVertical="true"
                    android:textColor="@color/white"
                    android:textSize="9pt"
                    android:text="2016年10月" />

                <ImageButton
                    android:id="@+id/imageButton1"
                    android:layout_width="30dp"
                    android:layout_height="20dp"
                    android:layout_alignParentLeft="true"
                    android:layout_centerVertical="true"
                    android:layout_marginLeft="16dp"
                    android:background="@drawable/back" />

                <ImageButton
                    android:id="@+id/imageButton2"
                    android:layout_width="20dp"
                    android:layout_height="20dp"
                    android:layout_alignTop="@+id/imageButton1"
                    android:layout_centerVertical="true"
                    android:layout_marginRight="16dp"
                    android:layout_toLeftOf="@+id/textView1"
                    android:background="@drawable/pre" />

                <ImageButton
                    android:id="@+id/imageButton3"
                    android:layout_width="18dp"
                    android:layout_height="18dp"
                    android:layout_centerVertical="true"
                    android:layout_alignTop="@+id/textView1"
                    android:layout_marginLeft="16dp"
                    android:layout_toRightOf="@+id/textView1"
                    android:background="@drawable/back11" />

            </RelativeLayout>

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_marginTop="10dp" >

            <GridLayout
                android:id="@+id/gridLayout01"
                android:layout_width="match_parent"
                android:layout_height="match_parent" >
            <--!自定義的單個日曆按鈕控件就放在這裏-->
            </GridLayout>

        </LinearLayout>

        <ListView
            android:id="@+id/listView1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >
        </ListView>

    </LinearLayout>

</LinearLayout>
package com.包名.myCalendarView;

import java.util.Calendar;
import java.util.Date;

import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.GridLayout;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.xuy849.utils.Info;
import com.xuy849.weightapp.R;

public class MyCalendar extends LinearLayout implements OnClickListener{
	Context context;
	TextView tv_yearAndMonth;
	ImageButton ib_pre;
	ImageButton ib_next;
	ImageButton ib_back;
	GridLayout gl_calendar;
	View view;
	CalendarButton buttons[];
	int sideLength;
	String week[] = {"日","一","二","三","四","五","六"};
	Date date;
	Calendar calendar;
	int year,month,day;
	int res;
	
	public MyCalendar(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		
		this.context = context;
		// TODO Auto-generated constructor stub
		
		init();
	}

	public MyCalendar(Context context, AttributeSet attrs) {
		super(context, attrs);
		
		this.context = context;
		// TODO Auto-generated constructor stub
		
		init();
	}

	public MyCalendar(Context context) {
		super(context);
		
		this.context = context;
		// TODO Auto-generated constructor stub
		
		init();
	}
	
	private void init(){
		this.view = LayoutInflater.from(context).inflate(R.layout.my_calendar_view, this);
		
		
	}
}

效果圖:(請無視ListView).net

第二步:自定義單個日期按鈕控件3d

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/background01"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="wrap_content"
        android:id="@+id/linearLayout01"
        android:layout_height="wrap_content"
        android:background="@color/calendarBackground"
        android:orientation="vertical" 
        android:layout_marginBottom="1dp">

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent" >

            <ImageView
                android:id="@+id/imageView1"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:visibility="invisible"
                android:src="@drawable/selected_date" />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical" 
                android:gravity="center">

                <TextView
                    android:id="@+id/textView1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textSize="8pt"
                    android:text="20" />

                <TextView
                    android:id="@+id/textView2"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="3dp"
                    android:textColor="@color/blue"
                    android:visibility="invisible"
                    android:text="65.1" />

            </LinearLayout>

        </FrameLayout>

    </LinearLayout>

</LinearLayout>
package com.包名.myCalendarView;

import java.util.Date;

import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.xuy849.utils.Info;
import com.xuy849.weightapp.R;


class CalendarButton extends LinearLayout{

	Context context;
	TextView tv_date;
	TextView tv_data;
	ImageView iv_note;
	LinearLayout ll_container;
	View view;
	Date date;
	
	public CalendarButton(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		
		this.context = context;
		// TODO Auto-generated constructor stub
		
		init();
	}

	public CalendarButton(Context context, AttributeSet attrs) {
		super(context, attrs);
		
		this.context = context;
		// TODO Auto-generated constructor stub
		
		init();
	}
	
	public void setTotalEnable(boolean b){
		this.setEnabled(b);
	}

	public CalendarButton(Context context) {
		super(context);
		
		this.context = context;
		// TODO Auto-generated constructor stub
		
		init();
		
	}
	
	public void setDate(Date date){
		this.date = date;
	}

	public Date getDate(){
		return this.date;
	}
	
	private void init(){
		view = LayoutInflater.from(context).inflate(R.layout.date_button, this);
	
		//findViewById
		tv_date =(TextView)view.findViewById(R.id.textView1);
		tv_data = (TextView)view.findViewById(R.id.textView2);
		iv_note = (ImageView)view.findViewById(R.id.imageView1);
		ll_container = (LinearLayout)view.findViewById(R.id.linearLayout01);
		
	}
	
	public void setDateText(String text){
		tv_date.setText(text);
	}
	
	public void setDateTextColor(int color){
		tv_date.setTextColor(color);
	}
	}
	
}

效果圖:code

第二步:將第二步獲得的控件在java代碼中添加到第一步的佈局中,並添加相關邏輯

package com.包名.myCalendarView;

import java.util.Calendar;
import java.util.Date;

import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.GridLayout;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.xuy849.utils.Info;
import com.xuy849.weightapp.R;

public class MyCalendar extends LinearLayout implements OnClickListener{
	Context context;
	TextView tv_yearAndMonth;
	ImageButton ib_pre;
	ImageButton ib_next;
	ImageButton ib_back;
	GridLayout gl_calendar;
	View view;
	CalendarButton buttons[];
	int sideLength;
	String week[] = {"日","一","二","三","四","五","六"};
	Date date;
	Calendar calendar;
	int year,month,day;
	int res;
	
	public MyCalendar(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		
		this.context = context;
		// TODO Auto-generated constructor stub
		
		init();
	}

	public MyCalendar(Context context, AttributeSet attrs) {
		super(context, attrs);
		
		this.context = context;
		// TODO Auto-generated constructor stub
		
		init();
	}

	public MyCalendar(Context context) {
		super(context);
		
		this.context = context;
		// TODO Auto-generated constructor stub
		
		init();
	}
	
	private void init(){
		this.view = LayoutInflater.from(context).inflate(R.layout.my_calendar_view, this);
		
		WindowManager ww = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
		sideLength = ww.getDefaultDisplay().getWidth()/Info.COLUMN_COUNT;
		
		//
		myFindViewById();
		
		//初始化日曆按鈕佈局
		initCalendarLayout();
		
		//初始化按鈕點擊事件
		initButton();
		
	}
	
	private void initButton(){
		ib_pre.setOnClickListener(this);
		ib_next.setOnClickListener(this);
		ib_back.setOnClickListener(this);
	}
	
	private void myFindViewById(){
		tv_yearAndMonth = (TextView)view.findViewById(R.id.textView1);
		ib_pre = (ImageButton)view.findViewById(R.id.imageButton2);
		ib_next = (ImageButton)view.findViewById(R.id.imageButton3);
		ib_back = (ImageButton)view.findViewById(R.id.imageButton1);
		gl_calendar =(GridLayout)view.findViewById(R.id.gridLayout01);
		
		//
		buttons = new CalendarButton[Info.COLUMN_COUNT*Info.ROW_COUNT];
	
	}
	
    //根據傳遞過來的calendar,繪製當月的日曆視圖
    private void initCalendar(Calendar calendar){
		int year = calendar.get(Calendar.YEAR);
		int month = (calendar.get(Calendar.MONTH)+1);
		int date = calendar.get(Calendar.DATE);
		
		//設置標題
		String todayStr = String.format("%04d年%02d月", calendar.get(Calendar.YEAR),(calendar.get(Calendar.MONTH)+1));
		tv_yearAndMonth.setText(todayStr);
		
		//
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		int currentMonthFirstDateInWeek = calendar.get(Calendar.DAY_OF_WEEK)-1;
		calendar.set(Calendar.DAY_OF_MONTH, date);
		int currentMonthDaysSum = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
		
		calendar.roll(Calendar.MONTH, -1);
		int lastMonthDaysSum = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
		int i;
		calendar.roll(Calendar.MONTH, 1);
		
		Log.w("月", currentMonthDaysSum+"天");
		Log.w("上月", lastMonthDaysSum +"天");
		
		/*
		 * 設置日期
		 */
		//設置本月
		Log.w("currentMonthFirstDateInWeek",currentMonthFirstDateInWeek+"");
		Log.w("currentMonthFirstDateInWeek%7111",currentMonthDaysSum+currentMonthFirstDateInWeek%7+"");
		
		for(i=currentMonthFirstDateInWeek%7+7;i<=(currentMonthDaysSum+currentMonthFirstDateInWeek%7+7-1)&&i<Info.COLUMN_COUNT*Info.ROW_COUNT;i++){
			buttons[i].changeToState(Info.STATE_NORMAL_NORECORED);
			buttons[i].setDateText((i-currentMonthFirstDateInWeek%7-7+1)+"");
			buttons[i].setDateTextColor(Color.BLACK);
			buttons[i].setEnabled(true);
			buttons[i].setDate(new Date(year,month,i-(currentMonthFirstDateInWeek%7+7)+1));
		}
		
		//設置上一個月
		for(i=7;i<(currentMonthFirstDateInWeek%7+7)&&i<Info.COLUMN_COUNT*Info.ROW_COUNT;i++){
			buttons[i].changeToState(Info.STATE_NORMAL_NORECORED);
			buttons[i].setDateTextColor(Color.GRAY);
			buttons[i].setDateText(lastMonthDaysSum-(currentMonthFirstDateInWeek%7-i%7)+1+"");
			buttons[i].setEnabled(false);
		}
		
		//設置下一個月
		for(i =currentMonthDaysSum+currentMonthFirstDateInWeek%7+7;i<Info.ROW_COUNT*Info.COLUMN_COUNT;i++){
			buttons[i].changeToState(Info.STATE_NORMAL_NORECORED);
			buttons[i].setDateTextColor(Color.GRAY);
			buttons[i].setDateText((i-(currentMonthDaysSum+currentMonthFirstDateInWeek%7+7)+1)+"");
			buttons[i].setEnabled(false);
		}
		
		//設置當天
		if(year==this.year&&month==this.month&&day==this.day)
			buttons[date+currentMonthFirstDateInWeek%7+7-1].changeToState(Info.STATE_TODAY_NORECORED);
		
		//初始化界面
		if(res!=0)
			initLayout(res);
	
	}
		
	
	private void initCalendarLayout(){
		//設置行數,列數
		gl_calendar.setRowCount(Info.ROW_COUNT);
		gl_calendar.setColumnCount(Info.COLUMN_COUNT);
		
		
		/*
		 * 添加按鈕到佈局
		 */
		int i;
		int sum = Info.ROW_COUNT*Info.COLUMN_COUNT;
		
		//設置星期
		for(i=0;i<Info.COLUMN_COUNT;i++){
			buttons[i] = new CalendarButton(context);
			buttons[i].setDateText(week[i]);
			buttons[i].setLayoutParams(new LayoutParams(sideLength, sideLength));
			gl_calendar.addView(buttons[i], i);
			buttons[i].setEnabled(false);
		}
		
		for(i = Info.COLUMN_COUNT;i<sum;i++){
			buttons[i] = new CalendarButton(context);
			buttons[i].setDateText("55");
			buttons[i].setLayoutParams(new LayoutParams(sideLength, sideLength));
			gl_calendar.addView(buttons[i], i);
		}
		
		
		//根據當月設置狀況
		calendar = Calendar.getInstance();
		year = calendar.get(Calendar.YEAR);
		month = calendar.get(Calendar.MONTH)+1;
		day = calendar.get(Calendar.DATE);
		initCalendar(calendar);
		
		
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch(v.getId()){
		
		//上一個月
		case R.id.imageButton2:{
			calendar.roll(Calendar.MONTH, -1);
			initCalendar(calendar);
			break;
		}
		
		//下一個月
		case R.id.imageButton3:{
			calendar.roll(Calendar.MONTH, 1);
			initCalendar(calendar);
			break;
		}
		}
	}
	
	public void setOnClickButtonListener(OnClickListener l,int index){		
		buttons[index].setOnClickListener(l);
	}
	
	public Date getDate(int index){
		return buttons[index].getDate();
	}
	
	public void setData(float f,int index){
		buttons[index].tv_data.setText(String.format("%.1f", f));
		buttons[index].tv_data.setVisibility(TextView.VISIBLE);
	}
	
	public void initLayout(int res){
		switch(res){
		case Info.VIEW_WEIHT:{
			
			
			break;
		}
		
		default:{
			break;
		}
		}
	}
	
	public void setRes(int res){
		this.res = res;
	}
}

第四步:編寫單個日期點擊監聽器接口

在第三步中添加方法:

//設置下標是index的日期按鈕的點擊事件監聽器
public void setOnClickButtonListener(OnClickListener l,int index){		
		buttons[index].setOnClickListener(l);
	}
相關文章
相關標籤/搜索