<html> <head> <title>checkbox lab</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script> <script> // chkAll 點擊事件 function checkAll() { var isChecked = $('#chkAll').prop('checked'); // 更新所有 nameCheckbox 的狀態 $('.nameCheckbox').prop('checked', isChecked).trigger('change'); } // 更新 chkAll 狀態 function updateChkAll() { var totalCheckboxes = $('.nameCheckbox').length; var checkedCheckboxes = $('.nameCheckbox:checked').length; var $chkAll = $('#chkAll'); if (checkedCheckboxes === 0) { // 全部未選中 $chkAll.prop('checked', false); $chkAll.removeClass('partial'); } else if (checkedCheckboxes === totalCheckboxes) { // 全部選中 $chkAll.prop('checked', true); $chkAll.removeClass('partial'); } else { // 部分選中 $chkAll.prop('checked', false); // 關鍵修改:部分選中時保持 checked 但變灰色 $chkAll.prop('checked', true).addClass('partial'); } } </script> <style type="text/css"> #chkAll { margin-bottom: 10px; font-size: 10px; } /* 部分選中時的灰色打勾 */ #chkAll.partial { accent-color: gray; /* 現代瀏覽器 */ filter: grayscale(50%) opacity(80%); /* 舊瀏覽器備用 */ } </style> </head> <body> <center> <form name="frmInput" id="frmInput" method="post" action="func.php"> <input type="hidden" name="act" value="input" /> <table border="1"> <tr> <th nowrap="nowrap"><input type="checkbox" id="chkAll" onchange="checkAll()" />全選</th> <th nowrap="nowrap">姓名</th> </tr> <tr> <td><input type="checkbox" class="nameCheckbox" id="chk1" onchange="updateChkAll()" /></td> <td>張三</td> </tr> <tr> <td><input type="checkbox" class="nameCheckbox" id="chk2" onchange="updateChkAll()" /></td> <td>李四</td> </tr> <tr> <td><input type="checkbox" class="nameCheckbox" id="chk3" onchange="updateChkAll()" /></td> <td>王五</td> </tr> </table> </form> </center> </body> </html>
老灰鴨的筆記本
2025-06-08
【jQuery】jQuery + CSS 多個 checkbox 勾選
2025-02-16
【PHP】以 Telegram bot 取代 LINE notify
* 先準備 2 支手機(在本筆記,2 支手機都是 Android),telegram 沒法建立一人群組(應該說我沒試成功)
* 2 支手機都安裝 telegram,並建立一個群組
* 在尋找聯絡人輸入 @botfather,找到後,將 botfather 加入聯絡人
* 進入 botfather 的聊天室,會看到 botfather 的招呼語【What can this bot do?】
* 輸入【/start】,botfather 會列出一堆跟 bot 有關的指令
* 輸入【/newbot】
* botfather 會請您為您的 bot 取名字,因為後續的互動會是 json 格式,所以建議這次先以英文命名,較容易在 json 字串中辨識、找到。
* 接下來,botfather 請您設定您的 bot 的 id,bot 的 id 必須以 【bot】結尾,ex:TetrisBot 或 tetris_bot,這個 id 必須是在 telegram 唯一的,所以若您設定的名字已經有別人先用了,botfather 會請您改名字。
* 建立您的 bot 後,可輸入【/help】進一步了解
* 輸入【/mybots】,會得到您的 bot 的 token,格式是 【一串數字:大小寫英數字混合字串】很重要!請好好保存。
* 將 bot 加入群組
→ 由群組中的任一人發送一個訊息到群組
→ 點擊標題欄,可以看到這個群組的成員,並且下方有個標題為【Links】的區塊,點擊第一個連結(最後面以 【/getUpdates】結尾),就會看到一段 json 字串,將這段 json 字串複製出來,並尋找其中
... ... "chat":{"id":-0123456789, "title":"mytest", "type":"group", "all_members_are_administrators":false } ... ...這個就是群組的 id,通常是負數,type 是 group
<?php date_default_timezone_set('Asia/Taipei'); $sToken = "0123456789:AAG9Sxwv3zc9YblablablaiBBJ3ZOUO4lFY"; // bot 的 token $sGroupId = "-9876543210"; // 群組 id // 訊息內容 $sMsg = "Hello, this is oldgrayduck's telegram Bot test, ".date('Y-m-d H:i:s'); $url = "https://api.telegram.org/bot$sToken/sendMessage"; $data = [ 'chat_id' => $sGroupId, 'text' => $sMsg ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = curl_exec($ch); curl_close($ch); // 顯示回應 echo $result; ?>
群組就會收到訊息了。
2024-12-30
【LINE Messaging API】主動傳送訊息(推播) 給多位使用者
<php? date_default_timezone_set('Asia/Taipei'); $sRootDir = $_SERVER['DOCUMENT_ROOT']; $channelAccessToken = '您的 channel Access Token'; $bodyMsg = file_get_contents('php://input'); // LINE 不會幫我們記錄, 所以要自己寫 log // 這段不是必要, 只是方便自己除錯 $sLogfile = 'log_'.date('Ymd').'.log'; // 指定 log 檔名, 一天一個檔, 檔名格式為: log_yyyymmdd.log $fp = fopen($sLogfile, "a+"); fwrite($fp , print_r(date('Y-m-d H:i:s').', Recive: '.$bodyMsg."\n", true)); fclose($fp); ... ... // 取得 user id, 管道有很多, 此處不贅述 $arrUserId = ['...','...', ...]; ← 要推播的目標 UserId 存入陣列 $payload = [ 'to' => $arrUserId, 'messages' => [ ['type' => 'text', 'text' => '恭喜! 您中了特獎!', ] ] ]; SendMsg($payload); // 傳送訊息給指定使用者 function SendMsg($payload) { $ch = curl_init(); // curl_setopt($ch, CURLOPT_URL, 'https://api.line.me/v2/bot/message/push'); curl_setopt($ch, CURLOPT_URL, 'https://api.line.me/v2/bot/message/multicast'); ← 注意這裡要改成 multicast curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload)); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'Authorization: Bearer ' . $GLOBALS['channelAccessToken'] ]); $result = curl_exec($ch); curl_close($ch); // 寫 log $sLogfile = 'log_'.date('Ymd').'.log'; $fp = fopen($sLogfile, "a+"); fwrite($fp , print_r(date('Y-m-d H:i:s').', send message result: '.$result."\n", true)); fclose($fp); } ?>
2024-08-28
【Kotlin】隨機取出指定筆數的記錄
題目:
有一含 1000 筆記錄的資料表 table1,要從中取出任意 100 筆
在詢問 Google 的 Gemini、OpenAI 的 ChatGPT、Perplexity 的 Perplexity、微軟的 Copilot 後,多認識了一些類別及技巧,故做此筆記。
做法一:
val mScope = CoroutineScope(Job() + Dispatchers.IO) mScope.launch { val mDbHelper = SQLite(baseContext) var db = mDbHelper.readableDatabase // 查詢本機資料庫有幾筆記錄 var sSql = "SELECT * FROM table1 " val rs = db.rawQuery(sSql, null) val mRecnt = rs.count // 本機資料庫記錄筆數 var mSentence = 100 // 迴圈數, 要取出 100 筆記錄 val mList = mutableListOf<Int>() var xx = 1 // 這種做法, 有可能亂數取得的 mPos 已存在 mList 中 while(xx<=mSentence) { val mPos = (0 until mRecnt).random() // 每筆記錄在 table1 的位置 if(mPos !in mList) { mList.add(mPos) xx++ } } mList.sorted() // 將 mList 內的元素由小到大排序 // 如此, 在實際自 table1 取出記錄就會是自資料表首一路向資料表尾依序取出記錄 ... ... }
做法二:
val mScope = CoroutineScope(Job() + Dispatchers.IO) mScope.launch { ... ... val mRaw = mutableSetOf<Int>() // mutableSet 的特性是存入時就會檢查每個元素的值都是唯一 val mRandom = Random(System.currentTimeMillis()) while(mRaw.size<mSentence) { mRaw.add(mRandom.nextInt(mRecnt)) } // 但 mutableSet 不具排序功能, // 故將它轉型態成 list 並排序後存入 mList val mList = mRaw.toList().sorted() ... ... }
做法三:
val mScope = CoroutineScope(Job() + Dispatchers.IO) mScope.launch { ... ... // 這個做法最快, 一行指令搞定 // 以 shuffled() 洗牌後, 再以 take() 取前面幾個元素, 再將元素排序 // (0 until mRecnt) 是 IntRange val mList = (0 until mRecnt).shuffled().take(mSentence).sorted() // val mList = (0 until mRecnt).shuffled(Random(System.currentTimeMillis())).take(mSentence).sorted() // 可以在 shuffled() 內加上時間當做亂數種子, 增強其隨機性 ... ... }
2024-07-13
【網頁程式】土砲打造 -- 依數個地點距離由近至遠規劃行程導航
<?php date_default_timezone_set('Asia/Taipei'); // 用來查詢地址的經、緯度 class GMap { function getPageData($url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect: ')); curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_NOBODY, false); curl_setopt($ch, CURLOPT_FILETIME, true); curl_setopt($ch, CURLOPT_REFERER, $url); curl_setopt($ch, CURLOPT_BINARYTRANSFER, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 4); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($ch, CURLOPT_TIMEOUT, 10); curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)"); $result['data'] = curl_exec($ch); curl_close($ch); return $result; } // 初始化 apikey 金鑰 function __construct() { $this->apikey = '向 Google map 申請 apikey'; } // 從 google map 取得地址經緯度 public function getLngLat($addr='',$sDebug='') { $apikey = $this->apikey; $url = "https://maps.googleapis.com/maps/api/geocode/json?address=$addr&key=$apikey"; $geocode = $this->getPageData($url); if($sDebug=='debug') var_dump($geocode); if(isset($geocode['data'])) { if(!$geocode["data"]) // 當 Google map 解析不了時,回應 經/緯度值都是 -1 的虛擬經緯度 $geocode = '{"results":[{"geometry":{"location":{"lat":-1,"lng":-1}}}]}'; else $geocode = $geocode['data']; } else // 當 Google map 解析不了時,回應 經/緯度值都是 -1 的虛擬經緯度 $geocode = '{"results":[{"geometry":{"location":{"lat":-1,"lng":-1}}}]}'; $output = json_decode($geocode); $latitude = $output->results[0]->geometry->location->lat; $longitude = $output->results[0]->geometry->location->lng; return array('lat'=>$latitude,'lng'=>$longitude); } } ?>
<?php // 切換至 https if (empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] === "off") { $location = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; header('HTTP/1.1 301 Moved Permanently'); header('Location: ' . $location); exit; } include('gmap.php'); class MyDest { public $addr; public $len = 0; public $lng = -1; public $lat = -1; function __construct($aa) { $this->addr = $aa; } } if(isset($_GET['lat'])) { // 接收到起點 經/緯 度 // $sLat = 22.612058525444247; // 測試用 // $sLng = 120.3142669919977; // 測試用 $sLat = $_GET['lat']; $sLng = $_GET['lng']; $aDest = array(); // 存放上傳的目的地 $aSort = array(); // 排序後的目的地 $gmap = new GMap(); if(isset($_GET['dest1'])) { $obj = new MyDest($_GET['dest1']); $fLngLat = $gmap->getLngLat($obj->addr); // 上車地點經緯度 $obj->lat = $fLngLat["lat"]; // 緯度 $obj->lng = $fLngLat["lng"]; // 經度 array_push($aDest, $obj); } if(isset($_GET['dest2'])) { $obj = new MyDest($_GET['dest2']); $fLngLat = $gmap->getLngLat($obj->addr); // 上車地點經緯度 $obj->lat = $fLngLat["lat"]; // 緯度 $obj->lng = $fLngLat["lng"]; // 經度 array_push($aDest, $obj); } if(isset($_GET['dest3'])) { $obj = new MyDest($_GET['dest3']); $fLngLat = $gmap->getLngLat($obj->addr); // 上車地點經緯度 $obj->lat = $fLngLat["lat"]; // 緯度 $obj->lng = $fLngLat["lng"]; // 經度 array_push($aDest, $obj); } if(isset($_GET['dest4'])) { $obj = new MyDest($_GET['dest4']); $fLngLat = $gmap->getLngLat($obj->addr); // 上車地點經緯度 $obj->lat = $fLngLat["lat"]; // 緯度 $obj->lng = $fLngLat["lng"]; // 經度 array_push($aDest, $obj); } if(isset($_GET['dest5'])) { $obj = new MyDest($_GET['dest5']); $fLngLat = $gmap->getLngLat($obj->addr); // 上車地點經緯度 $obj->lat = $fLngLat["lat"]; // 緯度 $obj->lng = $fLngLat["lng"]; // 經度 array_push($aDest, $obj); } while(count($aDest)>0) { foreach($aDest as &$val) { // 注意:$val 前面有 & // 計算【各目的地】距離【起點】的長度 $url = "https://maps.googleapis.com/maps/api/directions/json?origin=$sLat,$sLng&destination=".urlencode($val->addr)."&key=$apiKey"; // 目的地 destination 參數也可以是經緯度 $url = "https://maps.googleapis.com/maps/api/directions/json?origin=$sLat,$sLng&destination=".urlencode($val->lat).",".urlencode($val->lng)."&key=$apiKey"; // 若希望路線避開上高速公路, 則可加 avoid=highways 參數 $url = "https://maps.googleapis.com/maps/api/directions/json?origin=$sLat,$sLng&destination=".urlencode($val->addr)."&avoid=highways&key=$apiKey"; // 此外, 還可避開 ---- // tolls:避開收費路段 // highways:避開高速公路 // ferries:避開渡輪 // indoor:避開室內路線(主要用於步行路線) // 初始化 cURL $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $response = curl_exec($ch); curl_close($ch); // 解析 json 響應 $data = json_decode($response, true); if ($data['status']=='OK') { $val->len = $data['routes'][0]['legs'][0]['distance']['value']; } else { $val->len = -1; } unset($val); } // 使用 usort 函數排序陣列,根據 $a 屬性值從小到大排序 usort($aDest, function($a, $b) { return $a->len <=> $b->len; }); // 排序後的第一個物件就是 距離最短的地址 $minObj = $aDest[0]; // print_r($aDest); array_push($aSort, ['addr' => ($minObj->addr)]); // 這個地址做為起點 $sLat = $minObj->lat; $sLng = $minObj->lng; array_splice($aDest, 0, 1); } echo json_encode($aSort); // 回傳依距離排序後的停靠點及目的地 } ?>
<?php // 切換至 https if(empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] === "off") { $location = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; header('HTTP/1.1 301 Moved Permanently'); header('Location: ' . $location); exit; } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html style="height:100%;"> <head> <meta charset="utf-8"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script> </head> <body> <br /> <button onclick="startNavigation()" style="font-size:40pt;">巡航</button><br /> <span style="font-size:40pt;">提醒:在 Android Chrome 開啟本網頁</span><br /> <br /> <br /> <script> function startNavigation() { var aRoute = [ "高雄市苓雅區四維三路2號", "高雄市前鎮區中華五路789號", "高雄市鼓山區濱海二路1號", "高雄市左營區博愛二路777號", "高雄市左營區高鐵路107號" ]; if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(function(position) { var latitude = position.coords.latitude; // 緯度 var longitude = position.coords.longitude; // 經度 var str = "https://您自己的網址/getroute.php?lat="+latitude+"&lng="+longitude+"&dest1="+aRoute[0]+"&dest2="+aRoute[1]+"&dest3="+aRoute[2]+"&dest4="+aRoute[3]+"&dest5="+aRoute[4]; // alert('str = '+str); // return; var destinations = new Array(); $.getJSON(str, function(res) { // alert("res = "+res); // 這段是從 client 端向 server 請求查詢 // server 回傳 json 型態的陣列 // 陣列內的元素是 addr res.forEach(function(element) { destinations.push(element.addr); }); var waypoints = destinations.map(function(destination) { // Google map 規定停靠點以【|】字元分隔 // 將 5 個地點以【|】字元分隔 return encodeURIComponent(destination); }).join("|"); destination = waypoints.split('|').pop(); // 取得最後【|】右邊的字串做為目的地 waypoints = waypoints.slice(0, waypoints.lastIndexOf('|')); // 取得最後【|】的左邊字串做為停靠點 // 構建導航 URL var mapsURL = "https://www.google.com/maps/dir/?api=1&origin=" + latitude + "," + longitude + "&destination=" + destination + "&waypoints=" + waypoints + "&travelmode=driving"; // alert(mapsURL); // return; // 跳轉到 Google Maps window.location.href = mapsURL; }); // return; }, function(error) { alert("無法取得地理位置: " + error.message); } ); } else { alert("瀏覽器不支援地理定位功能。"); } } </script> <br /> <br /> </body> </html>
2024-07-10
【MySQL】國定假日應用
-- csv 最前面補加 西元年度欄位 -- 將 csv 上傳存入 holiday_tmp -- holiday 和 holiday_tmp 差別只在 holiday 有 autoincrement 的 primary key -- 刪除平日, 只留假日 DELETE FROM holiday_tmp WHERE 休假=0 -- 存入 holiday INSERT INTO holiday (年度,日期,星期,休假,備註) SELECT * FROM holiday_tmp -- 清空 holiday_tmp DELETE FROM holiday_tmp
2024-06-13
【SQLite】以預設值新增一筆記錄
當 CREATE TABLE 的欄位定義有預設值,或無預設值(NULL) 且未限制 NOT NULL 時,可使用下面指令。
INSERT INTO 資料表名 DEFAULT VALUES;
2024-06-05
【Android】RelativeLayout 對齊螢幕中垂線
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:ads="http://schemas.android.com/apk/res-auto" tools:context=".MainActivity"> ... ... <TextView android:id="@+id/TextView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_centerVertical="true" android:text="中心對齊" /> </RelativeLayout>
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:ads="http://schemas.android.com/apk/res-auto" tools:context=".MainActivity"> ... ... <!-- 看不見的中垂線 --> <View android:id="@+id/vCenterVertical" android:layout_width="0dp" android:layout_height="match_parent" android:layout_centerInParent="true" /> <TextView android:id="@+id/TextView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toEndOf="@id/vCenterVertical" android:text="左邊對齊中垂線" /> </RelativeLayout>
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:ads="http://schemas.android.com/apk/res-auto" tools:context=".MainActivity"> ... ... <!-- 看不見的中垂線 --> <View android:id="@+id/vCenterVertical" android:layout_width="0dp" android:layout_height="match_parent" android:layout_centerInParent="true" /> <TextView android:id="@+id/TextView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toStartOf="@id/vCenterVertical" android:text="右邊對齊中垂線" /> </RelativeLayout>
2024-04-07
【Kotlin】以資源檔自定向量圖 ImageButton(View) 外觀
... ... android { ... ... buildFeatures { viewBinding true } ... ...
<?xml version="1.0" encoding="utf-8"?> <resources> ... ... <color name="blue">#0000FF</color> <color name="red">#ffff0000</color> <color name="brown">#8B4513</color> <color name="gray">#ff888888</color> <color name="green">#ff00ff00</color> <color name="yellow">#FFFF00</color> ... ... </resources>
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:color="@color/brown" /> <item android:state_enabled="false" android:color="@color/gray" /> <item android:color="@color/blue" /> ← 預設值要放在最後順位 </selector>
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:color="@color/yellow" /> <item android:state_enabled="false" android:color="@color/green" /> </selector>
<vector android:height="48dp" android:width="48dp" android:tint="@color/image_state" ← 這裡指向 前景 image_state.xml android:viewportHeight="24" android:viewportWidth="24" xmlns:android="http://schemas.android.com/apk/res/android"> <path android:fillColor="@android:color/white" android:pathData="M13,24c-3.26,0 -6.19,-1.99 -7.4,-5.02l-3.03,-7.61C2.26,10.58 3,9.79 3.81,10.05l0.79,0.26c0.56,0.18 1.02,0.61 1.24,1.16L7.25,15H8V3.25C8,2.56 8.56,2 9.25,2s1.25,0.56 1.25,1.25V12h1V1.25C11.5,0.56 12.06,0 12.75,0S14,0.56 14,1.25V12h1V2.75c0,-0.69 0.56,-1.25 1.25,-1.25c0.69,0 1.25,0.56 1.25,1.25V12h1V5.75c0,-0.69 0.56,-1.25 1.25,-1.25S21,5.06 21,5.75V16C21,20.42 17.42,24 13,24z"/> </vector>
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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" tools:context=".MainActivity"> <Button android:id="@+id/Button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:onClick="onButton1Clicked"/> <ImageButton android:id="@+id/Button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" app:srcCompat="@drawable/hand" android:backgroundTint="@color/back_state" ← 這裡指向 背景 back_state.xml android:clickable="true" /> </RelativeLayout>
... ... class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) val view = binding.root setContentView(view) } fun onButton1Clicked(vv: View) { binding.Button2.isEnabled = !binding.Button2.isEnabled } }
2024-04-06
【Kotlin】刪除指定目錄內的所有檔案
class MainActivity : AppCompatActivity() { fun onButtonClicked(vv: View) { // 刪除內部儲存空間的所有檔案 delAll(filesDir.toString()) } ... ... fun delAll(sDir: String) { val mScope = CoroutineScope(Job() + Dispatchers.IO) mScope.launch { val directory = File(sDir) val files = directory.listFiles() for (file in files) { file.delete() } } } }