_HomeListPageState createState() => _HomeListPageState();
}
class _HomeListPageState extends State<HomeListPage> {br/>@override
Widget build(BuildContext context) {
var notes = widget._notes;
return ListView.builder(
itemCount: notes.length,
itemBuilder: (BuildContext context, int index) {
return renderItem(notes[index]);
},
);
}
//渲染条目
renderItem(NoteBean note) {
var line1_4 = Row(
children: <Widget>[
Image.asset("images/icon_90.png", width: 20, height: 20),
Expanded( child: pd(Text("张风捷特烈"), l: 5),),
Text( note.type,style: infoStyle,)
],
);
var center_right = Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[Text(note.name,style: littelStyle,maxLines: 2,),
pd(Text( note.info, style: infoStyle, maxLines: 2,
overflow: TextOverflow.ellipsis, ), t: 5),
],
);
//中间的信息
var center4 = Row(
children: <Widget>[
Expanded(child: pda(center_right, 5)),
Image.network( note.imgUrl,
width: 80, height: 80, fit: BoxFit.fitHeight )
],
);
var end4 = Row(
children: <Widget>[
Icon( Icons.grade, color: Colors.green, size: 20, ),
Text( "1000W", style: infoStyle,),
pd(Icon(Icons.tag_faces, color: Colors.lightBlueAccent, size: 20),
l: 15, r: 5),
Text("2000W", style: infoStyle),
],
);
var item4 = Column(
children: <Widget>[line1_4, Expanded(child: center4), end4],
);
var aCard = Card(
child: Container( height: 160,color: Colors.white,
padding: EdgeInsets.all(10), child: item4));
return aCard;
}
}
* * *
> `现在万事俱备,东风也到了,num小小动一下:num=30`
| /-- | /-- |
| --- | --- |
| ![](https://s2.51cto.com/images/20210910/1631213024854886.jpg) | ![](https://s2.51cto.com/images/20210910/1631213025335991.jpg) |
> 也许你感觉还未开始,但确实已经结束了...
* * *
##### 6.底部导航栏的切换:(下面两个图一样的,为了撑场面...)
> 刚才是数据没有分类型,现在点击底部导航,按范围进行展示
`get(style: "area/A", num: 30)//这样就是展示又有安卓类的文章`
| /- | /- |
| --- | --- |
| ![](https://s2.51cto.com/images/20210910/1631213025560375.jpg) | ![](https://s2.51cto.com/images/20210910/1631213025560375.jpg) |
> `android_stack.dart`添加成员变量
这里我默认加载完,做分页的话,再添加个/_count的成员变量就行了
String style = "area/A";
//底部栏点击监听—动态改变范围
void _onTapBNB(int position) {
switch (position) {
case 0:
style = "area/A";
break;
case 1:
style = "area/SB";
break;
case 2:
style = "area/Re";
break;
case 3:
style = "area/Note";
break;
case 4:
style = "area/A";
break;
}
_curIndex = position;
get(style: style, num: 1000).then((beanLi) {
_notes = beanLi;
setState(() {});
});
}
* * *
##### 7.底部栏和搜索功能
> 底部栏用法详情在[第四篇](
)
| /-- | /-- |
| --- | --- |
| ![底部栏.gif](https://s2.51cto.com/images/20210910/1631213027630167.jpg) | ![搜索功能.gif](https://s2.51cto.com/images/20210910/1631213027663351.jpg) |
* * *
> 底部栏:这里把事件写在里面了,你也可以抽成方法
或者有些控件太长,你也可以抽出来做变量
var searchSheet = BottomSheet(
onClosing: () {},
builder: (context) => (Card(
color: Color.fromARGB(255, 214, 242, 251),
child: Wrap(
children: <Widget>[
Center(child: pdhv(TextField(
onChanged: (v) {style = "name/" + v;}), h: 60)),
Center(child: pdhv( GestureDetector(child:
Image.asset("images/icon_90.png",width: 50,height: 50 ),
onTap: () {
get(style: style, num: 1000).then((beanLi) {
_notes = beanLi;
setState(() {});
});
},
),
v: 10)),
],
))));
//点击按钮弹出:
var scContext; //先声明一下Scaffold的context
var scaffold = Scaffold(
appBar: AppBar(
title: Text("张风捷特烈"),
),
body: Builder(builder: (context) {
scContext = context;
return HomeListPage(_notes);
}),
floatingActionButton: FloatingActionButton(
onPressed: () {
Scaffold.of(scContext).showBottomSheet(searchSheet.builder);
},
//下面不用修改,略…
> Ok,小案例就这样
* * *
#### 三、Android代码交互
##### 1.最简单的无参无返回函数调用:`两对应`
> 不得不说:前六天不能弹吐司真是不好受,原生交互肯定先拿他开刀
![toast](https://s2.51cto.com/images/20210910/1631213028416553.jpg)
* * *
##### 1.1:Android代码
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "www.toly1994.com/test.名字随意起";br/>@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
new MethodChannel.MethodCallHandler() {
@Override
public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
if (methodCall.method.equals("showToast")) {
showToast("Hello Flutter,I am in Android");
} else {
result.notImplemented();
}
}
}
);
}
/**
* 显示吐司
*
* @param msg 信息
*/
public void showToast(String msg) {
Toast toast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
toast.show();
}
}
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
const platform = const MethodChannel("www.toly1994.com/test.名字随意起");
var toastTest = Center(
child: RaisedButton(
onPressed: () {
platform.invokeMethod("showToast");
},
child: new Text("点击弹吐司"),
),
);
2.Flutter中传参,调用Android含参方法:三对应
2.1:Android代码
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "www.toly1994.com/test.名字随意起";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
new MethodChannel.MethodCallHandler() {
@Override
public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
if (methodCall.method.equals("showToast")) {
//解析参数
String msg = methodCall.argument("msg");
showToast(msg);
} else {
result.notImplemented();
}
}
}
);
}
/**
* 显示吐司
*
* @param msg 信息
*/
public void showToast(String msg) {
Toast toast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
toast.show();
}
}
2.2:Flutter代码:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
const platform = const MethodChannel("www.toly1994.com/test.名字随意起");
var toastTest = Center(
child: RaisedButton(
onPressed: () {
platform.invokeMethod("showToast",{"msg":"Flutter大爷我赏你一口吐司"});
},
child: new Text("点击弹吐司"),
),
);
2.3:加返回值的方法调用:
举什么例子,我想了一会,就来个MD5码吧
//Activity添加判断分支
if (methodCall.method.equals("getMD5")) {
String arg = methodCall.argument("arg");
String md5 = getMD5(arg);
result.success(md5);
}
/**
* 获取一个字符串的Md5值
*
* @param content 内容
* @return Md5值
*/
public String getMD5(String content) {
content = content + "芝麻开门";
try {
MessageDigest digest = MessageDigest.getInstance("MD5");
digest.update(content.getBytes());
return getHashString(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
private static String getHashString(MessageDigest digest) {
StringBuilder builder = new StringBuilder();
for (byte b : digest.digest()) {
builder.append(Integer.toHexString((b >> 4) & 0xf));
builder.append(Integer.toHexString(b & 0xf));
}
return builder.toString();
}
2.2:Flutter代码:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
const platform = const MethodChannel("www.toly1994.com/test.名字随意起");
var toastTest = Center(
child: RaisedButton(
onPressed: () {
var result= platform.invokeMethod("getMD5",{"arg":"https://www.jianshu.com/p/9bac0072d1a0"});
result.then((str){
platform.invokeMethod("showToast",{"msg":str});
});
},
child: new Text("点击弹吐司"),
),
);
基本上也就这三种情况
[彩蛋]–以前Mark的一个小点:Card的shape
有人说学习的时候一个问题会牵扯到很多其他的问题,问题一多就无从下手
我只说一个字:"栈":来最后一波学习看源码的方法了,走起
1.shape是什么:形状
现在的问题栈
可见默认圆角是4的RoundedRectangleBorder
---->[shape属性]----
/// The default shape is a [RoundedRectangleBorder] with a circular corner
/// radius of 4.0.
final ShapeBorder shape;
---->[RoundedRectangleBorder]----
const RoundedRectangleBorder({
this.side = BorderSide.none,
this.borderRadius = BorderRadius.zero,
//可见有两个属性:BorderSide和BorderRadius
---->[BorderSide]----
class BorderSide {
/// Creates the side of a border.
///
/// By default, the border is 1.0 logical pixels wide and solid black.
const BorderSide({
this.color = const Color(0xFF000000),
this.width = 1.0,
this.style = BorderStyle.solid,
---->[BorderRadius]----
class BorderRadius extends BorderRadiusGeometry {
/// Creates a border radius where all radii are [radius].
const BorderRadius.all(Radius radius) : this.only(
topLeft: radius,
topRight: radius,
bottomLeft: radius,
bottomRight: radius,
);
/// Creates a border radius where all radii are [Radius.circular(radius)].
BorderRadius.circular(double radius) : this.all(
Radius.circular(radius),
);
---->[Radius]------
class Radius {
/// Constructs a circular radius. [x] and [y] will have the same radius value.
const Radius.circular(double radius) : this.elliptical(radius, radius);
/// Constructs an elliptical radius with the given radii.
const Radius.elliptical(this.x, this.y);
/// The radius value on the horizontal axis.
final double x;
/// The radius value on the vertical axis.
final double y;
一个shape牵扯出这么多类,有人可能就
栈溢出
了,还是使用默认的吧,等一下,且听我分析
当Radius入问题栈之后,看一下也就是两个值,就出栈了,BorderRadius跟着也出栈了
BorderSide三个字段,看一下,出栈了,现在栈顶是RoundedRectangleBorder
你还不会吗?
2. RoundedRectangleBorder改变圆角大小+边线
var card_shape = Card(
// shape: CircleBorder(side: BorderSide(width: 1)),
shape: RoundedRectangleBorder(
side:BorderSide(color: Color(0xffD516F5),width: 5) ,
borderRadius: BorderRadius.all(Radius.circular(20))),
clipBehavior: Clip.antiAlias,
child: Container(
width: 100,
height: 100,
color: Color(0xffCDECF6),
child: Center(child:Text(
"捷",
style: TextStyle(color: Colors.black,fontSize: 40),
) ,),
));
那弹栈过后问题跑哪里?
我想应该是临时知识库
吧,你解决的问题中获取的知识,经验会累积
可能长久不用知识库里的知识会漏掉,但印象有的,下一次再入栈,解决起来会更快
在的知识库里扎根的知识,那当你遇到时,就不是问题,直接弹栈,这样想学习是不是也挺好玩的
大神级的Coder知识库丰富,问题都不是问题,也许偶尔入栈一两个,但栈很深(感觉挺浪费哈)
新手就是栈比较浅,问题多,所以容易StackOver
,所以修炼你容忍问题的能力(栈深)很有必要
像我这样不深不浅的刚刚好,会碰到问题,也能一点点解决,一点一点踏上封神之路
但所有的大神也都是从新手这样过来的,解决问题的能力也不是与生俱来,祝你慢慢弹栈,收获多多。
3.接下来看ShapeBorder
在栈顶,我们去瞅瞅
BorderSide现在已经化敌为友,CircleBorder岂不是秒出栈,并且俘获
CircleBorder
一枚
而且BorderSide强化+1,知识就是这样积累的,难道还有别的方法吗?除非记忆拷贝…
转一转当CD背景感觉挺不错
var card_shape = Card(
shape: CircleBorder(side: BorderSide(width: 15,color: Color(0xffF9DFA7))),
clipBehavior: Clip.antiAlias,
child: Container(
width: 100,
height: 100,
color: Color(0xffCDECF6),
child: Center(child:Text(
"捷",
style: TextStyle(color: Colors.black,fontSize: 40),
) ,),
));
4.前方高能,非战斗人员带好零食
其实觉得shape好玩,是在粗略看源码时,看到了canvas,才mark的
自定义ShapeBorder走起:画具在手,天下我有
var card_shape = Card(
shape: StarBorder(),
// shape: CircleBorder(side: BorderSide(width: 15,color: Color(0xffF9DFA7))),
// shape: RoundedRectangleBorder(
// side:BorderSide(color: Color(0xffD516F5),width: 5) ,
// borderRadius: BorderRadius.all(Radius.circular(20))),
clipBehavior: Clip.hardEdge,
child: Container(
width: 100,
height: 100,
color: Color(0xffCDECF6),
child: Center(
child: Text(
"捷",
style: TextStyle(color: Colors.black, fontSize: 40),
),
),
));
class StarBorder extends ShapeBorder {
@override
// TODO: implement dimensions
EdgeInsetsGeometry get dimensions => null;
@override
Path getInnerPath(Rect rect, {TextDirection textDirection}) {
// TODO: implement getInnerPath
return null;
}
@override
Path getOuterPath(Rect rect, {TextDirection textDirection}) {
print(rect.right);
return regularPolygonPath(10, 50,x: rect.height/2,y: rect.width/2);
}
@override
void paint(Canvas canvas, Rect rect, {TextDirection textDirection}) {
canvas.translate(50, 50);
// canvas.drawPath(nStarPath(5, 40, 20), new Paint());
}
@override
ShapeBorder scale(double t) {
// TODO: implement scale
return null;
}
}
路径封装(稍微优化了一下)
/**
* n角星路径
*
* @param num 几角星
* @param R 外接圆半径
* @param r 内接圆半径
* @return n角星路径
*/
Path nStarPath(int num, double R, double r, {x = 0, y = 0}) {
Path path = new Path();
double perDeg = 360 / num; //尖角的度数
double degA = perDeg / 2 / 2;
原创文章,作者:3628473679,如若转载,请注明出处:https://blog.ytso.com/148618.html