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

Flutter實(shí)現(xiàn)文字鏤空效果的詳細(xì)步驟

 更新時(shí)間:2025年05月03日 08:19:51   作者:淡寫成灰  
這篇文章主要介紹了如何使用Flutter實(shí)現(xiàn)文字鏤空效果,包括創(chuàng)建基礎(chǔ)應(yīng)用結(jié)構(gòu)、實(shí)現(xiàn)自定義繪制器、構(gòu)建UI界面以及實(shí)現(xiàn)顏色選擇按鈕等步驟,并詳細(xì)解析了混合模式、Canvas圖層和文字居中處理等關(guān)鍵技術(shù)點(diǎn),需要的朋友可以參考下

引言

哈哈,2019年初我剛?cè)肼殨r(shí),遇到了一個(gè)特別的需求:學(xué)校的卡片上要有個(gè)分類標(biāo)簽,文字部分還得鏤空。當(dāng)時(shí)我剛開始接觸Flutter,對(duì)很多功能都不熟悉,這個(gè)需求就一直沒能實(shí)現(xiàn),成了我的一個(gè)小執(zhí)念。現(xiàn)在我早已不在那兒工作了,可這兩天閑來無事,突然想起了這個(gè)事。趁著五一假期,我開始琢磨畫筆功能,終于把當(dāng)年實(shí)現(xiàn)不了的功能給實(shí)現(xiàn)了。

Tip: 這時(shí)候可能會(huì)有人說:啊,這道題我會(huì),用ShaderMask配置blendMode: BlendMode.srcOut就能實(shí)現(xiàn),但實(shí)際上這個(gè)組件不能設(shè)置圓角,內(nèi)邊距等相關(guān)內(nèi)容,如果這時(shí)候添加一個(gè)Container那么鏤空效果也只能看到Container的顏色,而不能看到最底部的圖片

實(shí)現(xiàn)原理

文字鏤空效果的核心是使用Canvas和自定義繪制(CustomPainter)來創(chuàng)建一個(gè)矩形,然后從中"切出"文字形狀。我們將使用Flutter的BlendMode.dstOut混合模式來實(shí)現(xiàn)這一效果。

開始實(shí)現(xiàn)

步驟1:創(chuàng)建基礎(chǔ)應(yīng)用結(jié)構(gòu)

首先,我們需要設(shè)置基本的應(yīng)用結(jié)構(gòu):

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Rectangle Text Cutout',
      theme: ThemeData(
        primarySwatch: Colors.teal,
        useMaterial3: true,
      ),
      home: const RectangleDrawingScreen(),
    );
  }
}

這里我們創(chuàng)建了一個(gè)基本的MaterialApp,并設(shè)置了主題顏色為teal(青色),啟用了Material 3設(shè)計(jì)。

步驟2:創(chuàng)建主屏幕

接下來,我們創(chuàng)建主屏幕,這是一個(gè)StatefulWidget,因?yàn)槲覀冃枰芾矶鄠€(gè)可變狀態(tài):

class RectangleDrawingScreen extends StatefulWidget {
  const RectangleDrawingScreen({super.key});

  @override
  State<RectangleDrawingScreen> createState() => _RectangleDrawingScreenState();
}

class _RectangleDrawingScreenState extends State<RectangleDrawingScreen> {
  // 定義狀態(tài)變量
  double _cornerRadius = 20.0;
  String _text = "FLUTTER";
  double _fontSize = 60.0;
  Color _rectangleColor = Colors.teal;
  Color _backgroundColor = Colors.white;
  
  // 構(gòu)建UI...
}

我們定義了幾個(gè)關(guān)鍵狀態(tài)變量:

  • _cornerRadius:矩形的圓角半徑
  • _text:要鏤空的文字
  • _fontSize:文字大小
  • _rectangleColor:矩形的顏色
  • _backgroundColor:背景顏色

步驟3:實(shí)現(xiàn)自定義繪制器

這是實(shí)現(xiàn)鏤空效果的核心部分 - 自定義繪制器:

class RectangleTextCutoutPainter extends CustomPainter {
  final double cornerRadius;
  final String text;
  final double fontSize;
  final Color rectangleColor;

