您的位置:首页 > 其它

股票数量价格加减控件

2017-03-22 09:21 127 查看
做股票软件的都应该知道,交易买卖的页面都有用到一个控件就是数量和价格的加减,根据在项目开发中的经验,我把加减控件进行了封装。

自定义组合控件

一般的实现步骤如下:

一、创建要进行组合的布局trade_number_add_sub_view.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/total_view"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_gravity="center"
android:background="@drawable/trade_number_add_sub_default_background"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/sub"
android:layout_width="40dp"
android:layout_height="match_parent"
android:background="@color/view_background_red"
android:orientation="vertical">
<ImageView
android:layout_weight="1"
android:layout_gravity="center"
android:paddingTop="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/btn_subtract"/>
<com.eno.widget.AutofitTextView
android:layout_weight="1"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textColor="@color/text_color_white"
android:text="100"/>
</LinearLayout>

<EditText
android:id="@+id/edit"
android:layout_weight="1"
android:background="@android:color/transparent"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text="600000"/>

<LinearLayout
android:id="@+id/add"
android:layout_width="40dp"
android:layout_height="match_parent"
android:background="@color/view_background_red"
android:orientation="vertical">
<ImageView
android:layout_weight="1"
android:paddingTop="5dp"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/btn_add"/>
<com.eno.widget.AutofitTextView
android:layout_weight="1"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textColor="@color/text_color_white"
android:text="100"/>
</LinearLayout>

</LinearLayout>


上面的布局中,我这里是用图片来显示加减号,你也可以替换为TextView。但是这样涉及到的ImageView控件就要修改。

缺少的文件类AutofitTextView.java

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.TextView;

/**
* 作者:willkong on 2017/3/16.
* QQ号:547860818
* 作用:字体超出自动适配
*/

@SuppressLint("AppCompatCustomView")
public class AutofitTextView extends TextView {
//unit px
private static float DEFAULT_MIN_TEXT_SIZE = 8;
private static float DEFAULT_MAX_TEXT_SIZE = 100;
// Attributes
private TextPaint testPaint;
/**
* 最小字体
*/
private float minTextSize;
/**
* 最大字体
*/
private float maxTextSize;

public AutofitTextView(Context context, AttributeSet attrs) {
super(context, attrs);
initialise();
}

private void initialise() {
testPaint = new TextPaint();
testPaint.set(this.getPaint());
//字体大小限制
maxTextSize = this.getTextSize();
if (maxTextSize <= DEFAULT_MIN_TEXT_SIZE) {
maxTextSize = DEFAULT_MAX_TEXT_SIZE;
}
minTextSize = DEFAULT_MIN_TEXT_SIZE;
}

/**
* 适配字体的大小和控件宽度
*/
private void refitText(String text, int textWidth, int textHeight) {
if (textWidth > 0&&textHeight>0) {
//字体有效显示宽度和高度
int availableWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight();
int availableHeight = textHeight - this.getPaddingBottom() - this.getPaddingTop();
//设置字体有效显示宽度
int autoWidth = availableWidth;
float mult=1f;
float add=0;
if (Build.VERSION.SDK_INT>16)
{
mult=getLineSpacingMultiplier();
add=getLineSpacingExtra();
}else{
//the mult default is 1.0f,if you need change ,you can reflect invoke this field;
}
float trySize = maxTextSize;
testPaint.setTextSize(trySize);
int oldline=1,newline=1;
while ((trySize > minTextSize)) {
//计算字体单行宽度
int displayW = (int) testPaint.measureText(text);
//计算字体高度
int displaH=round(testPaint.getFontMetricsInt(null)*mult+add);
if (displayW < autoWidth) {
break;
}
//calculate maxLines
newline = availableHeight / displaH;
//if line change ,calculate new autoWidth
if (newline > oldline) {
oldline=newline;
autoWidth = availableWidth * newline;
continue;
}
//try more small TextSize
trySize -= 1;
if (trySize <= minTextSize) {
trySize = minTextSize;
break;
}

testPaint.setTextSize(trySize);
}
//setMultiLine
if (newline>=2)
{
this.setSingleLine(false);
this.setMaxLines(newline);
}
this.setTextSize(TypedValue.COMPLEX_UNIT_PX, trySize);
}
}

@Override
protected void onTextChanged(CharSequence text, int start, int before, int after) {
super.onTextChanged(text, start, before, after);
refitText(text.toString(), this.getWidth(), this.getHeight());
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if (w != oldw || h != oldh) {
refitText(this.getText().toString(), w, h);
}
}
//FastMath.round()
public static int round(float value) {
long lx = (long) (value * (65536 * 256f));
return (int) ((lx + 0x800000) >> 24);
}
}


二、分析需要自定义的属性,在values文件夹下创建一个属性类attr.xml,在该类中编写需要的属性

