android自定义View之刻度尺MnScaleBar
2015-12-01 21:07
459 查看
在Q群里看到有同学需要自定义刻度尺如图:
1. 需求:
1)指针固定在屏幕中间;
2)左右可以滑动直尺;
3)返回选择的刻度值;
2. 需要的知识点:
1)继承View重写onDraw()方法
2)重写onTouchEvent()方法
3)Scroller滑动帮助类
4)OnScrollListener回调方法
3. 代码如下:
布局代码:
Activity代码:
运行结果如图:
1. 需求:
1)指针固定在屏幕中间;
2)左右可以滑动直尺;
3)返回选择的刻度值;
2. 需要的知识点:
1)继承View重写onDraw()方法
2)重写onTouchEvent()方法
3)Scroller滑动帮助类
4)OnScrollListener回调方法
3. 代码如下:
package cc.mnbase.view.progress.bar; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.view.MotionEvent; import android.view.View; import android.widget.LinearLayout; import android.widget.Scroller; /** * User: 山野书生(1203596603@qq.com) * Date: 2015-11-30 * Time: 14:29 * Version 1.0 */ public class MnScaleBar extends View { private Context mContext; private Rect mRect; private int max = 200; //最大刻度 private int mCountScale; //滑动的总刻度 private int screenWidth = 720; //默认屏幕分辨率 private int mScaleMargin = 15; //刻度间距 private int mScaleHeight = 20; //刻度线的高度 private int mScaleMaxHeight = mScaleHeight*2; //整刻度线高度 private int mRectWidth = max * mScaleMargin; //总宽度 private int mRectHeight = 150; //高度 private Scroller mScroller; private int mScrollLastX; private int mTempScale = screenWidth/mScaleMargin/2; //判断滑动方向 private int mScreenMidCountScale = screenWidth/mScaleMargin/2; //中间刻度 private OnScrollListener onScrollListener; private String tag = MnScaleBar.class.getSimpleName(); public MnScaleBar(Context context) { this(context, null); } public MnScaleBar(Context context, AttributeSet attrs) { this(context, attrs, -1); } public MnScaleBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mContext = context; screenWidth = getPhoneW(mContext); mTempScale = screenWidth/mScaleMargin/2; //判断滑动方向 mScreenMidCountScale = screenWidth/mScaleMargin/2; //中间刻度 mScroller = new Scroller(mContext); } @Override protected void onDraw(Canvas canvas) { //设置LayoutParams LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(mRectWidth, mRectHeight); this.setLayoutParams(lp); //相对位置坐标 mRect = new Rect(0, 0, mRectWidth, mRectHeight); //画笔 Paint mPaint = new Paint(); mPaint.setColor(Color.GRAY); mPaint.setAntiAlias(true); mPaint.setDither(true); mPaint.setStyle(Paint.Style.STROKE); canvas.drawRect(mRect, mPaint); onDrawScale(canvas); //画刻度 onDrawPointer(canvas); //画指针 super.onDraw(canvas); } /** * 画刻度 * */ private void onDrawScale(Canvas canvas){ if(canvas == null) return; Paint mPaint = new Paint(); mPaint.setColor(Color.GRAY); mPaint.setTextAlign(Paint.Align.CENTER); //文字居中 mPaint.setTextSize(20); for(int i=0; i<max; i++){ if(i!=0 && i!=max){ if(i%10==0){ //整值 canvas.drawLine(i*mScaleMargin, mRectHeight, i*mScaleMargin, mRectHeight-mScaleMaxHeight, mPaint); //整值文字 canvas.drawText(String.valueOf(i), i*mScaleMargin, mRectHeight-mScaleMaxHeight-10, mPaint); } else { canvas.drawLine(i*mScaleMargin, mRectHeight, i*mScaleMargin, mRectHeight-mScaleHeight, mPaint); } } } } /** * 画指针 * */ private void onDrawPointer(Canvas canvas){ if(canvas == null) return; Paint mPaint = new Paint(); mPaint.setColor(Color.RED); mPaint.setTextAlign(Paint.Align.CENTER); mPaint.setTextSize(20); //每一屏幕刻度的个数/2 int countScale = screenWidth/mScaleMargin/2; //根据滑动的距离,计算指针的位置【指针始终位于屏幕中间】 int finalX = mScroller.getFinalX(); //滑动的刻度 int tmpCountScale = (int) Math.rint((double)finalX/(double)mScaleMargin); //四舍五入取整 //总刻度 mCountScale = tmpCountScale+countScale; if(onScrollListener!=null){ //回调方法 onScrollListener.onScrollScale(mCountScale); } canvas.drawLine(countScale * mScaleMargin + finalX, mRectHeight, countScale * mScaleMargin + finalX, mRectHeight - mScaleMaxHeight, mPaint); canvas.drawText(String.valueOf(mCountScale), countScale * mScaleMargin + finalX, mRectHeight - mScaleMaxHeight - 10, mPaint); } @Override public void computeScroll() { if(mScroller.computeScrollOffset()){ scrollTo(mScroller.getCurrX(), 0); postInvalidate(); } super.computeScroll(); } @Override public boolean onTouchEvent(MotionEvent event) { int x = (int) event.getX(); switch (event.getAction()){ case MotionEvent.ACTION_DOWN: if(mScroller != null && !mScroller.isFinished()){ mScroller.abortAnimation(); } mScrollLastX = x; return true; case MotionEvent.ACTION_MOVE: int dataX = mScrollLastX - x; if(mCountScale-mTempScale<0){ //向右边滑动 if(mCountScale<0) { if(dataX<0) //禁止继续向右滑动 return super.onTouchEvent(event); } } else if(mCountScale-mTempScale>0){ //向左边滑动 if (mCountScale>max) { if(dataX>0) //禁止继续向左滑动 return super.onTouchEvent(event); } } smoothScrollBy(dataX, 0); mScrollLastX = x; postInvalidate(); mTempScale = mCountScale; return true; case MotionEvent.ACTION_UP: if(mCountScale<0) mCountScale=0; if(mCountScale>max) mCountScale=max; int finalX = (mCountScale-mScreenMidCountScale) * mScaleMargin; mScroller.setFinalX(finalX); //纠正指针位置 postInvalidate(); return true; } return super.onTouchEvent(event); } public void smoothScrollBy(int dx, int dy){ mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx, dy); } public void smoothScrollTo(int fx, int fy){ int dx = fx - mScroller.getFinalX(); int dy = fy - mScroller.getFinalY(); smoothScrollBy(dx, dy); } public void setOnScrollListener(OnScrollListener onScrollListener) { this.onScrollListener = onScrollListener; } public interface OnScrollListener{ void onScrollScale(int scale); } /** * 获取手机分辨率--W * */ public static int getPhoneW(Context context){ DisplayMetrics dm = new DisplayMetrics(); ((Activity)context).getWindowManager().getDefaultDisplay().getMetrics(dm); int disW = dm.widthPixels; return disW; } }
布局代码:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <cc.mnbase.view.progress.bar.MnScaleBar android:layout_width="match_parent" android:layout_height="100dp" android:layout_margin="5dp" android:id="@+id/scale_bar" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/text" /> </LinearLayout>
Activity代码:
package cc.mnbase; import android.os.Bundle; import android.widget.TextView; import cc.mn.BaseActivity; import cc.mnbase.view.progress.bar.MnScaleBar; /** * User: 山野书生(1203596603@qq.com) * Date: 2015-11-30 * Time: 14:44 * Version 1.0 */ public class MnScaleBarActivity extends BaseActivity{ private TextView text; private MnScaleBar scale_bar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_scale_bar_layout); scale_bar = (MnScaleBar)findViewById(R.id.scale_bar); text = (TextView)findViewById(R.id.text); scale_bar.setOnScrollListener(new MnScaleBar.OnScrollListener() { @Override public void onScrollScale(int scale) { text.setText("身高:"+scale+"cm"); } }); } }
运行结果如图:
相关文章推荐
- 支付宝集成获取私钥与公钥
- android CHMOD命令用法
- [Android学习笔记八] 使用VideoView屏幕方向发生变化,视频方向自动切换
- Android异步加载(二)
- android 计算器
- android118 上拉下拉刷新列表listView实现
- Android之下拉列表Spinner控件使用
- android控件的监听绑定方法
- android studio 9.png 报错
- Android Manifest标签之data, grant-uri-permission, instrumentation, intent-filter
- Android并发编程之全方位解析AsyncTask
- Xamarin.Android 实现虾米音乐搜索下载
- android框架搭建——封装一个属于自己的数据存储工具类(SQLite篇)
- android---Scroll实现滑动效果
- Android 4.4 U盘挂载
- android117 下拉列表
- Android Touch事件之二:dispatchTouchEvent()和onTouchEvent()篇
- Android ClickableRoundedBackground Span实现(初版)
- Android 实用功能收藏
- 面向企业应用的Android开发从入门到精通