2013年9月7日 星期六

平分多少錢



生活中免不了要與朋友聚餐,那結帳時該怎麼平分呢? 這款應用程式除了可以計算每個人平均要付多少錢, 還提供了計算該找多少錢的功能,延伸傳統計算機不能一次多工計算的缺失。 
 -------------------------------------------------詳細說明如下--------------------------------------------
功能描述:
1.具備金額平分計算 
2.處理多筆找錢功能 
3.提供自由配置背景設定 
4.加入語音辨識功能,減少輸入負擔

apk檔案下載


(一)輸入總金額以及平分人數
(二)說明
(三)設定畫面


(四)Menu選單
(五)技術重點一{實作TextWatcher完成editText文字改變事件監聽}



package com.example.sharecost;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
public class CustomTextWatcher implements TextWatcher{ 
 private EditText etShould;
 private EditText etPay;
 private EditText etGet;
 public CustomTextWatcher(EditText etShould,EditText etPay,EditText etGet){  
  this.etShould = etShould;
  this.etPay = etPay;
  this.etGet = etGet;
 }
 @Override
 public void afterTextChanged(Editable s) {//文字改變後  
  int iPay = getInteger(etPay.getText().toString());//付了多少錢
  if (iPay == Integer.MAX_VALUE) return;
  int iShould = getInteger(etShould.getText().toString());//應該付多少
  if (iShould == Integer.MAX_VALUE) return;
  int iGet = iPay-iShould;//餘額  
  etGet.setText(String.valueOf(iGet));
 }

 @Override
 public void beforeTextChanged(CharSequence s, int start, int count,
   int after) {  
 }

 @Override
 public void onTextChanged(CharSequence s, int start, int before, int count) {
  
  
 }
 private int getInteger(String s){
  int n = Integer.MAX_VALUE;
  try {n = Integer.valueOf(s);}
  catch (Exception e) {n = Integer.MAX_VALUE;}     
  return n;
 }
}
(六)技術重點二-主畫面{漸層背景}
private EditText etTotalMoney,etTotalPeople;//總金額,總人數
private boolean bStatus = false;//是否支持語音辨識判斷用 
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        setButtonEvent();//設定語音按鈕事件
        Random rnd = new Random();         
        int color = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));//隨機背景
        setBackGround(new int[]{Color.WHITE,color});//設定漸層
        etTotalMoney = (EditText)findViewById(R.id.etTotalMoney);     
        etTotalPeople = (EditText)findViewById(R.id.etTotalPeople);      
        etTotalMoney.setOnFocusChangeListener(this);
        etTotalPeople.setOnFocusChangeListener(this);
}   
private void setBackGround(int colorList[]){漸層設定
     GradientDrawable grDr =new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, colorList);
        RelativeLayout rl = (RelativeLayout)findViewById(R.id.layout);
        rl.setBackgroundDrawable(grDr);
}   
private void setButtonEvent(){
     btnVoiceStatus = (ToggleButton)findViewById(R.id.btnVoiceStatus);
     btnVoiceStatus.setOnClickListener(new Button.OnClickListener(){ 
             @Override
             public void onClick(View v) {                                 
                 bStatus = (bStatus)?!bStatus:getStatus();
                 btnVoiceStatus.setChecked(bStatus);
             }         
         });     
}
 private boolean getStatus(){
     ConnectivityManager conManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);//先取得此service
     PackageManager pm =getPackageManager();//取得套件
     List list = pm.queryIntentActivities(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);//語音辨識相關套件
     NetworkInfo networInfo = conManager.getActiveNetworkInfo();       //在取得相關資訊
     if (networInfo == null || !networInfo.isAvailable()){ //判斷是否有網路
      showAlertDialog("警告", "請檢查網路狀態\n是否開啟");
      return false;
     }else if (list.size() <= 0){
      showAlertDialog("警告", "您的裝置不支援語音辨識");
      return false;
     }
     return true;
 }
(七)技術重點三{動態產生元件}
public void setContent(View view){    
     EditText etTotalMoney = (EditText)findViewById(R.id.etTotalMoney);     
        EditText etTotalPeople = (EditText)findViewById(R.id.etTotalPeople);      
        etTotalMoney.setOnFocusChangeListener(this);
        etTotalPeople.setOnFocusChangeListener(this);
        int iNum = getInteger(etTotalPeople.getText().toString());
        if (iNum == Integer.MIN_VALUE) iNum = 1; 
        int iSum = getInteger(etTotalMoney.getText().toString());
        if (iSum == Integer.MIN_VALUE) iSum = 0; 
        int iGiveMoney = (iNum > iSum)?0:(int)(Math.ceil(iSum/(double)iNum));
     etShould = new EditText[iNum];
     etPay = new EditText[iNum];
     etGet = new EditText[iNum];
     TableLayout layout = (TableLayout)findViewById(R.id.table);
     layout.removeAllViews();
     int avgWidth = layout.getWidth()/3 - 5;
     Log.e("test", String.valueOf(avgWidth));
     for (int i = 0; i < iNum;i++){     
   etPay[i] = new EditText(this);
   etPay[i].setWidth(avgWidth);
   etPay[i].setId(i); 
   etPay[i].setInputType(InputType.TYPE_CLASS_NUMBER);
   etPay[i].setOnFocusChangeListener(this);   
   etShould[i] = new EditText(this);
   etShould[i].setWidth(avgWidth);
   etShould[i].setInputType(InputType.TYPE_CLASS_NUMBER);
   etShould[i].setText(String.valueOf(iGiveMoney));
   etShould[i].setId(i + iNum);//設定應付ID
   etShould[i].setOnFocusChangeListener(this);
   etGet[i] = new EditText(this);
   etGet[i].setWidth(avgWidth);
   etGet[i].setEnabled(false);
   etPay[i].addTextChangedListener(new CustomTextWatcher(etShould[i], etPay[i], etGet[i]));
   etShould[i].addTextChangedListener(new CustomTextWatcher(etShould[i], etPay[i], etGet[i]));
   tvMinus = new TextView(this);
   tvMinus.setText("─");   
   tvEqual = new TextView(this);
   tvEqual.setText("=");   
   TableRow tr = new TableRow(this);
   tr.addView(etPay[i]);
   tr.addView(tvMinus);
   tr.addView(etShould[i]);
   tr.addView(tvEqual);
   tr.addView(etGet[i]);
   layout.addView(tr);  
  }
} 
(八)技術重點四{Menu選單事件}
@Override
 public boolean onCreateOptionsMenu(Menu menu) {
  menu.addSubMenu(0, 0, 0, "設定");
  menu.addSubMenu(0, 1, 1, "說明"); 
  menu.addSubMenu(0,2,2,"製作團隊");
  menu.addSubMenu(0,3,3,"離開");
  return super.onCreateOptionsMenu(menu);
 }
 @Override
 public boolean onOptionsItemSelected(MenuItem item) {
  switch (item.getItemId()) {//設定顏色
  case 0:
    DisplayMetrics dm = new DisplayMetrics();
       this.getWindowManager().getDefaultDisplay().getMetrics(dm);          
       int vWidth = dm.widthPixels;
       int vHeight = dm.heightPixels;
   ColorPickerDialog cpd=new ColorPickerDialog(this, listener, 0,vWidth,vHeight);     
         cpd.show();          
   break;
  case 1:  
   String msg =  (String) this.getResources().getText(R.string.Explain);
   showAlertDialog("說明", msg);
     
   break;   
  case 2:   
   showAlertDialog("關於", this.getResources().getText(R.string.About).toString());// 關於
   break;
  case 3:
   finish();
  }
  return super.onOptionsItemSelected(item);
 }
 private void showAlertDialog(final String title, String msg) {
  AlertDialog.Builder dialog = new AlertDialog.Builder(this);
  dialog.setTitle(title);// 標題
  dialog.setMessage(msg);// 訊息 
  dialog.setPositiveButton("確定", null);
  dialog.show();// 顯示視窗
}
(九)技術重點五{語音辨識事件}
@Override
 public void onFocusChange(View v, boolean hasFocus) {
     if (!bStatus) return;
     if (v.getId() == R.id.etTotalMoney || v.getId() == R.id.etTotalPeople){
      etTmp = (EditText)v;
     }else etTmp = etPay[v.getId() % etPay.length];  
  Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
  intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
  intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "請說數字");
  MainActivity.this.startActivityForResult(intent, 16888);
 }
 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (requestCode == 16888 && resultCode == this.RESULT_OK){
   final ArrayList list = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
   AlertDialog.Builder builder = new AlertDialog.Builder(this);
   builder.setTitle("可能的結果");
   builder.setSingleChoiceItems(list.toArray(new String[0]), -1, new DialogInterface.OnClickListener() {
       public void onClick(DialogInterface dialog, int item) {
           int num = getInteger(list.get(item).toString().replaceAll("\\s+", ""));
        if (num != Integer.MIN_VALUE)etTmp.setText(String.valueOf(num));
        dialog.cancel();
       }
   });
   AlertDialog alert = builder.create();
   alert.show();
  }
  
  super.onActivityResult(requestCode, resultCode, data);
} 
(十)技術重點六{顏色選擇器,ColorPickerDialog}
package com.example.sharecost;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
public class ColorPickerDialog extends Dialog {  
    private int width,height;
    public interface OnColorChangedListener {  
      void colorChanged(int color);  
    }  
    private OnColorChangedListener mListener;  
    private int mInitialColor;      
    private static class ColorPickerView extends View {  
      private Paint mPaint;  
      private Paint mCenterPaint;  
      private final int[] mColors;  
      private OnColorChangedListener mListener;        
      private int CENTER_X;  
      private int CENTER_Y;  
      private int CENTER_RADIUS;  
      public ColorPickerView(Context c, OnColorChangedListener l, int color,int width,int height) {  
        super(c);
        //BitHand = BitmapFactory.decodeResource(this.getResources(),R.drawable.hand);
        mListener = l;         
        mColors = new int[] {  
          0xFFFF0000, 0xFFFF00FF, 0xFF0000FF, 0xFF00FFFF, 0xFF00FF00,  
          0xFFFFFF00, 0xFFFF0000  
        };  
        CENTER_X = height/2;
        CENTER_Y = height/2;
        CENTER_RADIUS = height/6;
        Shader s = new SweepGradient(0, 0, mColors, null);  
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
        mPaint.setShader(s);  
        mPaint.setStyle(Paint.Style.STROKE);  
        mPaint.setStrokeWidth(CENTER_RADIUS);  
        mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
        mCenterPaint.setColor(color);  
        mCenterPaint.setStrokeWidth(5);  
      }  
      private boolean mTrackingCenter;         
      @Override  
      protected void onDraw(Canvas canvas) {  
        float r = CENTER_X - mPaint.getStrokeWidth()*0.5f;  
        canvas.translate(CENTER_X, CENTER_X);  
        canvas.drawOval(new RectF(-r, -r, r, r), mPaint);  
        canvas.drawCircle(0, 0, CENTER_RADIUS, mCenterPaint);
        int c = mCenterPaint.getColor();  
        mCenterPaint.setStyle(Paint.Style.STROKE);
        mCenterPaint.setAlpha((mTrackingCenter)?0x80:0xFF);         
        canvas.drawCircle(0, 0,  
                   CENTER_RADIUS + mCenterPaint.getStrokeWidth(),  
                   mCenterPaint);  
        //canvas.drawBitmap(BitHand, -BitHand.getWidth()/2, -BitHand.getHeight()/2, mCenterPaint);        
        mCenterPaint.setStyle(Paint.Style.FILL);  
        mCenterPaint.setColor(c);  
      }  
      @Override  
      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
        setMeasuredDimension(CENTER_X*2, CENTER_Y*2);  
      }        
      private int floatToByte(float x) {  
        int n = java.lang.Math.round(x);  
        return n;  
      }  
      private int pinToByte(int n) {  
        if (n < 0) {  
          n = 0;  
        } else if (n > 255) {  
          n = 255;  
        }  
        return n;  
      }  
      private int ave(int s, int d, float p) {  
        return s + java.lang.Math.round(p * (d - s));  
      }  
      private int interpColor(int colors[], float unit) {  
        if (unit <= 0) {  
          return colors[0];  
        }  
        if (unit >= 1) {  
          return colors[colors.length - 1];  
        }  
        float p = unit * (colors.length - 1);  
        int i = (int)p;  
        p -= i;           
        int c0 = colors[i];  
        int c1 = colors[i+1];  
        int a = ave(Color.alpha(c0), Color.alpha(c1), p);  
        int r = ave(Color.red(c0), Color.red(c1), p);  
        int g = ave(Color.green(c0), Color.green(c1), p);  
        int b = ave(Color.blue(c0), Color.blue(c1), p);  
        return Color.argb(a, r, g, b);  
      }  
      private int rotateColor(int color, float rad) {  
        float deg = rad * 180 / 3.1415927f;  
        int r = Color.red(color);  
        int g = Color.green(color);  
        int b = Color.blue(color);  
        ColorMatrix cm = new ColorMatrix();  
        ColorMatrix tmp = new ColorMatrix();  
        cm.setRGB2YUV();  
        tmp.setRotate(0, deg);  
        cm.postConcat(tmp);  
        tmp.setYUV2RGB();  
        cm.postConcat(tmp);  
        final float[] a = cm.getArray();  
        int ir = floatToByte(a[0] * r + a[1] * g + a[2] * b);  
        int ig = floatToByte(a[5] * r + a[6] * g + a[7] * b);  
        int ib = floatToByte(a[10] * r + a[11] * g + a[12] * b);  
        return Color.argb(Color.alpha(color), pinToByte(ir),  
                 pinToByte(ig), pinToByte(ib));  
      }  
      private static final float PI = 3.1415926f;  
      @Override  
      public boolean onTouchEvent(MotionEvent event) {  
        float x = event.getX() - CENTER_X;  
        float y = event.getY() - CENTER_Y;  
        boolean inCenter = java.lang.Math.sqrt(x*x + y*y) <= CENTER_RADIUS;  
        switch (event.getAction()) {  
          case MotionEvent.ACTION_DOWN:  
            mTrackingCenter = inCenter;  
            if (inCenter) {            
              invalidate();  
              break;  
            }  
          case MotionEvent.ACTION_MOVE:                              
            if (!mTrackingCenter) { 
              float angle = (float)java.lang.Math.atan2(y, x);                
              float unit = angle/(2*PI);  
              if (unit < 0)  unit += 1;                                   
              mCenterPaint.setColor(interpColor(mColors, unit));  
              invalidate();  
            }  
            break;  
          case MotionEvent.ACTION_UP:  
            if (mTrackingCenter) {                
              mListener.colorChanged(mCenterPaint.getColor());                               
              invalidate();  
            }  
            break;  
        }  
        return true;  
      }  
    }  
    public ColorPickerDialog(Context context,  
                 OnColorChangedListener listener,  
                 int initialColor,int width,int height) {  
      super(context);  
      mListener = listener;  
      mInitialColor = initialColor; 
      this.width = width;
      this.height = height;
    }  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
      super.onCreate(savedInstanceState);       
      OnColorChangedListener l = new OnColorChangedListener() {  
        public void colorChanged(int color) {  
          mListener.colorChanged(color);  
          dismiss();  
        }  
      };  
      setContentView(new ColorPickerView(getContext(), l, mInitialColor,this.width/2,this.height/2));  
      setTitle("設定背景顏色");  
    }      
}  
//-------------------主畫面監聽事件-----------------
OnColorChangedListener listener=new OnColorChangedListener() {  
        @Override  
        public void colorChanged(int color) {  
         setBackGround(new int[]{Color.WHITE,color});         
        }  
};  

沒有留言:

張貼留言