視頻效果預(yù)覽
添加賬目記錄
效果預(yù)覽


添加賬目記錄實(shí)現(xiàn)
簡述
日期選擇采用CalendarView
控件,時(shí)間選擇采用TimePicker
控件,然后通過switch
控件控制其VISIBLE
和GONE
屬性,類型通過PopUpWindows彈窗顯示,標(biāo)簽通過SharedPreferences
進(jìn)行傳遞。最后插入SQLite數(shù)據(jù)庫中。
實(shí)現(xiàn)
獲取日期
因?yàn)楂@取的日歷控件的月份要比實(shí)際少一個(gè)月,故因此需要把月份加上一。
然后將獲取的年月日字符串?dāng)?shù)據(jù)轉(zhuǎn)為Date格式,最后將Date格式轉(zhuǎn)為當(dāng)時(shí)的星期
字符串時(shí)間戳轉(zhuǎn)Date
public static Date getStringToDate(String str){
mSimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
try {
Date date = mSimpleDateFormat.parse(str);
return date;
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
Date轉(zhuǎn)星期
public static String getWeekOfDate(Date date) {
String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
if (w < 0)
w = 0;
return weekDays[w];
}
最后將獲取的日期、星期進(jìn)行保存
/**
* 顯示選擇的年月日,并將選擇的年月日轉(zhuǎn)為星期
*/
private void getDate() {
mCalendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
@Override
public void onSelectedDayChange(@NonNull CalendarView view, int year, int month, int dayOfMonth) {
month = month + 1;
CNDate = year + "年" + month + "月" + dayOfMonth + "日";
String date = year + "-" + month + "-" + dayOfMonth;
Log.d(TAG, "date=" + date);
Log.d(TAG, "CNdate=" + CNDate);
//string日期轉(zhuǎn)date日期,在轉(zhuǎn)為星期
String week = DateUtils.getWeekOfDate(DateUtils.getStringToDate(date));
Log.d(TAG, "week=" + week);
SelectDate.setText(CNDate + " " + week);
}
});
}
獲取時(shí)間
直接對TimePicker
控件進(jìn)行事件監(jiān)聽,然后將獲取的時(shí)間進(jìn)行保存即可
private void getTime() {
mTimePicker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
String time = hourOfDay + ":" + minute;
SelectTime.setText(time);
Log.d(TAG, time);
}
});
}
Switch控制顯示和隱藏
更改Switch樣式
建立thumb.xml和track.xml兩個(gè)選擇器
thumb.xml如下
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="@drawable/open_thumb"/>
<item android:drawable="@drawable/shut_thumb"/>
</selector>
track.xml如下
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="@drawable/open_track"/>
<item android:drawable="@drawable/shut_track"/>
</selector>
然后分別建立兩個(gè)選擇器的不同狀態(tài)下的效果文件
open_thumb.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<!-- 高度40 -->
<size android:height="30dp" android:width="30dp"/>
<!-- 圓角弧度 20 -->
<corners android:radius="15dp"/>
<!-- 變化率 -->
<gradient
android:endColor="#eeeeee"
android:startColor="#eeeeee" />
<!--<stroke android:width="1dp"-->
<!-- android:color="#2196F3"/>-->
</shape>
shut_thumb.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<size android:height="30dp" android:width="30dp"/>
<!-- 圓角弧度 20 -->
<corners android:radius="15dp"/>
<!-- 變化率 -->
<gradient
android:endColor="#eeeeee"
android:startColor="#eeeeee" />
<stroke android:width="1dp"
android:color="#A8A7A7"/>
</shape>
open_track.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- 高度30 此處設(shè)置寬度無效-->
<size android:height="30dp"/>
<!-- 圓角弧度 15 -->
<corners android:radius="15dp"/>
<!-- 變化率 定義從左到右的顏色不變 -->
<solid android:color="#07ED7D"/>
</shape>
shut_track.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size android:height="30dp" android:width="30dp"/>
<corners android:radius="15dp"/>
<gradient android:startColor="#eeeeee"
android:endColor="#eeeeee"/>
<stroke android:width="1dp"
android:color="#A8A7A7"/>
</shape>
最后應(yīng)用于switch效果如下
<Switch
android:id="@+id/DateSwitch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:thumb="@drawable/thumb"
android:track="@drawable/track" />
事件監(jiān)聽
通過監(jiān)聽Switch事件,判斷false和true兩種狀態(tài),分別對應(yīng)控件的隱藏和顯示
class SwitchListener implements CompoundButton.OnCheckedChangeListener {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
switch (buttonView.getId()) {
case R.id.DateSwitch:
if (isChecked)
DateLayout.setVisibility(View.VISIBLE);
else
DateLayout.setVisibility(View.GONE);
break;
case R.id.TimeSwitch:
if (isChecked)
TimeLayout.setVisibility(View.VISIBLE);
else
TimeLayout.setVisibility(View.GONE);
break;
}
}
}
保存至SQLite數(shù)據(jù)庫
/**
* 賬單記錄保存到SQLite中
*/
public void SaveMessage(View view) {
String date = SelectDate.getText().toString().trim();
String time = SelectTime.getText().toString().trim();
String type = TypeText.getText().toString();
String label = TextLabel.getText().toString();
String name = GoodsName.getText().toString();
String price = GoodsPrice.getText().toString().trim();
if (TextUtils.isEmpty(type) || type.equals("支出or收入")){
toastUtils.ShowFail("類型錯(cuò)誤!");
return;
}
if (TextUtils.isEmpty(label) || label.equals("暫未選擇")){
toastUtils.ShowFail("標(biāo)簽錯(cuò)誤!");
return;
}
if (TextUtils.isEmpty(name) || TextUtils.isEmpty(price)){
toastUtils.ShowFail("商品信息或者商品價(jià)格格式!");
return;
}
int t = type.equals("支出") ? 1 : 0;
Record record = new Record(date,time,t,label,name,price);
int flag = dao.Insert(record);
if (flag == 1){
toastUtils.ShowSuccess("保存成功!");
}else {
toastUtils.ShowFail("保存失敗!");
}
}
標(biāo)簽選擇實(shí)現(xiàn)
效果預(yù)覽


