在线不卡日本ⅴ一区v二区_精品一区二区中文字幕_天堂v在线视频_亚洲五月天婷婷中文网站

  • <menu id="lky3g"></menu>
  • <style id="lky3g"></style>
    <pre id="lky3g"><tt id="lky3g"></tt></pre>

    Android開發(fā)一個(gè)簡(jiǎn)單實(shí)用的鬧鈴APP

    Android開發(fā)一個(gè)簡(jiǎn)單實(shí)用的鬧鈴APP

    一個(gè)簡(jiǎn)單鬧鐘

    生活中我們會(huì)常常遇到需要鬧鐘提醒;不管是起床還是生活中的事件提醒。

    那作為Android開發(fā)如何自己開發(fā)一個(gè)鬧鐘功能呢,是不是覺得很酷呢?接下來我們就實(shí)戰(zhàn)一個(gè)鬧鐘。

    效果視頻

    鬧鐘子項(xiàng)

    子項(xiàng)布局效果圖

    鬧鐘適配器

    本示例采用的是RecyclerView,其適配器類與常無(wú)二,其異在于繼承一個(gè)代理類,為適配之后側(cè)滑刪除而準(zhǔn)備

    public class ClockAdapter extends WeSwipeProxyAdapter

    建立一個(gè)內(nèi)部類ViewHolder實(shí)現(xiàn)控件定義申明

    public ViewHolder(@NonNull View itemView) { super( itemView ); DeleteBtn = itemView.findViewById( R.id.DeleteBtn ); Hour = itemView.findViewById( R.id.Hour ); Split = itemView.findViewById( R.id.Split ); Min = itemView.findViewById( R.id.Min ); Layout = itemView.findViewById( R.id.ItemLayout ); ClockSwitch = itemView.findViewById( R.id.ClockSwitch ); }

    實(shí)現(xiàn)onCreateViewHolder方法載入子項(xiàng)布局文件

    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from( parent.getContext() ).inflate( R.layout.clock_item,parent,false ); return new ViewHolder( view ); }

    綁定實(shí)體類,實(shí)現(xiàn)onBindViewHolder獲取數(shù)據(jù)

    public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) { final ClockTime clockTime = timeList.get( position ); holder.Hour.setText( clockTime.getHour() ); holder.Split.setText( “:” ); holder.Min.setText( clockTime.getMin() ); boolean isSelect = clockTime.isSelect(); if (isSelect){ holder.ClockSwitch.setChecked( true ); }else { holder.ClockSwitch.setChecked( false ); } holder.DeleteBtn.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { DeleteItem(position); } } ); holder.ClockSwitch.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked){ SelectModel(holder,clockTime); }else { NormalModel(holder); } } } ); }

    鬧鐘初始數(shù)據(jù)

    此處有三處狀態(tài),第一種狀態(tài):第一次進(jìn)入程序,默認(rèn)加載固定鬧鐘子項(xiàng);第二種狀態(tài):進(jìn)入添加子項(xiàng)頁(yè)面,然后返回其主頁(yè)面,并判斷其switch是否為ture,如果為ture則添加子項(xiàng);第三種狀態(tài):程序被系統(tǒng)回收或者用戶停止程序,并再次進(jìn)入程序,防止加載前一時(shí)刻鬧鐘子項(xiàng);

    /** * 默認(rèn)數(shù)據(jù)*/ private void InitData(){ if (flag == START){ for (int i = 6; i < 20 ; i+=2) { ClockTime clockTime = new ClockTime( timeFormat.HandleHour( i ),timeFormat.HandleHour( i ),false ); clockTimeList.add( clockTime ); clockTime.setClockTimeList( clockTimeList ); } }else if (flag == PAUSE){ GetCallBackData(); }else { Log.d( TAG,"Restart App" ); } }

    側(cè)滑刪除鬧鐘子項(xiàng)

    添加依賴 實(shí)現(xiàn)側(cè)滑主要依賴于一個(gè)第三方包,然后使用RecyclerView進(jìn)行子項(xiàng)綁定 依賴如下:

    implementation ‘com.github.WangcWj:WeSwipe:1.0.2’ implementation ‘cn.wang.we:network:1.0.0’

    并在目錄build.gradle包下添加如下庫(kù)

    maven { url ‘https://jitpack.io’ }

    布局設(shè)置

    其實(shí)現(xiàn)側(cè)滑刪除主要的玄機(jī)在于布局文件當(dāng)中,使用RelativeLayout布局,將刪除按鈕固定在布局右方,并使用其他布局將其覆蓋,只有滑動(dòng)時(shí),才將其顯示。掩蓋側(cè)滑刪除按鈕與暴露側(cè)滑刪除按鈕效果對(duì)比圖如下

    實(shí)現(xiàn)側(cè)滑回調(diào)方法

    然后,在適配器類中,實(shí)現(xiàn)WeSwipeHelper.SwipeLayoutTypeCallBack接口,實(shí)現(xiàn)如下三個(gè)方法,第一個(gè)方法為獲取側(cè)滑刪除按鈕的寬度;第二個(gè)方法為需要滑動(dòng)的視圖,也就是覆蓋側(cè)滑刪除按鈕的布局;第三個(gè)方法為當(dāng)視圖正在滑動(dòng)時(shí),用戶觸發(fā)單擊事件,自動(dòng)還原滑動(dòng)狀態(tài)

    float getSwipeWidth();//獲取側(cè)滑刪除按鈕的寬度 View needSwipeLayout(); View onScreenView();

    綁定RecyclerView

    最后,在需要添加子項(xiàng)的視圖中綁定RecyclerView即可

    WeSwipe.attach( mRecyclerView );

    刪除子項(xiàng)

    通過監(jiān)聽子項(xiàng)滑動(dòng)刪除按鈕點(diǎn)擊事件,實(shí)現(xiàn)子項(xiàng)刪除

    holder.DeleteBtn.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { DeleteItem(position); } } ); private void DeleteItem(int position){ timeList.remove( position ); notifyDataSetChanged(); }

    新增鬧鐘子項(xiàng)

    序列化實(shí)體類

    跳轉(zhuǎn)新增鬧鐘子項(xiàng)Acticity需要傳輸實(shí)體類對(duì)象,傳輸對(duì)象一般需要序列化改類,其操作如下

    定義實(shí)體類,并實(shí)現(xiàn)序列化

    public class ClockTime implements Serializable

    然后通過Intent傳輸Bundle對(duì)象

    public void Add(View view){ flag = 1; Intent intent = new Intent( context,AddClockActivity.class ); Bundle bundle = new Bundle( ); bundle.putSerializable( “list”,(Serializable)clockTimeList ); intent.putExtras( bundle ); startActivity( intent ); }

    取出序列化實(shí)體類對(duì)象

    clockTimeList = (List) getIntent().getSerializableExtra( “list” );

    TimePicker

    實(shí)現(xiàn)時(shí)間選擇主要使用系統(tǒng)集成的組件TimePicker,其使用方法如下 其有兩種顯示方式,第一種為spinner,就是下拉滑動(dòng)式,第二種為clock,即顯示一個(gè)時(shí)鐘,通過滑動(dòng)指針選擇時(shí)間

    自定義TimePicker文字大小及顏色

    在style.xml文件中申明如下樣式

    @style/Widget.Picker.Style @color/colorWhite 15sp

    然后再指定Activcty申明即可

    獲取時(shí)間數(shù)據(jù)

    獲取數(shù)據(jù)比較簡(jiǎn)單,實(shí)現(xiàn)對(duì)應(yīng)接口即可

    timePicker.setOnTimeChangedListener( new TimePicker.OnTimeChangedListener() { @Override public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { mHour = hourOfDay; mMin = minute; } } );

    返回時(shí)間數(shù)據(jù)

    將獲取的數(shù)據(jù)通過SharedPreferences存儲(chǔ)起來,然后點(diǎn)擊存儲(chǔ)時(shí),進(jìn)行頁(yè)面跳轉(zhuǎn),然后再該界面進(jìn)行取出數(shù)據(jù)

    存儲(chǔ)數(shù)據(jù)

    sp.PutData( context, “Hour”, mHour ); sp.PutData( context, “Min”, mMin ); sp.PutData( context, “isSelect”, isSelect );

    取出數(shù)據(jù)

    首先判斷回調(diào)的switch數(shù)據(jù)是否為ture,如果為ture則保存該子項(xiàng),然后再適配器類中進(jìn)行數(shù)據(jù)添加

    boolean access = (Boolean) sp.GetData( context,”access”,false ); if (access) { int Hour = (int) sp.GetData( context, “Hour”, 0 ); int Min = (int) sp.GetData( context, “Min”, 0 ); boolean isSelect = (boolean) sp.GetData( context, “isSelect”, false ); Log.d( TAG, Hour + “firstHour” ); Log.d( TAG, Min + “firstMin” ); if (Hour == 0 || Min == 0) { Log.d( TAG, “null” ); } else { clockTime = new ClockTime( timeFormat.HandleHour( Hour ), timeFormat.HandleHour( Min ), isSelect ); adapter.AddItem( clockTime ); } }else { Log.d( TAG,”Cancel Set AlarmClock” ); }

    子項(xiàng)添加

    public void AddItem(ClockTime clockTime){ timeList.add( clockTime ); notifyDataSetChanged(); }

    自定義Switch樣式

    Switch效果如圖

    選中與默認(rèn)兩種狀態(tài)效果圖如下

    創(chuàng)建thumb和track樣式

    thumb樣式

    創(chuàng)建一個(gè)選擇器文件,有選中和默認(rèn)兩種狀態(tài)

    選中狀態(tài)

    創(chuàng)新open_thumb.xml文件

    默認(rèn)狀態(tài)

    創(chuàng)建shut_thumb.xml文件

    track樣式

    同樣創(chuàng)建一個(gè)選擇器,并用于兩種狀態(tài)

    選中狀態(tài)

    默認(rèn)狀態(tài)

    鬧鐘提醒服務(wù)

    Service

    創(chuàng)建一個(gè)服務(wù)類

    其中AlarmManager為系統(tǒng)主要操作類,參數(shù)為提醒模式、提醒時(shí)間(long型)、PendingIntent對(duì)象 以下有三種時(shí)間傳入,第一種,直接傳入一個(gè)Long型時(shí)間用于測(cè)試,第二種,通過設(shè)置系統(tǒng)啟動(dòng)至今而設(shè)置時(shí)間,第三種,通過取出設(shè)置的時(shí)間,然后獲取系統(tǒng)當(dāng)前時(shí)間,將其差傳入其中。

    public class ClockService extends Service { private Intent intent; private PendingIntent pendingIntent; private AlarmManager alarmManager; private int Hour,Min; private Calendar calendar; @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); calendar = Calendar.getInstance(); /** * 10秒,用于測(cè)試*/ long Minutes = 60*1000*60; //long triggerAtTime = SystemClock.elapsedRealtime() + Minutes; //alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pendingIntent); /** * 理論*/ Hour = intent.getIntExtra(“Hour”,0); Min = intent.getIntExtra(“Min”,0); Log.d( TAG,Hour+”ClockServiceHour” ); Log.d( TAG,Min+”ClockServiceMin” ); calendar.setTimeZone( TimeZone.getTimeZone( “GMT+8:00″ ) ); calendar.set( Calendar.HOUR_OF_DAY, Hour ); calendar.set( Calendar.MINUTE, Min ); long clockTime = calendar.getTimeInMillis(); long current = System.currentTimeMillis(); long time = clockTime – current; Log.d( TAG,clockTime+”Clock” ); Log.d( TAG,current+”Current” ); Log.d( TAG,time+”Millisecond” ); intent = new Intent(this, WarnActivity.class); pendingIntent = PendingIntent.getActivity(this, 0, intent, 0); alarmManager.set(AlarmManager.RTC_WAKEUP, time, pendingIntent); return super.onStartCommand( intent, flags, startId ); } @Override public void onDestroy() { super.onDestroy(); //alarmManager.cancel(pendingIntent); }

    然后再清單文件中注冊(cè)服務(wù)

    開始服務(wù)

    使用Intent實(shí)現(xiàn)服務(wù)啟動(dòng)

    private void StartService(){ Intent intent = new Intent( this, ClockService.class ); intent.putExtra( “Hour”,mHour ); intent.putExtra( “Min”,mMin ); startService( intent ); }

    暫停服務(wù)

    殺死程序

    public void Exit(View view){ killProcess.finishAll(); }

    單例類

    本示例總共使用到了三個(gè)單例類:SP(SharedPreferences封裝)、TimeFormat(時(shí)間數(shù)據(jù)格式封裝)、KillProcess(殺死所有Activity)

    SP封裝類

    SharedPreferences

    KillProcess封裝類

    KillProcess

    TimeFormat封裝類

    ublic class TimeFormat { private static TimeFormat timeFormat; private TimeFormat(){ } public static TimeFormat getInstance(){ if (timeFormat == null){ sync(); } return timeFormat; } private static synchronized void sync(){ if (timeFormat == null){ timeFormat = new TimeFormat(); } } public String HandleHour(int hour){ if (hour < 10){ return "0"+hour; }else { return String.valueOf( hour ); } } public String HandleWeek(int week){ String weekday = ""; switch (week){ case 1: weekday = "星期一"; break; case 2: weekday = "星期二"; break; case 3: weekday = "星期三"; break; case 4: weekday = "星期四"; break; case 5: weekday = "星期五"; break; case 6: weekday = "星期六"; break; case 7: weekday = "星期七"; break; } return weekday; }}

    文末

    文章帶這里就完成了一個(gè)簡(jiǎn)單的鬧鐘;Android開發(fā)還有許多更加更多的知識(shí)學(xué)習(xí)。進(jìn)一步學(xué)習(xí)Android技術(shù),我這里推薦這份筆記方便學(xué)習(xí),我就放在私信,發(fā)送“核心筆記”或“手冊(cè)”即可獲取。朋友們可以免費(fèi)領(lǐng)??!

    鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場(chǎng),版權(quán)歸原作者所有,如有侵權(quán)請(qǐng)聯(lián)系管理員(admin#wlmqw.com)刪除。
    上一篇 2022年6月25日 21:22
    下一篇 2022年6月25日 21:22

    相關(guān)推薦

    聯(lián)系我們

    聯(lián)系郵箱:admin#wlmqw.com
    工作時(shí)間:周一至周五,10:30-18:30,節(jié)假日休息