Zerohuan的专栏

github地址:https://github.com/zerohuan/SlideLayout/tree/master

实际效果图:

该自定义控件继承FrameLayout, 包含一个ViewPager和横向排列的LinearLayout。后者用于包含显示表示轮播位置的点集,使用ViewPager的好处在于可以灵活的定义item的内容,而不仅仅是图片。</p><p></p><p>为了便于使用,通过自定义属性的方式定义了所须的运行参数:</p><p><pre name="code" class="html"><declare-styleable name="SlideLayout"><attr name="viewpagerId" format="reference"/><attr name="dotsId" format="reference"/><attr name="autoPlay" format="boolean" /><attr name="slide_interval" format="integer" /><attr name="dotRadius" format="dimension" /><attr name="onDotColor" format="color" /><attr name="offDotColor" format="color" /><attr name="strokeColor" format="color" /></declare-styleable>对应的数据成员如下:

//轮播容器viewPagerprivate ViewPager viewPager;//标示位置的点集private LinearLayout dots;//viewPager的资源IDprivate int viewPagerId;//包含点的LinearLayout的资源IDprivate int dotsId;//该手机的px-dp比例倍数private float scale;//ViewPager的Adapterprivate PagerAdapter adapter;//是否自动播放private boolean isAutoPlay;//播放的间隔private int interval;//当前页位置private int currentItem;//圆点半径private float dotRadius;//是否正在轮播运行private boolean isRunning;//位于当前页,点标志的颜色private int onDotColor;//未位于当前页,点标志的颜色private int offDotColor;//点边框颜色private int strokeColor;private final static int SCROLL_WHAT = 0x7549;

使用时,通过Xml文件来定义:

<com.luckymore.ydd.app.view.selfView.SlideLayoutxmlns:attrs=""android:id="@+id/news_slide_bar"android:layout_width="match_parent"android:layout_height="match_parent"swipe:dotsId="@+id/test_1"attrs:viewpagerId="@+id/test_2"attrs:autoPlay="true"attrs:dotRadius="3dp"attrs:slide_interval="4000"attrs:offDotColor="@color/alpha_black"attrs:onDotColor="@color/alpha_white"attrs:strokeColor="#77626262"><android.support.v4.view.ViewPager android:id="@+id/test_2"android:layout_width="match_parent"android:layout_height="match_parent" /><LinearLayout android:id="@+id/test_1"android:layout_width="wrap_content"android:layout_height="20dp"android:orientation="horizontal"android:layout_gravity="bottom|center_horizontal"android:gravity="center"android:paddingLeft="8dp"android:paddingRight="8dp"/></com.luckymore.ydd.app.view.selfView.SlideLayout>获取自定义参数值:/*** 获取自定义参数,在构造器中调用* @param context* @param attrs*/private void init(Context context, AttributeSet…attrs) {if(attrs.length > 0) {TypedArray typedArray = context.obtainStyledAttributes(attrs[0], R.styleable.SlideLayout);viewPagerId = typedArray.getResourceId(R.styleable.SlideLayout_viewpagerId, -1);dotsId = typedArray.getResourceId(R.styleable.SlideLayout_dotsId, -1);scale = getResources().getDisplayMetrics().density;isAutoPlay = typedArray.getBoolean(R.styleable.SlideLayout_autoPlay, false);interval = typedArray.getInteger(R.styleable.SlideLayout_slide_interval, 4000);dotRadius = typedArray.getDimension(R.styleable.SlideLayout_dotRadius, 2f * scale);onDotColor = typedArray.getColor(R.styleable.SlideLayout_onDotColor, 0x77FFFFFF);offDotColor = typedArray.getColor(R.styleable.SlideLayout_offDotColor, 0x77000000);strokeColor = typedArray.getColor(R.styleable.SlideLayout_strokeColor, 0x77626262);}}ViewPager的ID和LinearLayout的ID通过自定义属性的方式传入,注入到SlideLayout中,在onFinishInflate中实现:@Overrideprotected void onFinishInflate() {super.onFinishInflate();if(viewPagerId != -1 && dotsId != -1) {viewPager = (ViewPager)findViewById(viewPagerId);dots = (LinearLayout)findViewById(dotsId);viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {@Overridepublic void onPageScrolled(int i, float v, int i2) {}@Overridepublic void onPageSelected(int i) {currentItem = i;for(int j = 0; j < viewPager.getAdapter().getCount(); j++) {DotView dot = (DotView)dots.getChildAt(j);if(j == i)dot.setOn(true);elsedot.setOn(false);dot.invalidate();}}@Overridepublic void onPageScrollStateChanged(int i) {switch (i) {case 1:// 手势滑动,空闲中isAutoPlay = false;break;case 2:// 界面切换中isAutoPlay = true;break;case 0:// 滑动结束,即切换完毕或者加载完毕// 当前为最后一张,此时从右向左滑,则切换到第一张if (viewPager.getCurrentItem() == viewPager.getAdapter().getCount() – 1 && !isAutoPlay) {viewPager.setCurrentItem(0);}// 当前为第一张,此时从左向右滑,则切换到最后一张else if (viewPager.getCurrentItem() == 0 && !isAutoPlay) {viewPager.setCurrentItem(viewPager.getAdapter().getCount() – 1);}break;}}});}}接着实现,LinearLayout中的“点”的填充,首先定义内部类DotView:/*** 点状UI, 正方形View, 包含一个圆形点*/public class DotView extends View {private Paint mPaint = new Paint();//两种状态, 是否是当前页private boolean isOn;//正方形边长private int mSize;public DotView(Context context) {super(context);}public DotView(Context context, AttributeSet attrs) {super(context, attrs);}public DotView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}/*** 比onDraw先执行* @param widthMeasureSpec* @param heightMeasureSpec*/@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {mSize = (int)Math.ceil(dotRadius) * 3;setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));}private int measureWidth(int measureSpec) {int result = 0;int specMode = MeasureSpec.getMode(measureSpec);int specSize = MeasureSpec.getSize(measureSpec);if (specMode == MeasureSpec.EXACTLY) {// We were told how big to beresult = specSize;} else {// Measure the textresult = mSize + getPaddingLeft() + getPaddingRight();if (specMode == MeasureSpec.AT_MOST) {// Respect AT_MOST value if that was what is called for by// measureSpecresult = Math.min(result, specSize);// 60,480}}return result;}private int measureHeight(int measureSpec) {int result = 0;int specMode = MeasureSpec.getMode(measureSpec);int specSize = MeasureSpec.getSize(measureSpec);if (specMode == MeasureSpec.EXACTLY) {// We were told how big to beresult = specSize;} else {// Measure the text (beware: ascent is a negative number)result = mSize + getPaddingTop() + getPaddingBottom();if (specMode == MeasureSpec.AT_MOST) {// Respect AT_MOST value if that was what is called for by// measureSpecresult = Math.min(result, specSize);}}return result;}//绘制点@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);mPaint.setAntiAlias(true);if(isOn()) {mPaint.setColor(onDotColor);} else {mPaint.setColor(offDotColor);}mPaint.setStyle(Paint.Style.FILL);canvas.drawCircle(dotRadius, dotRadius, dotRadius, mPaint);mPaint.setStyle(Paint.Style.STROKE);mPaint.setStrokeWidth(0.7f * scale);mPaint.setColor(strokeColor);canvas.drawCircle(dotRadius, dotRadius, dotRadius, mPaint);}public boolean isOn() {return isOn;}public void setOn(boolean isOn) {this.isOn = isOn;}}DotView包含是否是当前页两种状态,填充颜色和边框颜色都从自定义属性中获得。

都成为命途中美丽的点缀,看天,看雪,安安静静,不言不语都是好风景。

Zerohuan的专栏

相关文章:

你感兴趣的文章:

标签云: