欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

利用Flutter制作經(jīng)典貪吃蛇游戲

 更新時(shí)間:2022年04月25日 08:34:55   作者:大前端之旅  
Flutter框架可以使用單一代碼庫(kù)為 Android、iOS、Web ,桌面平臺(tái)構(gòu)建應(yīng)用程序。本文將利用它制作經(jīng)典的貪吃蛇游戲,感興趣的小伙伴可以了解一下

前言

Flutter (Channel stable, 2.10.3, on Microsoft Windows [Version 10.0.19044.1586], locale zh-CN)

Android toolchain - develop for Android devices (Android SDK version 30.0.3)

Flutter 框架讓你可以使用單一代碼庫(kù)為 Android、iOS、Web ,桌面平臺(tái)構(gòu)建應(yīng)用程序。盡管許多大公司都將 Flutter 用于他們蓬勃發(fā)展的應(yīng)用程序,包括 Google Pay 和阿里巴巴閑魚(yú),但沒(méi)有多少人正在探索使用 Flutter 進(jìn)行游戲開(kāi)發(fā)。這就是你將在本教程中所做的。

由于 Flutter 能夠以高達(dá) 60 FPS 的速度渲染 UI,你將利用該功能在 Flutter 中構(gòu)建簡(jiǎn)單的 2D Snake 游戲。

在此過(guò)程中,你將學(xué)習(xí)如何:

  • 使用 Flutter 作為游戲引擎
  • 移動(dòng)對(duì)象
  • 控制運(yùn)動(dòng)
  • 構(gòu)建游戲用戶界面
  • 添加游戲元素

啟動(dòng)項(xiàng)目設(shè)置了競(jìng)爭(zhēng)環(huán)境。你將在構(gòu)建游戲時(shí)為其添加 UI 元素。入門(mén)項(xiàng)目還提供了一些有用的實(shí)用方法,因此你可以專注于更大的場(chǎng)景:編寫(xiě)游戲。以下是你可以在項(xiàng)目中找到的預(yù)構(gòu)建函數(shù),以及如何使用它們:

  • roundToNearestTens(int num):將傳遞的整數(shù)參數(shù)四舍五入到最接近的步長(zhǎng)值。 這使你可以在假想的網(wǎng)格上獲得與當(dāng)前位置相距步進(jìn)單位的確切下一個(gè)位置。
  • getRandomPositionWithinRange() :在游戲區(qū)域范圍內(nèi)的屏幕上生成一個(gè)隨機(jī)位置。你將使用此函數(shù)生成一條新蛇并為蛇提供食物。
  • showGameOverDialog() :當(dāng) Snake 與游戲區(qū)域的任何邊界發(fā)生碰撞時(shí),顯示一個(gè)樣式化的對(duì)話框彈出窗口。此對(duì)話框顯示用戶的分?jǐn)?shù)和重新開(kāi)始游戲的按鈕。
  • getRandomDirection([String type]) :隨機(jī)返回四個(gè)方向之一:上、下、左或右。你主要使用此函數(shù)在 Snake 生成時(shí)將其沿隨機(jī)方向移動(dòng)。它可選地接受一個(gè)參數(shù),指定你希望它返回的隨機(jī)方向是水平還是垂直。
  • getRandomPositionWithinRange() :返回游戲區(qū)域內(nèi)屏幕上的隨機(jī)位置。它確保隨機(jī)位置位于蛇移動(dòng)的網(wǎng)格上。
  • getControls() : 實(shí)現(xiàn)ControlPanel,一個(gè)在屏幕上顯示四個(gè)圓形按鈕以控制蛇的移動(dòng)的小部件。
  • getPlayAreaBorder() :沿屏幕邊緣繪制邊框,表示屏幕移動(dòng)的播放區(qū)域。

使用 Flutter 作為游戲引擎

游戲引擎是一套工具和服務(wù),可幫助游戲開(kāi)發(fā)者構(gòu)建游戲。他們處理很多不同的事情,比如圖形、聲音、人工智能、用戶輸入、網(wǎng)絡(luò)等等。Flutter 也可以處理大部分這些事情。作為 Flutter 開(kāi)發(fā)人員,你可以訪問(wèn)整個(gè)世界的 Dart 插件。另外,如果不存在,你始終可以自己編寫(xiě)代碼。