實(shí)現(xiàn)
狀態(tài)改變
每一個(gè)標(biāo)簽有兩種狀態(tài),選擇和不被選擇狀態(tài),分別對應(yīng)兩種樣式效果,一種呈灰色,另一種呈高亮,在進(jìn)行選擇時(shí)可以同時(shí)點(diǎn)亮多個(gè)標(biāo)簽,但最后進(jìn)行保存時(shí),只能選擇一個(gè)標(biāo)簽,若條件不滿足,系統(tǒng)給予錯(cuò)誤提示。
事件監(jiān)聽
class TypeListener implements View.OnClickListener{
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.type_1:
setTag(type_1,getTag(type_1));
setBG(type_1,1);
break;
case R.id.type_2:
setTag(type_2,getTag(type_2));
setBG(type_2,2);
break;
case R.id.type_3:
setTag(type_3,getTag(type_3));
setBG(type_3,3);
break;
case R.id.type_4:
setTag(type_4,getTag(type_4));
setBG(type_4,4);
break;
case R.id.type_5:
setTag(type_5,getTag(type_5));
setBG(type_5,5);
break;
case R.id.type_6:
setTag(type_6,getTag(type_6));
setBG(type_6,6);
break;
case R.id.type_7:
setTag(type_7,getTag(type_7));
setBG(type_7,7);
break;
case R.id.type_8:
setTag(type_8,getTag(type_8));
setBG(type_8,8);
break;
}
}
}
狀態(tài)監(jiān)聽
每一個(gè)標(biāo)簽被點(diǎn)擊,其tag自增一次,若未被點(diǎn)擊,初始值為1
private void setTag(LinearLayout layout,int tag){
tag++;
layout.setTag(tag);
}
private int getTag(LinearLayout layout){
Object tag = layout.getTag();
if (tag == null)return 1;
return (int) tag;
}
然后通過tag值改變標(biāo)簽的樣式,成偶數(shù)則高亮,奇數(shù)則灰色,并記錄當(dāng)前狀態(tài)值,同時(shí)保存被選擇的標(biāo)簽數(shù)量。
private void setBG(LinearLayout layout,int index){
int tag = (int)layout.getTag();
if (tag % 2 == 0) {
layout.setBackground(getResources().getDrawable(R.drawable.blue_radius_bg));
TotalNum++;
b_select[index-1] = true;
}
else {
layout.setBackground(getResources().getDrawable(R.drawable.grey_radius_bg));
TotalNum--;
b_select[index-1] = false;
}
}
然后通過監(jiān)聽保存按鈕點(diǎn)擊事件,取出狀態(tài)值為true的標(biāo)簽值進(jìn)行返回
private String selectTag(){
for (int i = 0; i < 8; i++) {
if ( b_select[i]){
return s_select[i];
}
}
return null;
}
同時(shí)監(jiān)聽被選擇的標(biāo)簽總數(shù),若小于1,則未選擇任何標(biāo)簽,給予提升;若大于1,則選擇多個(gè)標(biāo)簽,同樣給予提升。最后通過SharedPreferences
進(jìn)行數(shù)據(jù)傳回;使用Intent傳輸應(yīng)該會更安全,一開始設(shè)計(jì)使用EventBus,但最后不了了。
public void SaveMessage(View view){
if (TotalNum > 1){
toastUtils.ShowFail("選擇標(biāo)簽數(shù)量不能超過一");
}else if (TotalNum <= 0){
toastUtils.ShowFail("選擇標(biāo)簽數(shù)量不能少于一");
}else {
toastUtils.ShowSuccess("success");
String tag = selectTag();
Log.d(TAG,"TAG="+tag);
SP sp = SP.getInstance();
sp.PutData(LabelActivity.this,"Label",tag);
//EventBus.getDefault().post(new TextClass(tag));
KillProcess.POP(LabelActivity.this);
}
}
導(dǎo)航界面
采用底部導(dǎo)航控件BottomNavigationView
切換賬單記錄界面和賬單概覽界面,并通過ViewPager
進(jìn)行頁面滑動(dòng),兩個(gè)子頁面采用兩個(gè)不同的Fragment
。
創(chuàng)建menu
次menu即為底部導(dǎo)航的文字和圖片效果,可以使用選擇器,監(jiān)聽選擇和不被選擇兩種狀態(tài),改變其效果。若不設(shè)置,系統(tǒng)模式使用樣式顏色作為高亮顯示?;疑什槐贿x擇狀態(tài)。
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/menu_navigation_record"
android:icon="@drawable/ic_home_black_24dp"
android:title="@string/title_record" />
<item
android:id="@+id/menu_navigation_general"
android:icon="@drawable/ic_dashboard_black_24dp"
android:title="@string/title_general" />
</menu>
創(chuàng)建Fragment
由于本APP只需要兩個(gè)節(jié)目,故只需要?jiǎng)?chuàng)建兩個(gè)fragment,然后在與nav進(jìn)行綁定即可,此處僅作為標(biāo)記,詳細(xì)介紹如下文所示
綁定Fragment
/**
* Set a listener that will be notified when a bottom navigation item is selected. This listener
* will also be notified when the currently selected item is reselected, unless an {@link
* OnNavigationItemReselectedListener} has also been set.
*
* @param listener The listener to notify
* @see #setOnNavigationItemReselectedListener(OnNavigationItemReselectedListener)
*/
設(shè)置底部導(dǎo)航欄當(dāng)前頁面顯示
navView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_navigation_record:
mViewPager.setCurrentItem(0);
return true;
case R.id.menu_navigation_general:
mViewPager.setCurrentItem(1);
return true;
}
return false;
}
});
將ViewPager和兩個(gè)fragment進(jìn)行綁定
private void setupViewPager(ViewPager viewPager) {
BottomAdapter adapter = new BottomAdapter(getSupportFragmentManager());
adapter.addFragment(new RecordFragment());
adapter.addFragment(new GeneralFragment());
viewPager.setAdapter(adapter);
}
并通過監(jiān)聽ViewPager事件,進(jìn)行頁面切換
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
navView.getMenu().getItem(position).setChecked(true);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
賬單記錄顯示
效果預(yù)覽


