本来工作很忙,没时间写什么博客或研究小技术。昨晚实在是太无奈了,被兄弟拿枪顶着写了个引导页指示器的动态添加功能。描述的不详细,来张图片:
其实 实现原理很简单,一般都在app的初次启动时出现,一个左右滑动的viewpager,页面底部再搭配一个标识位置的小点点。
有人或立马喷饭,说这不是很简单吗?
确实简单,我现在做的不是静态在Activity底部写死几个view标识。我是自定义了一个容器,根据开发者切换页面的个数,来动态创建下面需要几个view控件。
其实这也是很简单,对于那些3~5年经验的老牛们,小鸟值得看看。没什么神奇的,但还是分享下吧。
原理+代码段解释+demo:
如何Activity底部有一个控件,能在代码里动态设置view的个数生成小点点就好了。
/**
* @Author: duke
* @DateTime: 2017-04-22 21:59
* @Description:
*/
public class BottomLineLayout extends LinearLayout {
private int itemDefaultBgResId = R.drawable.normal;//单个元素默认背景样式
private int itemSelectedBgResId = R.drawable.select;//单个元素选中背景样式
private int currentPosition;//当前选中位置
private int itemHeight = 50;//item宽高
private int itemMargin = 5;//item间距
public BottomLineLayout(Context context) {
this(context, null, 0);
}
public BottomLineLayout(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public BottomLineLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setOrientation(HORIZONTAL);
setGravity(Gravity.CENTER);
}
}
自定义控件有三大方法,onMeasure、onLayout、onDraw。对于自定义ViewGroup,onDraw就不存在了。由于我继承的是LinearLayout,排版的活儿也就不用了,故忽略onLayout。测量?根据自己的需要吧,我懒得测量了,每个child的宽高都从外面传过来,省事。也是这三大方法我都忽略了。
那么接下来我需要做的是什么呢?添加child,容器类控件都有addView方法。
那创建什么view呢!button?imageview?textview?还是view?
随便了,我textview。你可以拿我的demo去扩展下,没切换到一个小点点,就显示顺序数字,更酷,我懒没写这个。
加下来添加view吧。
public void initViews(int count, int itemHeight, int itemMargin) {
this.itemHeight = itemHeight;
this.itemMargin = itemMargin;
removeAllViews();
if(count == 0 || itemHeight == 0){
return;
}
View view = createView(itemHeight,itemMargin);
view.setBackgroundResource(itemSelectedBgResId);
addView(view);
if(count == 1){
return;
}
for (int i = 1; i < count; i++) {
view = createView(itemHeight,itemMargin);
view.setBackgroundResource(itemDefaultBgResId);
addView(view);
}
}
在代码里面初始化控件,传递参数过来(item个数,item的宽高,item的外间距)
既然是初始化,第一个就设置成选中样式了,第二个开始后面的都用默认样式了。你也许会想,我这代码写的,一个循环搞定,在里面判断不行吗?遗憾的 告诉你,个人感觉在循环里面判断会损耗性能,不跟你扯了。
在每次初始化的时候,移除所有child,万一用户无聊多次调用这个方法呢!然后创建第一个child,设置选中样式并添加到容器中。后面的来个循环,搞定。
那里面的createView方法是个什么模样?莫急:
/**
* 创建view
* @param sideLength 边长
* @param itemMargin 外间距
* @return
*/
public View createView(int sideLength,int itemMargin){
TextView textview = new TextView(getContext());
LinearLayout.LayoutParams params = new LayoutParams(sideLength, sideLength);
if(itemMargin > 0){
params.setMargins(itemMargin,0,itemMargin,0);
}
textview.setLayoutParams(params);
return textview;
}
//切换到目标位置
public void changePosition(int position) {
if(getChildCount() <= 1){
return;
}
getChildAt(currentPosition).setBackgroundResource(itemDefaultBgResId);
currentPosition = position % getChildCount();
getChildAt(currentPosition).setBackgroundResource(itemSelectedBgResId);
}
先修改当前位置的view为默认样式,然后把这次的位置赋给当前位置,同时修改成选中样式。
?咋了?完事了,就这么多。
在Activity中怎么用呢?
bottomLineLayout = (BottomLineLayout) findViewById(R.id.bottomlayoutl);
bottomLineLayout.initViews(item个数,item宽高,item外间距);
viewPager.addOnPageChangeListener(new MyOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
if(bottomLineLayout != null){
bottomLineLayout.changePosition(position);
}
}
});
主要代码就这些,没啥了。viewpager的代码不贴出来了。都在demo里,后面提供下载。
http://download.csdn.net/detail/fesdgasdgasdg/9822984