自定义view,垂直seekbar
来源:互联网 发布:物理模拟实验室软件 编辑:程序博客网 时间:2024/05/05 09:12
话不多说,公司接到的项目中有个效果是上下拉的窗帘,本来是用seekbar旋转90°做的,但是seekbar的属性太多,而且seekbar的滑块会直接显示最底层的颜色(我也不知道为什么), 所有就写了一个自定义view,其实就是一个垂直的seekbar,实现一些简单的操作,例如设置进度,设置前景色和背景色、滑块图片。
首先先看看这个最终效果是什么样的:
然后我们再分析一下这个效果的构成:
1.最底层是白色的。
2.上一层是绿色的(管他什么绿,反正就是绿)。
3.在上层颜色的底部中间有一个滑块。
分析之后,我们就可以开始考虑怎么写了,下面直接上代码。
<declare-styleable name="WindowBarView"> <!--bgcolor:背景颜色--> <!--cendiagram:中心原点的图片--> <!--foreground:前景颜色--> <!--maxprogress:最大进度--> <!--nowrogress:当前进度--> <attr name="bgcolor" format="color" /> <attr name="cendiagram" format="color|reference" /> <attr name="foreground" format="color" /> <attr name="maxprogress" format="integer" /> <attr name="nowrogress" format="integer" /> </declare-styleable>因为需要给控件设置一些属性,我们就先在attrs文件中加入属性(没有这个文件就先创建一个)。
然后就是java文件了,我们让这个自定义view集成自view,代码是酱婶儿的。
public class WindowBarView extends View { private int progress = 0; private int maxprogress = 0; private int nowrogress = 0; private int bgcolor = 0; private int Foreground = 0; //窗帘下拉的覆盖的颜色 private Paint paint; private Paint foregrodpaint; private Drawable cendiagram = null; //中心圆点的图片 private Bitmap cendiagrambp = null; // 获得图片的宽高 int widthbm = 0; int heightbm = 0; // 取得想要缩放的matrix参数 Matrix matrix; Bitmap newbm; private float mPreX, mPreY; int width, height; Rect rect; Rect rectforegroud; public setonBarTouthnListener touthnListener = null; public interface setonBarTouthnListener { public void GetProgress(int progress); } public void getonBarProgressListener(setonBarTouthnListener touthnListener) { this.touthnListener = touthnListener; } public WindowBarView(Context context) { super(context); } public WindowBarView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); initView(context, attrs); } public WindowBarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(context, attrs); } public WindowBarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); initView(context, attrs); } private void initView(Context context, AttributeSet attrs) { paint = new Paint(); foregrodpaint = new Paint(); TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.WindowBarView); Foreground = array.getInteger(R.styleable.WindowBarView_foreground, Color.WHITE); cendiagram = array.getDrawable(R.styleable.WindowBarView_cendiagram); maxprogress = array.getInteger(R.styleable.WindowBarView_maxprogress, 100); nowrogress = array.getInteger(R.styleable.WindowBarView_nowrogress, 0); bgcolor = array.getInteger(R.styleable.WindowBarView_bgcolor, Color.WHITE); setProgress(array.getInteger(R.styleable.WindowBarView_nowrogress, nowrogress)); array.recycle(); cendiagrambp = drawableToBitmap(cendiagram); // 获得图片的宽高 widthbm = cendiagrambp.getWidth(); heightbm = cendiagrambp.getHeight(); // 设置想要的大小 int newWidth = 100; int newHeight = 100; // 计算缩放比例 float scaleWidth = ((float) newWidth) / widthbm; float scaleHeight = ((float) newHeight) / heightbm; // 取得想要缩放的matrix参数 matrix = new Matrix(); matrix.postScale(scaleWidth, scaleHeight); // 得到新的图片 newbm = Bitmap.createBitmap(cendiagrambp, 0, 0, widthbm, heightbm, matrix, true); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int wideSize = MeasureSpec.getSize(widthMeasureSpec); int wideMode = MeasureSpec.getMode(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); if (wideMode == MeasureSpec.EXACTLY) { //精确值 或matchParent width = wideSize; } else { width = getPaddingLeft() + getPaddingRight(); if (wideMode == MeasureSpec.AT_MOST) { width = Math.min(width, wideSize); } } if (heightMode == MeasureSpec.EXACTLY) { //精确值 或matchParent height = heightSize; } else { height = getPaddingTop() + getPaddingBottom(); if (heightMode == MeasureSpec.AT_MOST) { height = Math.min(height, heightSize); } } setMeasuredDimension(width, height); rect = new Rect(0, 0, width, height); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); rectforegroud = new Rect(0, 0, width, (int) mPreY); paint.setStyle(Paint.Style.FILL); paint.setColor(bgcolor); paint.setAntiAlias(true); canvas.drawRect(rect, paint); foregrodpaint.setStyle(Paint.Style.FILL); foregrodpaint.setAntiAlias(true); foregrodpaint.setColor(Foreground); canvas.drawRect(rectforegroud, foregrodpaint); canvas.drawBitmap(newbm, width / 2 - newbm.getWidth() / 2, (int) mPreY - newbm.getHeight() / 2, paint); //绘制滑块 } /** * 获取当前位置 */ public int getProgress() { if(mPreY==0){ progress = (int) ((float) nowrogress / (float) maxprogress * 100); //当前进度 }else{ progress = Math.round(mPreY / height*(float) maxprogress); //当前进度 } return progress; } /** * 设置当前进度 */ public synchronized void setProgress(final int nowrogress) { if(height != 0){ mPreY = ((int) ((float) nowrogress / (float) maxprogress * height)); invalidate(); }else{ new Thread() { @Override public void run() { super.run(); try { Thread.sleep(100); if (height != 0) { mPreY = ((int) ((float) nowrogress / (float) maxprogress * height)); postInvalidate(); } } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); } } /** * 判断,如果滑动的位置大于控件的高度,说明此事滑块已经滑到下面 * 如果小于0说明在上面 * * @param event * @return */ @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mPreX = event.getX(); mPreY = event.getY(); touthnListener.GetProgress((int) (mPreY / height * maxprogress)); invalidate(); return true; case MotionEvent.ACTION_MOVE: mPreY = event.getY(); if (mPreY < 0) { mPreY = 0; } else if (mPreY > height) { mPreY = height; } else { mPreY = event.getY() + 8; } touthnListener.GetProgress((int) (mPreY / height * maxprogress)); invalidate(); break; } return super.onTouchEvent(event); } /** * drawable转bitmap * * @param drawable * @return */ public static Bitmap drawableToBitmap(Drawable drawable) { Bitmap bitmap = Bitmap.createBitmap( drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565); Canvas canvas = new Canvas(bitmap); //canvas.setBitmap(bitmap); drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); drawable.draw(canvas); return bitmap; }}
主要就是onDraw中的内容。
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); rectforegroud = new Rect(0, 0, width, (int) mPreY); paint.setStyle(Paint.Style.FILL); paint.setColor(bgcolor); paint.setAntiAlias(true); canvas.drawRect(rect, paint); foregrodpaint.setStyle(Paint.Style.FILL); foregrodpaint.setAntiAlias(true); foregrodpaint.setColor(Foreground); canvas.drawRect(rectforegroud, foregrodpaint); canvas.drawBitmap(newbm, width / 2 - newbm.getWidth() / 2, (int) mPreY - newbm.getHeight() / 2, paint); //绘制滑块 }这个控件我将它分为了三层,这样我就需要在画布上画三次,第一次,绘制最底层颜色,第二次,绘制上一层颜色,第三次绘制滑块,这样才能得到想要的效果。
下面就是使用方法。
<com.tianer.dooya.weight.WindowBarView android:id="@+id/timeline" android:layout_width="200dp" android:layout_height="300dp" app:bgcolor="@color/white" app:foreground="@color/windowbar" app:cendiagram="@drawable/bgg" app:maxprogress="100"/>
最后,上个效果图。
上个源码地址
https://github.com/dzghxs/WindowBarView点击打开链接
阅读全文
1 0
- 自定义view,垂直seekbar
- 自定义View实现环形SeekBar
- 自定义View实现环形SeekBar
- Android 自定义UI-垂直方向的SeekBar
- Android 自定义UI-垂直方向的SeekBar
- 垂直的SeekBar以及自定义布局
- 自定义垂直文字view
- 自定义View实现拖动条SeekBar
- Andrid自定义组件之垂直SeekBar以及播放帧动画
- 自定义垂直的SeekBar并用图片做滑块和背景
- Android开发之如何自定义垂直方向的SeekBar
- Android 垂直Seekbar
- android垂直seekbar
- 垂直的SeekBar探讨
- 垂直的SeekBar:VerticalSeekBar
- 垂直方向的seekbar
- Android 垂直seekbar
- android自定义View-垂直滚动的TextView
- 好测试,坏测试
- mysqldump数据库备份,参数详解
- HDOJ 1171 Big Event in HDU(二进制拆分+0 1背包)
- 最小二乘法拟合曲线:二次函数
- Arduino的传感器使用教程1:PM2.5、温度和大气压传感器
- 自定义view,垂直seekbar
- 欢迎使用CSDN-markdown编辑器
- Java+selenium+testng+ant框架搭建-环境搭建01
- JDBC连接MySql数据库
- 算法设计大作业 8章第3题
- BZOJ 2748 音量调节
- Minimum supported Gradle version is 3.3. Current version is 2.14.1
- rn中访问相册和保存图片
- python 3.5中如何用input输入多个数值?用什么分隔开?