要從 Flutter 作為游戲開(kāi)發(fā)引擎開(kāi)始,你將使用框架的渲染功能來(lái)為蛇、食物和游戲分?jǐn)?shù)等游戲?qū)ο笤O(shè)置動(dòng)畫(huà)。在這種情況下,你將使用計(jì)時(shí)器每秒重新生成 60 次 UI,并在屏幕上顯示一條蛇。通過(guò)在改變其位置的同時(shí)以高達(dá) 60 FPS 的速度渲染蛇,你可以獲得非常平滑的移動(dòng)動(dòng)畫(huà)效果。

像 Unity 這樣的游戲引擎以類似的方式工作。這里的不同之處在于,過(guò)多地推動(dòng)框架的限制可能最終導(dǎo)致需要大量資源的應(yīng)用程序。然而,在測(cè)試這款游戲時(shí),F(xiàn)lutter 的表現(xiàn)驚人地好,根本沒(méi)有加熱設(shè)備。

畫(huà)蛇

你的第一步是創(chuàng)建蛇。你將從啟動(dòng)Piece項(xiàng)目中的小部件開(kāi)始,它會(huì)在屏幕上呈現(xiàn)一個(gè)彩色圓圈。使用此小部件,你將逐個(gè)繪制蛇以及蛇食。

但是,在繪制蛇之前,有必要花點(diǎn)時(shí)間了解使用 Flutter 進(jìn)行 2D 渲染的基礎(chǔ)知識(shí)。

2D 渲染的基礎(chǔ)

要渲染任何在屏幕上不斷改變其位置的東西,你需要使用 和 之類的小Stack部件Positioned。給定 x 和 y 坐標(biāo),這些小部件可以將子小部件放置在屏幕上的任何位置。

要記住的最重要的事情是,你正在開(kāi)發(fā)一個(gè)移動(dòng)應(yīng)用程序,該應(yīng)用程序需要在具有各種屏幕尺寸和縱橫比的設(shè)備上運(yùn)行。這意味著你不能對(duì)游戲領(lǐng)域的任何維度進(jìn)行硬編碼。相反,你將使用MediaQuery獲取用戶屏幕的寬度和高度,然后根據(jù)這些值計(jì)算位置。

例如,這是一個(gè)簡(jiǎn)單的代碼片段,它聲明變量,然后將屏幕的寬度和高度分配給它們。

final screenSize = MediaQuery.of(context).size;
final screenWidth = screenSize.width;
final screenHeight = screenSize.height;

在上面的代碼片段中,MediaQuery繼承的小部件用于獲取當(dāng)前設(shè)備屏幕的寬度和高度。這需要傳遞內(nèi)容,因此,我們?cè)谄鋬?nèi)部擁有此代碼build()。

既然你知道如何在屏幕上放置對(duì)象,就該畫(huà)蛇了。

創(chuàng)建蛇

你將使用它Piece來(lái)創(chuàng)建蛇。首先,你將根據(jù)蛇在屏幕上的位置進(jìn)行創(chuàng)建。然后,你會(huì)將組成蛇的所有部分的位置存儲(chǔ)在被調(diào)用的。

首先將getPieces()位于lib/game.dart中的 替換為:

 List<Piece> getPieces() {
    final pieces = <Piece>[];
    draw();
    drawFood();
?
    // 1
    for (var i = 0; i < length; ++i) {
      // 2
      if (i >= positions.length) {
        continue;
      }
?
      // 3
      pieces.add(
        Piece(
          posX: positions[i].dx.toInt(),
          posY: positions[i].dy.toInt(),
          // 4
          size: step,
          color: Colors.red,
        ),
      );
    }
?
    return pieces;
}

