前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >自定义View概述

自定义View概述

作者头像
flyou
发布2018-10-16 11:02:41
7300
发布2018-10-16 11:02:41
举报
文章被收录于专栏:flutter开发者flutter开发者

前言


在前面的文章中我们学习了ExpansionPanelList的用法,使用ExpansionPanelList可以很轻松的实现可展开列表的效果,在文章的最后依然给大家留下了个小问题,实现如下效果。

在前面已经提到了,使用ExpansionPanelList.radio()每次只能打开一个Item,当有一个item处于打开状态时在点击其他item就没有效果了,所以在这里我们依然要借助于ExpansionPanelList来实现,其实实现起来还是很简单的,只不过是记录下打开的position而已。

代码如下:

代码:


代码语言:javascript
复制
import 'package:flutter/material.dart';

void main() {
  runApp(new MaterialApp(
    home: ExpansionPanelListDemo(),
  ));
}

class ExpansionPanelListDemo extends StatefulWidget {
  @override
  _ExpansionPanelListDemoState createState() => _ExpansionPanelListDemoState();
}

class _ExpansionPanelListDemoState extends State<ExpansionPanelListDemo> {
  var currentPanelIndex = -1;
  List<int> mList;

  _ExpansionPanelListDemoState() {
    mList = new List();
    for (int i = 0; i < 10; i++) {
      mList.add(i);
    }
  }


  _setCurrentIndex(int index) {
    setState(() {

      if(currentPanelIndex==index){
        index=-1;
      }
      currentPanelIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("ExpansionPanelList"),
        ),
        body: SingleChildScrollView(child: ExpansionPanelList(
          children: mList.map((index) {
            return new ExpansionPanel(
              headerBuilder: (context, isExpanded) {
                return new ListTile(
                  title: new Text('我是第$index个标题'),
                );
              },
              body: new Padding(
                padding: EdgeInsets.symmetric(horizontal: 5.0),
                child: Container(height: 100.0,
                  color: Colors.blue,
                  alignment: Alignment.center,
                  child:Icon(Icons.security,size: 35.0,),),
              ),
              isExpanded: currentPanelIndex == index,
            );
          }).toList(),

          expansionCallback: (index, bol) {
            _setCurrentIndex(index);
          },

        ),));
  }
}

Flutter中的自定义View


在往期文章中我们花了很多篇文章来学习Flutter Widget 的用法,在Flutter中Widget有很多,我不肯能每个都给大家介绍到,但是我基本上把常用的都给大家介绍到了(想太多了^_^)。

当然,如果你觉得我有哪些你特别想要了解而我没有涉及的,可以在文章下面或者公众号留言,我会抽时间安排的。

但是,我觉得这也仅仅是个开始,因为就算官方的Wdiget再多也是有限的再多也不一定就能满足你应用的效果。

你以为就我能想到这个?官方肯定也会想到这一点啊,在Flutter中也是支持你自定义viewget的

在Flutter中与绘制相关的是在Painting层次,具体见下图:

Flutter架构图

和Flutter自带的Wdiget一样,自定义的Widget也会经过Skia被编译成原生代码,所以性能上也是不受影响的。

简单的步骤


  1. 新建类继承于CustomPainter实现paint()和shouldRepaint()方法
  2. 在paint方法中绘制你想要的内容
  3. 借助于 CustomPaint Widget来构建自己的Widget

当然,上面仅仅是自定义的流程,具体的实现还是有很多细节需要处理的。

与绘制相关的知识


学过前端或者终端开发的童鞋,应该对绘制都比较熟悉,绘制主要还是靠画布canvas和画笔Paint和完成的,画布就是你绘制图形的地方,画笔就是你用来作画的笔。

画布canvas

画布是一个矩形区域,我们可以控制其每一像素来绘制我们想要的内容

canvas 拥有多种绘制点、线、路径、矩形、圆形、以及添加图像的方法,结合这些方法我们可以绘制出千变万化的画面。

虽然,画布可以画这些东西,但是决定这些图形颜色、粗细表现的还是画笔。

画笔Paint

Paint非常好理解,就是我们用来画图形的工具,我们可以设置画笔的颜色、粗细、是否抗锯齿、笔触形状以及作画风格。

通过这些属性我们可以很方便的来定制自己的UI效果,当然我们在“作画”的过程中可以定义多个画笔,这样更方便我们对图形的绘制

Offset坐标

这个就比较简单,一般指得是在坐标系中的一个点。

Rect

在图形的绘制中,一般都是分区域绘制的,这个区域一般都是一个矩形,在绘制中通常使用Rect来存储绘制的位置信息。

当然,你可以指定Rect的上、下、左、右

  • left : 矩形左边的X坐标
  • top: 矩形顶部的Y坐标
  • right : 矩形右边的X坐标
  • bottom: 矩形底部的Y坐标

使用你这四个值就可以确定这个矩形的位置和大小。

当然,在一些平台还会有Rect.fromCircle(Offset center, double radius)这个方法来构建矩形,其实想起来也是很简单的,center就是圆心的坐标,radius就是圆的半径,由这两个属性构成圆的外切矩形就是我们需要的矩形。

Flutter中的坐标系

在Flutter中坐标系的坐标原点在左上角,X坐标越往右越大,Y坐标越往下越大

Flutter坐标系

因为在View自定义过程中我们需要排放多个View,所哟弄清楚这一点,在以后自定义Wdiget中会轻松很多。

今天,就先说这么多,从下篇文章起我们就回来学习Flutter自定义Widget的相关内容。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-10-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 flutter开发者 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • Flutter中的自定义View
  • 简单的步骤
  • 与绘制相关的知识
    • 画布canvas
      • 画笔Paint
        • Offset坐标
          • Rect
            • Flutter中的坐标系
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档