Android使用GridView寫日歷

1.思路:

日歷內容我用了一個GridView裝多搀,實現(xiàn)的界面效果如下:

image.png

1.1分析:

1.1.1. 界面內容從上到下依次為:顯示當前頁面展示的年月;跳轉到上一個月或者下一個月的按鈕囊陡;周期標題頭纵竖;數(shù)據(jù)內容(即當前展示的月份所有日期,以及上一個月和下一個月的幾個日期)讳嘱。
1.1.2. 數(shù)據(jù)內容部分我使用了一個GridView來實現(xiàn)闯袒,其余部分均為ButtonTextView虎敦,因此最重要部分就是實現(xiàn)數(shù)據(jù)部分。
1.1.3. 數(shù)據(jù)內容部分分為三大塊:1.上一個月的最后幾天政敢,2.本月的所有日期其徙,3.下一個月的前幾天。
1.1.4. 獲得這三大塊的數(shù)據(jù)喷户,然后渲染在GridView上唾那。
1.1.5. 將獲得數(shù)據(jù)然后渲染在頁面上寫成一個方法,將當前年月的日期作為參數(shù)傳進去褪尝,實現(xiàn)點擊上一個月或下一個月按跳轉日期頁面闹获。

2.步驟詳情:

2.1.步驟一:

創(chuàng)建布局文件。
以下是布局文件的代碼:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    tools:context=".calendar.Calendar2Activity">

    <!--顯示當前展示的年月-->
    <TextView
        android:id="@+id/calendar_date"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="2020-10-1"/>
    <!--跳轉到上一個月或者下一個月的按鈕-->
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:id="@+id/calendar_last"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="上一個月"/>
        <Button
            android:id="@+id/calendar_next"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:text="下一個月"/>
    </LinearLayout>
    <!--周一到周日的標題-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <TextView
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="周一"
            android:background="@drawable/bg_white_black_border_yuanjiao"/>
        <TextView
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="周二"
            android:background="@drawable/bg_white_black_border_yuanjiao"/>
        <TextView
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="周三"
            android:background="@drawable/bg_white_black_border_yuanjiao"/>
        <TextView
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="周四"
            android:background="@drawable/bg_white_black_border_yuanjiao"/>
        <TextView
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="周五"
            android:background="@drawable/bg_white_black_border_yuanjiao"/>
        <TextView
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="周六"
            android:background="@drawable/bg_white_black_border_yuanjiao"/>
        <TextView
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="周日"
            android:background="@drawable/bg_white_black_border_yuanjiao"/>
    </LinearLayout>
    <!--日歷內容-->
    <GridView
        android:id="@+id/calendar_gridview"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:numColumns="7"/>

</LinearLayout>

預覽界面如下:


image.png

2.2.步驟二:

獲得數(shù)據(jù)并將其渲染到GridView上河哑。
數(shù)據(jù)分為下圖標出的三部分:

image.png

藍色部分為當前顯示年月的一個月的所有日期避诽,因此,我們需要獲取當前顯示的月份有多少天璃谨。代碼如下:

Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR,year);
        calendar.set(Calendar.MONTH,month-1);
        calendar.set(Calendar.DATE,1);//把日期設置為當月第一天
        calendar.roll(Calendar.DATE,-1);//日期回滾一天沙庐,也就最后一天
        int date = calendar.get(Calendar.DATE);

紅色部分為上一個月的最后幾天鲤妥,因此,我們需要得到上一個月的最后一天是幾號拱雏,也就是上一個月的總天數(shù)(因為每個月的第一天都是1號棉安,所以每個月的最后一天的號數(shù)就等于這個月的總天數(shù)),因此我將上面的求某個月份的天數(shù)的代碼寫成了一個方法铸抑,如下:

    //獲取輸入月份的總天數(shù)
    private int getMonthNum(int year,int month){
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR,year);
        calendar.set(Calendar.MONTH,month-1);
        calendar.set(Calendar.DATE,1);//把日期設置為當月第一天
        calendar.roll(Calendar.DATE,-1);//日期回滾一天贡耽,也就最后一天
        return calendar.get(Calendar.DATE);
    }

先將紅色和藍色部分的數(shù)據(jù)放好,最后剩余幾個格子就從1開始依次遞增放入鹊汛。
注意:當前月份1號是星期天蒲赂,且這個月有30天或31天的天數(shù)則總共GridView有6行,即總共有42個格子柒昏,(例如2020年11月)凳宙。
在這里你可以直接將所有的月份的格子都規(guī)定成42個熙揍,也可以在當前月份的最后一天超出35個格子(即5行)的時候換成42個格子职祷。在這里我就讓它在超出35個格子的時候再換成42個格子。
這里我們要抓住零界點届囚,也就是上一個月的最后一天到本月第一天和本月最后一天到下一個月的第一天有梆。
由于我寫的周期是從周一到周日,因此要先獲取本月的第一天是周幾意系,就能獲得本月第一天的下標位置泥耀。獲得當天是周幾的代碼如下(同樣我將它寫成了一個方法,方便多次使用)蛔添,上一個月的總天數(shù)用變量lastdates表示痰催,本月總天數(shù)用變量dates表示:

