-
2021-08-26 18:12:26
交 流 分 享 扣 扣 群 : 925920448 \color{red}{交流分享扣扣群:925920448} 交流
更多相关内容 -
flutter 仿微信朋友圈发布图片
2019-12-05 17:46:48控件类, 里面放了很多自己写的一些组件,所以有很多相机用不...另外也可以传网络图片进去显示,格式为: PhotoFrame(imagesShow:_imagesShow); _imagesShow = [ {id: 60, image: https://www.tricklen.com/p...控件类,
里面放了很多自己写的一些组件,所以有很多相机用不到的引用,
但为了防止误删一些引用,所有的都没有删除,如果拿去用,灰色的可以直接删掉即可,
另外也可以传网络图片进去显示,格式为:PhotoFrame(imagesShow:_imagesShow); _imagesShow = [ {id: 60, image: https://www.tricklen.com/publicImage/1bed62c0e9e7406795317f1b16e94632.jpg}, {id: 61, image: https://www.tricklen.com/publicImage/ed179d808682455e9cf8b8f0f9d40f08.jpg}, {id: 62, image: https://www.tricklen.com/publicImage/4015cf30afd94e60a3d3a5b2bd562827.jpg}, {id: 137, image: https://www.tricklen.com/publicImage/3046cc0f8d8746e7a0f3c70cb7add240.jpg}, {id: 138, image: https://www.tricklen.com/publicImage/5a668a7baae941a6ac826978ddbdf84e.jpg} ];
其中,id为网图的id,是为了删除识别的需要
import 'package:flutter/material.dart'; import 'dart:math' as math; import 'package:redenvelope/pages/extendBlackList/blackLiatDetails.dart'; import 'package:redenvelope/pages/extendBlackList/blackLiatDetails1.dart'; import 'package:redenvelope/constant/colors.dart'; import 'package:redenvelope/widget/UserImg.dart'; import 'package:fluttertoast/fluttertoast.dart'; //弹出框库 import 'package:image_picker/image_picker.dart'; //调用相机 相册 import 'package:dio/dio.dart'; import 'dart:io'; import 'package:photo/photo.dart'; //调用photo库 import 'package:photo_manager/photo_manager.dart'; import 'package:flutter_image_compress/flutter_image_compress.dart'; //图片压缩 import 'dart:async'; import 'package:redenvelope/constant/App.dart'; import 'package:redenvelope/widget/UserImg.dart'; import 'package:redenvelope/pages/extendBlackList/domeData.dart'; // 相机组件 class PhotoFrame extends StatefulWidget{ var imagesShow; PhotoFrame({this.imagesShow}); @override State<StatefulWidget> createState() { print("---------------图片是否传递---------------------"); print(imagesShow); return new PhotoFrameState(); } } class PhotoFrameState extends State<PhotoFrame> with WidgetsBindingObserver { List<Widget> _imageShow = []; // 获取的需要显示的数组 List _imageUrlShow = []; var item; //数据封装 Widget addImage; int index = 1; List<String> imageUrl = []; //存放偶像头像地址的数组 File _image; //当前图片 List<File> images = []; //记录所有图片 List<Widget> ConList = []; //显示复数图片的数组 List<UploadFileInfo> _rq = []; //FormData内传递的值 // 单张相机取图片 Future getImage() async { var image = await ImagePicker.pickImage(source: ImageSource.camera); //相机 _image = image; print(_image); images.add(_image); ff(); } // 多张连选取图 void _pickImage() async { List<AssetEntity> imgList = await PhotoPicker.pickAsset( //需要BuildContext context: context, ///以下是可选参数。 themeColor: AppColors.colorPrimary, //标题颜色和底部颜色 padding: 1.0, //项目填充 dividerColor: Colors.grey, //分隔线颜色 disableColor: Colors.grey.shade300, //复选框禁用颜色 itemRadio: 0.88, //内容项目radio maxSelected: 8 - images.length -_imageUrlShow.length, //最大选择器图像计数 provider: I18nProvider.chinese, //提供者:I18nProvider.chinese, // i18n提供者,默认为中文。 ,您可以自定义I18nProvider或使用ENProvider() rowCount: 3, //项目行数 textColor: Colors.white, //文字颜色 thumbSize: 150, //预览拇指大小,默认为64 sortDelegate: SortDelegate.common, //默认是常见的,或者您可以自定义委托来对图库进行排序 checkBoxBuilderDelegate: DefaultCheckBoxBuilderDelegate( activeColor: Colors.white, unselectedColor: Colors.white, ), //默认为DefaultCheckBoxBuilderDelegate,或者您创建自定义委托以创建复选框 //loadingDelegate: this, //如果你想构建自定义加载小部件,请扩展LoadingDelegate,[参见example / lib / main.dart] badgeDelegate: const DurationBadgeDelegate(), ); //List<String> r = [];//路径 for (var e in imgList) { _image = await e.file; //r.add(_image.absolute.path);//获取路径 print(_image); images.add(_image); } ff(); } // 处理图片 void ff() { if (ConList.length > 1) { ConList.removeRange(1, ConList.length); } // 先读取传过来的图片,并显示 if(_imageUrlShow.length!=0){ for (var i = 0; i < _imageUrlShow.length; i++) { ConList.add( new Stack( alignment: const FractionalOffset(1.30, -0.3), children: <Widget>[ Container( height: 95, width: 95, child: Image.network(_imageUrlShow[i]["image"], fit: BoxFit.cover), ), IconButton( iconSize: 20, icon: Container( child: Icon(Icons.clear,color: Colors.black,), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10.0), //10像素圆角 ), ), onPressed: () { setState(() { print("--------------------是否传递图片过来过---------------------------"); print(_imageUrlShow[i]["id"].toString()); print(ConList); print(_imageUrlShow); // 添加删除图片的id SaveData.imagesRemoveId = SaveData.imagesRemoveId +_imageUrlShow[i]["id"].toString()+"|"; //删除数组中存储的图片地址 var x = _imageUrlShow.remove(_imageUrlShow[i]); print(x); //删除组件 ConList.remove(ConList[i + 1]); ff(); }); }, ), ], ), ); } } // 在读取本地图片,并显示 if(images.length!=0){ for (var i = 0; i < images.length; i++) { ConList.add( new Stack( alignment: const FractionalOffset(1.30, -0.3), children: <Widget>[ Container( height: 95, width: 95, child: Image.file(images[i], fit: BoxFit.cover), ), IconButton( color: Colors.grey[350], iconSize: 20, icon: Container( child: Icon(Icons.clear,color: Colors.black,), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10.0), //10像素圆角 ), ), onPressed: () { setState(() { //删除当前图片 _image = null; //删除数组中存储的图片地址 var x = images.remove(images[i]); print(x); //删除组件 ConList.remove(ConList[i + 1]); print(ConList); ff(); }); }, ), ], ), ); } _saveDate(); } setState(() {}); } // 封装数据 Future _saveDate() async { _rq.clear(); //压缩图片并封装 for (var i = 0, len = images.length; i < len; i++) { File file = images[i]; file = await FlutterImageCompress.compressAndGetFile( file.absolute.path, Directory.systemTemp.path + '/head' + i.toString() + '.jpg', minWidth: 1920, minHeight: 1080, quality: 60, ); _rq.add(new UploadFileInfo( file, App.userid.toString() + i.toString() + ".jpg")); } SaveData.imagesListFlie = images; SaveData.imagesList = _rq; print("图片文件数组长度"+SaveData.imagesListFlie.length.toString()); print("图片上传数据流数组长度"+SaveData.imagesList.length.toString()); return true; } @override void initState() { super.initState(); _imageUrlShow = widget.imagesShow==null? []: widget.imagesShow; ConList.add(Container( color: Colors.grey[200], height: 95, width: 95, child: FlatButton( onPressed: () { //弹出底部弹窗 showModalBottomSheet( context: context, builder: (BuildContext context) { return Column( mainAxisSize: MainAxisSize.min, children: <Widget>[ Container( decoration: BoxDecoration( //背景装饰 borderRadius: BorderRadius.circular(5.0), ), child: Column( mainAxisSize: MainAxisSize.min, children: <Widget>[ ListTile( title: Center( child: Center( child: Text( '请选择', style: TextStyle(color: Colors.black26,fontFamily:'appIconFonts'), ), ), ), ), Divider2(), ListTile( title: Center( child: Text("拍照",style: TextStyle(fontFamily:'appIconFonts'),), ), onTap: () { //调用相机 Navigator.of(context).pop(); images.length + _imageUrlShow.length < 8 ? getImage() : Fluttertoast.showToast( msg: "图片的数量不能超过8张", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.CENTER, timeInSecForIos: 1, backgroundColor: Colors.black12, textColor: Colors.black, fontSize: 16.0); }, ), Divider2(), ListTile( title: Center( child: Text("从本地相册选择",style: TextStyle(fontFamily:'appIconFonts'),), ), onTap: () { Navigator.of(context).pop(); //读取相册 images.length + _imageUrlShow.length < 8 ? _pickImage() : Fluttertoast.showToast( msg: "图片的数量不能超过8张", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.CENTER, timeInSecForIos: 1, backgroundColor: Colors.black12, textColor: Colors.black, fontSize: 16.0); }, ), ], ), ), Container( height: 10, color: Colors.black26, ), ListTile( title: Center( child: Text( "取消", style: TextStyle( fontWeight: FontWeight.w600,fontFamily:'appIconFonts' ), textScaleFactor: 1.0, ), ), ), ], ); }); }, child: Icon( Icons.add_a_photo, color: Colors.black26, )), )); ff(); } @override void dispose() { super.dispose(); } @override Widget build(BuildContext context) { if (App.wangLuoZhaugnTai == 1) { return Center( child: Text('网络错误,无法执行...',style: TextStyle(fontFamily:'appIconFonts'),), ); } print(ConList); return Container( // padding: EdgeInsets.fromLTRB(10, 5, 10, 5), margin: EdgeInsets.only(left: 10.0, right: 10.0, bottom: 0.0), child: Container( child: Wrap( spacing: 8.0, // 主轴(水平)方向间距 runSpacing: 4.0, // 纵轴(垂直)方向间距 children: ConList, ), )); } }
需要几个插件
image_picker
flutter_image_compress
photo
这个是压缩图片的,非必须,但是如果不用,就可以直接注释掉关于这个插件的调用调用很简单,一句话,如果不用显示上次图片,不用传递参数
PhotoFrame();
另外需要一个存储类,用来存储选中的图片
// 存储选择图片 class SaveData { // 存储图片文件 static List imagesListFlie=[] ; // 存储图片字节码 static List imagesList = []; // 需要删除的图片的id,这些图片为上次上传的图片 static String imagesRemoveId = ''; // 当前坐标 static double X; static double Y; // 清除缓存,初始化数据 static void clearListFlie(){ SaveData.imagesListFlie.clear(); SaveData.imagesList.clear(); SaveData.imagesRemoveId = ""; } }
clearListFlie方法用于重复调用此控件的时候防止上次的数据残留,可以写在每次调用控件的之前
-
R plot图片背景设置为透明_R语言(绘图入门)
2020-10-22 18:08:18原文链接:...用了 Python 的 matplolibt 和 R 的 ggplot2 后,我再也不想用 MATLAB 画图了。我现在这里先给出本博文用到的包:libraryLoading required package: latticeLoading req...原文链接:https://wklchris.github.io/R-plotting-basic.html
R 的绘图功能一直为业内所津津乐道。用了 Python 的 matplolibt 和 R 的 ggplot2 后,我再也不想用 MATLAB 画图了。
我现在这里先给出本博文用到的包:
library
Loading required package: lattice
Loading required package: survival
Loading required package: Formula
Loading required package: ggplot2
Attaching package: 'Hmisc'
The following objects are masked from 'package:base':
format.pval, round.POSIXt, trunc.POSIXt, unitslibrary
Loading required package: sm
Package 'sm', version 2.2-5.4: type help(sm) for summary information基础命令
使用
dev.new()
命令新建一个图片视图,这样你可以输出多个图片到屏幕,而不是让之后输出的覆盖之前的图形。关于 dev.next(), dev.prev(), dev.set() 及 dev.off() 等内容,参考 help(dev.cur).plot() 绘图类型
基本的绘图类型有以下几种,使用 type= 参数指定:
p:仅数据点,默认值。
l:仅线段
b:线段与点
c:仅线段,但点的位置留出空白
o:线段与点,但线段会延伸到点内部
h:直方图风格,即带竖直密度线
s:阶梯图
S:其他特殊情况
n;不绘制图形。用于指定标题、坐标轴名称的情况
输出到文件
将画图的内容输出到文件,可以指定路径,不指定就输出到当前工作目录。例如输出 pdf:
pdf("plot.pdf")
plot(c(1, 2, 3), c(3, 4, 2))
dev.off()除了 pdf() 外,其他可用的输出格式对应函数:
wmf:win.metafile(),仅在 Windows 系统下使用
png: png()
jpeg: jpeg()
bmp: bmp()
tiff: tiff()
ps: postscript()
例子。详细的参数在下文讨论。
x
绘图参数:par()
函数 par() 用来获取当前图形的参数。如果加入 no.readonly=TRUE, 表示该参数列表是非只读的,即用户可以进行修改。例如对于上图,我们获取其参数,进行更改后再传到新的图中(pch 参数可能有些费解,我们在下文讨论):
# 方法一:类交互式的更改方法
点样式、线宽与线型
参数 可选值 pch 点样式 0空方块,1空圆,2空三角,3加号,4乘号,5斜空方块,6空倒三角,7叉方块,8星号,9斜叉方块,10圈加号,11六芒星,12田,13圈乘号,14加框尖角,15方块,16圆点,17三角,18斜方块,19带边线圆点,20带边线2/3圆点,21填充圆,22填充方块,23填充斜方块,24填充三角,25填充倒三角。 cex 点大小 数字,例如 0.5。 lty 线型 1实线,2短虚线,3点线,4点划线,5长虚线,6长短划线。 lwd 线宽 数字。 注: pch = 19 相比 pch = 16,主要体现在 lwd 与 cex 不同时,带边线圆点的尺寸较大。
颜色
调整颜色的参数有:
col: 绘图颜色。
col.axis:坐标轴刻度颜色。
col.lab:坐标轴名称颜色。
col.main:图形标题颜色。
col.sub:副标题颜色。
fg:图形前景色。
bf:图形背景色。
指定颜色的方式有如下几种:
数字下标:col=1
名称:col=”white”
十六进制值:col=”#FFFFFF”
标准化RGB/HSV值:col=rgb(0,1,1)/hsv(0,0,1)
至于 R 支持的颜色名称,多达 600 余种,这里给出一些我认为常见的:
OutputColors
R 中还有其他方式可以生成一系列的颜色,比如:
par
标签和标题文本
从上文可以看出端倪,标签与标题参数有:
标题/副标题:title/sub
坐标轴标题:xlab/ylab
在标题中使用上文介绍的参数:
title(main="My Title", col.main="red",
sub="My Subtitle", col.sub="blue",
xlab="My X label", ylab="My Y label",
col.lab="green", cex.lab=0.75)要定义它们的字体,可添加的参数有:
参数 含义 cex 基础缩放倍数 cex.axis 坐标轴刻度的缩放倍数 cex.lab 坐标轴标题的缩放倍数 cex.main 图形标题的缩放倍数 cex.sub 图形副标题的缩放倍数 font 字体样式。1常规,2加粗,3加斜,4加粗加斜,5符号字体 font.axis 坐标轴刻度的字体样式 font.lab/ main/ sub 类推 ps 字体磅值。文字的最终大小为 cex * ps family 字族。例如 serif衬线, sans无衬线, mono等宽 字族的使用需要注意:Windows 中,等宽映射为 Courier New,衬线 Times New Roman,无衬线 Arial。你可以使用 windowsFonts() 函数来更改或者创建映射,例如我个人常用的 DejaVu 等宽字体:
windowsFonts
如果你需要将图片输出到 pdf,这个参数也是可以使用的:
pdf(file="filename.pdf", family="M")
图形尺寸与边距
参数 pin 用于指定图形尺寸(英寸),例如
pin=c(4, 3)
表示 4 英寸宽 3 英寸高。用 mai()/mar() 依次指定下左上右四个方向的边距,单位分别是英寸与英分。默认是
mar(c(5, 4, 4, 2)) + 0.1
自定义其他元素
坐标轴
函数 side() 用于自定义坐标轴:
axis(side, at=, labels=, pos=, lty=, col=, las=, tck=, ...)
side: 指定在哪绘制坐标轴:1下2左3上4右
at:刻度线位置
labels:刻度线旁的标签,缺省时使用 at 中的值
pos:坐标轴与另一坐标轴相交位置的值
lty/col:线型/线与刻度的颜色
las:标签平行于(=0)或垂直于(=2)坐标轴
tck:刻度线。负值表示在图形外侧,0表示禁用刻度,1表示全长(即网格线);默认 -0.01
网格线:abline() 与次要刻度
如果想使用次要刻度,请安装 Hmisc 包。次要刻度的长度将会是主刻度的
tick.ratio
倍。网格线使用 abline() 命令,并分别用 h/v 指定网格线是竖直还是水平。
# 需要加载:library(Hmisc)
图例
命令 legend() 用于添加图例。
legend(location, legend, [title=, ...])
参数含义:
location:指定图例左上角的坐标,或者使用以下关键字:
关键字:left/right, bottom/top, bottomleft/right, topleft/right, center
如果使用了以上关键字,可以使用 inset= 参数指定向图形内移动的比例(分数形式)
legend:标签组成的字符型向量。
title:图例标题的字符串
其他参数:
col/pch/lwd/lty:图例线条颜色/点样式/线宽/线型
bty/fill:盒型样式/颜色填充(用于条形图、箱形图或饼图)
bg:背景色
text.col:文本颜色
horiz:TRUE 会将图例水平放置
例子参见“直方图”一节的最后一例。
标注
文字标注
主要有两个函数:text() 与 mtext()。前者向绘图区添加标注,后者向图形的边界添加标注。
text(location, "string", pos, ...)
mtext("string", side, line=n, ...)可以参考“标签和标题文本”一节的例子。其中:
pos:使用1下2左3上4右的对应关系,比如“颜色”一节中就使用了 pos=1 的参数。
如果指定了 pos,那么也可以指定 offset= 作为偏移量比值(相对单个字符宽)
side:指定放置文本的图片边界,同样是1下2左3上4右。
你可以使用 line= 来移动文本(正值向外,负值向内);
还可以通过 adj=0/1 指定文本向左下/右上对齐。
数学标注
类似 LaTeX 的标注方式,不过实质上仍有一些区别:
代码 效果 代码 效果 代码 效果 x%+-%y x±y" role="presentation" style="display: inline-block; line-height: 0; text-align: left; font-size: 18.72px; overflow-wrap: normal; word-spacing: normal; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border-width: 0px; border-style: initial; border-color: initial; padding-top: 1px; padding-bottom: 1px;">x±yx±y x%/%y x÷y" role="presentation" style="display: inline-block; line-height: 0; text-align: left; font-size: 18.72px; overflow-wrap: normal; word-spacing: normal; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border-width: 0px; border-style: initial; border-color: initial; padding-top: 1px; padding-bottom: 1px;">x÷yx÷y x%*%y x×y" role="presentation" style="display: inline-block; line-height: 0; text-align: left; font-size: 18.72px; overflow-wrap: normal; word-spacing: normal; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border-width: 0px; border-style: initial; border-color: initial; padding-top: 1px; padding-bottom: 1px;">x×yx×y x%.%y x⋅y" role="presentation" style="display: inline-block; line-height: 0; text-align: left; font-size: 18.72px; overflow-wrap: normal; word-spacing: normal; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border-width: 0px; border-style: initial; border-color: initial; padding-top: 1px; padding-bottom: 1px;">x⋅yx⋅y x[i] xi" role="presentation" style="display: inline-block; line-height: 0; text-align: left; font-size: 18.72px; overflow-wrap: normal; word-spacing: normal; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border-width: 0px; border-style: initial; border-color: initial; padding-top: 1px; padding-bottom: 1px;">xixi x^2 x2" role="presentation" style="display: inline-block; line-height: 0; text-align: left; font-size: 18.72px; overflow-wrap: normal; word-spacing: normal; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border-width: 0px; border-style: initial; border-color: initial; padding-top: 1px; padding-bottom: 1px;">x2x2 x%prop%y x∝y" role="presentation" style="display: inline-block; line-height: 0; text-align: left; font-size: 18.72px; overflow-wrap: normal; word-spacing: normal; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border-width: 0px; border-style: initial; border-color: initial; padding-top: 1px; padding-bottom: 1px;">x∝yx∝y sqrt(x, y) xy" role="presentation" style="display: inline-block; line-height: 0; text-align: left; font-size: 18.72px; overflow-wrap: normal; word-spacing: normal; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border-width: 0px; border-style: initial; border-color: initial; padding-top: 1px; padding-bottom: 1px;">y√xxy x!=y x≠y" role="presentation" style="display: inline-block; line-height: 0; text-align: left; font-size: 18.72px; overflow-wrap: normal; word-spacing: normal; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border-width: 0px; border-style: initial; border-color: initial; padding-top: 1px; padding-bottom: 1px;">x≠yx≠y x%~~%y x≈y" role="presentation" style="display: inline-block; line-height: 0; text-align: left; font-size: 18.72px; overflow-wrap: normal; word-spacing: normal; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border-width: 0px; border-style: initial; border-color: initial; padding-top: 1px; padding-bottom: 1px;">x≈yx≈y x%=~%y x≅y" role="presentation" style="display: inline-block; line-height: 0; text-align: left; font-size: 18.72px; overflow-wrap: normal; word-spacing: normal; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border-width: 0px; border-style: initial; border-color: initial; padding-top: 1px; padding-bottom: 1px;">x≅yx≅y x%==%y x≡y" role="presentation" style="display: inline-block; line-height: 0; text-align: left; font-size: 18.72px; overflow-wrap: normal; word-spacing: normal; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border-width: 0px; border-style: initial; border-color: initial; padding-top: 1px; padding-bottom: 1px;">x≡yx≡y 部分字体相关的命令:
plain(x):正体
italic(x):意大利字族(加斜)
bold(x):加粗
bolditalic(x):加斜加粗
underline(x):下划线
叠加绘图
叠加绘图最简单的方法,就是使用绘图的
new=TRUE
:plot
如果想要添加额外的点、线,使用
points()
命令与lines()
命令。以及上面提到的参考线abline()
命令:plot
子图
函数 layout()
函数 layout() 是一个强大的命令。例如:
layout(matrix(c(1,1,2,3), 2, 2, byrow = TRUE))
就指定了图 1 占用第一行,图 2 和 3 共用第二行。也可以用 widths=/heights= 参数指定各列宽/各行高之间的比例:
tmp
函数 par() 的 mfrow 参数
前文介绍过的 par() 中的 mfrow= 参数也是一个控制子图的方式。下例是两行两列的子图:
opar par(mfrow=c(2,2))
plot(...) # 图 1,左上
plot(...) # 图 2,右上
plot(...) # 图 3,左下
plot(...) # 图 4,右下
par(opar)函数 par() 的 fig 参数
这种方式支持你以任何的位置、组合任意的图形。它比规整的 layout() 更加灵活。以下不使用 0.8 而使用 0.65 是为了看上去更紧凑。
opar
统计图
条形图:barplot()
直接上例子。
tmp
饼图:pie()
并不推荐的统计图类型,因此 R 中的功能也很有限。
pie
dt
直方图:hist() 及核密度曲线
直方图表示的是一维的数据(连续型)特征,纵轴是其在对应横轴区间内的频数或者频率。
hist
其中 freq 参数默认指定纵轴为频数而不是频率,break 用于指定横轴上分组的个数。
set.seed
轴须图是一种一维的数据呈现,而上面的左图中的密度曲线是一种核密度估计。要比较核密度图,参考 sm 包的 sm.density.compare() 函数。如果只是要绘制,使用 density() 函数辅助即可:
plot
箱形图:boxplot() 及小提琴图
或者叫箱线图、盒须图。它描述了连续变量的五个特征参数:
fig
如果是 dataframe 数据集中的类别型变量 A ,使用如下语句生成并列箱形图:
boxplot(y~A, data=dataframe)
如果将公式改写成
y~A*B
,那么会将类别型变量 A 和 B 的各水平两两组合,再生成箱形图。其他参数:
varwidth=F/T:为 TRUE 时,箱形图的宽度与样本数的算术平方根成正比。
horizontal=F/T:为 TRUE 时,箱形图被横置。
notch=F/T:为 TRUE 时,箱形图在绘制时会显示“凹槽”。
df
最后再提一下箱形图与核密度图的一个结合体:小提琴图(violin plot)。这种图的绘制需要 vioplot 包。
在小提琴图中,核密度曲线被竖直放置,并对称地显示于数据轴的两侧:
# 需要加载:library(vioplot)
点图
用于在水平刻度上绘制大量标签。本例选自参考书目同名章节。各参数:
groups:选定一个因子,作为分组依据。
gcolor:各组标签的颜色。
# mtcars 是 R 预装的数据集,其 cyl 变量有三个水平
猜你可能喜欢
MySQL 面试之必会知识点
R语言文本分词之——Rwordseg包
Python科学计算:pandas
Python科学计算:numpy
kmeans算法python代码——可直接运行
梯度下降算法
-
Android仿微信朋友圈图片查看器
2021-06-02 17:52:53再看文章之前,希望大家先打开自己的微信点到朋友圈中去,仔细观察是不是发现朋友圈里的有个“九宫格”的图片区域,点击图片又会跳到图片的详细查看页面,并且支持图片的滑动和缩放?这个功能是不是很常用呢?!那么...再看文章之前,希望大家先打开自己的微信点到朋友圈中去,仔细观察是不是发现朋友圈里的有个“九宫格”的图片区域,点击图片又会跳到图片的详细查看页面,并且支持图片的滑动和缩放?这个功能是不是很常用呢?!那么我今天正好做了这个Demo,下面为大家讲解一下。首先按照惯例先看一下效果图吧,尤其不会录制gif动画(哎~没办法,模拟器不支持多点触控,刚好我的手机又没有Root,不能录屏,悲催啊,大家见谅,想要看真实效果的话,烦请移到文章最下方转载文章中进行源码下载,点击下载源码,运行后再看效果哈~~),这里先就拿几张静态的图片顶替一下好了。见谅!
效果嘛,将就着看吧!实在看不明白就想想微信朋友圈,或者拖到下方,点击下载源码!这里,首先分析一下主界面吧,布局都是很简单的,主界面仅仅就是一个ListView的控件,ListView的Item上值得注意的是,Item上包含了一个GridView,这个GridView呗用作实现“九宫格”的效果,主界面布局就是一个ListView,这里不说了,我们先来看看ListView的Item的布局吧,以下是item_list.xml
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="5dp"
android:paddingTop="5dp" >
android:id="@+id/iv_avatar"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@drawable/ic_launcher"
android:scaleType="centerCrop" />
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_toRightOf="@id/iv_avatar"
android:text="爷,今天心情好!"
android:textSize="16sp" />
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_title"
android:layout_marginLeft="5dp"
android:layout_marginTop="3dp"
android:layout_toRightOf="@id/iv_avatar"
android:text="今天又是雾霾!"
android:textSize="16sp" />
android:id="@+id/gridview"
android:layout_width="220dp"
android:layout_height="wrap_content"
android:layout_below="@id/tv_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="3dp"
android:layout_toRightOf="@id/iv_avatar"
android:columnWidth="70dp"
android:gravity="center"
android:horizontalSpacing="2.5dp"
android:numColumns="3"
android:stretchMode="columnWidth"
android:verticalSpacing="2.5dp" />
好了,大家看到了,布局也是极其简单的,但是有个问题就是ListView嵌套进了GridView,那么就会出现一个问题,导致GridView显示的不全,那么该怎么解决这个问题呢?其实也简单,就是重写一个GridView,测量一下GridView的高度,再设置上去。具体解决方案请看上篇博文ListView嵌套GridView显示不全解决方法或者源码,如下NoScrollGridView.java
package com.example.imagedemo;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.GridView;
/**
* 自定义的“九宫格”——用在显示帖子详情的图片集合 解决的问题:GridView显示不全,只显示了一行的图片,比较奇怪,尝试重写GridView来解决
*
* @author lichao
* @since 2014-10-16 16:41
*
*/
public class NoScrollGridView extends GridView {
public NoScrollGridView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public NoScrollGridView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public NoScrollGridView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
接下来看看ListView上面Item的实体是什么样的数据结构,这就显得非常简单了。
public class ItemEntity {
private String avatar; // 用户头像URL
private String title; // 标题
private String content; // 内容
private ArrayList imageUrls; // 九宫格图片的URL集合
public ItemEntity(String avatar, String title, String content,
ArrayList imageUrls) {
super();
this.avatar = avatar;
this.title = title;
this.content = content;
this.imageUrls = imageUrls;
}
...
}
好了,有了ListView,那么不可避免的就是做Item上的数据适配了。继承一个BaseAdapter,代码如下,都比较简单:
/**
* 首页ListView的数据适配器
*
* @author Administrator
*
*/
public class ListItemAdapter extends BaseAdapter {
private Context mContext;
private ArrayList items;
public ListItemAdapter(Context ctx, ArrayList items) {
this.mContext = ctx;
this.items = items;
}
@Override
public int getCount() {
return items == null ? 0 : items.size();
}
@Override
public Object getItem(int position) {
return items.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = View.inflate(mContext, R.layout.item_list, null);
holder.iv_avatar = (ImageView) convertView
.findViewById(R.id.iv_avatar);
holder.tv_title = (TextView) convertView
.findViewById(R.id.tv_title);
holder.tv_content = (TextView) convertView
.findViewById(R.id.tv_content);
holder.gridview = (NoScrollGridView) convertView
.findViewById(R.id.gridview);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
ItemEntity itemEntity = items.get(position);
holder.tv_title.setText(itemEntity.getTitle());
holder.tv_content.setText(itemEntity.getContent());
// 使用ImageLoader加载网络图片
DisplayImageOptions options = new DisplayImageOptions.Builder()//
.showImageOnLoading(R.drawable.ic_launcher) // 加载中显示的默认图片
.showImageOnFail(R.drawable.ic_launcher) // 设置加载失败的默认图片
.cacheInMemory(true) // 内存缓存
.cacheOnDisk(true) // sdcard缓存
.bitmapConfig(Config.RGB_565)// 设置最低配置
.build();//
ImageLoader.getInstance().displayImage(itemEntity.getAvatar(),
holder.iv_avatar, options);
final ArrayList imageUrls = itemEntity.getImageUrls();
if (imageUrls == null || imageUrls.size() == 0) { // 没有图片资源就隐藏GridView
holder.gridview.setVisibility(View.GONE);
} else {
holder.gridview.setAdapter(new NoScrollGridAdapter(mContext,
imageUrls));
}
// 点击回帖九宫格,查看大图
holder.gridview.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
imageBrower(position, imageUrls);
}
});
return convertView;
}
/**
* 打开图片查看器
*
* @param position
* @param urls2
*/
protected void imageBrower(int position, ArrayList urls2) {
Intent intent = new Intent(mContext, ImagePagerActivity.class);
// 图片url,为了演示这里使用常量,一般从数据库中或网络中获取
intent.putExtra(ImagePagerActivity.EXTRA_IMAGE_URLS, urls2);
intent.putExtra(ImagePagerActivity.EXTRA_IMAGE_INDEX, position);
mContext.startActivity(intent);
}
/**
* listview组件复用,防止“卡顿”
*
* @author Administrator
*
*/
class ViewHolder {
private ImageView iv_avatar;
private TextView tv_title;
private TextView tv_content;
private NoScrollGridView gridview;
}
}
这里有需要解释的地方了,看看listview上的图片处理,由于图片都是从网络获取的,为了避免图片过多造成OOM,那么这里加载图片的时候必不可少的需要做内存优化,图片的优化方式有很多,我这里采取了最简单最直接得方式,使用了开源的ImageLoader这个图片加载框架,这个框架简直是太优秀了,减少了开发者一系列不必要而且时常会出现的麻烦,关于ImageLoader并不是本篇博文需要讲解的知识,关于ImageLoader,欢迎在GitHub主页上下载,地址是https://github.com/nostra13/Android-Universal-Image-Loader,既然使用了ImageLoader这个框架,就不得不在程序上做一些初始化的操作,首先需要自定义一个全局的上下文Application类,将ImageLoader的相关属性初始化上去,直接看代码好了,见名知意:MyApplication.java
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder() //
.showImageForEmptyUri(R.drawable.ic_launcher) //
.showImageOnFail(R.drawable.ic_launcher) //
.cacheInMemory(true) //
.cacheOnDisk(true) //
.build();//
ImageLoaderConfiguration config = new ImageLoaderConfiguration//
.Builder(getApplicationContext())//
.defaultDisplayImageOptions(defaultOptions)//
.discCacheSize(50 * 1024 * 1024)//
.discCacheFileCount(100)// 缓存一百张图片
.writeDebugLogs()//
.build();//
ImageLoader.getInstance().init(config);
}
}
定义这个Application之后,需要在清单文件中配置一下,在Manifest.xml中的Application节点上添加:
android:name="com.example.imagedemo.MyApplication" 此外由于ImageLoader是网络获取图片,又需要本地sdcard缓存图片,所以需要加上一下的权限,这是Imageloader标准权限:
再看看上面的Item上数据,里面有个GridView,显然这个GridView也是需要做数据适配的,这个数据反应的是从网络加载图片,比较简单,看代码NoScrollGridAdapter.java
......
Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = View.inflate(ctx, R.layout.item_gridview, null);
ImageView imageView = (ImageView) view.findViewById(R.id.iv_image);
DisplayImageOptions options = new DisplayImageOptions.Builder()//
.cacheInMemory(true)//
.cacheOnDisk(true)//
.bitmapConfig(Config.RGB_565)//
.build();
ImageLoader.getInstance().displayImage(imageUrls.get(position),
imageView, options);
return view;
}
......
这样,所有的数据适配就做好了,接下来就需要做图片查看器了,当我们点击ListView上Item里的“九宫格”——NoScrollGridView的某张图片的时候,需要把这个图片的url传给一个图片查看器,图片查看器里会根据传递进来的url去网络加载这张图片,那么其实图片查看器就是一个新的单独的Activity,这个Activity会包含一个ViewPager,用来管理多张图片的查看。image_detail_pager.xml
android:layout_width="match_parent"
android:layout_height="match_parent" >
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black" />
android:id="@+id/indicator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@android:color/transparent"
android:gravity="center"
android:text="@string/viewpager_indicator"
android:textColor="@android:color/white"
android:textSize="18sp" />
HackyViewPager.java
public class HackyViewPager extends ViewPager {
private static final String TAG = "HackyViewPager";
public HackyViewPager(Context context) {
super(context);
}
public HackyViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
try {
return super.onInterceptTouchEvent(ev);
} catch (IllegalArgumentException e) {
// 不理会
Log.e(TAG, "hacky viewpager error1");
return false;
} catch (ArrayIndexOutOfBoundsException e) {
// 不理会
Log.e(TAG, "hacky viewpager error2");
return false;
}
}
}
ImagePagerActivity.java
/**
* 图片查看器
*/
public class ImagePagerActivity extends FragmentActivity {
private static final String STATE_POSITION = "STATE_POSITION";
public static final String EXTRA_IMAGE_INDEX = "image_index";
public static final String EXTRA_IMAGE_URLS = "image_urls";
private HackyViewPager mPager;
private int pagerPosition;
private TextView indicator;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.image_detail_pager);
pagerPosition = getIntent().getIntExtra(EXTRA_IMAGE_INDEX, 0);
ArrayList urls = getIntent().getStringArrayListExtra(
EXTRA_IMAGE_URLS);
mPager = (HackyViewPager) findViewById(R.id.pager);
ImagePagerAdapter mAdapter = new ImagePagerAdapter(
getSupportFragmentManager(), urls);
mPager.setAdapter(mAdapter);
indicator = (TextView) findViewById(R.id.indicator);
CharSequence text = getString(R.string.viewpager_indicator, 1, mPager
.getAdapter().getCount());
indicator.setText(text);
// 更新下标
mPager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageScrollStateChanged(int arg0) {
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageSelected(int arg0) {
CharSequence text = getString(R.string.viewpager_indicator,
arg0 + 1, mPager.getAdapter().getCount());
indicator.setText(text);
}
});
if (savedInstanceState != null) {
pagerPosition = savedInstanceState.getInt(STATE_POSITION);
}
mPager.setCurrentItem(pagerPosition);
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putInt(STATE_POSITION, mPager.getCurrentItem());
}
private class ImagePagerAdapter extends FragmentStatePagerAdapter {
public ArrayList fileList;
public ImagePagerAdapter(FragmentManager fm, ArrayList fileList) {
super(fm);
this.fileList = fileList;
}
@Override
public int getCount() {
return fileList == null ? 0 : fileList.size();
}
@Override
public Fragment getItem(int position) {
String url = fileList.get(position);
return ImageDetailFragment.newInstance(url);
}
}
}
已知图片查看的界面是继承自FragmentActivity的,所以支持显示的界面必须需要Fragment来实现,那么就自定义个Frangment吧,用这个Fragment来从url中获取图片资源,显示图片。image_detail_fragment.xml
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black" >
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:contentDescription="@string/app_name"
android:scaleType="centerCrop" />
android:id="@+id/loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
ImageDetailFragment.java
/**
* 单张图片显示Fragment
*/
public class ImageDetailFragment extends Fragment {
private String mImageUrl;
private ImageView mImageView;
private ProgressBar progressBar;
private PhotoViewAttacher mAttacher;
public static ImageDetailFragment newInstance(String imageUrl) {
final ImageDetailFragment f = new ImageDetailFragment();
final Bundle args = new Bundle();
args.putString("url", imageUrl);
f.setArguments(args);
return f;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mImageUrl = getArguments() != null ? getArguments().getString("url")
: null;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.image_detail_fragment,
container, false);
mImageView = (ImageView) v.findViewById(R.id.image);
mAttacher = new PhotoViewAttacher(mImageView);
mAttacher.setOnPhotoTapListener(new OnPhotoTapListener() {
@Override
public void onPhotoTap(View arg0, float arg1, float arg2) {
getActivity().finish();
}
});
progressBar = (ProgressBar) v.findViewById(R.id.loading);
return v;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ImageLoader.getInstance().displayImage(mImageUrl, mImageView,
new SimpleImageLoadingListener() {
@Override
public void onLoadingStarted(String imageUri, View view) {
progressBar.setVisibility(View.VISIBLE);
}
@Override
public void onLoadingFailed(String imageUri, View view,
FailReason failReason) {
String message = null;
switch (failReason.getType()) {
case IO_ERROR:
message = "下载错误";
break;
case DECODING_ERROR:
message = "图片无法显示";
break;
case NETWORK_DENIED:
message = "网络有问题,无法下载";
break;
case OUT_OF_MEMORY:
message = "图片太大无法显示";
break;
case UNKNOWN:
message = "未知的错误";
break;
}
Toast.makeText(getActivity(), message,
Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.GONE);
}
@Override
public void onLoadingComplete(String imageUri, View view,
Bitmap loadedImage) {
progressBar.setVisibility(View.GONE);
mAttacher.update();
}
});
}
}
写到这里,此篇博文也宣告结束了。需要提出的是,我这里的图片查看器实现的图片的缩放效果使用的是开源组件PhotoView,关于PhotoView的github项目地址在这里,https://github.com/chrisbanes/PhotoView需要点进去这个项目的网址,去下载源码,将源码全部拷贝到项目中来,使用也是相当方便的,demo如下:
ImageView mImageView;
PhotoViewAttacher mAttacher;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Any implementation of ImageView can be used!
mImageView = (ImageView) findViewById(R.id.iv_photo);
// Set the Drawable displayed
Drawable bitmap = getResources().getDrawable(R.drawable.wallpaper);
mImageView.setImageDrawable(bitmap);
// Attach a PhotoViewAttacher, which takes care of all of the zooming functionality.
mAttacher = new PhotoViewAttacher(mImageView);
}
// If you later call mImageView.setImageDrawable/setImageBitmap/setImageResource/etc then you just need to call
attacher.update();
刚开始这个图片查看器是我自己自定义View来实现的,其实需要实现图片的手势识别+多点触控+缩放,是可以使用矩阵Matrix来实现的,只不过这样显得特别的麻烦不说,而且极易出现BUG,这对于某些“急功近利”的项目来说,是个不好的兆头。所以,我这里摒弃了我用Matrix自定义的效果,改用github大牛为我们写好的开源组件,这样效率就上去了,大家也可以用Matrix自己去实现一下图片的多点触摸缩放的效果,关于Matrix的学习,请参加我以前的博文,Android自定义控件——3D画廊和图像矩阵。其实关于android上的图片缩放真没什么其它的方式,唯一能使用的还是Matrix这个类,不信先来瞧瞧Github大牛写的开源组件PhotoView是怎么实现的,查看以下部分源码:
// These are set so we don't keep allocating them on the heap
private final Matrix mBaseMatrix = new Matrix();
private final Matrix mDrawMatrix = new Matrix();
private final Matrix mSuppMatrix = new Matrix();
private final RectF mDisplayRect = new RectF();
private final float[] mMatrixValues = new float[9];
/**
* Set's the ImageView's ScaleType to Matrix.
*/
private static void setImageViewScaleTypeMatrix(ImageView imageView) {
/**
* PhotoView sets it's own ScaleType to Matrix, then diverts all calls
* setScaleType to this.setScaleType automatically.
*/
if (null != imageView && !(imageView instanceof IPhotoView)) {
if (!ScaleType.MATRIX.equals(imageView.getScaleType())) {
imageView.setScaleType(ScaleType.MATRIX);
}
}
}
以上只是PhotoView的部分源码,一目了然的发现它的实现也是基于Matrix的,时间与篇幅的局限性,大家需要更好的了解PhotoView的实现的话,就下载它的源码查看吧,要理解大神的想法是需要一些扎实的基础,关于PhotoView的具体实现细节,我也弄不太明白,可能是我对Matrix了解的不深刻吧,希望以后加强学习,也希望以后跟你们交流学习,共同进步!
-
android微信分享到朋友圈 图片过大闪退
2021-05-28 05:30:49项目上线由于图片各异,最近会偶尔出现分享到朋友圈时候根本就打不开share的界面,但是到微信聊天是可以;下面贴出先前的代码:Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.send_img);... -
仿微信朋友圈发表图片拖拽和删除功能
2022-01-19 10:13:06仿微信朋友圈发表图片拖拽和删除功能 -
如何分享多张图片到微信朋友圈?
2021-04-27 00:54:22微信sdk暂未开放一次分享多张图片到朋友圈,但是有没有别的办法解决呢?显然是有的,不然我也不在这废话了。下面的代码亲测有效,轻轻松松分享多图:判断是否安装了微信代码if(!AppUtils.isInstalled... -
Android实现微信朋友圈图片和视频播放
2021-05-27 05:25:36本文实例为大家分享了Android实现微信朋友圈图片和视频播放的具体代码,供大家参考,具体内容如下1.效果图:2.源码地址:链接3.参数控制,是否显示播放按钮holder.layout.setIsShowAll(mList.get(position).... -
【R语言】利用RCricos绘制简单圈图
2020-12-21 04:37:22Circos图是在基因组相关的分析结果展示中非常常见的一类图型。由于Circos图中展示的信息量大,图形十分美观,很...在R语言中,RCircos这个软件包可以实现快速生成Circos图片。接下来,我们就来看看怎样用R来绘制圈图... -
用R语言做弦图增加外圈
2017-12-31 13:30:00如图所示,想要增加外圈显示每个模块的百分比分布,这个用R能做到吗?希望有大佬能帮忙解答,感谢! -
android7.0实现分享图片到朋友圈功能
2021-05-27 04:12:28android7.0实现分享图片到朋友圈功能发布时间:2020-08-29 00:46:50来源:脚本之家阅读:132作者:十个雨点本文实例为大家分享了android实现分享图片到朋友圈功能的具体代码,供大家参考,具体内容如下在Android7.0... -
Android 仿微信朋友圈图片效果
2019-11-14 16:12:51最新项目需求展示图片,在网上找了一圈,发现这个比较好用,和大家分享一下。但是还有个图片的点击滑动查看功能,等我找到后会在发布博客的 二、使用方法 1、核心类是NineGridLayout,继承自ViewGroup的抽象类,... -
android选择图片分享微信好友和朋友圈
2020-07-09 11:41:441、true分享好友,false分享朋友圈 class ShareActivity : AppCompatActivity() { private val imageUris: ArrayList<Uri> = ArrayList() override fun onCreate(savedInstanceState: Bundle?) { ... -
Android-自定义view,仿微信朋友圈新增图片功能,九宫格新增图片功能
2020-09-10 15:00:39一、该功能可以用recycleview实现,只是判断比较多 二、自定义view ...//每张图片的横向间距 int vSpace = Utils.dip2px(30);//每张图片的纵向间距 int childWidth = 0;//每张图片的宽度 int childHeight = 0; -
Android仿微信朋友圈图片上传选择器布局
2020-03-31 19:23:38对android有点了解的人都知道在列表显示中我们可以使用GridLayoutManager这个布局可以轻松实现图片文字的一行显示的个数,所以在使用recyclerview渲染列表的时候我们就使用GridLayoutManager这个布局来代替以往的Li.... -
探究微信朋友圈,图片点击效果
2017-04-25 10:19:09有段时间闲来没事的时候,想研究一下微信朋友圈的图片点击效果,一开始的感觉是用跳转activity去实现。但是后面为了封装而好用。于是自己重新写了一个类,封装其它们。 我是准备用PopupWindow来做整体框架;简单来... -
js 轮播图中点击小圆圈图片跳到指定图片
2020-09-13 10:58:28html代码(部分) <div class="w"> <div class="main"> <!--焦点图模块--> <div class="focus fl"> <a href="javascript:;" class="arrow-l">..." class="arrow-r". -
Android 仿微信朋友圈9宫格图片展示&多选图片
2016-03-31 14:50:44最近的一个项目中,有一个类似于朋友圈的小模块,发现里面有几个技术点网上记录的并不多,值得记录一下,于是把两个主要的功能给抽取成了一个Demo,分享给大家希望对大家有所帮助。 -
Android 仿微信朋友圈添加图片
2018-05-09 22:31:00github地址(欢迎下载Demo) ... 老习惯,先上图,着急用的朋友,直接带走Demo,先拿来用吧,毕竟老板催...仿微信添加图片.gif 1、首先这是用GridView实现的 <?xml version="1.0" encodin... -
android-listview-GridView-ViewPager(朋友圈样式+点击预览图片)
2021-12-09 23:27:011.朋友圈listview适配器 import android.content.Context; import android.content.Intent; import android.nfc.Tag; import android.util.Log; import android.view.LayoutInflater; import android.view.View; ... -
android 仿微信朋友圈图片查看(带动画效果)
2020-09-07 14:52:22= null) { ImageView thumbView = itemView.findViewById(R.id.iamge_view); thumbView.getGlobalVisibleRect(bounds); } list.get(i).setBounds(bounds); // list.get(i).setUrl(list.get(i).getUrl()); } } 这个... -
Android仿微信朋友圈点击加号添加图片功能
2021-06-02 14:37:34本文为大家分享了类似微信朋友圈,点击+号图片,可以加图片功能,供大家参考,具体内容如下xml:xmlns:app=... -
页面长按生成图片,可分享至微信好友或者朋友圈
2021-09-24 16:16:18页面长按生成图片,可分享至微信好友或者朋友圈 vue h5页面长按保存为图片,页面长按生成图片,可分享至微信好友或者朋友圈 qrcodejs2–Vue生成二维码,支持微信扫描 生成 整体图片: HTML格式 <div class="" v... -
仿微信朋友圈图片点击浏览和关闭时的图片缩放的过渡动画。
2018-04-26 19:53:06首先上效果图上图功能具体思路是一个activity跳转,跳转到一个新的页面查看图片,中间加了一个缩放的过渡动画。 要实现这种,我们要先去掉activity的跳转动画startActivity(intent); //取消activity动画 ... -
模仿朋友圈分享图片
2020-05-28 17:43:34今天学习了Android主要实现的是模仿朋友圈分享图片,接下来请欣赏一下我写的代码。 先来看看效果图,这是一个手机模拟器。 MainActivity 代码: public class MainActivity extends AppCompatActivity { ... -
Android 高仿微信发朋友圈浏览图片效果
2015-11-23 22:18:46最近一直在高仿微信、高仿微信,今天小编再给大家分享一个仿微信发朋友圈浏览图片的效果.... 好了,先看一下效果吧: 下面就来说一下具体怎么实现的:实现思路1.首先我们要获取数据源,数据源就是我们的每条说说...