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;
	
	
	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);
	}

	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);
		}
		
		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);
		}
		//画¥
		mPaint.setTextSize(moneySize);
		canvas.drawText(money, moneyStart, getMeasuredHeight() - getPaddingBottom(), mPaint);
		//画整数部分
		mPaint.setTextSize(intSize);
		canvas.drawText(intPart, intStart, getMeasuredHeight() - getPaddingBottom(), mPaint);
		//画小数部分
		mPaint.setTextSize(decimalSize);
		canvas.drawText(decimalPart, decimalStart, getMeasuredHeight() - getPaddingBottom(), 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 void setText(String text){
		this.value = text;
		calcTextDimens();
	}
}

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>

工程源码下载:http://download.csdn.net/download/goldenfish1919/8512713


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。