簡述
此界面就比較簡單,從數(shù)據(jù)庫中拿出所有數(shù)據(jù)并構(gòu)建一個(gè)集合類對象,然后放入RecyclerView中進(jìn)行顯示,最后根據(jù)類型計(jì)算總支出和總收入金額
RecyclerView顯示
建立適配器
public class OrderAdapter extends RecyclerView.Adapter<OrderAdapter.ViewHolder> {
private String[] s_select = {"日用百貨","文化休閑","交通出行","生活服務(wù)","服裝裝扮","餐飲美食","數(shù)碼電器","其他標(biāo)簽"};
private int[] img_select = {
R.drawable.icon_type_one,
R.drawable.icon_type_two,
R.drawable.icon_type_three,
R.drawable.icon_type_four,
R.drawable.icon_type_five,
R.drawable.icon_type_six,
R.drawable.icon_type_seven,
R.drawable.icon_type_eight};
private List<Record> recordList;
public OrderAdapter(List<Record> recordList){
this.recordList = recordList;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.order_item,parent,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Record record = recordList.get(position);
holder.item_date.setText(record.getDate());
holder.item_time.setText("時(shí)間 "+record.getTime());
holder.item_label.setText("["+record.getLabel()+"]");
holder.item_name.setText(record.getGoodsName());
if (record.getType() == 1){
holder.item_price.setText("-"+record.getGoodsPrice());
}else {
holder.item_price.setText("+"+record.getGoodsPrice());
}
for (int i = 0; i < 8; i++) {
if (record.getLabel().equals(s_select[i])){
holder.item_img.setImageResource(img_select[i]);
}
}
}
@Override
public int getItemCount() {
return recordList.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
private TextView item_date,item_time,item_label,item_name,item_price;
private ImageView item_img;
public ViewHolder(@NonNull View itemView) {
super(itemView);
item_date = itemView.findViewById(R.id.item_date);
item_time = itemView.findViewById(R.id.item_time);
item_label = itemView.findViewById(R.id.item_label);
item_name = itemView.findViewById(R.id.item_name);
item_price = itemView.findViewById(R.id.item_price);
item_img = itemView.findViewById(R.id.item_img);
}
}
}
獲取數(shù)據(jù)源
從數(shù)據(jù)庫中獲取實(shí)體類集合對象,然后根據(jù)其收入和支出兩種狀態(tài)計(jì)算相對應(yīng)的總金額
/**
* 獲取RecyclerView數(shù)據(jù)源*/
private void getData(){
recordList = dao.QueryAll();
if (recordList.size() == 0 || recordList == null){
IsEmpty(true);
return;
}
for (int i = 0; i < recordList.size(); i++) {
/**
* 1為支出
* 0為收入*/
if (recordList.get(i).getType() == 1){
totalPay += Double.parseDouble(recordList.get(i).getGoodsPrice());
}else {
totalIncome += Double.parseDouble(recordList.get(i).getGoodsPrice());
}
}
IsEmpty(TotalPay,totalPay,1);
IsEmpty(TotalIncome,totalIncome,0);
}
保留兩位小數(shù)
由于在轉(zhuǎn)換格式的之后,進(jìn)行加減運(yùn)算精度會失衡,會產(chǎn)生很多位小數(shù)點(diǎn),但由于美觀以及界面設(shè)計(jì),一般設(shè)計(jì)保留2位小數(shù)即可
以12.345678為例:
12.345678*100 = 1234.5678
然后將其轉(zhuǎn)為整數(shù),則變?yōu)?1234
最后除以100.0,此處標(biāo)簽,是100.0不是100,因?yàn)榍懊嬉呀?jīng)為整型數(shù)據(jù),整型除整型依舊為整型,只有除100.0,int數(shù)據(jù)類型才會強(qiáng)制轉(zhuǎn)換為float或者double類型
private double SaveDecimal(double n){
return n = ((int)(n*100))/100.0;
}
概覽
效果預(yù)覽

