Android 引导页动态添加圆点指示器

本来工作很忙,没时间写什么博客或研究小技术。昨晚实在是太无奈了,被兄弟拿枪顶着写了个引导页指示器的动态添加功能。描述的不详细,来张图片:


其实 实现原理很简单,一般都在app的初次启动时出现,一个左右滑动的viewpager,页面底部再搭配一个标识位置的小点点。
有人或立马喷饭,说这不是很简单吗?
确实简单,我现在做的不是静态在Activity底部写死几个view标识。我是自定义了一个容器,根据开发者切换页面的个数,来动态创建下面需要几个view控件。
其实这也是很简单,对于那些3~5年经验的老牛们,小鸟值得看看。没什么神奇的,但还是分享下吧。
原理+代码段解释+demo:

如何Activity底部有一个控件,能在代码里动态设置view的个数生成小点点就好了。

<com.example.viewpager_bottom_line_test.BottomLineLayout
        android:id="@+id/bottomlayoutl"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="50dp" />

试一试吧,接下来定义这个类。

/**
 * @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);
    }
}

我选择了继承LinearLayout布局,原因很简单:设置好方向,放心添加view就可以了。还需要两个drawable,一个是选中的样式,一个是未选中的。还有当前选中的view的position,还得设置view的宽高和外间距,不能挨得太近了。
(如果你不会自动以控件的话,此处略有遗憾。我之前也是不会,然后励志学习。研究了整个自定义控件的原理,review了网上90%的自定义控件。后来本打算写一序列自定义控件的文章与大家分享,但是时间总是不知道去哪儿了。如果你不会,还是要提醒你,自定义控件不是什么高深的东西,但是想成为大牛哥,还是快速搞定这家伙。)



自定义控件有三大方法,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;
    }

简单吧,创建TextView,创建LinearLayout.LayoutParams,设置宽高,设置Margin。


最后,还有个切换选中位置的方法,那更是简单了。


//切换到目标位置
    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每次切换时,更新指示器的状态:


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


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值