private int getWeek(String date){
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        try {
            calendar.setTime(format.parse(date));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        //1:周日,7:周六
        return calendar.get(Calendar.DAY_OF_WEEK);
    }

getWeek()方法返回的的周期數(shù)為:1迎瞧,2夸溶,3,4凶硅,5缝裁,6,7足绅,分別對應:周日捷绑,周一,周二氢妈,周三粹污,周四,周五首量,周六壮吩;
但是我們需要讓它的對應關系為:1,2,...粥航,7琅捏,分別對應:周一,周二递雀,...柄延,周日。因此我們需要對獲得到的周期數(shù)進行處理缀程,代碼如下:

//獲取當前月份1號是周幾
        int week = getweek(today);
        if (week == 1) {
            week = 7;//周日
        } else week = week - 1;

接下來就是重點了:獲得三個部分的數(shù)據(jù)集合搜吧,直接放代碼:

        int num = week+dates-1;//當下標從1開始,num為輸入月份的最后一個值的下標
        if (num > 35){
            gridview_size = 42;
        }else gridview_size = 35;
        int j = 1, a = 1; //當前月份的各個日期以及下一個月的日期
        int last = lastdates - (week - 2);//第一個單元格的值
        for (int i = 1; i <= gridview_size; i++) {
            if (i < week) {//上月剩余
                dataList.add(last);
                last++;
            } else if (i <= num) {
                dataList.add(j);//本月
                j++;
            } else {
                dataList.add(a);//下月
                a++;
            }
        }

dataList為放三個部分的數(shù)據(jù)的整數(shù)型集合杨凑,即:
List<Integer> dataList = new ArrayList<>();
我將下標從1開始
int num = week+dates-1,num為本月最后一天的下標滤奈,等于周期數(shù)(第一天的下標)+本月總天數(shù)-1
int last = lastdates - (week - 2);last為第一個格子的值,lastdates為上一個月的最后一天的號數(shù)撩满,用最后一天的號數(shù)減去最后一天所在格子的前面的總格子數(shù)(最后一天的格子不算在內)蜒程,就等于第一個格子內的值,比如數(shù)據(jù):__伺帘,23昭躺,24,25伪嫁,26领炫;26數(shù)字前面有4個數(shù),所以:26-4=22张咳,所得的22就是橫線處的值帝洪。

2.3.步驟三:

將獲得的dataList渲染到GridView上。

3.所有代碼(代碼分為兩部分:布局文件代碼和Java代碼):

1.布局文件的代碼如上述的布局代碼脚猾。
2.Java代碼部分如下:

public class CalendarActivity extends AppCompatActivity implements View.OnClickListener {

    private Button calendar_last;
    private Button calendar_next;
    private GridView calendar_gridview;
    private List<Integer> dataList = new ArrayList<>();
    private String today;
    private TextView calendar_date;
    private int week,dates;
    private MyAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_calendar);
        initView();
        //獲取當前月份
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");
        Date date = new Date(System.currentTimeMillis());
        today = simpleDateFormat.format(date);
        getData(today);
    }

    private void getData(String today) {
        calendar_date.setText(today);
        today = today + "-01";
        String years = today.split("-")[0];
        String months = today.split("-")[1];
        Log.i("日歷", months);
        //獲取當前月份日期數(shù)
        dates = getmoth(Integer.parseInt(years), Integer.parseInt(months));
        //獲取當前月份1號是周幾
        week = getweek(today);
        if (week == 1) {
            week = 7;//周日
        } else week = week - 1;

        //獲取上一個月份的天數(shù)
        int lastdates;
        if (Integer.parseInt(months) == 1) {
            lastdates = getmoth(Integer.parseInt(years) - 1, 12);
        } else {
            lastdates = getmoth(Integer.parseInt(years), Integer.parseInt(months) - 1);
        }

        //獲取當前展示的日歷界面的數(shù)據(jù)
        int num = week+dates-1;//當下標從1開始葱峡,num為輸入月份的最后一個值的下標
        int gridview_size;
        if (num > 35){
            gridview_size = 42;
        }else gridview_size = 35;

        int j = 1, a = 1; //當前月份的各個日期以及下一個月的日期
        int last = lastdates - (week - 2);//第一個單元格的值
        for (int i = 1; i <= gridview_size; i++) {
            if (i < week) {//上月剩余
                dataList.add(last);
                last++;
            } else if (i <= num) {
                dataList.add(j);//本月
                j++;
            } else {
                dataList.add(a);//下月
                a++;
            }
        }
        //渲染數(shù)據(jù)
        if (adapter == null){
            adapter = new MyAdapter(CalendarActivity.this, dataList);
            calendar_gridview.setAdapter(adapter);
        }else adapter.notifyDataSetChanged();
    }

    private int getmoth(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month - 1);
        calendar.set(Calendar.DATE, 1);
        calendar.roll(Calendar.DATE, -1);
        int date = calendar.get(Calendar.DATE);
        return date;
    }

    private int getweek(String date) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        try {
            calendar.setTime(simpleDateFormat.parse(date));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        //1:周日,7:周六
        return calendar.get(Calendar.DAY_OF_WEEK);
    }

    private void initView() {
        calendar_last = (Button) findViewById(R.id.calendar_last);
        calendar_next = (Button) findViewById(R.id.calendar_next);
        calendar_gridview = (GridView) findViewById(R.id.calendar_gridview);

        calendar_last.setOnClickListener(this);
        calendar_next.setOnClickListener(this);
        calendar_date = (TextView) findViewById(R.id.calendar_date);
        calendar_date.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.calendar_last:
                //上一個月按鈕的點擊事件
                dataList.clear();
                int years = Integer.parseInt(today.split("-")[0]);
                int months = Integer.parseInt(today.split("-")[1]);
                if (months == 1) {
                    months = 12;
                    years = years - 1;
                    getData(years + "-" + months);
                    today = years + "-" + months;
                } else {
                    months = months - 1;
                    getData(years + "-" + months);
                    today = years + "-" + months;
                }
                break;
            case R.id.calendar_next:
                //下一個月按鈕的點擊事件
                dataList.clear();
                int years1 = Integer.parseInt(today.split("-")[0]);
                int months1 = Integer.parseInt(today.split("-")[1]);
                if (months1 == 12) {
                    months1 = 1;
                    years1 = years1 + 1;
                    getData(years1 + "-" + months1);
                    today = years1 + "-" + months1;
                } else {
                    months1 = months1 + 1;
                    getData(years1 + "-" + months1);
                    today = years1 + "-" + months1;
                }
                break;
        }
    }

    class MyAdapter extends BaseAdapter {
        private Context context;
        private List<Integer> list;

        public MyAdapter(Context context, List<Integer> list) {
            this.context = context;
            this.list = list;
        }

        @Override
        public int getCount() {
            return list.size();
        }

        @Override
        public Object getItem(int position) {
            return list.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = LayoutInflater.from(context).inflate(R.layout.calendar_gridview_item, null, false);
            }
            final TextView textView = (TextView) convertView.findViewById(R.id.calendar_gridview_item_tv);
            textView.setText(list.get(position) + "");

            //設置本月的日期高亮顯示婚陪,非本月的日期灰色顯示
            if (position >= week-1 && position < week+dates-1){//判斷是當月的日期
                textView.setTextColor(Color.BLACK);//黑色
            }else textView.setTextColor(Color.GRAY);//灰色

            return convertView;
        }
    }
}

友情鏈接(都是寫日歷的內容):https://nowtime.cc/android/1115.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末族沃,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子泌参,更是在濱河造成了極大的恐慌脆淹,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沽一,死亡現(xiàn)場離奇詭異盖溺,居然都是意外死亡,警方通過查閱死者的電腦和手機铣缠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門烘嘱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來昆禽,“玉大人,你說我怎么就攤上這事蝇庭∽肀睿” “怎么了?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵哮内,是天一觀的道長盗棵。 經(jīng)常有香客問我,道長北发,這世上最難降的妖魔是什么纹因? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮琳拨,結果婚禮上瞭恰,老公的妹妹穿的比我還像新娘。我一直安慰自己狱庇,他們只是感情好惊畏,可當我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著僵井,像睡著了一般陕截。 火紅的嫁衣襯著肌膚如雪驳棱。 梳的紋絲不亂的頭發(fā)上批什,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天,我揣著相機與錄音社搅,去河邊找鬼驻债。 笑死,一個胖子當著我的面吹牛形葬,可吹牛的內容都是我干的合呐。 我是一名探鬼主播,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼笙以,長吁一口氣:“原來是場噩夢啊……” “哼淌实!你這毒婦竟也來了?” 一聲冷哼從身側響起猖腕,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤拆祈,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后倘感,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體放坏,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年老玛,在試婚紗的時候發(fā)現(xiàn)自己被綠了淤年。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钧敞。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖麸粮,靈堂內的尸體忽然破棺而出溉苛,到底是詐尸還是另有隱情,我是刑警寧澤弄诲,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布炊昆,位于F島的核電站,受9級特大地震影響威根,放射性物質發(fā)生泄漏凤巨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一洛搀、第九天 我趴在偏房一處隱蔽的房頂上張望敢茁。 院中可真熱鬧,春花似錦留美、人聲如沸彰檬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽逢倍。三九已至,卻和暖如春景图,著一層夾襖步出監(jiān)牢的瞬間较雕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工挚币, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留亮蒋,地道東北人。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓妆毕,卻偏偏與公主長得像慎玖,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子笛粘,可洞房花燭夜當晚...
    茶點故事閱讀 45,851評論 2 361