  RectangleTextCutoutPainter({
    required this.cornerRadius,
    required this.text,
    required this.fontSize,
    required this.rectangleColor,
  });

  @override
  void paint(Canvas canvas, Size size) {
    // 創(chuàng)建矩形區(qū)域
    final Rect rect = Rect.fromLTWH(
      20,
      20,
      size.width - 40,
      size.height - 40,
    );

    // 創(chuàng)建圓角矩形
    final RRect roundedRect = RRect.fromRectAndRadius(
      rect,
      Radius.circular(cornerRadius),
    );

    // 設(shè)置文字樣式
    final textStyle = TextStyle(
      fontSize: fontSize,
      fontWeight: FontWeight.bold,
    );

    final textSpan = TextSpan(
      text: text,
      style: textStyle,
    );

    // 創(chuàng)建文字繪制器
    final textPainter = TextPainter(
      text: textSpan,
      textDirection: TextDirection.ltr,
    );

    // 計(jì)算文字位置
    textPainter.layout(
      minWidth: 0,
      maxWidth: size.width,
    );
    final double xCenter = (size.width - textPainter.width) / 2;
    final double yCenter = (size.height - textPainter.height) / 2;

    // 使用圖層和混合模式實(shí)現(xiàn)鏤空效果
    canvas.saveLayer(rect.inflate(20), Paint());
    final Paint rectanglePaint = Paint()
      ..color = rectangleColor
      ..style = PaintingStyle.fill;

    canvas.drawRRect(roundedRect, rectanglePaint);
    final Paint cutoutPaint = Paint()
      ..color = Colors.white
      ..style = PaintingStyle.fill
      ..blendMode = BlendMode.dstOut;

    canvas.saveLayer(rect.inflate(20), cutoutPaint);
    textPainter.paint(canvas, Offset(xCenter, yCenter));
    canvas.restore();
    canvas.restore();
  }

  @override
  bool shouldRepaint(covariant RectangleTextCutoutPainter oldDelegate) {
    return oldDelegate.cornerRadius != cornerRadius ||
        oldDelegate.text != text ||
        oldDelegate.fontSize != fontSize ||
        oldDelegate.rectangleColor != rectangleColor;
  }
}

這個(gè)自定義繪制器的工作原理是:

  • 創(chuàng)建一個(gè)圓角矩形
  • 使用saveLayerBlendMode.dstOut創(chuàng)建一個(gè)混合圖層
  • 在矩形上"切出"文字形狀
  • 使用shouldRepaint方法優(yōu)化重繪性能

步驟4:構(gòu)建UI界面

現(xiàn)在,讓我們實(shí)現(xiàn)主界面,包括預(yù)覽區(qū)域和控制面板:

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: const Text('Rectangle Text Cutout'),
      backgroundColor: Colors.teal.shade100,
    ),
    body: Column(
      children: [
        // 預(yù)覽區(qū)域
        Expanded(
          child: Container(
            color: Colors.grey[200],
            child: Center(
              child: Stack(
                children: [
                  // 背景圖片
                  Positioned.fill(
                    child: Image.network(
                      "https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/d11fee3a97464bca82c9291435cc2a89~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5reh5YaZ5oiQ54Gw:q75.awebp?rk3s=f64ab15b&x-expires=1746213056&x-signature=ylstmk1m2eVeu8bI%2BhDJkVUHe7U%3D",
                      fit: BoxFit.cover,
                    ),
                  ),
                  // 自定義繪制
                  CustomPaint(
                    size: const Size(double.infinity, double.infinity),
                    painter: RectangleTextCutoutPainter(
                      cornerRadius: _cornerRadius,
                      text: _text,
                      fontSize: _fontSize,
                      rectangleColor: _rectangleColor,
                    ),
                  ),
                  // 額外的ShaderMask效果
                  ShaderMask(
                    blendMode: BlendMode.srcOut,
                    child: Text(
                      _text,
                    ),
                    shaderCallback: (bounds) =>
                        LinearGradient(colors: [Colors.black], stops: [0.0])
                            .createShader(bounds),
                  ),
                ],
              ),
            ),
          ),
        ),
        // 控制面板
        Container(
          padding: const EdgeInsets.all(16),
          color: Colors.grey[200],
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // 圓角控制
              const Text('Corner Radius:', style: TextStyle(fontWeight: FontWeight.bold)),
              Slider(
                value: _cornerRadius,
                min: 0,
                max: 100,
                divisions: 100,
                label: _cornerRadius.round().toString(),
                activeColor: Colors.teal,
                onChanged: (value) {
                  setState(() {
                    _cornerRadius = value;
                  });
                },
              ),
              // 字體大小控制
              const SizedBox(height: 10),
              const Text('Font Size:', style: TextStyle(fontWeight: FontWeight.bold)),
              Slider(
                value: _fontSize,
                min: 20,
                max: 120,
                divisions: 100,
                label: _fontSize.round().toString(),
                activeColor: Colors.teal,
                onChanged: (value) {
                  setState(() {
                    _fontSize = value;
                  });
                },
              ),
              // 文字輸入
              const SizedBox(height: 10),
              TextField(
                decoration: const InputDecoration(
                  labelText: 'Text to Cut Out',
                  border: OutlineInputBorder(),
                  focusedBorder: OutlineInputBorder(
                    borderSide: BorderSide(color: Colors.teal),
                  ),
                ),
                onChanged: (value) {
                  setState(() {
                    _text = value;
                  });
                },
                controller: TextEditingController(text: _text),
              ),
              // 矩形顏色選擇
              const SizedBox(height: 16),
              Row(
                children: [
                  const Text('Rectangle Color: ', style: TextStyle(fontWeight: FontWeight.bold)),
                  const SizedBox(width: 10),
                  _buildColorButton(Colors.teal),
                  _buildColorButton(Colors.blue),
                  _buildColorButton(Colors.red),
                  _buildColorButton(Colors.purple),
                  _buildColorButton(Colors.orange),
                ],
              ),
              // 背景顏色選擇
              const SizedBox(height: 16),
              Row(
                children: [
                  const Text('Background Color: ', style: TextStyle(fontWeight: FontWeight.bold)),
                  const SizedBox(width: 10),
                  _buildBackgroundColorButton(Colors.white),
                  _buildBackgroundColorButton(Colors.grey.shade300),
                  _buildBackgroundColorButton(Colors.yellow.shade100),
                  _buildBackgroundColorButton(Colors.blue.shade100),
                  _buildBackgroundColorButton(Colors.pink.shade100),
                ],
              ),
            ],
          ),
        ),
      ],
    ),
  );
}

步驟5:實(shí)現(xiàn)顏色選擇按鈕

最后,我們實(shí)現(xiàn)顏色選擇按鈕的構(gòu)建方法:

Widget _buildColorButton(Color color) {
  return GestureDetector(
    onTap: () {
      setState(() {
        _rectangleColor = color;
      });
    },
    child: Container(
      margin: const EdgeInsets.only(right: 8),
      width: 30,
      height: 30,
      decoration: BoxDecoration(
        color: color,
        shape: BoxShape.circle,
        border: Border.all(
          color: _rectangleColor == color ? Colors.black : Colors.transparent,
          width: 2,
        ),
      ),
    ),
  );
}

Widget _buildBackgroundColorButton(Color color) {
  return GestureDetector(
    onTap: () {
      setState(() {
        _backgroundColor = color;
      });
    },
    child: Container(
      margin: const EdgeInsets.only(right: 8),
      width: 30,
      height: 30,
      decoration: BoxDecoration(
        color: color,
        shape: BoxShape.circle,
        border: Border.all(
          color: _backgroundColor == color ? Colors.black : Colors.transparent,
          width: 2,
        ),
      ),
    ),
  );
}

關(guān)鍵技術(shù)點(diǎn)解析

1. 混合模式(BlendMode)的應(yīng)用 

在這個(gè)效果中,最關(guān)鍵的技術(shù)是使用BlendMode.dstOut混合模式。這個(gè)混合模式會(huì)從目標(biāo)圖像(矩形)中"減去"源圖像(文字),從而創(chuàng)建出文字形狀的"洞"。

final Paint cutoutPaint = Paint()
  ..color = Colors.white
  ..style = PaintingStyle.fill
  ..blendMode = BlendMode.dstOut;

2. Canvas圖層(Layer)的使用

