Android 图解创建外部 lib 库及自定义 View
随着插件化/组件化的快速发展,现在大部分的项目开发中都会提取公共的代码制作成 Library module,根据具体的业务需求进行拆分。小菜也学习一下如何拆分 lib 包,实际操作很简单,整理一下操作步骤。
拆分创建 Library
(1) 在当前 Project 下,File -> New Module,选择 Android Library,进行下一步;
(2) 设置具体的 Library/Module/Package 等名称,注意:Module 名称与 Library 相匹配默认为小写,需要的话手动调整,进行下一步;
(3) 此时在当前 Project 中就已经创建好 Library;
(4) 在当前 Project 的 settings.gradle 中就会自动生成创建的 Module;
Tips: :myview 中的 : 代表的与 app 同级目录下的 Module。
- 在当前 app 的 build.gradle 中 dependencies{} 中添加 implementation project(':myview') 即可正常接入。
自定义 View
小菜在新建的 Library 中添加一个自定义按钮,可以添加配置图标和文字以及背景样式。因为只是为了测试 Library Module,所以功能很简单,实现方式也很简单,只是几个基本控件的组合。小菜只是简单的整理一下。
- 新建一个 MyView 继承自 RelativeLayout,实现基本的构造方法;
- 在构造方法中实现对布局的添加,控件的绑定以及一些基本的 setXX 方法;
- 至此 MyView 就可以应用,但所有但属性都需要通过 setXX 方法来设置;这当然是不合理的,于是小菜新建一个 attrs 文件,在资源文件中设置基本的样式,并在 MyView 的 obtainAttributes 方法中逐一绑定即可;
<?xml version="1.0" encoding="utf-8"?> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <declare-styleable name="my_view" tools:ignore="MissingDefaultResource"> <!-- 中间文字颜色 --> <attr name="tv_color" format="color" /> <!-- 中间文字显隐性 --> <attr name="tv_show" format="boolean" /> <!-- 中间文字内容 --> <attr name="tv_str" format="string" /> <!-- 中间文字大小 --> <attr name="tv_size" format="float" /> <!-- 右侧文字颜色 --> <attr name="right_tv_color" format="color" /> <!-- 右侧文字显隐性 --> <attr name="right_tv_show" format="boolean" /> <!-- 右侧文字内容 --> <attr name="right_tv_str" format="string" /> <!-- 右侧文字大小 --> <attr name="right_tv_size" format="float" /> <!-- 整体背景颜色 --> <attr name="bg_color" format="color" /> <!-- 整体边框颜色 --> <attr name="strok_color" format="color" /> <!-- 整体边框圆角 --> <attr name="bg_radius" format="float" /> <!-- 中间图片显隐性 --> <attr name="iv_show" format="boolean" /> <!-- 中间图片资源 --> <attr name="iv_src" format="reference" /> </declare-styleable> </resources>
- 至此,MyView 自定义按钮以及完成,在 app 中也是正常调用即可。
public class MyView extends RelativeLayout { private Context mContext; private RelativeLayout mRlay; private ImageView mIv; private TextView mTv, mRightTv; GradientDrawable drawable = new GradientDrawable(); int mTvColor, mRightTvColor, mRlayBgColor, mStrokeColor, mIvSrc; boolean isTvShow, isRightTvShow, isIvShow; float mTvSize, mRightTvSize, mRadiusSize; String mTvStr, mRightTvStr; public MyView(Context context) { super(context); mContext = context; initView(); } public MyView(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; initView(); obtainAttributes(context,attrs); } private void initView() { LayoutInflater.from(mContext).inflate(R.layout.my_view_btn, this,true); mRlay = findViewById(R.id.my_view_rly); mIv = findViewById(R.id.my_view_iv); mTv = findViewById(R.id.my_view_tv); mRightTv = findViewById(R.id.my_view_rtv); } private void obtainAttributes(Context context, AttributeSet attrs) { TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.my_view); mTvColor = ta.getColor(R.styleable.my_view_tv_color, Color.BLACK); mTv.setTextColor(mTvColor); mRightTvColor = ta.getColor(R.styleable.my_view_right_tv_color, Color.BLACK); mRightTv.setTextColor(mRightTvColor); mRlayBgColor = ta.getColor(R.styleable.my_view_bg_color, Color.WHITE); mRlay.setBackgroundColor(mRlayBgColor); mStrokeColor = ta.getColor(R.styleable.my_view_strok_color, Color.BLACK); isIvShow = ta.getBoolean(R.styleable.my_view_iv_show, true); mIv.setVisibility(isIvShow?View.VISIBLE:View.GONE); isRightTvShow = ta.getBoolean(R.styleable.my_view_right_tv_show, true); mRightTv.setVisibility(isRightTvShow?View.VISIBLE:View.GONE); isTvShow = ta.getBoolean(R.styleable.my_view_tv_show, true); mTv.setVisibility(isTvShow?View.VISIBLE:View.GONE); mTvSize = ta.getFloat(R.styleable.my_view_tv_size, 16.0f); mTv.setTextSize(mTvSize); mRightTvSize = ta.getFloat(R.styleable.my_view_right_tv_size, 14.0f); mRightTv.setTextSize(mRightTvSize); mRadiusSize = ta.getFloat(R.styleable.my_view_bg_color, 80.0f); drawable = (GradientDrawable) getResources().getDrawable(R.drawable.user_login_corner_qq); drawable.setCornerRadius(mRadiusSize); drawable.setStroke(1, mStrokeColor); drawable.setColor(mRlayBgColor); mRlay.setBackground(drawable); mTvStr = ta.getString(R.styleable.my_view_tv_str); mTv.setText(mTvStr); mRightTvStr = ta.getString(R.styleable.my_view_right_tv_str); mRightTv.setText(mRightTvStr); mIvSrc = ta.getResourceId(R.styleable.my_view_iv_src, R.mipmap.user_login_icon_qq); mIv.setImageResource(mIvSrc); ta.recycle(); } public void setMyViewTv(String textStr) { mTv.setText(textStr); } public void setMyViewTvColor(int color) { mTv.setTextColor(color); } public void setMyViewTvSize(float size) { mTv.setTextSize(size); } public void isMyViewTvShow(boolean state) { mTv.setVisibility(state ? View.VISIBLE : View.GONE); } public void setMyViewIv(Drawable drawable) { mIv.setImageDrawable(drawable); } public void isMyViewIvShow(boolean state) { mIv.setVisibility(state ? View.VISIBLE : View.GONE); } public void isMyViewRightTvShow(boolean state) { mRightTv.setVisibility(state ? View.VISIBLE : View.GONE); } public void setMyViewRightTvText(String textStr) { mRightTv.setText(textStr); } public void setMyViewRightTvSize(float size) { mRightTv.setTextSize(size); } public void setMyViewRightTvColor(int color) { mRightTv.setTextColor(color); } public void setMyViewBgColor(int color) { drawable.setColor(color); mRlay.setBackground(drawable); } public void setMyViewBgRadius(float radius) { drawable.setCornerRadius(radius); mRlay.setBackground(drawable); } public void setMyViewBgStrokeColor(int color) { drawable.setStroke(1, color); mRlay.setBackground(drawable); } public void setMyViewBgDrawable(Drawable drawable) { mRlay.setBackground(drawable); } }
Tips: attrs.xml 中如果需要用到资源文件,可以使用 format="reference",代表某一个资源ID。
小菜也是初步尝试,有不对的地方烦请提醒。以下是小菜公众号,欢迎闲来吐槽~
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
11月14日云栖精选夜读 | 动画+原理+代码,解读十大经典排序算法
排序算法是《数据结构与算法》中最基本的算法之一。 排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。 热点热议 动画+原理+代码,解读十大经典排序算法 作者:技术小能手发表在:机器学习算法与Python学习 面试前你必须知道的三个排序算法 作者:技术小能手发表在:web项目聚集地 不会用kotlin?这篇看完不懂,我跪搓衣板 作者:技术小能手发表在:终端研发部 知识整理 TensorFlow系列专题(七):一文综述RNN循环神经网络 作者:技术小能手发表在:磐创AI Linux 问题故障定位,看这一篇就够了 作者:技术小能手发表在:高效运维 流量激增不宕机,服务限流系统架构解密 作者:技术小能手发表在:dbaplus社群 MySQL:Innodb page clean 线程 (二) :解析 作者:技术小能手发表在:老叶茶馆 Android爬坑之旅之WebView 作者:技术小能手发表在:安卓巴士Android开发者门户 美文回顾 用于 CKeditor 编辑器的可视化数学公式插件 ...
- 下一篇
在Flutter中嵌入Native组件的正确姿势是...
作者:闲鱼技术-尘萧 引言 在漫长的从Native向Flutter过渡的混合工程时期,要想平滑地过渡,在Flutter中使用Native中较为完善的控件会是一个很好的选择。本文希望向大家介绍AndroidView的使用方式以及在此基础之上拓展的双端嵌入Native组件的解决方案。 1. 使用教程 1.1. DemoRun 嵌入地图这一场景可能在很多App中都会存在,但是现在的地图SDK都没有提供Flutter的库,而自己开发一套地图显然不太现实。这种场景下,使用混合栈的形式是一个比较好的选择。我们可以直接在Native的绘图树中嵌入一个Map,但是这个方案嵌入的View并不在Flutter的绘图树中,是一种比较暴力且不优雅的方式,使用起来也很费劲。 这时候,使用Flutter官方提供的控件AndroidView就是一种比较优雅的解决方案了。这
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS7安装Docker,走上虚拟化容器引擎之路
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Mario游戏-低调大师作品
- 2048小游戏-低调大师作品
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- Red5直播服务器,属于Java语言的直播服务器