這是上面代碼中發(fā)生的事情:

  • 你使用的 for loop一直運(yùn)行到它覆蓋了蛇的整個(gè)長(zhǎng)度。
  • 當(dāng)蛇的長(zhǎng)度與列表的長(zhǎng)度不匹配時(shí),if內(nèi)部的塊處理for loop邊緣情況。當(dāng)蛇在吃一些食物后長(zhǎng)度增加時(shí),就會(huì)發(fā)生這種情況。``
  • 對(duì)于每次迭代,它都會(huì)創(chuàng)建一個(gè)Piece具有正確位置的 a 并將其添加到pieces它返回的列表中。
  • 除了位置,你還通過(guò)size和。在這種情況下,大小是,這確保了 Snake 沿著網(wǎng)格移動(dòng),其中每個(gè)網(wǎng)格單元的大小都是。顏色值是個(gè)人喜好。隨意使用自己的顏色。``

保存文件并讓?xiě)?yīng)用程序熱重新加載。到目前為止,什么都沒(méi)有發(fā)生,你也不會(huì)注意到 UI 中的任何變化。

填寫(xiě)列表

你需要實(shí)施draw()以實(shí)際填寫(xiě)positions列表。因此draw(),在同一文件中替換為以下內(nèi)容:

  void draw() async {
    // 1
    if (positions.length == 0) {
      positions.add(getRandomPositionWithinRange());
    }
?
    // 2
    while (length > positions.length) {
      positions.add(positions[positions.length - 1]);
    }
?
    // 3
    for (var i = positions.length - 1; i > 0; i--) {
      positions[i] = positions[i - 1];
    }
?
    // 4
    positions[0] = await getNextPosition(positions[0]);
  }

以下是上述函數(shù)的工作原理:

  • 如果positions為空,則getRandomPositionWithinRange()生成一個(gè)隨機(jī)位置并開(kāi)始該過(guò)程。
  • 如果蛇剛剛吃了食物,它length就會(huì)增加。增加了一個(gè)新的while loop位置,positions這樣length并且positions始終保持同步。
  • 它檢查positions的長(zhǎng)度并移動(dòng)每個(gè)位置。這會(huì)產(chǎn)生蛇在移動(dòng)的錯(cuò)覺(jué)。
  • 最后,getNextPosition()將第一塊蛇頭移動(dòng)到一個(gè)新位置。

你在這里需要做的最后一件事是實(shí)現(xiàn) at getNextPosition()。

將蛇移動(dòng)到下一個(gè)位置

將以下代碼添加到lib/game.dart中的函數(shù)中:

  Future<Offset> getNextPosition(Offset position) async {
    Offset nextPosition;
?
    if (direction == Direction.right) {
      nextPosition = Offset(position.dx + step, position.dy);
    } else if (direction == Direction.left) {
      nextPosition = Offset(position.dx - step, position.dy);
    } else if (direction == Direction.up) {
      nextPosition = Offset(position.dx, position.dy - step);
    } else if (direction == Direction.down) {
      nextPosition = Offset(position.dx, position.dy + step);
    }
?
    return nextPosition;
  }

以下是上面代碼的作用:

  • 根據(jù)對(duì)象的當(dāng)前位置及其方向值創(chuàng)建對(duì)象的新位置。改變方向會(huì)導(dǎo)致對(duì)象朝不同的方向移動(dòng)。稍后你將使用控制按鈕來(lái)執(zhí)行此操作。
  • 如果方向設(shè)置為right則增加 x 坐標(biāo)值,如果方向設(shè)置為left則減小值。
  • 同樣,如果方向設(shè)置為向上,則增加 y 坐標(biāo)的值,如果方向設(shè)置為向下,則減少它。

最后,

  return Scaffold(
    body: Container(
      color: Color(0XFFF5BB00),
      child: Stack(
        children: [
          Stack(
            children: getPieces(),
          ),
        ],
      ),
    ),
  );

在上面的代碼片段中,我們只是添加了getPieces()將小部件返回到堆棧的方法,因此我們可以在屏幕上看到一些 UI。請(qǐng)注意,如果你不將小部件添加到build(),屏幕上不會(huì)發(fā)生任何變化。

保存所有內(nèi)容并重新啟動(dòng)應(yīng)用程序。你會(huì)看到的:

你可以看到一條蛇……它什么也沒(méi)做。那是因?yàn)槟銢](méi)有添加任何東西來(lái)重建 UI。但是,一次又一次地保存文件并讓熱重載完成它的工作,你會(huì)看到蛇移動(dòng)。

添加運(yùn)動(dòng)和速度

現(xiàn)在,讓蛇移動(dòng)所需的只是一種重建 UI 的方法。每次build調(diào)用,都需要計(jì)算新的位置,并在Piece屏幕上渲染新的 s 列表。為此,你將使用Timer.

changeSpeed()在lib/game.dart中添加以下定義:

  void changeSpeed() {
    if (timer != null && timer.isActive) timer.cancel();
?
    timer = Timer.periodic(Duration(milliseconds: 200 ~/ speed), (timer) {
      setState(() {});
    });
  }

上面的代碼只是簡(jiǎn)單地重置了timer一個(gè)包含speed. speed每次蛇吃食物時(shí),你控制并增加它。最后,在計(jì)時(shí)器的每一個(gè)滴答聲中,你都會(huì)調(diào)用setState(),它會(huì)重建整個(gè) UI。

changeSpeed()接下來(lái),從restart()同一文件中調(diào)用:

  void restart() {
    changeSpeed();
  }

timer每次用戶重新啟動(dòng)游戲時(shí)都會(huì)重新初始化。

保存所有文件并重新啟動(dòng)應(yīng)用程序?,F(xiàn)在,每次重新啟動(dòng)應(yīng)用程序時(shí),蛇都會(huì)向隨機(jī)方向移動(dòng)。

添加控件

現(xiàn)在你有了一條移動(dòng)的蛇,你需要添加更多的旋鈕和轉(zhuǎn)盤(pán),以便用戶可以控制蛇的方向和速度。請(qǐng)記住以下幾點(diǎn):

  • 你將使用 來(lái)控制運(yùn)動(dòng)和方向ControlPanel
  • 每次蛇吃食物時(shí),速度都必須增加。
  • restart()重置蛇與邊界框碰撞時(shí)的速度、長(zhǎng)度和方向。
  • 發(fā)生碰撞后,你將向用戶顯示Game Over警報(bào)。

改變方向

ControlPanel擁有讓用戶控制蛇的方向所需的一切。它由四個(gè)圓形按鈕組成,每個(gè)按鈕都會(huì)改變蛇的運(yùn)動(dòng)方向。該小部件位于lib/control_panel.dart中。隨意挖掘并查看實(shí)現(xiàn)。

現(xiàn)在,將以下代碼添加到getControls()lib /game.dart 中:

  Widget getControls() {
    return ControlPanel( // 1
      onTapped: (Direction newDirection) { // 2
        direction = newDirection; // 3
      },
    );
  }

在上面的代碼片段中:

  • 我們正在使用ControlPanel已經(jīng)在啟動(dòng)項(xiàng)目中為你創(chuàng)建的小部件。ControlPanel 小部件呈現(xiàn) 4 個(gè)按鈕,你將使用這些按鈕來(lái)控制蛇的移動(dòng)。
  • 我們還使用onTapped接收蛇移動(dòng)的新方向作為參數(shù)的方法。
  • 我們direction用新的方向更新變量newDirection。這將導(dǎo)致蛇改變方向。

此外,在文檔頂部添加以下導(dǎo)入:

  import 'control_panel.dart';

接下來(lái),添加getControls()為外部Stackin的第二個(gè)孩子build()

@override
Widget build(BuildContext context) {
  // ...
  return Scaffold(
    body: Container(
      color: Color(0XFFF5BB00),
      child: Stack(
        children: [
          Stack(
            children: getPieces(),
          ),
          getControls(),
        ],
      ),
    ),
  );
}

上面的代碼將 getControls 方法返回的小部件添加到 Stack 內(nèi)屏幕上的 UI,但位于 UI 的其余部分之上。

保存文件并重新啟動(dòng)應(yīng)用程序?,F(xiàn)在,你將看到一組控制蛇方向的按鈕。

點(diǎn)擊按鈕會(huì)改變蛇的方向。到目前為止,游戲在一個(gè)簡(jiǎn)單的級(jí)別上運(yùn)行,但你仍然需要添加玩家應(yīng)該努力的東西。只是在屏幕上移動(dòng)一條五顏六色的蛇并不是很有趣,對(duì)吧?所以你的下一步是給蛇一些食物來(lái)加速它。

吃東西和提高速度

要在屏幕上渲染食物,你將Piece再次使用,但你將更改其顏色。請(qǐng)記住,你不希望食物出現(xiàn)在任意位置。相反,它應(yīng)該始終在游戲區(qū)域內(nèi)的隨機(jī)位置渲染,并且它應(yīng)該始終位于蛇移動(dòng)的網(wǎng)格上。

現(xiàn)在,你將實(shí)現(xiàn)在屏幕上drawFood()呈現(xiàn)食物。Piece將以下代碼添加到drawFood()同一文件中:

  void drawFood() {
?
    // 1
    if (foodPosition == null) {
      foodPosition = getRandomPositionWithinRange();
    }
?
    // 2
    food = Piece(
      posX: foodPosition.dx.toInt(),
      posY: foodPosition.dy.toInt(),
      size: step,
      color: Color(0XFF8EA604),
      isAnimated: true,
    );
  }

這是上面發(fā)生的事情。

  • 上面的代碼創(chuàng)建 aPiece并將其存儲(chǔ)在food.
  • 它存儲(chǔ)對(duì)象food內(nèi)部的位置 。最初,這是,因此你可以在游戲區(qū)域內(nèi)的屏幕上任意位置隨機(jī)渲染食物。`

在屏幕上顯示食物

接下來(lái),你需要添加foodbuildinsideStack以將其呈現(xiàn)在屏幕上。

@override
Widget build(BuildContext context) {
  //...
  return Scaffold(
    body: Container(
      color: Color(0XFFF5BB00),
      child: Stack(
        children: [
          Stack(
            children: getPieces(),
          ),
          getControls(),
          food,
        ],
      ),
    ),
  );
}

保存所有文件并重新啟動(dòng)應(yīng)用程序以查看實(shí)際更改。應(yīng)用程序重新啟動(dòng)后,你會(huì)在屏幕上看到綠色食物。

然而,如果你試圖讓蛇找到食物,什么都不會(huì)發(fā)生——它只會(huì)越過(guò)食物圖標(biāo)。那是因?yàn)槟銢](méi)有做任何事情讓蛇吃掉食物。接下來(lái)你會(huì)解決這個(gè)問(wèn)題。

消耗和再生食物

現(xiàn)在,你需要檢查蛇和食物在 2D 空間中是否處于相同坐標(biāo)。如果是,你將對(duì)蛇進(jìn)行一些更改并在新位置呈現(xiàn)一些新食物。

drawFood()在第一個(gè)if塊結(jié)束后將以下代碼添加到:

  void drawFood() {
?
    // ...
?
    if (foodPosition == positions[0]) {
      length++;
      speed = speed + 0.25;
      score = score + 5;
      changeSpeed();
?
      foodPosition = getRandomPositionWithinRange();
    }
?
    // ...
  }

上面的代碼只是檢查你存儲(chǔ)foodPosition的位置和蛇的第一Piece個(gè)小部件的位置是否相同。如果它們匹配,你將length增加1、speed和。然后調(diào)用,它使用新設(shè)置重新初始化。0.25``score``5``changeSpeed()``timer

最后,你foodPosition在屏幕上使用新的隨機(jī)位置進(jìn)行更新,從而呈現(xiàn)新的食物Piece

保存文件并重新啟動(dòng)應(yīng)用程序以使更改生效。

蛇現(xiàn)在可以吃食物了。當(dāng)它這樣做時(shí),它的長(zhǎng)度會(huì)大大增加。

檢測(cè)碰撞并顯示游戲結(jié)束對(duì)話框

到目前為止,這條蛇可以自由地四處走動(dòng)——這就造成了一個(gè)問(wèn)題。沒(méi)有什么可以阻止蛇走出矩形游樂(lè)區(qū)。你需要限制蛇的移動(dòng)以保持在你在屏幕上定義的游戲區(qū)域內(nèi)。

首先,使用 渲染該游戲區(qū)域getPlayAreaBorder(),這會(huì)為游戲區(qū)域添加輪廓。只需添加getPlayAreaBorder()到外部Stackin build()

@override
Widget build(BuildContext context) {
  //...
  return Scaffold(
      body: Container(
        color: Color(0XFFF5BB00),
        child: Stack(
          children: [
            getPlayAreaBorder(),
            Stack(
              children: getPieces(),
            ),
            getControls(),
            food,
          ],
        ),
      ),
    );
}

上面的代碼將food小部件添加到Stackinbuild()所以現(xiàn)在它將呈現(xiàn)在屏幕上。

接下來(lái),將以下代碼添加到detectCollision()

  bool detectCollision(Offset position) {
?
    if (position.dx >= upperBoundX && direction == Direction.right) {
      return true;
    } else if (position.dx <= lowerBoundX && direction == Direction.left) {
      return true;
    } else if (position.dy >= upperBoundY && direction == Direction.down) {
      return true;
    } else if (position.dy <= lowerBoundY && direction == Direction.up) {
      return true;
    }
?
    return false;
  }

上面的函數(shù)檢查蛇是否到達(dá)了四個(gè)邊界中的任何一個(gè)。如果有,則返回true,否則返回false。它使用lowerBoundX、upperBoundX和變量lowerBoundY來(lái)upperBoundY檢查蛇是否仍在游戲區(qū)域內(nèi)。

接下來(lái),你需要在每次生成蛇的下一個(gè)位置時(shí)使用detectCollision()inside來(lái)檢查碰撞。getNextPosition()將以下代碼添加到getNextPosition()的聲明之后nextPosition

Future<Offset> getNextPosition(Offset position) async {
  //...
  if (detectCollision(position) == true) {
      if (timer != null && timer.isActive) timer.cancel();
      await Future.delayed(
          Duration(milliseconds: 500), () => showGameOverDialog());
      return position;
    }
  //...
}

上面的代碼檢查碰撞。如果蛇與邊界框發(fā)生碰撞,代碼會(huì)取消計(jì)時(shí)器并向用戶顯示Game Over對(duì)話框showGameOverDialog()

保存所有文件并熱重載應(yīng)用程序。

這一次,如果蛇接觸到周?chē)倪吔缈颍銓⒘⒓纯吹揭粋€(gè)對(duì)話框,通知用戶游戲結(jié)束并顯示他們的分?jǐn)?shù)。點(diǎn)擊對(duì)話框中的重新啟動(dòng)按鈕以關(guān)閉對(duì)話框并重新開(kāi)始游戲。接下來(lái)你會(huì)這樣做。

添加一些收尾工作

比賽開(kāi)始成形。你接下來(lái)的步驟是編寫(xiě)代碼以重新啟動(dòng)游戲,然后添加分?jǐn)?shù)以賦予游戲競(jìng)爭(zhēng)元素。

重啟游戲

接下來(lái),你將在用戶點(diǎn)擊Restart按鈕時(shí)重新啟動(dòng)游戲。將lib/game.dartrestart中的現(xiàn)有替換為:

  void restart() {
?
    score = 0;
    length = 5;
    positions = [];
    direction = getRandomDirection();
    speed = 1;
?
    changeSpeed();
  }

上面的代碼只是將所有內(nèi)容重置為其初始值。它也會(huì)清除positions,因此蛇會(huì)失去它length并從頭開(kāi)始重生。

顯示分?jǐn)?shù)

接下來(lái),你需要添加代碼以在屏幕右上角顯示分?jǐn)?shù)。為此,請(qǐng)實(shí)施getScore()

  Widget getScore() {
    return Positioned(
      top: 50.0,
      right: 40.0,
      child: Text(
        "Score: " + score.toString(),
        style: TextStyle(fontSize: 24.0),
      ),
    );
  }

添加getScore()build()作為外部的最后一個(gè)孩子Stack在. 最后,你應(yīng)該如下所示:`

@override
Widget build(BuildContext context) {
  //...
  return Scaffold(
    body: Container(
      color: Color(0XFFF5BB00),
      child: Stack(
        children: [
          getPlayAreaBorder(),
          Stack(
            children: getPieces(),
          ),
          getControls(),
          food,
          getScore(),
        ],
      ),
    ),
  );
}

保存所有文件并重新啟動(dòng)應(yīng)用程序。

現(xiàn)在,你應(yīng)該會(huì)實(shí)時(shí)看到分?jǐn)?shù)更新。

以上就是利用Flutter制作經(jīng)典貪吃蛇游戲的詳細(xì)內(nèi)容,更多關(guān)于Flutter貪吃蛇的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Android實(shí)現(xiàn)炫酷輪播圖效果

    Android實(shí)現(xiàn)炫酷輪播圖效果

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)炫酷輪播圖效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • android ndk程序獲取外置SD沙盒目錄的方法講解

    android ndk程序獲取外置SD沙盒目錄的方法講解

    今天小編就為大家分享一篇android ndk程序獲取外置SD沙盒目錄的方法講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • Android開(kāi)發(fā)之permission動(dòng)態(tài)權(quán)限獲取詳解

    Android開(kāi)發(fā)之permission動(dòng)態(tài)權(quán)限獲取詳解

    這篇文章主要為大家詳細(xì)介紹了Android開(kāi)發(fā)之permission動(dòng)態(tài)權(quán)限獲取,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • 利用flutter實(shí)現(xiàn)炫酷的list

    利用flutter實(shí)現(xiàn)炫酷的list

    這篇文章主要給大家介紹了關(guān)于利用flutter實(shí)現(xiàn)炫酷的list的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用flutter具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • Android中GIF動(dòng)圖的播放控制和監(jiān)聽(tīng)詳解

    Android中GIF動(dòng)圖的播放控制和監(jiān)聽(tīng)詳解

    android下播放gif圖片功能似乎并不常用,很多時(shí)候還是以展示靜態(tài)圖片為主,可能是由于gif圖體積比較大吧。不過(guò)像表情動(dòng)畫(huà)什么的,可能還是需要gif圖的。本文主要給大家介紹了關(guān)于Android中GIF動(dòng)圖的播放控制和監(jiān)聽(tīng)的相關(guān)資料,需要的朋友可以參考下。
    2017-05-05
  • Android自定義EditText實(shí)現(xiàn)登錄界面

    Android自定義EditText實(shí)現(xiàn)登錄界面

    這篇文章主要為大家詳細(xì)介紹了Android自定義EditText實(shí)現(xiàn)登錄界面,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Android ViewModel的使用總結(jié)

    Android ViewModel的使用總結(jié)

    ViewModel 是 Jetpack 的一部分。 ViewModel 類旨在以注重生命周期的方式存儲(chǔ)和管理界面相關(guān)的數(shù)據(jù)。ViewModel 類讓數(shù)據(jù)可在發(fā)生屏幕旋轉(zhuǎn)等配置更改后繼續(xù)留存。本文簡(jiǎn)單講解ViewModel的使用
    2021-06-06
  • android圖像繪制(二)畫(huà)布上放大縮小問(wèn)題

    android圖像繪制(二)畫(huà)布上放大縮小問(wèn)題

    android中圖像在畫(huà)布上放大縮小時(shí),圖像的邊框大小沒(méi)有改變,很是疑惑,應(yīng)該怎樣解決呢?接下來(lái)為您詳細(xì)介紹,感興趣的的朋友可以了解下
    2013-01-01
  • Qt qml中l(wèi)istview 列表視圖控件(下拉刷新、上拉分頁(yè)、滾動(dòng)軸)

    Qt qml中l(wèi)istview 列表視圖控件(下拉刷新、上拉分頁(yè)、滾動(dòng)軸)

    這篇文章主要介紹了Qt qml中l(wèi)istview 列表視圖控件(下拉刷新、上拉分頁(yè)、滾動(dòng)軸) 的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • Android通用LoadingView加載框架詳解

    Android通用LoadingView加載框架詳解

    這篇文章主要為大家詳細(xì)介紹了Android通用LoadingView加載框架的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-07-07

最新評(píng)論