<!--自定义加减控件-->
<declare-styleable name="TradeNumberAddSubView">
<attr name="totalViewBackground" format="color|reference"></attr>
<attr name="buttonBackground" format="color|reference"></attr>
<attr name="subImg" format="reference"></attr>
<attr name="addImg" format="reference"></attr>
<attr name="numerical" format="integer|float"></attr>
<attr name="btnWidth" format="integer"></attr>
<attr name="totalViewHeight" format="integer"></attr>
</declare-styleable>


三、新建一个类TradeNumberAddSubView.java继承LinearLayout,编写组合式控件。

import android.content.Context;
import android.content.res.TypedArray;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.eno.R;

import java.math.BigDecimal;

/**
* 作者:willkong on 2017/3/16.
* QQ号:547860818
* 作用:自定义交易加减控件
*/

public class TradeNumberAddSubView extends LinearLayout implements View.OnClickListener {
private Context mContext;
private LinearLayout total_view;
private LinearLayout btn_sub;
private LinearLayout btn_add;
private ImageView img_sub;
private ImageView img_add;
private AutofitTextView tv_sub;
private AutofitTextView tv_add;
private EditText edit;
/**
* 控件背景
*/
private int totalViewBackground;
/**
* 按钮背景
*/
private int buttonBackground;
/**
* 减号图片
*/
private int subImg;
/**
* 加号图片
*/
private int addImg;
/**
* 加减按钮宽度
*/
private int btnWidth;
/**
* 控件高度
*/
private int totalViewHeight;
/**
* 计算数值
*/
private float numerical;
/**
* 加减后的结果值
*/
private float value;
/**
* 精度,保留小数位默认2位
*/
private int precision=2;

public TradeNumberAddSubView(Context context) {
this(context,null);
}

public TradeNumberAddSubView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}

public TradeNumberAddSubView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
LayoutInflater.from(context).inflate(R.layout.trade_number_add_sub_view,this);
findViews();
setSubAddOnClickListener();
initAttrs(attrs);
}

/**
* 设置加减按钮的监听事件
*/
private void setSubAddOnClickListener() {
btn_sub.setOnClickListener(this);
btn_add.setOnClickListener(this);
}

/**
* 初始化属性
* @param attrs
*/
private void initAttrs(AttributeSet attrs) {
TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.TradeNumberAddSubView);
totalViewBackground = a.getResourceId(R.styleable.TradeNumberAddSubView_totalViewBackground,R.drawable.trade_number_add_sub_default_background);
buttonBackground = a.getResourceId(R.styleable.TradeNumberAddSubView_buttonBackground,R.color.view_background_red);
subImg = a.getResourceId(R.styleable.TradeNumberAddSubView_subImg,R.mipmap.btn_subtract);
addImg = a.getResourceId(R.styleable.TradeNumberAddSubView_addImg,R.mipmap.btn_add);
numerical = a.getFloat(R.styleable.TradeNumberAddSubView_numerical,100);
totalViewHeight = a.getInt(R.styleable.TradeNumberAddSubView_totalViewHeight,40);
btnWidth = a.getInt(R.styleable.TradeNumberAddSubView_btnWidth,40);
a.recycle();
setTotalViewBackground(totalViewBackground);
setButtonBackground(buttonBackground);
setTotalViewHeight(totalViewHeight);
setBtnWidth(btnWidth);
setSubImg(subImg);
setAddImg(addImg);
setNumerical(numerical);
getValue();
}

/**
* 找到要用到的控件
*/
private void findViews() {
total_view = (LinearLayout) findViewById(R.id.total_view);
btn_sub = (LinearLayout) findViewById(R.id.sub);
img_sub = (ImageView) btn_sub.getChildAt(0);
tv_sub = (AutofitTextView) btn_sub.getChildAt(1);
btn_add = (LinearLayout) findViewById(R.id.add);
img_add = (ImageView) btn_add.getChildAt(0);
tv_add = (AutofitTextView) btn_add.getChildAt(1);
edit = (EditText) findViewById(R.id.edit);
edit.setSelection(edit.getText().length());
}

public int getTotalViewBackground() {
return totalViewBackground;
}

public void setTotalViewBackground(int totalViewBackground) {
this.totalViewBackground = totalViewBackground;
total_view.setBackgroundResource(totalViewBackground);
}

public int getButtonBackground() {
return buttonBackground;
}

public void setButtonBackground(int buttonBackground) {
this.buttonBackground = buttonBackground;
btn_sub.setBackgroundResource(buttonBackground);
btn_add.setBackgroundResource(buttonBackground);
}

public int getTotalViewHeight() {
return totalViewHeight;
}

public void setTotalViewHeight(int totalViewHeight) {
this.totalViewHeight = totalViewHeight;
LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dp2px(totalViewHeight));
total_view.setLayoutParams(layoutParams);
}

public int getBtnWidth() {
return btnWidth;
}

