Android自动生成Shape资源文件(下)

简介: 这个Shape,在正常的开发中,无非就是,实心的,空心的,渐变的,左上右下带角度的,那么针对常见的几种方式,我们做好模板,然后根据你在可视化工具的选择,动态的进行改变即可。

系列文章Github开源地址(源码及各项资料不间断进行更新):

https://github.com/AbnerMing888/AndroidShortcutTools


上半部分,我们已经实现了可视化的基本信息配置,也就是可视化的第一个页面,这仅仅是一个前奏,在第一章里,我已经罗列了很多的功能,所以啊老铁们,抽个时间一定要去前边看一看,因为很多人的问题,我基本上前边都已经给出了解答,比如为什么不采用Android studio里的插件实现,工具在哪下载等等,都诉说的很清楚,这里就不一一赘述了,我们继续上半部分陈述。


针对Shape的实现,是可视化脚手架里最简单的,因为没有什么逻辑可言,都是现成的模板,无非就是改里面的属性而已,老铁们,记住啊,可视化说到底,确实没有什么技术含量,大多都是动态的更改,比如这个Shape,在正常的开发中,无非就是,实心的,空心的,渐变的,左上右下带角度的,那么针对常见的几种方式,我们做好模板,然后根据你在可视化工具的选择,动态的进行改变即可。


细节的源码,大家可以直接去GitHub上下载浏览,文章里就不过多的赘述,我们主要说下具体的实现方式。


一、页面绘制及保存到drawable文件夹下。


可视化的工具,之前说过,采用的是Web开发,相对于Android而言,还是比较简单的,无非就是各个标签的罗列,针对这个最终效果,毕竟我也不是搞Web开发的,也没有一个UI设计,所有的效果都是自己根据实际业务而来的,丑是丑了点,大家可以将就着看哈。


具体的页面,大家可以看源码中的shape.html这个文件,都是div标签,就不贴了,没啥好说的。



选择对应生成文件夹,这个功能是在你选择项目或者一个文件夹的时候,下面有很多的子目录,或者说直接是Module,这种情况下,你就可以进行选择生成到哪个Module下,这个选择是根据基础配置里的选择路径而来的,所以啊,基础配置选择项目生成路径,大家尽量选择一个Android项目。选择生成到哪个Module下之后,就会自动在保存在对应的res下的drawable文件夹下。


如何根据选择的Android项目,保存到对应的drawable下呢?这个就很简单了,项目路径(基础配置页面选择的路径)加上当前页面选择的生成文件夹路径,就可以很好的知道对应的drawable路径了。



每个module下的drawable是固定的,无非在上边的两个路径下,拼接后边的drawable路径即可。


如下图代码,selectPath是基础配置页面里选择的项目路径,selectFile是你选择的路径,后边拼接固定的 /src/main/res即可,再后面就是shape文件资源的名字了。



有一个需要注意的点是,drawable文件夹可能不在,那么你就要判断drawable是否存在了,存在就执行写入,不存在,就先创建drawable文件夹,然后在执行写入,这个写入就是,写入生成shape的代码,后面会说到。


//先判断drawable文件是否存在,不存在去创建fs.readdir(endPathFile, function (err, files) {
if (err) {
return    }
varbooDrawable=false;
files.forEach(function (item) {
if ("drawable"===item) {
booDrawable=true;
        }
    });
//存在if (booDrawable) {
writeDrawable(endPath, endShapeText);
    } else {
//不存在,创建fs.mkdir(endPathFile+"/drawable", function (err) {
if (err) {
return;
            }
writeDrawable(endPath, endShapeText);
        });
    }
});


还有一个问题需要注意,虽然我们说了,一定要选择Android项目,我相信,肯定有很多小老弟,就不选择Android项目,那么在不是Android项目的前提下,就不能执行同样的逻辑了,需要特殊处理,毕竟不是Android项目的路径,src,res的文件夹可能都不存在,所以,针对这个特殊情况,我们要提前的判断了。


我是这样判断的,当然大家如果有好的判断方式,也可以积极的共享哈,首先,拿到用户选择的项目路径,也就是基础配置页面选择的路径,然后进行遍历,遍历的时候当出现Android标识性文件的时候,我用个变量做个累加,比如出现,app文件夹,gradle.properties文件,build.gradle文件等,当定义的变量累计到定义的标识后,就认为选择的是一个Android项目。


