如何在Android中實(shí)現(xiàn)斷點(diǎn)續(xù)傳功能
1. 項(xiàng)目簡(jiǎn)介
隨著移動(dòng)端用戶越來(lái)越依賴(lài)視頻、文件下載以及大文件傳輸,斷點(diǎn)續(xù)傳作為一種有效節(jié)省帶寬和提高用戶體驗(yàn)的技術(shù)應(yīng)運(yùn)而生。所謂斷點(diǎn)續(xù)傳,就是指在下載過(guò)程中如果網(wǎng)絡(luò)發(fā)生中斷或用戶取消下載,再次啟動(dòng)下載時(shí)能從上一次結(jié)束的地方繼續(xù),而不必從頭開(kāi)始,節(jié)省下載時(shí)間和數(shù)據(jù)流量。本項(xiàng)目旨在實(shí)現(xiàn)一個(gè)基于 Android 的斷點(diǎn)續(xù)傳功能,通過(guò) HTTP Range 請(qǐng)求下載文件,并對(duì)部分下載數(shù)據(jù)進(jìn)行存儲(chǔ)與管理,實(shí)現(xiàn)斷點(diǎn)續(xù)傳效果。項(xiàng)目可以應(yīng)用于視頻、軟件更新、圖片大文件下載等場(chǎng)景。
2. 背景與需求分析
2.1 項(xiàng)目背景
在實(shí)際開(kāi)發(fā)中,下載大文件時(shí)網(wǎng)絡(luò)波動(dòng)、連接中斷等問(wèn)題經(jīng)常發(fā)生,如果從頭開(kāi)始下載,用戶體驗(yàn)大打折扣。實(shí)現(xiàn)斷點(diǎn)續(xù)傳功能能夠:
提高文件下載的效率;
節(jié)省用戶數(shù)據(jù)流量;
改善用戶體驗(yàn),特別是在網(wǎng)絡(luò)不穩(wěn)定環(huán)境下。
常見(jiàn)實(shí)現(xiàn)方式通常利用 HTTP 協(xié)議中的 Range 頭字段請(qǐng)求下載指定位置的數(shù)據(jù),再將分段下載的數(shù)據(jù)合并成完整文件。同時(shí)需要對(duì)下載過(guò)程中可能出現(xiàn)的錯(cuò)誤進(jìn)行處理,并保存當(dāng)前下載狀態(tài),便于下次繼續(xù)。
2.2 需求分析
本項(xiàng)目主要需要滿足以下功能需求:
斷點(diǎn)續(xù)傳下載
支持當(dāng)下載中斷后,下次啟動(dòng)能從上一次下載結(jié)束處繼續(xù);
利用 HTTP Range 請(qǐng)求方式,指定請(qǐng)求數(shù)據(jù)的起始位置;
對(duì)服務(wù)器返回的響應(yīng)進(jìn)行解析,校驗(yàn)下載數(shù)據(jù)的完整性,并將分段數(shù)據(jù)合并成完整文件。
下載狀態(tài)管理
保存當(dāng)前下載位置和已下載的數(shù)據(jù)大小到本地存儲(chǔ)(例如 SharedPreferences 或數(shù)據(jù)庫(kù));
在重新啟動(dòng)下載時(shí),從保存的斷點(diǎn)開(kāi)始繼續(xù)下載。
異常處理
處理網(wǎng)絡(luò)中斷、超時(shí)等異常情況;
能夠進(jìn)行多次重試和錯(cuò)誤提示;
避免因下載過(guò)程中的異常導(dǎo)致文件損壞。
用戶界面及反饋
提供簡(jiǎn)潔直觀的用戶界面顯示下載進(jìn)度和斷點(diǎn)狀態(tài);
當(dāng)下載完成或失敗時(shí)給出明確的提示信息;
支持暫停、恢復(fù)、取消下載操作。
性能與擴(kuò)展性
下載過(guò)程盡量在子線程中執(zhí)行,避免阻塞 UI 線程;
模塊化設(shè)計(jì),便于在不同項(xiàng)目中復(fù)用(如視頻下載、文件更新等);
提供對(duì)接第三方網(wǎng)絡(luò)庫(kù)(如 OkHttp、Retrofit)的擴(kuò)展方案。
3. 關(guān)鍵技術(shù)與實(shí)現(xiàn)原理
3.1 斷點(diǎn)續(xù)傳的原理
斷點(diǎn)續(xù)傳依賴(lài)于 HTTP 協(xié)議中 Range 請(qǐng)求頭,它允許客戶端請(qǐng)求資源的某個(gè)部分,例如 “Range: bytes=xxx-” 表示從指定字節(jié)開(kāi)始下載。服務(wù)端收到請(qǐng)求后,會(huì)返回狀態(tài)碼 206(Partial Content),同時(shí)返回響應(yīng)頭中包含 Content-Range 信息??蛻舳耸盏綌?shù)據(jù)后,只保存這部分?jǐn)?shù)據(jù),并在后續(xù)請(qǐng)求中指定下一個(gè)起點(diǎn),從而實(shí)現(xiàn)文件的分段下載與合并。
3.2 HTTP Range 頭與響應(yīng)解析
Range 頭
格式:Range: bytes=起始位置-結(jié)束位置。
在斷點(diǎn)續(xù)傳中,通常只指定起始位置,服務(wù)器根據(jù)文件大小自動(dòng)返回后續(xù)數(shù)據(jù)。Content-Range 響應(yīng)頭
格式:Content-Range: bytes 起始位置-結(jié)束位置/文件總大小。
通過(guò)這個(gè)頭信息,客戶端可以核對(duì)下載數(shù)據(jù)是否完整,并計(jì)算下次請(qǐng)求的起始位置。
3.3 文件讀寫(xiě)與狀態(tài)管理
文件寫(xiě)入
使用 RandomAccessFile 可以指定寫(xiě)入位置,非常適用于斷點(diǎn)續(xù)傳。
打開(kāi)文件后,將下載數(shù)據(jù)從當(dāng)前的斷點(diǎn)開(kāi)始寫(xiě)入,并不斷更新寫(xiě)入位置。狀態(tài)管理
通過(guò) SharedPreferences、數(shù)據(jù)庫(kù)或本地文件保存當(dāng)前下載位置和文件總大小,確保在斷點(diǎn)續(xù)傳時(shí)能夠正確讀取上次下載狀態(tài)。
3.4 網(wǎng)絡(luò)請(qǐng)求與異常處理
網(wǎng)絡(luò)請(qǐng)求庫(kù)
可以使用 OkHttp 等網(wǎng)絡(luò)庫(kù)發(fā)送 GET 請(qǐng)求,并在請(qǐng)求頭中加入 Range 字段。異常處理
對(duì)網(wǎng)絡(luò)中斷、HTTP 狀態(tài)碼異常、文件寫(xiě)入異常等進(jìn)行捕獲和重試策略設(shè)計(jì),確保下載過(guò)程魯棒性。
4. 項(xiàng)目實(shí)現(xiàn)思路與架構(gòu)設(shè)計(jì)
4.1 整體架構(gòu)設(shè)計(jì)
項(xiàng)目大致分為以下幾個(gè)模塊:
網(wǎng)絡(luò)請(qǐng)求模塊
負(fù)責(zé)構(gòu)造 HTTP 請(qǐng)求,并在請(qǐng)求頭中設(shè)置 Range;
接收服務(wù)器返回的 206 部分內(nèi)容響應(yīng),并將數(shù)據(jù)傳遞給文件寫(xiě)入模塊。
文件管理模塊
利用 RandomAccessFile 對(duì)下載文件進(jìn)行寫(xiě)入;
每次下載時(shí)記錄當(dāng)前寫(xiě)入位置,并保存至本地持久化存儲(chǔ);
文件合并與校驗(yàn),確保下載數(shù)據(jù)完整無(wú)誤。
狀態(tài)管理模塊
保存和讀取斷點(diǎn)續(xù)傳狀態(tài)(下載進(jìn)度、總文件大小等),便于斷點(diǎn)續(xù)傳的實(shí)現(xiàn);
提供暫停、恢復(fù)、取消等功能接口。
用戶界面模塊
展示下載進(jìn)度、剩余時(shí)間和狀態(tài)提示;
提供暫停、恢復(fù)、取消等交互按鈕,便于用戶控制下載進(jìn)程。
4.2 下載流程與斷點(diǎn)續(xù)傳實(shí)現(xiàn)
初始化
獲取文件總大?。梢酝ㄟ^(guò) HEAD 請(qǐng)求獲取或第一次完整請(qǐng)求獲?。?;
檢查本地是否存在部分下載文件,并讀取已經(jīng)下載的字節(jié)數(shù)。
開(kāi)始下載
通過(guò)網(wǎng)絡(luò)請(qǐng)求發(fā)送 Range 請(qǐng)求,起始位置為已下載的字節(jié)數(shù);
將返回的數(shù)據(jù)寫(xiě)入文件,并實(shí)時(shí)更新當(dāng)前下載字節(jié)數(shù);
更新 UI 顯示進(jìn)度。
異常與重試
當(dāng)網(wǎng)絡(luò)中斷或其它異常發(fā)生時(shí),通過(guò)狀態(tài)管理保存當(dāng)前進(jìn)度;
用戶恢復(fù)網(wǎng)絡(luò)后,可再次啟動(dòng)下載,從斷點(diǎn)繼續(xù)。
完成處理
下載完成后進(jìn)行文件校驗(yàn)(例如 MD5 校驗(yàn)),確保數(shù)據(jù)正確;
更新?tīng)顟B(tài),通知用戶下載完成,并清除保存的斷點(diǎn)狀態(tài)。
4.3 斷點(diǎn)續(xù)傳狀態(tài)管理
采用 SharedPreferences 或本地?cái)?shù)據(jù)庫(kù)存儲(chǔ)當(dāng)前下載的進(jìn)度信息;
每次寫(xiě)入文件時(shí)更新當(dāng)前已下載字節(jié)數(shù),方便下次啟動(dòng)時(shí)繼續(xù)下載;
提供接口方便用戶手動(dòng)重置或取消斷點(diǎn)狀態(tài)。
5. 詳細(xì)代碼示例與注釋
下面給出基于 OkHttp 的斷點(diǎn)續(xù)傳示例代碼。代碼中利用 HTTP Range 請(qǐng)求、RandomAccessFile 寫(xiě)入以及 SharedPreferences 保存進(jìn)度。同時(shí)提供完整注釋?zhuān)敿?xì)解釋每個(gè)步驟。
5.1 基于 OkHttp 實(shí)現(xiàn)斷點(diǎn)續(xù)傳示例代碼
package com.example.breakpointdownload;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Environment;
import android.util.Log;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
public class DownloadManager {
private static final String TAG = "DownloadManager";
private static final String PREFS_NAME = "download_prefs";
private static final String KEY_DOWNLOAD_PROGRESS = "download_progress";
private OkHttpClient client;
private Context context;
public DownloadManager(Context context) {
this.context = context;
client = new OkHttpClient();
}
/**
* 開(kāi)始下載文件,實(shí)現(xiàn)斷點(diǎn)續(xù)傳。
*
* @param fileUrl 文件下載地址
* @param destFilePath 本地文件保存路徑
*/
public void downloadFile(String fileUrl, String destFilePath) {
// 讀取已下載的字節(jié)數(shù)
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
long downloadedBytes = prefs.getLong(KEY_DOWNLOAD_PROGRESS, 0);
Request request = new Request.Builder()
.url(fileUrl)
// 設(shè)置 Range 請(qǐng)求頭,從斷點(diǎn)位置開(kāi)始下載
.addHeader("Range", "bytes=" + downloadedBytes + "-")
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e(TAG, "下載失?。? + e.getMessage());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
// 下載成功后寫(xiě)入文件
if (response.code() == 206 || response.code() == 200) {
File file = new File(destFilePath);
// 使用 RandomAccessFile 從指定位置寫(xiě)入數(shù)據(jù)
RandomAccessFile raf = new RandomAccessFile(file, "rw");
raf.seek(downloadedBytes);
byte[] buffer = new byte[1024 * 4];
int len;
long currentBytes = downloadedBytes;
while ((len = response.body().byteStream().read(buffer)) != -1) {
raf.write(buffer, 0, len);
currentBytes += len;
// 保存當(dāng)前下載進(jìn)度
saveProgress(currentBytes);
}
raf.close();
Log.d(TAG, "下載完成:" + currentBytes + " 字節(jié)");
} else {
Log.e(TAG, "服務(wù)器響應(yīng)異常:" + response.code());
}
}
});
}
/**
* 保存當(dāng)前下載進(jìn)度到 SharedPreferences 中
*
* @param bytes 當(dāng)前已下載的字節(jié)數(shù)
*/
private void saveProgress(long bytes) {
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
prefs.edit().putLong(KEY_DOWNLOAD_PROGRESS, bytes).apply();
}
/**
* 重置下載進(jìn)度(例如取消或重新開(kāi)始下載時(shí)調(diào)用)
*/
public void resetProgress() {
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
prefs.edit().putLong(KEY_DOWNLOAD_PROGRESS, 0).apply();
}
}5.2 使用示例 Activity
package com.example.breakpointdownload;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
public class DownloadActivity extends AppCompatActivity {
private DownloadManager downloadManager;
// 下載目標(biāo)文件 URL(示例 URL,請(qǐng)?zhí)鎿Q為實(shí)際文件地址)
private String fileUrl = "https://example.com/path/to/your/file.apk";
// 本地保存路徑
private String destFilePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/download/file.apk";
private Button btnDownload;
private Button btnReset;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_download);
downloadManager = new DownloadManager(this);
btnDownload = findViewById(R.id.btn_download);
btnReset = findViewById(R.id.btn_reset);
btnDownload.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
downloadManager.downloadFile(fileUrl, destFilePath);
}
});
btnReset.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
downloadManager.resetProgress();
}
});
}
}5.3 XML 布局文件示例
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="24dp">
<Button
android:id="@+id/btn_download"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="開(kāi)始下載" />
<Button
android:id="@+id/btn_reset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="重置斷點(diǎn)"
android:layout_marginTop="16dp" />
</LinearLayout>6. 代碼解析與講解
6.1 核心模塊與關(guān)鍵方法詳解
DownloadManager 類(lèi)
該類(lèi)封裝了斷點(diǎn)續(xù)傳的核心邏輯。在下載開(kāi)始前,通過(guò) SharedPreferences 獲取已下載的字節(jié)數(shù)。
構(gòu)造 HTTP 請(qǐng)求時(shí),在請(qǐng)求頭中添加 Range 字段,實(shí)現(xiàn)從斷點(diǎn)續(xù)傳。
使用 OkHttp 發(fā)送網(wǎng)絡(luò)請(qǐng)求,響應(yīng)狀態(tài)碼 206(Partial Content)表示服務(wù)端支持?jǐn)帱c(diǎn)續(xù)傳。
利用 RandomAccessFile 將下載數(shù)據(jù)寫(xiě)入指定位置,并不斷更新已下載的字節(jié)數(shù)保存至 SharedPreferences 中。
若下載中斷后重新啟動(dòng)下載,可從 SharedPreferences 中讀取上次進(jìn)度,繼續(xù)下載剩余數(shù)據(jù)。
DownloadActivity 類(lèi)
作為 UI 層,提供兩個(gè)按鈕,分別觸發(fā)“開(kāi)始下載”和“重置斷點(diǎn)”操作,演示斷點(diǎn)續(xù)傳功能。用戶點(diǎn)擊“開(kāi)始下載”后,DownloadManager 開(kāi)始執(zhí)行下載任務(wù);若需要重新下載,則可以點(diǎn)擊重置按鈕。
6.2 數(shù)據(jù)分段讀取與文件合并邏輯
隨機(jī)文件訪問(wèn)
通過(guò) RandomAccessFile.seek() 方法調(diào)整寫(xiě)入位置,可將每次下載的數(shù)據(jù)拼接到文件末尾,實(shí)現(xiàn)斷點(diǎn)續(xù)傳。數(shù)據(jù)更新與持久化
每次寫(xiě)入操作后,調(diào)用 saveProgress() 方法更新 SharedPreferences 中存儲(chǔ)的下載進(jìn)度,確保發(fā)生中斷時(shí)能準(zhǔn)確恢復(fù)數(shù)據(jù)下載。
7. 項(xiàng)目測(cè)試與運(yùn)行效果
7.1 測(cè)試方案與流程
功能測(cè)試
在真實(shí)設(shè)備上測(cè)試下載功能,檢查當(dāng)下載中斷(例如網(wǎng)絡(luò)斷開(kāi))后再次啟動(dòng)下載時(shí)能否繼續(xù)從上次斷點(diǎn)繼續(xù)。
驗(yàn)證 HTTP Range 請(qǐng)求是否正確返回部分內(nèi)容,以及下載文件是否完整拼接。
穩(wěn)定性測(cè)試
模擬網(wǎng)絡(luò)異常、服務(wù)器響應(yīng)異常的情況,檢測(cè) DownloadManager 是否能夠捕獲異常并提示錯(cuò)誤。
檢查文件寫(xiě)入過(guò)程中是否出現(xiàn) I/O 異常,并確保相關(guān)資源及時(shí)釋放。
用戶體驗(yàn)測(cè)試
檢查“重置斷點(diǎn)”按鈕是否能正確清除已下載狀態(tài),確保下次下載從頭開(kāi)始;
觀察下載過(guò)程中的日志輸出,確認(rèn)斷點(diǎn)數(shù)據(jù)正確記錄與恢復(fù)。
7.2 性能與兼容性測(cè)試
網(wǎng)絡(luò)測(cè)試:
在不同網(wǎng)絡(luò)環(huán)境下測(cè)試下載速度和斷點(diǎn)續(xù)傳效果,確保在高延遲、弱信號(hào)等情況下也能正常工作。設(shè)備兼容性:
在不同 Android 系統(tǒng)版本和設(shè)備型號(hào)上進(jìn)行測(cè)試,確保文件操作和 SharedPreferences 的讀寫(xiě)表現(xiàn)一致,無(wú)兼容性問(wèn)題。
8. 項(xiàng)目總結(jié)與經(jīng)驗(yàn)分享
8.1 項(xiàng)目?jī)?yōu)缺點(diǎn)分析
項(xiàng)目?jī)?yōu)勢(shì)
通過(guò) HTTP Range 請(qǐng)求與 RandomAccessFile 實(shí)現(xiàn)斷點(diǎn)續(xù)傳效果,充分利用了標(biāo)準(zhǔn)協(xié)議與 API;
采用 SharedPreferences 存儲(chǔ)下載進(jìn)度,簡(jiǎn)單易用;
支持暫停、斷點(diǎn)恢復(fù)等常見(jiàn)下載場(chǎng)景,可擴(kuò)展性較強(qiáng)。
項(xiàng)目不足
僅針對(duì)單個(gè)文件進(jìn)行斷點(diǎn)續(xù)傳,未涉及多任務(wù)并發(fā)下載;
對(duì)于大文件下載時(shí),可能需要引入更高效的 I/O 緩存機(jī)制;
異常處理和錯(cuò)誤重試機(jī)制可進(jìn)一步完善,增加日志記錄與用戶友好提示。
8.2 開(kāi)發(fā)心得與改進(jìn)建議
斷點(diǎn)續(xù)傳原理
關(guān)鍵在于正確使用 HTTP Range 頭和 RandomAccessFile,實(shí)現(xiàn)文件分段拼接與狀態(tài)保存。確保每次寫(xiě)入前將指針定位在合適的偏移量。資源管理
在下載任務(wù)過(guò)程中,注意關(guān)閉網(wǎng)絡(luò)流和 RandomAccessFile,防止內(nèi)存泄露。異常與重試機(jī)制
需要根據(jù)實(shí)際網(wǎng)絡(luò)狀況加入重試機(jī)制,增加健壯性,并實(shí)時(shí)反饋錯(cuò)誤信息給用戶。擴(kuò)展應(yīng)用
未來(lái)可結(jié)合多線程和分塊下載,進(jìn)一步提升大文件下載速度,同時(shí)加入下載管理界面顯示多任務(wù)下載進(jìn)度。
9. 后續(xù)優(yōu)化與拓展思考
多線程分塊下載
將文件切分為多個(gè)塊,并利用線程池同時(shí)下載不同塊,最后合并成完整文件。
提高下載速度和網(wǎng)絡(luò)利用效率,適用于大型資源下載。
進(jìn)度提示與通知功能
使用通知欄顯示下載進(jìn)度,提升用戶體驗(yàn);
支持暫停、繼續(xù)、取消下載的綜合下載管理。
斷點(diǎn)續(xù)傳狀態(tài)保存改進(jìn)
將下載狀態(tài)存儲(chǔ)到數(shù)據(jù)庫(kù)中,適用于多任務(wù)下載,便于管理和展示狀態(tài)。
提供下載記錄,便于用戶查詢(xún)歷史下載記錄。
擴(kuò)展到視頻、圖片等多媒體文件
針對(duì)不同類(lèi)型文件,優(yōu)化緩存處理機(jī)制。
借助 MD5 校驗(yàn)或其他完整性驗(yàn)證方法,確保下載文件無(wú)損。
與網(wǎng)絡(luò)庫(kù)整合
結(jié)合 Retrofit 或基于 OkHttp 的封裝,將斷點(diǎn)續(xù)傳功能作為下載模塊獨(dú)立出來(lái),提高代碼復(fù)用性。
結(jié)論
本文詳細(xì)講解了如何在 Android 中實(shí)現(xiàn)斷點(diǎn)續(xù)傳功能。從項(xiàng)目背景和需求分析入手,介紹了斷點(diǎn)續(xù)傳的基本原理和 HTTP Range 請(qǐng)求的使用,通過(guò) RandomAccessFile 實(shí)現(xiàn)文件分段寫(xiě)入和合并,并利用 SharedPreferences 保存下載進(jìn)度。整個(gè)方案從網(wǎng)絡(luò)請(qǐng)求、文件操作、狀態(tài)管理到異常處理均做了詳細(xì)設(shè)計(jì)和編碼示例說(shuō)明。
項(xiàng)目測(cè)試結(jié)果表明,該方案能夠有效實(shí)現(xiàn)斷點(diǎn)續(xù)傳功能,適用于文件下載、視頻、軟件更新等場(chǎng)景。同時(shí),本文還探討了多線程下載、進(jìn)度提示、擴(kuò)展到多任務(wù)下載等未來(lái)優(yōu)化方向,為開(kāi)發(fā)者提供了豐富的實(shí)現(xiàn)思路和參考資料。
希望本文能為各位 Android 開(kāi)發(fā)者提供充分的技術(shù)指導(dǎo)和實(shí)踐經(jīng)驗(yàn),助您在實(shí)際項(xiàng)目中實(shí)現(xiàn)既高效又穩(wěn)定的斷點(diǎn)續(xù)傳功能。
以上就是如何在Android中實(shí)現(xiàn)斷點(diǎn)續(xù)傳功能的詳細(xì)內(nèi)容,更多關(guān)于Android斷點(diǎn)續(xù)傳的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android 使用 Scroller 實(shí)現(xiàn)平滑滾動(dòng)功能的示例代碼
這篇文章主要介紹了Android 使用 Scroller 實(shí)現(xiàn)平滑滾動(dòng)功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07
Android 文件夾顯示紅色嘆號(hào)的解決方法(必看)
下面小編就為大家?guī)?lái)一篇Android 文件夾顯示紅色嘆號(hào)的解決方法(必看)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-04-04
android實(shí)現(xiàn)上傳本地圖片到網(wǎng)絡(luò)功能
這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)上傳本地圖片到網(wǎng)絡(luò)功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09
Flutter通過(guò)Container實(shí)現(xiàn)時(shí)間軸效果
時(shí)間軸是前端UI經(jīng)常用到的效果,本文講解下Flutter如何通過(guò)Container實(shí)現(xiàn),感興趣的朋友可以了解下2021-05-05
淺談Android輕量級(jí)的數(shù)據(jù)緩存框架RxCache
本篇文章主要介紹了淺談Android輕量級(jí)的數(shù)據(jù)緩存框架RxCache,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08
Android中RecyclerView實(shí)現(xiàn)多級(jí)折疊列表效果(二)
這篇文章主要給大家介紹了Android中RecyclerView實(shí)現(xiàn)多級(jí)折疊列表的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-05-05
Android自定義ViewGroup實(shí)現(xiàn)九宮格布局
這篇文章主要為大家詳細(xì)介紹了Android如何通過(guò)自定義ViewGroup實(shí)現(xiàn)九宮格布局,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-12-12

