Android实现无序树形结构图,类似思维导图和级联分层图(无序,随机位置)
参考文章:
利用递归算法、堆栈打造一个android可擦除思维导图
用SurfaceView实现级联分层图(粗略篇)
效果图打头阵:
这些和亲戚关系图谱,或者思维导图类似,最近公司的医疗项目也用到了这个,记录学习下;
刚开始的时候,也是脑子抽抽,毫无头绪,看完上面2篇文章后,有了大致模仿思路;
大致思路:
1.如何出现这种控件;
2.如何位置随机;
3.画线和画不封闭箭头;
4.扩展性
有了这些想法,就开始动手了
这种控件逃不了自定义的范围:
public class BLzgView extends RelativeLayout {private Button blzg_btn;private TextView blzg_title_tv, blzg_describe_tv;public BLzgView(Context context) {this(context,null);}public BLzgView(Context context, AttributeSet attrs) {super(context, attrs);LayoutInflater.from(context).inflate(R.layout.view_blzg, this, true);blzg_describe_tv=(TextView) findViewById(R.id.blzg_describe_tv);blzg_title_tv=(TextView) findViewById(R.id.blzg_title_tv);blzg_btn=(Button) findViewById(R.id.blzg_btn);}public void setTitleText(String tString){blzg_title_tv.setText(tString);} public void setDecribeText(String string){blzg_describe_tv.setText(string);}public void setBtnClickListener(OnClickListener onClickListener){if (onClickListener!=null) {blzg_btn.setOnClickListener(onClickListener);}}//更改btn背景//如果需要其他的需求再接着写
}
对了,在这用Android Studio开发的时候遇到一个意想不到的问题:很意外的问题 这个问题致使布局是下面的写法;
布局文件
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="120dp"android:layout_height="70dp"android:layout_gravity="center_horizontal"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="70dp"android:layout_gravity="center_horizontal"android:orientation="vertical"><Buttonandroid:id="@+id/blzg_btn"android:layout_width="120dp"android:layout_height="70dp"android:layout_gravity="center_horizontal"android:background="@mipmap/xxk_n" /></LinearLayout><TextViewandroid:id="@+id/blzg_title_tv"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="4dp"android:gravity="center_horizontal"android:maxLines="1"android:text="@string/blzg_title"android:textColor="#ffffff" /><TextViewandroid:id="@+id/blzg_describe_tv"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="24dp"android:gravity="center_horizontal"android:maxLines="2"android:text="内容描述"android:textColor="@color/black" /></merge>
有了这些控件之后,开始考虑位置随机的问题;公司的项目因为给了具体的坐标,所以直接传递坐标即可,在这为实现效果,使用的随机位置
主Activity如下:
public class UnOrderTree extends Activity {private DrawGeometryView line_view[] = new DrawGeometryView[30];private RelativeLayout.LayoutParams[] layoutParams = new RelativeLayout.LayoutParams[15];private RelativeLayout.LayoutParams[] layoutParams1 = new RelativeLayout.LayoutParams[15];private BLzgView[] bLzgViews = new BLzgView[15];private RelativeLayout insertLayout;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_unordertree);insertLayout = (RelativeLayout) findViewById(R.id.layout_zone);initData();//初始化数据}private int start_line_x = 0, start_line_y = 0;private int topMargin = 0, leftMargin = 0;private void initData() {for (int i = 0; i < 6; i++) { // 开始绘制topMargin = new Random().nextInt(20) * 30;leftMargin = new Random().nextInt(10) * 40;initUnOrder(start_line_x, start_line_y, topMargin, leftMargin, i, 0, 0, 2, 1, "");start_line_x = leftMargin;start_line_y = topMargin;}}private void initUnOrder(int start_x, int start_y, int topMargin, int leftMargin, int i,int line_start_x, int line_start_y, int tree_tier, int isleft, String data) {bLzgViews[i] = new BLzgView(this);bLzgViews[i].setBtnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(UnOrderTree.this, "功能快速开发中,敬请期待", Toast.LENGTH_SHORT).show();}});bLzgViews[i].setTitleText("标题" + i);bLzgViews[i].setDecribeText("内容" + i);ScaleAnimation animation = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF, 0.5f);animation.setInterpolator(new BounceInterpolator());animation.setStartOffset(100);// 动画秒数。animation.setFillAfter(true);animation.setDuration(700);bLzgViews[i].startAnimation(animation);layoutParams[i] = new RelativeLayout.LayoutParams(120, 70); // 大小layoutParams[i].topMargin = topMargin;layoutParams[i].leftMargin = leftMargin; // 设置的按钮位置insertLayout.addView(bLzgViews[i], layoutParams[i]);if (i != 0) { //第一个不用画线(画线方式为:当前的坐标去找上一个坐标,之后连线)line_view[i] = new DrawGeometryView(this, start_x + 60, start_y + 70,leftMargin + 40, topMargin, "线条", isleft);layoutParams1[i] = new RelativeLayout.LayoutParams(800, 800);line_view[i].invalidate();layoutParams1[i].topMargin = 0;// line_y-600;//Math.min(line_y+100,button_y+100layoutParams1[i].leftMargin = 0;// line_x+300;insertLayout.addView(line_view[i], layoutParams1[i]);}}
}
其实,思路也是另类的,利用数组初始多个自定义的View,坐标位置就是topMargin和leftMargin(相对于屏幕左上角,即给的坐标)
剩下的就是画线了,走到这,其实已经知道了各个大控件的坐标位置,那么画线的起点和终点就很明确了
public class DrawGeometryView extends View {private int beginx = 0;private int beginy = 0;private int stopx = 100;private int stopy = 100;/*** @param context* @param attrs*/public DrawGeometryView(Context context, AttributeSet attrs) {super(context, attrs);}/*** @param context*/public DrawGeometryView(Context context, int beginx, int beginy, int stopx, int stopy, String word, int isleft) {super(context);this.beginx = beginx;this.beginy = beginy;this.stopx = stopx;this.stopy = stopy;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);Paint redPaint = new Paint(); // 红色画笔redPaint.setAntiAlias(true); // 抗锯齿效果,显得绘图平滑redPaint.setColor(Color.BLACK); // 设置画笔颜色redPaint.setStrokeWidth(2.0f);// 设置笔触宽度redPaint.setStyle(Style.STROKE);// 设置画笔的填充类型(完全填充)redPaint.setTextSize(50);// 字体Path mPath = new Path();mPath.reset();// 起点mPath.moveTo(beginx, beginy);// 贝塞尔曲线// mPath.cubicTo(beginx+80, beginy, beginx+80, stopy,stopx-100, stopy);mPath.cubicTo(beginx, beginy + 30, stopx, stopy - 50, stopx, stopy);// // 画直线// mPath.lineTo(stopx, stopy);// 画pathcanvas.drawPath(mPath, redPaint);//下面是画箭头线的Paint left_paint = new Paint();Paint right_paint = new Paint();Path left_path = new Path();Path right_path = new Path();left_path.reset();right_path.reset();left_paint.setAntiAlias(true);left_paint.setColor(Color.BLACK);right_paint.setAntiAlias(true);right_paint.setColor(Color.BLACK);left_paint.setStrokeWidth(2.0f);right_paint.setStrokeWidth(2.0f);left_paint.setStyle(Style.STROKE);right_paint.setStyle(Style.STROKE);left_path.moveTo(stopx, stopy);right_path.moveTo(stopx, stopy);left_path.quadTo(stopx - 3, stopy - 3, stopx - 6, stopy - 6);right_path.quadTo(stopx + 3, stopy - 3, stopx + 6, stopy - 6);canvas.drawPath(left_path, left_paint);canvas.drawPath(right_path, right_paint);}
}
贝塞尔曲线绘制,略微平滑的引导线,再画2个箭头的边(其实就是花的线段);
既然是自定义的View,那加动画肯定没问题;除了这些,还能更完善:比如箭头的平滑,大控件的各种事件等等,暂时待续.....
大致的效果出来了;恩 需求解决!
若您有相近的需求或解决思路,欢迎在下方留下地址!
附下载链接:CSDN下载链接
Android实现无序树形结构图,类似思维导图和级联分层图(无序,随机位置)相关推荐
- 天球坐标系、地球坐标系与地球自转有无关系,哪一种便于描述地面观测站的空间位置,哪一种便于描述人造地球卫星的位置?请用类似思维导图的方式总结GNSS定位的时空基准?GPS卫星定位中时间系统有何重要意义?
答: 1.天球坐标系.地球坐标系与地球自转有无关系,哪一种便于描述地面观测站的空间位置,哪一种便于描述人造地球卫星的位置? 卫星定位中常采用空间直角坐标系及其相应的大地坐标系,一般取地球质心为坐标系的 ...
- 模式识别知识结构图(思维导图)
<模式识别>边肇祺 张学工等编著 清华大学出版社 知识结构图(思维导图)
- Android复习13【广播:思维导图、音乐播放器】
音乐播放器Android代码下载:https://wws.lanzous.com/ifqzihaxvij 思维导图 https://share.weiyun.com/1vVLYnlb 音乐播放器
- 《机器人知识结构图》思维导图,探索人工智能领域
随着时代快速发展,经济快速进步的趋势,人工智能领域越来越被重视,它是一门边缘学科,属于自然科学和社会科学的交叉界限.实际应用的课程非常多.他的研究范畴又包括了自然语言处理,知识表现,机器学习,不精确和 ...
- Android.view.View类全貌【思维导图】
初学Android,仅一大堆布局.组件,以及它们的属性,就能把人绕晕. 学习策略是,先不必图太多,学会几个常用布局和组件,然后再慢慢拓展.甚至,不必专门学,在有需要求时,依据资料的指引,现学现用即可. ...
- Android课程思维导图,Android实现思维导图
最近,小弟在实现一个思维导图的开源控件.下面我简单介绍一下如下打造一个类似思维导图软件的ViewGroup. 基本结构.png 建立模型 主要模型结构相对简单:TreeModel,NoteModel, ...
- html5脑图_使用HTML5技术绘制思维导图
客户常常提到思维导图,喜欢它的结构展示方式,和交互的友好,从图论的角度看,思维导图本质上是一种树,有一个根节点(主题)出发,联想到其他话题,于是分支开花,再分支,有时候也会构成网络结构,由子分支联想到 ...
- 大学物理质点动力学思维导图_非物理专业大学物理课程教与学
[摘要]地方高等院校非物理专业大学物理课程教学中普遍存在课时少进度快.学生学习难度大等问题.针对以上问题,从优化教学内容,重视课堂教学活动和教授大一新生好的学习方法等方面入手,探讨大学物理课程的教与学 ...
- 忘掉 MindNode, 这才是Mac颜值最高的思维导图工具
思维导图是一款帮助我们将大脑中浮现的各种思维串联起来的工具,非常适合用于逻辑性写作或者团队的头脑风暴,应用的范围比较广.关于写如何用思维导图工具的文章多如牛毛,不管是对职场人士.学生,还是全职妈妈的作 ...
最新文章
- python获取当前进程id_Python进程,多进程,获取进程id,给子进程传递参数操作示例...
- php 文件移动到文件夹,PHP-将文件移至服务器上的其他文件夹
- 常考数据结构与算法:单链表的排序
- 自动化办公之excel教程(8):单变量求解,规划求解,页面布局,打印设置
- 【matlab-2】Matlab语法
- 懂得永恒,得要我们进化成更好的人。
- c语言贪吃蛇最简单代码_让我们跑一个最简单的GAN网络吧!(附Jupyter Notebook 代码)...
- 主流HTML5游戏框架的分析和对比(Construct2、ImpactJS、CreateJS、Cocos2d-html5……)
- WORD中的格式控制符号
- 测试开发工程师的学习之路---1--规划
- 凸函数与优化,以及海森矩阵
- Audio Hijack for Mac(音频录制工具)
- 利用python修改Excel内容
- 加载property配置文件
- 蚂蚁java一二三面面经
- 个推数说中国42年冬奥史,可视化演绎冰雪奇缘
- 【244天】我爱刷题系列(3)
- 百战RHCE(第十五战:Linux进阶命令十二-主机名和域名解析极简管理)
- 推动量子计算与AI融合,飞桨成为中国首个支持量子机器学习的深度学习平台...
- 正奇学苑游学活动走进腾讯 腾讯安全持续共建生态 助力创新企业成长
热门文章
- 一款不错的PHP在线文件管理系统,PHP WEBFTP
- 在Word简历中插入照片(图片)
- 电脑蓝屏怎么解决?一键快速解决蓝屏问题
- Java NIO框架(Java编程)
- 新版RE管理器 (Root Explorer)修改方法(去广告,时间日期排序,默认文件夹优先)
- 获取Obb包里面的某个资源文件
- GBASE 8s 安装指导
- 【FFMPEG】视频压制效果对比
- 计算机科学高校,科学网—中国顶尖计算机高校实力大起底
- Step by Step学习CANoe三大工具链——DBC数据库编辑器(CANdb++ Editor)、面板设计(Panel Designer)和CAPL浏览器(CAPL Browser)