//检测选择的是否是一个Android项目,通过是否包含app,gradle,settings.gradle,当然也可以判断其他if (item==="app"||item==="gradle"||item==="settings.gradle") {
numAndroid++;
}


是Android项目就可以生成到对应的drawable下,否则就普通文件夹下,具体可以看源码示例。


二、根据对应模板代码和UI视图选择,生成对应的资源


模板是固定的,唯一改变的就是里面的属性,比如下图,无非就是radius和color里属性需要改,其他的都是固定的,需要改的就要绘制相关的UI视图了。



目前的UI视图,很简单,无非就是三个功能,实心,空心,和渐变,当然了,这是我定义的,如果你还有拓展的功能,可以自己在源码中自己拓展。


根据这三个功能,我们定义好固定的三个模板,根据视图中相关选择,动态改变即可。


实心模板,注意看相关注释。



实现代码,需要注意,这里我在视图中,定义了左上,右上,左下,右下,四个选择框,就是对应代码里左上右下相关的角度,依次对应的点击记录为,0,1,2,3。


//获取实心的代码functiongetSolidText(radius, color, checkText) {
varcontent="<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"+"<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n";
//不为空if (radius!=""&&radius!=null&&selectDp!=null&&selectDp!="") {
//取出默认的dp配置前缀radius=selectDp+radius;
    } else {
radius= (radius==null||radius==="") ?"" : radius+"dp";
    }
if (radius!=null&& (checkText==""||checkText=="0123")) {
//全部content=content+"    <corners android:radius=\""+radius+"\"></corners>\n";
    } else {
content=content+"    <corners\n";
if (checkText.indexOf("0") !=-1) {
content=content+"        android:topLeftRadius=\""+radius+"\"\n";
        }
if (checkText.indexOf("1") !=-1) {
content=content+"        android:topRightRadius=\""+radius+"\"\n";
        }
if (checkText.indexOf("2") !=-1) {
content=content+"        android:bottomLeftRadius=\""+radius+"\"\n";
        }
if (checkText.indexOf("3") !=-1) {
content=content+"        android:bottomRightRadius=\""+radius+"\"\n";
        }
content=content+"        />\n";
    }
//基础信息color不为空,就追加前缀color=getEndColor(color);
content=content+"    <solid android:color=\""+color+"\" />\n";
content=content+"</shape>";
returncontent;
}


空心(带有边框的shape)模板


和实心的区别就是,加了一个边框,其他的都没怎么变。



代码实现:


//获取空心也就是带有边框的代码functiongetStrokeText(radius, solid, react, reactSize, checkText) {
//不为空if (radius!=""&&radius!=null&&selectDp!=null&&selectDp!="") {
//取出默认的dp配置前缀radius=selectDp+radius;
    } else {
radius=radius+"dp";
    }
if (reactSize!=""&&reactSize!=null&&selectDp!=null&&selectDp!="") {
//取出默认的dp配置前缀reactSize=selectDp+reactSize;
    } else {
reactSize=reactSize+"dp";
    }
//边框颜色//基础信息color不为空,就追加前缀react=getEndColor(react);
varcontent="<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"+"<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"+"    >\n";
content=content+"    <stroke\n"+"        android:width=\""+reactSize+"\"\n"+"        android:color=\""+react+"\" />\n";
if (radius!=null&& (checkText==""||checkText=="0123")) {
//全部content=content+"    <corners android:radius=\""+radius+"\" />\n";
    } else {
content=content+"    <corners \n";
if (checkText.indexOf("0") !=-1) {
content=content+"android:topLeftRadius=\""+radius+"\"\n";
        }
if (checkText.indexOf("1") !=-1) {
content=content+"        android:topRightRadius=\""+radius+"\"\n";
        }
if (checkText.indexOf("2") !=-1) {
content=content+"        android:bottomLeftRadius=\""+radius+"\"\n";
        }
if (checkText.indexOf("3") !=-1) {
content=content+"        android:bottomRightRadius=\""+radius+"\"\n";
        }
content=content+"        />\n";
    }
solid=getEndColor(solid);
content=content+" <solid android:color=\""+solid+"\"/>\n";
content=content+"</shape>"returncontent;
}


渐变模板:



  代码实现:


//获取渐变functiongetGradientXml(radius, checkText) {
//渐变varinputReactStartColor=$(".input_react_start_color").val();//起始颜色varinputReactCenterColor=$(".input_react_center_color").val();//中间颜色varinputReactEndColor=$(".input_react_end_color").val();//结束颜色letinputReactGradientRadius=$(".input_react_gradient_radius").val();//渐变角度letshapeGradientType=$("input[name='shapeGradientType']:checked").val();
inputReactStartColor=getEndColor(inputReactStartColor);
inputReactCenterColor=getEndColor(inputReactCenterColor);
inputReactEndColor=getEndColor(inputReactEndColor);
if (inputReactGradientRadius==null||inputReactGradientRadius=="") {
showToast("请输入渐变角度");
return"";
    }
varsgType;
if (shapeGradientType==0) {
sgType="linear";
    } elseif (shapeGradientType==1) {
sgType="radial";
    } else {
sgType="sweep";
    }
vargradient="<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"+"<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n"+"\n"+"    <gradient\n"+"        android:angle=\""+inputReactGradientRadius+"\"\n";
if (inputReactCenterColor!=null&&inputReactCenterColor!="") {
gradient=gradient+"        android:centerColor=\""+inputReactCenterColor+"\"\n";
    }
gradient=gradient+"        android:endColor=\""+inputReactEndColor+"\"\n"+"        android:startColor=\""+inputReactStartColor+"\"\n"+"        android:type=\""+sgType+"\" />\n"//不为空if (radius!=""&&radius!=null) {
//取出默认配置前缀,若不为空,就追加if (selectDp!=""&&selectDp!=null) {
radius=selectDp+radius;
        } else {
radius=radius+"dp";
        }
if (checkText==""||checkText=="0123") {
//全部gradient=gradient+"    <corners android:radius=\""+radius+"\"></corners>\n";
        } else {
gradient=gradient+"    <corners\n";
if (checkText.indexOf("0") !=-1) {
gradient=gradient+"        android:topLeftRadius=\""+radius+"\"\n";
            }
if (checkText.indexOf("1") !=-1) {
gradient=gradient+"        android:topRightRadius=\""+radius+"\"\n";
            }
if (checkText.indexOf("2") !=-1) {
gradient=gradient+"        android:bottomLeftRadius=\""+radius+"\"\n";
            }
if (checkText.indexOf("3") !=-1) {
gradient=gradient+"        android:bottomRightRadius=\""+radius+"\"\n";
            }
gradient=gradient+"        />\n";
        }
    }
gradient=gradient+"</shape>";
returngradient;
}


当然了具体逻辑相关的,大家可以查看源码,有任何问题,也可以留言咨询。


选择颜色这块用到了一个三方,也放到源码里面了,方便大家进行取色,UI图里特意设置了一个名字,因为shape资源生成有一定的规范用名,特别是在组件化开发的项目,所以简单的设置了一下规范用名,可以一键获取,根据你设置的颜色,角度来进行填充。


Shape的可视化生成就是如此的简单,好了各位老铁,下一篇,我们搞一个可视化的多渠道打包,一秒可生成N个渠道包,敬请期待!



相关文章
|
8月前
|
XML Android开发 数据格式
Android中利用shape属性自定义设置Button按钮
Android中利用shape属性自定义设置Button按钮
137 0
|
4月前
|
Android开发
[Android]Shape Drawable
[Android]Shape Drawable
42 0
|
9月前
|
存储 JavaScript 数据可视化
Android自动生成Shape资源文件,迈出可视化脚手架第一步(上)
这章我们就进入到了撸码时刻,逐步来开发出一个一个应对我们Android场景的功能,这章对应的功能是,Shape的自动生成
103 0
|
8月前
|
Android开发
Android Shape 详细使用
Android Shape 详细使用
59 0
|
9月前
|
XML 前端开发 Android开发
|
11月前
|
XML 前端开发 Android开发
Android 实现圆弧背景(Shape实现和自定义View)
如今Android系统的App,很多时候为了有更好的用户体验,都会有各种好看的UI,动画,点击效果等等,其中圆弧的控件在App中很常见,今儿就自己总结下自己实现圆弧的两种基础的方法。即Shape方法和使用View里面的方法自己画。
|
11月前
|
XML Android开发 数据格式
Android shape的用法详解
Android shape的用法详解
Android shape的用法详解
|
Android开发
Android 自定义样式Shape
Android 自定义样式Shape
230 0
Android 自定义样式Shape
|
XML Android开发 数据格式