public void setBtnWidth(int btnWidth) {
this.btnWidth = btnWidth;
LayoutParams layoutParams = new LayoutParams(dp2px(btnWidth), ViewGroup.LayoutParams.MATCH_PARENT);
btn_sub.setLayoutParams(layoutParams);
btn_add.setLayoutParams(layoutParams);
}

public int getSubImg() {
return subImg;
}

public void setSubImg(int subImg) {
this.subImg = subImg;
img_sub.setImageResource(subImg);
}

public int getAddImg() {
return addImg;
}

public void setAddImg(int addImg) {
this.addImg = addImg;
img_add.setImageResource(addImg);
}

public float getNumerical() {
return numerical;
}

public void setNumerical(float numerical) {
this.numerical = numerical;
tv_add.setText(clearZero(numerical));
tv_sub.setText(clearZero(numerical));
}

public int getPrecision() {
return precision;
}

public void setPrecision(int precision) {
this.precision = precision;
}

public float getValue() {
if (!TextUtils.isEmpty(edit.getText().toString().trim())){
value = Float.valueOf(edit.getText().toString().trim());
}else {
value = 0;
}
return value;
}

public void setValue(float value) {
this.value = value;
//保留小数位数
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(precision,BigDecimal.ROUND_HALF_UP);
edit.setText(clearZero(bd.floatValue()));
}

@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.sub:
subNumber();
if (listener != null){
listener.onButtonSub(v,value);
}
break;
case R.id.add:
addNumber();
if (listener != null){
listener.onButtonAdd(v,value);
}
break;
}
}

/**
* 减法运算
*/
private void subNumber() {
getValue();
if (value>numerical){
value=BigDecimalSub(value,numerical);
}else {
value = 0;
}
setValue(value);
}

/**
* 加法运算
*/
private void addNumber() {
getValue();
value=BigDecimalAdd(value,numerical);
setValue(value);
}

/**
* 监听数字增加减少控件
*/
public interface OnNumberClickListener{
/**
* 当减少按钮被点击的时候回调
* @param view
* @param value
*/
void onButtonSub(View view,float value);
/**
* 当增加按钮被点击的时候回调
* @param view
* @param value
*/
void onButtonAdd(View view,float value);
}

public OnNumberClickListener listener;

/**
* 设置监听数字按钮
* @param listener
*/
public void setOnNumberClickListener(OnNumberClickListener listener){
this.listener = listener;
}

/**
* 正则表达式
* 去掉float后无用的0
*/
public String clearZero(float number){
String s = String.valueOf(number);
if(s.indexOf(".") > 0){
//正则表达
s = s.replaceAll("0+?$", "");//去掉后面无用的零
s = s.replaceAll("[.]$", "");//如小数点后面全是零则去掉小数点
}
/**
*还原科学计数法
*/
if (s.indexOf("E")!=-1){
String sarr[] = s.split("E");
double res1 = Double.valueOf(sarr[0]);
int ci = Integer.valueOf(sarr[1]);
double cinum = 10;
if (ci>0){
for(int i=0;i<ci;i++){
cinum = cinum*10;
}
double res = res1*cinum;

String result = String.valueOf(res);

return result;
}else {
ci = Math.abs(ci);
StringBuffer sb = new StringBuffer();
sb.append("0.");
for(int i=1;i<ci;i++){
sb.append("0");
}
//去除1.0后面的.0
String d = String.valueOf(res1);
if(d.indexOf(".") > 0){
//正则表达
d = d.replaceAll("0+?$", "");//去掉后面无用的零
d = d.replaceAll("[.]$", "");//如小数点后面全是零则去掉小数点
}
sb.append(d);
return sb.toString();
}
}
return s;
}

/**
* 使用BigDecimal类进行操作,防止精度丢失
* 注意:new BigDecimal(...)填写构造函数的时候,一定要使用String,而不要使用float或者double,否则同样会引起精度丢失。
* @param num1
* @param num2
* @return
*/
public float BigDecimalSub(float num1,float num2){
BigDecimal x1 = new BigDecimal(Float.toString(num1));
BigDecimal x2 = new BigDecimal(Float.toString(num2));
return x1.subtract(x2).floatValue();
}
/**
* 使用BigDecimal类进行操作,防止精度丢失
* 注意:new BigDecimal(...)填写构造函数的时候,一定要使用String,而不要使用float或者double,否则同样会引起精度丢失。
* @param num1
* @param num2
* @return
*/
public float BigDecimalAdd(float num1,float num2){
BigDecimal x1 = new BigDecimal(Float.toString(num1));
BigDecimal x2 = new BigDecimal(Float.toString(num2));
return x1.add(x2).floatValue();
}

protected int dp2px(float dp) {
final float scale = mContext.getResources().getDisplayMetrics().density;
return (int) (dp * scale + 0.5f);
}

protected int sp2px(float sp) {
final float scale = this.mContext.getResources().getDisplayMetrics().scaledDensity;
return (int) (sp * scale + 0.5f);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: