• Android-自己定义显示价格的PriceView


    转载请标明出处:http://blog.csdn.net/goldenfish1919/article/details/44418883

    先看一下我们要做的效果:


    价格分成了3部分。前面是一个¥,中间的整数部分,后面的小数部分,中间还带一个删除线。

    參考:http://blog.csdn.net/lmj623565791/article/details/44098729,我们这个事实上更简单,自己定义一个view。然后把三个部分和删除线分别画出来就能够了。

    PriceView.java:

    public class PriceView extends View{
    	
    	private String value = null;
    	
    	private int moneySize = -1;
    	private int intSize = -1;
    	private int decimalSize = -1;
    	
    	private String money = "¥";
    	private String decimalPart = "";
    	private String intPart = "";
    	
    	private int moneyStart = 0;
    	private int intStart = 0;
    	private int decimalStart = 0;
    	
    	private int textColor = 0;
    	private boolean strike = false;
    	private boolean withEndZero = true;
    	
    	private Paint mPaint;
    	private Rect mTextBound = new Rect();
    	private int totalWidth = 0;
    	private int maxHeight = 0;
    	private boolean hasComma = false;
    	
    	
    	public PriceView(Context context, AttributeSet attrs, int defStyleAttr) {
    		super(context, attrs, defStyleAttr);
    		init(context, attrs);
    	}
    
    	public PriceView(Context context, AttributeSet attrs) {
    		this(context, attrs, 0);
    	}
    
    	public PriceView(Context context) {
    		this(context, null);
    	}
    
    	public void setText(String text){
    		this.value = text;
    		calcTextDimens();
    	}
    	
    	private void init(Context context, AttributeSet attrs){
    		mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    		getProperties(context, attrs);
    		calcTextDimens();
    	}
    	
    	private void calcTextDimens() {
    		
    		totalWidth = 0;
    		maxHeight = 0;
    		
    		//把text分成三个部分
    		if(value == null || value.length() <= 0){
    			return;
    		}
    		String arr[] = value.split("\.");
    		//整数部分
    		intPart = arr[0];
    		if(intPart.length() > 0 && intPart.charAt(0) == '¥'){
    			intPart = intPart.substring(1);
    		}
    		if(intPart.indexOf(",") >= 0){
    			hasComma = true;
    		}else{
    			hasComma = false;
    		}
    		//小数部分
    		decimalPart = arr.length > 1?

    arr[1]:""; if(decimalPart != null){ if(!withEndZero){ decimalPart = decimalPart.replaceAll("0{1,}$", ""); } if(decimalPart != null && decimalPart.length() > 0){ decimalPart = "."+decimalPart; } } //处理¥ int moneyWidth = process(money, moneySize); moneyStart = getPaddingLeft(); //处理整数部分 int intWidth = process(intPart, intSize); intStart = moneyStart + moneyWidth; //处理小数部分 process(decimalPart, decimalSize); decimalStart = intStart + intWidth; totalWidth += getPaddingLeft() + getPaddingRight(); maxHeight += getPaddingTop() + getPaddingBottom(); } private int process(String text, int textSize){ if(text == null || text.length() <= 0){ return 0; } mPaint.setTextSize(textSize); int textWidth = (int) mPaint.measureText(text); mPaint.getTextBounds(text, 0, text.length(), mTextBound); totalWidth += textWidth; maxHeight = mTextBound.height() > maxHeight?

    mTextBound.height() : maxHeight; return textWidth; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = measureWidth(widthMeasureSpec); int height = measureHeight(heightMeasureSpec); setMeasuredDimension(width, height); } protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setColor(textColor); //画中间的删除线 if(strike){ //mPaint.setFlags(Paint.STRIKE_THRU_TEXT_FLAG);是不能够的。为什么不能够能够自己试一下 float startX = getPaddingLeft(); float startY = (getMeasuredHeight() - getPaddingBottom() - getPaddingTop()) /2 + getPaddingTop(); float stopX = getMeasuredWidth() - getPaddingRight(); float stopY = startY; canvas.drawLine(startX, startY , stopX, stopY, mPaint); } int y = getMeasuredHeight() - getPaddingBottom(); if(hasComma){ y -= dp2px(getContext(), 3); } //画¥ mPaint.setTextSize(moneySize); canvas.drawText(money, moneyStart, y, mPaint); //画整数部分 mPaint.setTextSize(intSize); canvas.drawText(intPart, intStart, y, mPaint); //画小数部分 mPaint.setTextSize(decimalSize); canvas.drawText(decimalPart, decimalStart, y, mPaint); } private int measureWidth(int measureSpec) { int mode = MeasureSpec.getMode(measureSpec); int val = MeasureSpec.getSize(measureSpec); int result = 0; switch (mode){ case MeasureSpec.EXACTLY: result = val; break; case MeasureSpec.AT_MOST: case MeasureSpec.UNSPECIFIED: result = totalWidth; break; } return result; } private int measureHeight(int measureSpec) { int mode = MeasureSpec.getMode(measureSpec); int val = MeasureSpec.getSize(measureSpec); int result = 0; switch (mode){ case MeasureSpec.EXACTLY: result = val; break; case MeasureSpec.AT_MOST: case MeasureSpec.UNSPECIFIED: result = maxHeight; break; } return result; } private void getProperties(Context context, AttributeSet attrs){ //自己定义的属性 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CartPriceValue); int textSize = a.getDimensionPixelSize(R.styleable.CartPriceValue_textSize, 14); String value = a.getString(R.styleable.CartPriceValue_value); int textColor = a.getColor(R.styleable.CartPriceValue_textColor, 0xffffff); int moneySize = a.getDimensionPixelSize(R.styleable.CartPriceValue_moneySize, textSize); int intSize = a.getDimensionPixelSize(R.styleable.CartPriceValue_intSize, textSize); int decimalSize = a.getDimensionPixelSize(R.styleable.CartPriceValue_decimalSize, textSize); boolean strike = a.getBoolean(R.styleable.CartPriceValue_strike, false); boolean withEndZero = a.getBoolean(R.styleable.CartPriceValue_withEndZero, true); this.value = value; this.textColor = textColor; this.moneySize = moneySize; this.intSize = intSize; this.decimalSize = decimalSize; this.strike = strike; this.withEndZero = withEndZero; a.recycle(); } public static int px2dp(Context context, float pxValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f); } public static int dp2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } }


    attr.xml:
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
         <declare-styleable name="CartPriceValue">
            <attr name="value" format="reference|string" />
            <attr name="textColor" format="reference|color" />
            <attr name="textSize" format="reference|dimension" />
            <attr name="moneySize" format="reference|dimension" />
            <attr name="intSize" format="reference|dimension" />
            <attr name="decimalSize" format="reference|dimension" />
            <attr name="strike" format="boolean" />
            <attr name="withEndZero" format="boolean" />
        </declare-styleable>
    
    </resources>

    布局文件main.xml:

    <?

    xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cart="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/white" android:orientation="vertical" > <com.example.priceview.PriceView android:id="@+id/priceview1" android:layout_width="wrap_content" android:layout_height="wrap_content" cart:value="¥12.345" cart:moneySize="14dp" cart:intSize="20dp" cart:decimalSize="16dp" cart:textColor="#ff0000" cart:strike="true" android:padding="10dp"/> <com.example.priceview.PriceView android:id="@+id/priceview2" android:layout_width="wrap_content" android:layout_height="wrap_content" cart:value="¥12.0" cart:moneySize="14dp" cart:intSize="20dp" cart:decimalSize="16dp" cart:textColor="#ff0000" cart:strike="true" android:padding="10dp"/> <com.example.priceview.PriceView android:id="@+id/priceview3" android:layout_width="wrap_content" android:layout_height="wrap_content" cart:value="¥12.0" cart:moneySize="14dp" cart:intSize="20dp" cart:decimalSize="16dp" cart:textColor="#ff0000" cart:strike="true" cart:withEndZero="false"/> </LinearLayout>


    project源代码下载:http://download.csdn.net/download/goldenfish1919/8512713

    ps:

    (1)在一个ListView中使用这个PriceView的时候,发现有的时候价格被截断没有展示出来,后来才发现是由于Listview中的View复用导致的。

    因此须要在setText()中显式的调用一下requestLayout()。它会导致又一次调用onMeasure()。

    (2)后来又发现个问题,当整数部分带有逗号的时候,逗号会显示不全,不知道是哪块代码出的问题。有大神不吝赐教下吗?


  • 相关阅读:
    vue2.5.2 在ie11打开空白的解决方法
    小程序自定义组件中observer函数的应用
    小程序将一个完整项目导入,报错ENOENT: no such file or directory(game.json)
    企业微信应用开发前准备
    jquery转盘抽奖游戏
    小程序路由跳转携带参数方法(直接跳转、事件委托跳转)
    小程序定义并使用模板template
    小程序真机预览,提示“音乐文件错误,播放失败”
    Java反编译
    DataX
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5244862.html
Copyright © 2020-2023  润新知