我們使用canvas.saveLayer()canvas.restore()來創(chuàng)建和管理圖層,這是實(shí)現(xiàn)復(fù)雜繪制效果的關(guān)鍵:

canvas.saveLayer(rect.inflate(20), Paint());
// 繪制矩形
canvas.saveLayer(rect.inflate(20), cutoutPaint);
// 繪制文字
canvas.restore();
canvas.restore();

3. 文字居中處理

為了讓文字在矩形中居中顯示,我們需要計(jì)算正確的位置:

final double xCenter = (size.width - textPainter.width) / 2;
final double yCenter = (size.height - textPainter.height) / 2;

code

為了方便大家查閱,下面貼出完整代碼

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Rectangle Text Cutout',
      theme: ThemeData(
        primarySwatch: Colors.teal,
        useMaterial3: true,
      ),
      home: const RectangleDrawingScreen(),
    );
  }
}

class RectangleDrawingScreen extends StatefulWidget {
  const RectangleDrawingScreen({super.key});

  @override
  State<RectangleDrawingScreen> createState() => _RectangleDrawingScreenState();
}

class _RectangleDrawingScreenState extends State<RectangleDrawingScreen> {
  double _cornerRadius = 20.0;
  String _text = "FLUTTER";
  double _fontSize = 60.0;
  Color _rectangleColor = Colors.teal;
  Color _backgroundColor = Colors.white;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Rectangle Text Cutout'),
        backgroundColor: Colors.teal.shade100,
      ),
      body: Column(
        children: [

          Expanded(
            child: Container(
              color: Colors.grey[200],
              child: Center(
                child: Stack(
                  children: [
                    Positioned.fill(
                      child: Image.network(
                        "https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/d11fee3a97464bca82c9291435cc2a89~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5reh5YaZ5oiQ54Gw:q75.awebp?rk3s=f64ab15b&x-expires=1746213056&x-signature=ylstmk1m2eVeu8bI%2BhDJkVUHe7U%3D",
                        fit: BoxFit.cover,
                      ),
                    ),
                    CustomPaint(
                      size: const Size(double.infinity, double.infinity),
                      painter: RectangleTextCutoutPainter(
                        cornerRadius: _cornerRadius,
                        text: _text,
                        fontSize: _fontSize,
                        rectangleColor: _rectangleColor,
                      ),
                    ),
                    ShaderMask(
                      blendMode: BlendMode.srcOut,
                      child: Text(
                        _text,
                      ),
                      shaderCallback: (bounds) =>
                          LinearGradient(colors: [Colors.black], stops: [0.0])
                              .createShader(bounds),
                    ),
                  ],
                ),
              ),
            ),
          ),
          Container(
            padding: const EdgeInsets.all(16),
            color: Colors.grey[200],
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const Text('Corner Radius:', style: TextStyle(fontWeight: FontWeight.bold)),
                Slider(
                  value: _cornerRadius,
                  min: 0,
                  max: 100,
                  divisions: 100,
                  label: _cornerRadius.round().toString(),
                  activeColor: Colors.teal,
                  onChanged: (value) {
                    setState(() {
                      _cornerRadius = value;
                    });
                  },
                ),
                const SizedBox(height: 10),
                const Text('Font Size:', style: TextStyle(fontWeight: FontWeight.bold)),
                Slider(
                  value: _fontSize,
                  min: 20,
                  max: 120,
                  divisions: 100,
                  label: _fontSize.round().toString(),
                  activeColor: Colors.teal,
                  onChanged: (value) {
                    setState(() {
                      _fontSize = value;
                    });
                  },
                ),
                const SizedBox(height: 10),
                TextField(
                  decoration: const InputDecoration(
                    labelText: 'Text to Cut Out',
                    border: OutlineInputBorder(),
                    focusedBorder: OutlineInputBorder(
                      borderSide: BorderSide(color: Colors.teal),
                    ),
                  ),
                  onChanged: (value) {
                    setState(() {
                      _text = value;
                    });
                  },
                  controller: TextEditingController(text: _text),
                ),
                const SizedBox(height: 16),
                Row(
                  children: [
                    const Text('Rectangle Color: ', style: TextStyle(fontWeight: FontWeight.bold)),
                    const SizedBox(width: 10),
                    _buildColorButton(Colors.teal),
                    _buildColorButton(Colors.blue),
                    _buildColorButton(Colors.red),
                    _buildColorButton(Colors.purple),
                    _buildColorButton(Colors.orange),
                  ],
                ),
                const SizedBox(height: 16),
                Row(
                  children: [
                    const Text('Background Color: ', style: TextStyle(fontWeight: FontWeight.bold)),
                    const SizedBox(width: 10),
                    _buildBackgroundColorButton(Colors.white),
                    _buildBackgroundColorButton(Colors.grey.shade300),
                    _buildBackgroundColorButton(Colors.yellow.shade100),
                    _buildBackgroundColorButton(Colors.blue.shade100),
                    _buildBackgroundColorButton(Colors.pink.shade100),
                  ],
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildColorButton(Color color) {
    return GestureDetector(
      onTap: () {
        setState(() {
          _rectangleColor = color;
        });
      },
      child: Container(
        margin: const EdgeInsets.only(right: 8),
        width: 30,
        height: 30,
        decoration: BoxDecoration(
          color: color,
          shape: BoxShape.circle,
          border: Border.all(
            color: _rectangleColor == color ? Colors.black : Colors.transparent,
            width: 2,
          ),
        ),
      ),
    );
  }

  Widget _buildBackgroundColorButton(Color color) {
    return GestureDetector(
      onTap: () {
        setState(() {
          _backgroundColor = color;
        });
      },
      child: Container(
        margin: const EdgeInsets.only(right: 8),
        width: 30,
        height: 30,
        decoration: BoxDecoration(
          color: color,
          shape: BoxShape.circle,
          border: Border.all(
            color: _backgroundColor == color ? Colors.black : Colors.transparent,
            width: 2,
          ),
        ),
      ),
    );
  }
}

class RectangleTextCutoutPainter extends CustomPainter {
  final double cornerRadius;
  final String text;
  final double fontSize;
  final Color rectangleColor;

  RectangleTextCutoutPainter({
    required this.cornerRadius,
    required this.text,
    required this.fontSize,
    required this.rectangleColor,
  });

  @override
  void paint(Canvas canvas, Size size) {
    final Rect rect = Rect.fromLTWH(
      20,
      20,
      size.width - 40,
      size.height - 40,
    );

    final RRect roundedRect = RRect.fromRectAndRadius(
      rect,
      Radius.circular(cornerRadius),
    );

    final textStyle = TextStyle(
      fontSize: fontSize,
      fontWeight: FontWeight.bold,
    );

    final textSpan = TextSpan(
      text: text,
      style: textStyle,
    );

    final textPainter = TextPainter(
      text: textSpan,
      textDirection: TextDirection.ltr,
    );

    textPainter.layout(
      minWidth: 0,
      maxWidth: size.width,
    );
    final double xCenter = (size.width - textPainter.width) / 2;
    final double yCenter = (size.height - textPainter.height) / 2;

    canvas.saveLayer(rect.inflate(20), Paint());
    final Paint rectanglePaint = Paint()
      ..color = rectangleColor
      ..style = PaintingStyle.fill;

    canvas.drawRRect(roundedRect, rectanglePaint);
    final Paint cutoutPaint = Paint()
      ..color = Colors.white
      ..style = PaintingStyle.fill
      ..blendMode = BlendMode.dstOut;

    canvas.saveLayer(rect.inflate(20), cutoutPaint);
    textPainter.paint(canvas, Offset(xCenter, yCenter));
    canvas.restore();
    canvas.restore();
  }

  @override
  bool shouldRepaint(covariant RectangleTextCutoutPainter oldDelegate) {
    return oldDelegate.cornerRadius != cornerRadius ||
        oldDelegate.text != text ||
        oldDelegate.fontSize != fontSize ||
        oldDelegate.rectangleColor != rectangleColor;
  }
}

以上就是Flutter實(shí)現(xiàn)文字鏤空效果的詳細(xì)步驟的詳細(xì)內(nèi)容,更多關(guān)于Flutter文字鏤空效果的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Android多種支付方式的實(shí)現(xiàn)示例

    Android多種支付方式的實(shí)現(xiàn)示例

    App的支付流程,添加多種支付方式,不同的支付方式,對(duì)應(yīng)的操作不一樣,有的會(huì)跳轉(zhuǎn)到一個(gè)新的webview,有的會(huì)調(diào)用系統(tǒng)瀏覽器,有的會(huì)進(jìn)去一個(gè)新的表單頁面,等等,本文就給大家詳細(xì)介紹一下Android 多種支付方式的優(yōu)雅實(shí)現(xiàn),需要的朋友可以參考下
    2023-09-09
  • Android音樂播放器簡單實(shí)現(xiàn)案例

    Android音樂播放器簡單實(shí)現(xiàn)案例

    我們平時(shí)長時(shí)間打代碼的時(shí)候肯定會(huì)感到疲憊和乏味,這個(gè)時(shí)候一邊播放自己喜歡的音樂,一邊繼續(xù)打代碼,心情自然也愉快很多。音樂帶給人的聽覺享受是無可比擬的,動(dòng)聽的音樂可以愉悅?cè)说纳硇模屓烁臃e極地去熱愛生活,這篇文章主要介紹了Android音樂播放器簡單實(shí)現(xiàn)案例
    2022-12-12
  • Android Shader應(yīng)用開發(fā)之雷達(dá)掃描效果

    Android Shader應(yīng)用開發(fā)之雷達(dá)掃描效果

    這篇文章主要為大家詳細(xì)介紹了Android Shader應(yīng)用開發(fā)之雷達(dá)掃描效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Android實(shí)現(xiàn)TextView兩端對(duì)齊的方法

    Android實(shí)現(xiàn)TextView兩端對(duì)齊的方法

    這篇文章主要介紹了Android實(shí)現(xiàn)TextView兩端對(duì)齊的方法,需要的朋友可以參考下
    2016-01-01
  • Android編程實(shí)現(xiàn)Gallery中每次滑動(dòng)只顯示一頁的方法

    Android編程實(shí)現(xiàn)Gallery中每次滑動(dòng)只顯示一頁的方法

    這篇文章主要介紹了Android編程實(shí)現(xiàn)Gallery中每次滑動(dòng)只顯示一頁的方法,涉及Android擴(kuò)展Gallery控件實(shí)現(xiàn)翻頁效果控制的功能,涉及Android事件響應(yīng)及屬性控制的相關(guān)技巧,需要的朋友可以參考下
    2015-11-11
  • Android開發(fā)兩個(gè)activity之間傳值示例詳解

    Android開發(fā)兩個(gè)activity之間傳值示例詳解

    這篇文章主要為大家介紹了Android開發(fā)兩個(gè)activity之間傳值示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • 理解關(guān)于Android系統(tǒng)中輕量級(jí)指針的實(shí)現(xiàn)

    理解關(guān)于Android系統(tǒng)中輕量級(jí)指針的實(shí)現(xiàn)

    由于android系統(tǒng)底層的很大的一部分是用C++實(shí)現(xiàn)的,C++的開發(fā)就難免會(huì)使用到指針的這個(gè)知識(shí) 點(diǎn)。而C++的難點(diǎn)和容易出問題的也在于指針。使用指針出錯(cuò),常常會(huì)引發(fā)帶來對(duì)項(xiàng)目具有毀滅性的錯(cuò)誤,內(nèi)存泄漏、邏輯錯(cuò)誤、系統(tǒng)崩潰
    2021-10-10
  • Android RecyclerView滾動(dòng)定位

    Android RecyclerView滾動(dòng)定位

    這篇文章主要為大家詳細(xì)介紹了Android RecyclerView滾動(dòng)定位的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • android嵌套滾動(dòng)入門實(shí)踐

    android嵌套滾動(dòng)入門實(shí)踐

    嵌套滾動(dòng)是 Android OS 5.0之后,google 為我們提供的新特性,本篇文章主要介紹了android嵌套滾動(dòng)入門實(shí)踐,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-05-05
  • Android自定義View實(shí)現(xiàn)音頻播放圓形進(jìn)度條

    Android自定義View實(shí)現(xiàn)音頻播放圓形進(jìn)度條

    這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)音頻播放圓形進(jìn)度條,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-06-06

最新評(píng)論