簡述
此界面顯示的內(nèi)容包括共計(jì)收入、支出多少筆和合計(jì)收入、支出多少金額,以及通過標(biāo)簽分類顯示支出、收入占比,以及全部收入、支出記錄中前三甲。
分類顯示
通過獲取單個(gè)標(biāo)簽的所有金額除以全部標(biāo)簽的總金額,獲取百分比占比,并通過view進(jìn)行顯示,條形bar通過獲取屏幕寬度,例如:我的手機(jī)屏幕寬度為1080,就以數(shù)碼電器為例:11998.99/總金額 * 1080 = 條形bar的長度
百分比占比同樣以數(shù)碼電器為例:11998.99/總金額 * 100 = 數(shù)碼電器百分比
創(chuàng)建適配器
public class BarAdapter extends RecyclerView.Adapter<BarAdapter.ViewHolder> {
private String[] s_select = {"日用百貨", "文化休閑", "交通出行", "生活服務(wù)", "服裝裝扮", "餐飲美食", "數(shù)碼電器", "其他標(biāo)簽"};
private int[] img_select = {
R.drawable.icon_type_one,
R.drawable.icon_type_two,
R.drawable.icon_type_three,
R.drawable.icon_type_four,
R.drawable.icon_type_five,
R.drawable.icon_type_six,
R.drawable.icon_type_seven,
R.drawable.icon_type_eight};
private List<ViewBar> viewBarList;
public BarAdapter(List<ViewBar> viewBarList) {
this.viewBarList = viewBarList;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.pay_type_item, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
holder.item_bar.measure(w, h);
ViewBar viewBar = viewBarList.get(position);
holder.item_bar.setLayoutParams(new LinearLayout.LayoutParams(viewBar.getWidth(), viewBar.getHeight()));
holder.item_label.setText(viewBar.getLabel());
holder.item_num.setText(viewBar.getNum());
holder.item_price.setText(viewBar.getPrice());
Log.d("testLabel",viewBar.getLabel());
for (int i = 0; i < 8; i++) {
if (viewBar.getLabel().trim().equals(s_select[i])){
Log.d("testLabel",viewBar.getLabel());
holder.item_img.setImageResource(img_select[i]);
}
}
}
@Override
public int getItemCount() {
return viewBarList.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
private TextView item_label, item_num, item_price;
private ImageView item_img;
private View item_bar;
public ViewHolder(@NonNull View itemView) {
super(itemView);
item_label = itemView.findViewById(R.id.pay_type_label);
item_num = itemView.findViewById(R.id.pay_type_num);
item_price = itemView.findViewById(R.id.pay_type_price);
item_img = itemView.findViewById(R.id.pay_type_img);
item_bar = itemView.findViewById(R.id.pay_type_bar);
}
}
}
獲取數(shù)據(jù)源
獲取屏幕寬度,以此作為基數(shù)
manager = requireActivity().getWindowManager();
width = manager.getDefaultDisplay().getWidth();
private void getData(){
if (TotalPrice <= 0)return;
for (int i = 0; i < d_price.length; i++) {
if (d_price[i] == 0)continue;
int n = (int) (d_price[i] / TotalPrice * width);
double t = SaveDecimal(d_price[i] / TotalPrice * 100);
barList.add(new ViewBar(s_select[i]+" ",t+"%","¥"+d_price[i],n,10));
}
}
前三甲
通過比較所有賬單記錄,根據(jù)金額升序獲取前三甲
創(chuàng)建適配器
public class RankAdapter extends RecyclerView.Adapter<RankAdapter.ViewHolder> {
private int[] img_select = {
R.drawable.gold,
R.drawable.silver,
R.drawable.tongpai,
};
private List<RankList> rankLists;
public RankAdapter(List<RankList> rankLists){
this.rankLists = rankLists;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.ranking_list_item,parent,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
RankList rank = rankLists.get(position);
holder.item_label.setText("["+rank.getLabel()+"]");
holder.item_content.setText(rank.getContent());
if (rank.getType() == 1){
holder.item_price.setText("-"+rank.getPrice());
}else {
holder.item_price.setText("+"+rank.getPrice());
}
switch (rank.getPosition()){
case 1:
holder.item_img.setImageResource(img_select[0]);
break;
case 2:
holder.item_img.setImageResource(img_select[1]);
break;
case 3:
holder.item_img.setImageResource(img_select[2]);
break;
}
}
@Override
public int getItemCount() {
return rankLists.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
private TextView item_label,item_content,item_price;
private ImageView item_img;
public ViewHolder(@NonNull View itemView) {
super(itemView);
item_label = itemView.findViewById(R.id.Rank_label);
item_content = itemView.findViewById(R.id.Rank_name);
item_price = itemView.findViewById(R.id.Rank_price);
item_img = itemView.findViewById(R.id.Rank_img);
}
}
}
獲取數(shù)據(jù)源
代碼雖不比遞歸以及排序整潔,但是時(shí)間復(fù)雜度控制在0(n),效率比冒泡排序、快速排序等要高一點(diǎn)
/**
* 選出賬單支出前三甲*/
private void getRankings(){
if (recordList.size() == 0 || recordList == null)return;
double maxPrice = -32768,midPrice = -32768,lowPrice = -32768;
int maxIndex = -1,midIndex = -1,lowIndex = -1;
for (int i = 0; i < recordList.size(); i++) {
double price = Double.parseDouble(recordList.get(i).getGoodsPrice());
if ( price > maxPrice){
lowPrice = midPrice;
lowIndex = midIndex;
midPrice = maxPrice;
midIndex = maxIndex;
maxPrice = price;
maxIndex = i;
}
if (price < maxPrice && price > midPrice){
lowPrice = midPrice;
lowIndex = midIndex;
midPrice = price;
midIndex = i;
}
if (price < maxPrice && price < midPrice && price > lowPrice){
lowPrice = price;
lowIndex = i;
}
}
int[] poi = {maxIndex,midIndex,lowIndex};
for (int i = 0; i < 3; i++) {
if (poi[i] == -1)continue;
rankListList.add(new RankList(i+1,recordList.get(poi[i]).getLabel(),recordList.get(poi[i]).getGoodsName(),recordList.get(poi[i]).getGoodsPrice(),recordList.get(poi[i]).getType()));
}
}
單標(biāo)簽總價(jià)以及總金額
/**
* 獲取單個(gè)標(biāo)簽總價(jià)以及所有商品總價(jià)*/
private void getPrice(){
if (recordList.size() == 0 || recordList == null)return;
d_price = new double[s_select.length];
for (int i = 0; i < recordList.size(); i++) {
for (int j = 0; j < s_select.length; j++) {
if (recordList.get(i).getLabel().equals(s_select[j])){
d_price[j] += Double.parseDouble(recordList.get(i).getGoodsPrice());
TotalPrice += Double.parseDouble(recordList.get(i).getGoodsPrice());
break;
}
}
}
}
可視化概覽
效果預(yù)覽

