自定义View仿魅族手机加速(手机管家)效果
2016-08-18 23:15
323 查看
转载请注明出处:http://blog.csdn.net/MAGIC_JSS/article/details/52245844;
看着魅族手机管家上的手机加速效果不错,决定自己实现之。希望自己加深对自定义View的理解和使用,也希望帮助需要类似效果的朋友。
先上效果:
由于是模拟器上运行的效果不是很好,真机上运行会好很多。
直接继承View的自定义控件需要考虑两个方面问题,当控件大小设置为wrap_content的时候和存在padding的情况。处理控件大小为wrap_content的情况一般是通过获取View的测量模式设置默认值。而处理padding的情况则是通过相关要求处理偏移量。
以上代码主要是在构造方法中进行画笔初始化操作和自定义属性获取;在onMeasure中设置默认宽高,获取padding值;onSizeChanged中获取宽高并进行所画弧高度、偏移量、文字大小、画笔宽度的动态设置;在onDraw中通过画布的平移和旋转对内容进行绘制。
引入自定义控件的命名控件,设置自定义属性。
END!
看着魅族手机管家上的手机加速效果不错,决定自己实现之。希望自己加深对自定义View的理解和使用,也希望帮助需要类似效果的朋友。
先上效果:
由于是模拟器上运行的效果不是很好,真机上运行会好很多。
1、继承View
废话少说,直接上码;/** * Created by magic on 2016年8月11日.仿魅族手机加速(手机管家)的效果 */ @SuppressLint({ "DrawAllocation", "Recycle" }) public class MyDataResidueView extends View { private Paint paint, paintText; private float arcWidth; private float width, height; // 中间数字描述 private double numberDesc = 99; // 中间的底部描述 private String desc = "内存剩余"; // 进度默认为全部 private int progress = 270; // 数值格式化 private DecimalFormat df; // 百分比文字大小 private int numberDescSize = 80; // 底部描述文字大小 private int descSize = 40; // 边框宽度大小 private int strokeWidth = 5; private int color; private int laterColor; private int textColor; private float paddingLeft, paddingTop, paddingRight, paddingBottom; private float offsetTop, offsetLeft; public MyDataResidueView(Context context) { super(context); init(); } public MyDataResidueView(Context context, AttributeSet attrs) { super(context, attrs); getCustomAttribute(context, attrs); init(); } public MyDataResidueView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); getCustomAttribute(context, attrs); init(); } /** * 获取自定义属性 * * @param context * @param attrs */ private void getCustomAttribute(Context context, AttributeSet attrs) { TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.MyDataResidueView); desc = array .getString(styleable.MyDataResidueView_MyDataResidueView_desc); if (desc == null)desc = "内存剩余"; color = array.getColor( styleable.MyDataResidueView_MyDataResidueView_color, context .getResources().getColor(R.color.white)); laterColor = array.getColor( styleable.MyDataResidueView_MyDataResidueView_laterColor, context.getResources().getColor(R.color.black)); textColor = array.getColor( styleable.MyDataResidueView_MyDataResidueView_textColor, context.getResources().getColor(R.color.white)); array.recycle(); } /** * 初始化画笔 */ private void init() { paint = new Paint(); paint.setAntiAlias(true); paint.setStyle(Style.FILL); // paint.setStrokeWidth(5); paintText = new Paint(); paintText.setAntiAlias(true); paintText.setStyle(Style.STROKE); paintText.setColor(textColor); df = new DecimalFormat("0%"); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int wMode = MeasureSpec.getMode(widthMeasureSpec); int wSize = MeasureSpec.getSize(widthMeasureSpec); int hMode = MeasureSpec.getMode(heightMeasureSpec); int hSize = MeasureSpec.getSize(heightMeasureSpec); //处理宽高为 wrap_content的情况 if (wMode == MeasureSpec.AT_MOST && hMode == MeasureSpec.AT_MOST) { setMeasuredDimension(200, 200); } else if (wMode == MeasureSpec.AT_MOST) { setMeasuredDimension(200, hSize); } else if (hMode == MeasureSpec.AT_MOST) { setMeasuredDimension(wSize, 200); } // 获取padding paddingLeft = getPaddingLeft(); paddingTop = getPaddingTop(); paddingRight = getPaddingRight(); paddingBottom = getPaddingBottom(); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); // 考虑存在padding的情况 this.width = w - paddingLeft - paddingRight; this.height = h - paddingTop - paddingBottom; if (width >= height) { arcWidth = height / 2; } else if (width < height) { arcWidth = width / 2; }// 91 offsetLeft = paddingLeft; offsetTop = paddingTop; //动态计算文字大小 numberDescSize = (int) (numberDescSize / 320f * arcWidth); descSize = numberDescSize / 2; //动态设置画笔宽度 paint.setStrokeWidth(strokeWidth / 320f * arcWidth); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //平移坐标 canvas.translate(width / 2 + offsetLeft, height / 2 + offsetTop); Rect rect = new Rect(); numberDesc = progress / 270f; String num = df.format(numberDesc); paintText.getTextBounds(num, 0, num.length(), rect); // 获取高度 int h = rect.height(); paintText.setTextSize(numberDescSize); canvas.drawText(num, -(paintText.measureText(num) / 2), -(h / 2), paintText); paintText.setTextSize(descSize); canvas.drawText(desc, -(paintText.measureText(desc) / 2), 1 * h, paintText); paint.setColor(color); canvas.rotate(-3 * 45); for (int i = 0; i < 90; i++) { canvas.rotate(3); canvas.drawLine(0, -arcWidth, 0, -(arcWidth - 5 * paint.getStrokeWidth()), paint); } canvas.rotate(-(270 - progress)); canvas.drawLine(0, -arcWidth, 0, -(arcWidth - 3 * 5 * paint.getStrokeWidth()), paint); paint.setColor(laterColor); canvas.rotate((270 - progress) + 3); for (int i = 0; i < (270 - progress) / 3; i++) { canvas.rotate(-3); canvas.drawLine(0, -arcWidth, 0, -(arcWidth - 5 * paint.getStrokeWidth()), paint); } } /** * 设置进度大小 * * @param progress */ public void setProgress(int progress) { this.progress = progress; postInvalidate(); } public int getProgress() { return this.progress; } }
直接继承View的自定义控件需要考虑两个方面问题,当控件大小设置为wrap_content的时候和存在padding的情况。处理控件大小为wrap_content的情况一般是通过获取View的测量模式设置默认值。而处理padding的情况则是通过相关要求处理偏移量。
以上代码主要是在构造方法中进行画笔初始化操作和自定义属性获取;在onMeasure中设置默认宽高,获取padding值;onSizeChanged中获取宽高并进行所画弧高度、偏移量、文字大小、画笔宽度的动态设置;在onDraw中通过画布的平移和旋转对内容进行绘制。
2、自定义属性
在values文件夹下创建attrs.xml<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="MyDataResidueView"> <!-- 底部文字描述 --> <attr name="MyDataResidueView_desc" format="string" /> <attr name="MyDataResidueView_color" format="color" /> <attr name="MyDataResidueView_laterColor" format="color" /> <!-- 文字颜色 --> <attr name="MyDataResidueView_textColor" format="color" /> </declare-styleable> </resources>
3、xml文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom_view="http://schemas.android.com/apk/res/com.magic.test_customview" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <com.magic.customview.MyDataResidueView android:id="@+id/myview" android:layout_width="match_parent" android:layout_height="200dp" android:background="@color/black" android:padding="10dp" android:visibility="visible" custom_view:MyDataResidueView_color="@color/white" custom_view:MyDataResidueView_desc="内存剩余" custom_view:MyDataResidueView_laterColor="@color/black" custom_view:MyDataResidueView_textColor="@color/white" /> </LinearLayout>
引入自定义控件的命名控件,设置自定义属性。
4、Activity中使用
/** * Created by magic on 2016年8月11日. */ public class MainActivity extends Activity { // 手机内存剩余 MyDataResidueView myView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myView = (MyDataResidueView) findViewById(R.id.myview); ObjectAnimator animator2 = ObjectAnimator.ofInt(myView, "progress", 135); animator2.setDuration(2000); animator2.setInterpolator(new AccelerateInterpolator()); animator2.start(); } }
END!
相关文章推荐
- android自定义组件(手机加速球+水面波动效果)
- Android自定义View实现内存清理加速球效果
- android自定义View实现图片上传进度显示(仿手机QQ上传效果)
- Android自定义View——仿vivo i管家病毒扫描动画效果
- android自定义组件(手机加速球+水面波动效果)
- android自定义View实现图片上传进度显示(仿手机QQ上传效果)
- Android 自定义View:教你轻松实现内存清理加速球的效果
- android自定义组件(手机加速球+水面波动效果)
- android自定义TextView实现安卓手机开机android文字Log的动画效果
- android自定义View实现图片上传进度显示(仿手机QQ上传效果)
- 手机卫士学习06-自定义滚动的TextView实现走马灯效果
- Android学习备忘020——android自定义ImageView实现缩放,回弹效果
- 使用自定义RadioButton和ViewPager实现TabHost效果和带滑动的页卡效果。
- 使用自定义RadioButton和ViewPager实现TabHost效果和带滑动的页卡效果。
- Android自定义View实现转盘旋转的效果
- android 自定义ImageView实现图片手势滑动,多点触摸放大缩小效果
- android 自定义ImageView实现图片手势滑动,多点触摸放大缩小效果
- 自定义TextView实现跑马灯效果
- 自定义TextView跑马灯效果,可控制启动,停止,和速度(含源码)
- andriod 自定义view动画效果