<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:state_pressed="true"> <shape android:shape="rectangle"> <!-- 圆角边框 --> <!-- <corners android:radius="1dp" /> --> <!-- 虚线 --> <stroke android:width="1.3dip" android:color="#000000" android:dashWidth="5dp" android:dashGap="2dp"/> <!-- 实线 --> <!-- <stroke android:width="1dp" android:color="#0000FF" /> --> <!-- padding --> <padding android:top="2dp" android:left="2dp" android:right="2dp" android:bottom="2dp" /> <!-- 设置矩形背景色 --> <solid android:color="@android:color/transparent" /></shape></item><item android:state_focused="true"> <shape android:shape="rectangle"> <!-- 圆角边框 --> <!-- <corners android:radius="1dp" /> --> <!-- 虚线 --> <stroke android:width="1.3dip" android:color="#000000" android:dashWidth="5dp" android:dashGap="2dp"/> <!-- 实线 --> <!-- <stroke android:width="1dp" android:color="#0000FF" /> --> <!-- padding --> <padding android:top="2dp" android:left="2dp" android:right="2dp" android:bottom="2dp" /> <!-- 设置矩形背景色 --> <solid android:color="@android:color/transparent" /></shape></item><item android:state_focused="false"> <shape android:shape="rectangle"> <!-- 设置shape形状为矩形 --> <!-- 圆角 --> <!-- <corners android:radius="1dp" /> --> <!-- padding --> <padding android:top="2dp" android:left="2dp" android:right="2dp" android:bottom="2dp" /> <!-- 设置矩形边框 --> <stroke android:width="0dp" android:color="#000000" /> <!-- 设置矩形背景色 --> <solid android:color="@android:color/transparent" /></shape></item></selector>
在这个selector中,定义了矩形shape,矩形不填充颜色当android:state_pressed为true或android:state_focused为true时,设置shape有边框线,当他们为false时,设置shape无边框线对于编辑区的所有View,都设置background为view_background.xml,这样便实现了View选中时有边框,失去焦点时无边框下一步,就是给这个边框添加“动画”效果了实现动画边框实现动画边框效果的思路,来自于我对虚线边框样式的调整过程中我注意到上面定义的shape虚线边框中,可以通过改变android:dashWidth、android:dashGap两项参数,即虚线条的长度和虚线条之间的间隔宽度来改变虚线条的样式所以,我就想到了通过不断变换这两个参数,来实现边框展示出一种“动画”效果首先,我们需要知道,上面xml定义的selector,对应于Android API中的GradientDrawable,可以通过下面的方式将selector资源转换为GradientDrawable://将XML定义的selector资源加载为GradientDrawable对象GradientDrawable gradientDrawable = (GradientDrawable)getDrawable(R.drawable.view_background);
然后,通过代码改变虚线条的长度和虚线条之间的间隔://setStroke方法可改变线条的粗细、颜色、虚线条的长度和虚线条之间的间隔gradientDrawable.setStroke(width, color, dashWidth, dashGap);
GradientDrawable对象的setStroke方法,接收4个参数,分别表示线条的粗细、颜色、虚线条的长度和虚线条之间的间隔,如果dashWidth, dashGap都为0,则表示实线在我预期的效果中,线条的粗细、颜色都不变,只是改变dashWidth, dashGap这两个参数要实现边框的“动画”效果,需要不断地改变这两项参数我分别定义了三组参数://定义3个不同的虚线条长度private float[] dashwidth = new float[]{15F, 14F, 13F};//定义3个不同的虚线条之间的间隔private float[] dashGap = new float[]{3F, 2.8F, 2.6F};
如果需要变换线条颜色,也可以定义一组颜色://定义3个不同的颜色private int[] strokeColor = new int[]{Color.parseColor("#FF0000"), Color.parseColor("#00FF00"), Color.parseColor("#0000FF")};
动态改变边框样式:int borderStyleIndex = 0;private Runnable borderChangeRunnable = new Runnable(){ @Override public void run() { if (selectedView != null) { StateListDrawable drawable = (StateListDrawable)selectedView.getBackground(); GradientDrawable gradientDrawable = (GradientDrawable)drawable.getCurrent(); borderStyleIndex = (borderStyleIndex + 1) % 3; gradientDrawable.setStroke(4, strokeColor[borderStyleIndex], dashwidth[borderStyleIndex], dashGap[borderStyleIndex]); selectedView.postDelayed(this, BORDER_STYLE_INTERVAL); } }};
上面的selectedView表示当前选中的View当View获取焦点或被点击后,只需这样调用://“动画”间的间隔时间private static long BORDER_STYLE_INTERVAL = 600;//改变选中View的边框selectedView.postDelayed(borderChangeRunnable, BORDER_STYLE_INTERVAL);
这样,便实现了“动画”边框的效果最初的预期的效果是虚线框看起来是一个顺时针流动的线条,这种实现方法与此有差距,不过通过微调上面定义的几组参数,在观感上可以达到近似的效果对于这一效果的实现,不知大家有没有更好的办法呢?(图片来源网络,侵删)
0 评论