簡述
本可視化圖表工具采用的是AAChartView,此工具相對于老牌MPChartView和HelloChartView而言,使用更加簡單,種類更加齊全,重點(diǎn)是粉粉嫩嫩,但他的導(dǎo)入方式與其他不同,不是通過導(dǎo)入閉包進(jìn)行使用;而且通過復(fù)制它到一些文件到自己工程項(xiàng)目中,其樣式使用的js寫的,所有需要導(dǎo)入一些js文件以及一些其他java文件。這一點(diǎn)不比導(dǎo)入閉包方便。根據(jù)需要進(jìn)行選擇使用。
折線圖
通過aa_drawChartWithChartModel()
方法獲取AAChartModel
對象即可,使用超級簡單
lineChartView.aa_drawChartWithChartModel(InitLineChart());
然后可通過配置一些參數(shù),更加形象化圖表
例如:categories 為 x軸數(shù)據(jù)源,類型為String[]
yAxisMin 為 y軸數(shù)據(jù)源最小值
yAxisMax 為 y軸數(shù)據(jù)源最大值
series 為 每個(gè)數(shù)據(jù)點(diǎn)的提示內(nèi)容,其中name為標(biāo)題;data為數(shù)據(jù),類型為Object[]
private AAChartModel InitLineChart() {
return new AAChartModel()
.chartType(AAChartType.Areaspline)
.legendEnabled(false)
.yAxisVisible(true)
.markerRadius(6f)
.markerSymbolStyle(AAChartSymbolStyleType.InnerBlank)
.zoomType(AAChartZoomType.XY)
.categories(s_select)
.yAxisMin(2.0f)//Y軸數(shù)據(jù)最大值和最小值范圍
.yAxisMax(2000.0f)
.xAxisTickInterval(2)
.series(new AASeriesElement[]{
new AASeriesElement()
.name("合計(jì)")
.color("#2494F3")
.data( getPrice())
});
}
獲取數(shù)據(jù)源
由于需要的是Object[] 類型數(shù)據(jù),所有需要將string類型數(shù)據(jù)轉(zhuǎn)為double,然后將double轉(zhuǎn)為Double類型,然后進(jìn)行強(qiáng)制轉(zhuǎn)換,最后變?yōu)镺bject類型
private Object[] getPrice(){
if (recordList.size() == 0 || recordList == null)return null;
double[] d_price = new double[s_select.length];
Object[] o_price = new Object[s_select.length];
for (int i = 0; i < recordList.size(); i++) {
for (int j = 0; j < s_select.length; j++) {
if (recordList.get(i).getLabel().equals(s_select[j])){
Log.d("DetailedActivity",Double.parseDouble(recordList.get(i).getGoodsPrice())+"");
d_price[j] += Double.parseDouble(recordList.get(i).getGoodsPrice());
break;
}
}
}
for (int i = 0; i < s_select.length; i++) {
o_price[i] = new Double(d_price[i]);
}
return o_price;
}
南丁格爾玫瑰圖
同樣適用aa_drawChartWithChartModel
方法進(jìn)行數(shù)據(jù)體現(xiàn),同時(shí)無論什么類型的圖表類型,都知使用AAChartView
控件,并且只需要返回AAChartModel
對象,這極大程度方便進(jìn)行封裝使用
mapChartView.aa_drawChartWithChartModel(InitRoseChart());
private AAChartModel InitRoseChart() {
return new AAChartModel()
.yAxisTitle("cm")
.chartType(AAChartType.Column)
.xAxisVisible(false)//是否顯示最外一層圓環(huán)
.yAxisVisible(true)//是否顯示中間的多個(gè)圓環(huán)
.yAxisAllowDecimals(true)
.legendEnabled(false)//隱藏圖例(底部可點(diǎn)按的小圓點(diǎn))
.categories(getTitles())
.dataLabelsEnabled(true)
.polar(true)//極地化圖形
.series(new AASeriesElement[]{
new AASeriesElement()
.name("價(jià)格")
.data(getRosePrice()),
}
);
}
獲取數(shù)據(jù)源
/**
* 南丁格爾玫瑰圖數(shù)據(jù)源x*/
private Object[] getRosePrice(){
if (recordList.size() == 0 || recordList == null)return null;
double[] d_price = new double[recordList.size()];
Object[] o_price = new Object[recordList.size()];
for (int i = 0; i < recordList.size(); i++) {
d_price[i] = Double.parseDouble(recordList.get(i).getGoodsPrice());
}
for (int i = 0; i < recordList.size(); i++) {
o_price[i] = new Double(d_price[i]);
}
return o_price;
}
記錄刪除
效果圖

釋
首先刪除數(shù)據(jù)庫中的對象,然后刪除當(dāng)前列表數(shù)據(jù)文章來源:http://www.zghlxwxcb.cn/news/detail-430599.html
adapter.setDeleteListener(new OrderAdapter.onDeleteListener() {
@Override
public void onClickListener(int pos, Record bean) {
dao.Delete(bean.getGoodsName());
recordList.remove(pos);
adapter.notifyDataSetChanged();
EventBus.getDefault().postSticky(new UpdateBean(false));
}
});
尾言
此代碼為剛?cè)腴T所敲,很多不足之處,最近有很多人找我要此項(xiàng)目代碼,修復(fù)了一些Bug,增加刪除功能,但由于之前技術(shù)不足,框架構(gòu)建不是很好,無心去重構(gòu),再次感謝大家的厚愛文章來源地址http://www.zghlxwxcb.cn/news/detail-430599.html
到了這里,關(guān)于Android——一個(gè)簡單的記賬本APP的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!