多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國(guó)內(nèi)最全I(xiàn)T社區(qū)平臺(tái) 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁(yè) > php開源 > 綜合技術(shù) > [置頂] 生活管家app

[置頂] 生活管家app

來(lái)源:程序員人生   發(fā)布時(shí)間:2016-06-08 13:47:38 閱讀次數(shù):2550次

這篇文章給大家?guī)?lái)的是1款android的生活管家app實(shí)現(xiàn)。
主要實(shí)現(xiàn)功能及其要求:
1、個(gè)人收入支出的管理。主要完成收入管理、支出管理、種別管理、收入查詢、支出查詢、統(tǒng)計(jì)信息等功能。
2、實(shí)現(xiàn)每次進(jìn)入利用需要進(jìn)行密碼輸入,增強(qiáng)安全性。
3、其他功能可根據(jù)個(gè)人自己的想法添加。
4、系統(tǒng)界面美觀,操作方便。
好了,根據(jù)這樣的要求,您會(huì)想到開發(fā)1個(gè)怎樣的app呢?快發(fā)揮您的想象能力和動(dòng)手能力吧!
接下來(lái),來(lái)看看博主的實(shí)現(xiàn),先來(lái)看看實(shí)現(xiàn)的效果展現(xiàn)吧。。。
進(jìn)入主界面密碼主界面類別管理收入查詢收入管理查詢結(jié)果用戶信息用戶信息修改
應(yīng)當(dāng)還可以吧,不算太丑。其中的統(tǒng)計(jì)和輔助工具就沒(méi)有實(shí)現(xiàn)了,太耽誤時(shí)間了,如果讀者有興趣,可自行完成。

項(xiàng)目源碼下載地址:`點(diǎn)擊下載地址
**作者:**IT_faquir
博客地址:http://blog.csdn.net/IT_faquir/article/details/51534408
重點(diǎn)內(nèi)容
java代碼塊和布局文件目錄結(jié)構(gòu):
java代碼塊文件 布局文件
重點(diǎn)來(lái)了,那就是實(shí)現(xiàn)它。來(lái)隨著博主1起來(lái)看看是怎樣實(shí)現(xiàn)的吧。(只講授1些重點(diǎn)部份)。
主函數(shù),作為程序的入口,直接上代碼:

public class MainActivity extends Activity { private SharedPreferences sp; private DatabaseUtils dbUtils; MyDialog mDialog; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sp = getSharedPreferences("firstInit", Context.MODE_PRIVATE); getActionBar().hide(); mDialog = new MyDialog(this); initDatabase(); } //作為第1次使用,將會(huì)初始化數(shù)據(jù)庫(kù) private void initDatabase() { // Boolean isFirst = sp.getBoolean("isFirst", true);// 用于得到是不是為第1次使用此程序 if (sp.getBoolean("isFirst", true)) {// 第1次使用初始化數(shù)據(jù)庫(kù) String sql1 = "create table userInfo(id INTEGER PRIMARY KEY,name,age,phone,birth,address,password)"; String sql2 = "create table income(id INTEGER PRIMARY KEY,date,type,money MONEY,remark)"; String sql3 = "create table outlay(id INTEGER PRIMARY KEY,date,type,money MONEY,remark)"; String sql4 = "create table incomeType(id INTEGER PRIMARY KEY,type)"; String sql5 = "create table outlayType(id INTEGER PRIMARY KEY,type)"; dbUtils = new DatabaseUtils(this); dbUtils.openDatabase(); dbUtils.create(sql1); dbUtils.create(sql2); dbUtils.create(sql3); dbUtils.create(sql4); dbUtils.create(sql5); dbUtils.insert("insert into userInfo(id) values(1)"); dbUtils.insert("insert into incomeType(type) values('工資')"); dbUtils.insert("insert into incomeType(type) values('股票')"); dbUtils.insert("insert into outlayType(type) values('消費(fèi)')"); dbUtils.closeDB(); sp.edit().putBoolean("isFirst", false).commit(); mDialog.showSetPswDialog(); } else { mDialog.showLoginDialog(null).setCancelable(false); dbUtils = new DatabaseUtils(this); dbUtils.openDatabase(); Cursor curson1 = dbUtils.query("select type from incomeType"); String[] s1 = new String[curson1.getCount()]; int count1 = 0; while (curson1.moveToNext()) { s1[count1] = curson1.getString(0); count1++; } curson1.close(); LifeButlerUtils.incomeType = s1; Cursor curson2 = dbUtils.query("select type from outlayType"); String[] s2 = new String[curson2.getCount()]; int count2 = 0; while (curson2.moveToNext()) { String s = curson2.getString(0); System.out.println("xiao:" + s); s2[count2] = s; count2++; } curson2.close(); dbUtils.closeDB(); LifeButlerUtils.outlayType = s2; } } public void incomeManagement(View v) { startActivity(MainActivity.this, IncomeManActivity.class); } public void outlayManagement(View v) { startActivity(MainActivity.this, OutlayManActivity.class); } //其他的按鈕啟動(dòng)界面就不在重復(fù)展現(xiàn)了。 ... public void exitSys(View v) { this.finish(); System.exit(0); } //封裝下啟動(dòng)界面的1個(gè)方法,以簡(jiǎn)化代碼 private void startActivity(Context context, Class c) { Intent intent = new Intent(context, c); startActivity(intent); } }

從主函數(shù)中可以看出,此程序用到了sqlite本地數(shù)據(jù)庫(kù)。同時(shí)SharedPreference也在程序中得到應(yīng)用,用于寄存1些簡(jiǎn)單的本地?cái)?shù)據(jù),作為是不是為第1次使用利用程序的根據(jù)。還有就是啟動(dòng)activity方法的奇妙封裝,這樣可以大大減少代碼量。
從代碼中同時(shí)看到的,樓主用到了1個(gè)關(guān)于數(shù)據(jù)的操作的1個(gè)工具類DatabaseUtils。
看看DatabaseUtils這工具類的代碼:

public class DatabaseUtils { public static final String DBNAME = "mydb.db"; private Context context; private SQLiteDatabase db; public DatabaseUtils(Context context) { this.context = context; } public void openDatabase() { db = context.openOrCreateDatabase(DBNAME, context.MODE_PRIVATE, null); } public void create(String sql) { db.beginTransaction(); db.execSQL(sql); db.setTransactionSuccessful(); db.endTransaction(); } public void insert(String sql) { db.beginTransaction(); db.execSQL(sql); db.setTransactionSuccessful(); db.endTransaction(); } //修改很刪除也類似進(jìn)行封裝。 ... public Cursor query(String sql) { db.beginTransaction(); Cursor cursor = db.rawQuery(sql, null); db.setTransactionSuccessful(); db.endTransaction(); return cursor; } // 判斷數(shù)據(jù)表是不是存在 public boolean isExsit(String tableName) { boolean result = false; if (tableName == null) { return false; } Cursor cursor = null; try { String sql = "select count(*) as c from sqlite_master where type ='table' and name ='" + tableName.trim() + "' "; cursor = db.rawQuery(sql, null); if (cursor.moveToNext()) { int count = cursor.getInt(0); if (count > 0) { result = true; } } } catch (Exception e) { e.printStackTrace(); } return result; } //要記得使用完數(shù)據(jù)庫(kù)要關(guān)閉它。 public void closeDB() { db.close(); } }

這個(gè)數(shù)據(jù)庫(kù)工具類很簡(jiǎn)單,就是對(duì)1些增刪改查操作的封裝。主要傳入sql語(yǔ)句進(jìn)行履行。因此需要讀者,有1點(diǎn)的sql語(yǔ)句基礎(chǔ)。
再回到主類,會(huì)發(fā)現(xiàn)有個(gè)Dialog,用于進(jìn)入利用時(shí)輸入密碼使用。
我們來(lái)看看吧:
MyDialog實(shí)現(xiàn):

public Dialog showLoginDialog(final Intent intent) { View li = LayoutInflater.from(context).inflate(R.layout.dialog_layout, null); final Dialog dialog = new AlertDialog.Builder(context).create(); // dialog.setTitle("給自己起個(gè)名字吧!"); dialog.show(); dialog.getWindow().setContentView(li); // dialog.setCancelable(false);// 是對(duì)話框不能按返回鍵取消 dialog.setCanceledOnTouchOutside(false);// 使對(duì)話框不能按旁邊取消 dialog.getWindow().clearFlags( WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); et = (EditText) li.findViewById(R.id.login_psw); li.findViewById(R.id.dialog_bn_ok).setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { String psw = null; String myPsw = et.getText().toString().trim(); dbUtils.openDatabase(); Cursor c = dbUtils .query("select password from userInfo where id = 1"); while (c.moveToNext()) { psw = c.getString(0).trim(); } dbUtils.closeDB(); if (!psw.equals(myPsw)) { Toast.makeText(context, "密碼毛病", 500).show(); } else { if (intent != null) { context.startActivity(intent); } else { dialog.cancel(); } } } }); return dialog; }

對(duì)話框的實(shí)現(xiàn),是否是和我們?cè)倌切峡吹降膶?duì)話框不1樣能,這里樓主用到了自定義對(duì)話框,對(duì)對(duì)話框布局進(jìn)行填充。

LayoutInflater.from(context).inflate(R.layout.dialog_layout,null); dialog.getWindow().setContentView(li);

這樣實(shí)現(xiàn)出來(lái)的效果既美觀,又可以更好的自我把控。
看到效果圖就知道;
InComeManActivity:
用于收入管理類用于輸入的錄入

public class IncomeManActivity extends BaseActivity { private EditText et_date, et_money, et_remark; private Spinner sp_source; private boolean haveDate = false; private DatabaseUtils dbUtils; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.incomeman_layout); dbUtils = new DatabaseUtils(this); init(); } private void init() { et_date = (EditText) findViewById(R.id.income_date); sp_source = (Spinner) findViewById(R.id.income_source); et_money = (EditText) findViewById(R.id.income_money); et_remark = (EditText) findViewById(R.id.income_remark); dbUtils.openDatabase(); Cursor c = dbUtils.query("select type from incomeType"); String types[] = new String[c.getCount()]; int count = 0; while(c.moveToNext()){ types[count] = c.getString(0); count++; } dbUtils.closeDB(); LifeButlerUtils.incomeType = types; ArrayAdapter<String> aAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, types); sp_source.setAdapter(aAdapter); et_date.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { showDialog(); } }); } public void hand(View v) { String date = et_date.getText().toString().trim(); String type = sp_source.getSelectedItem().toString(); String money = et_money.getText().toString().trim(); String remark = et_remark.getText().toString().trim(); if (chackContent(money, remark) && haveDate) { System.out.println(date + type + money + remark); dbUtils.openDatabase(); dbUtils.insert("insert into income(date,type,money,remark) values('" + date + "','" + type + "','" + money + "','" + remark + "')"); dbUtils.closeDB(); toast("添加成功。"); } else { toast("請(qǐng)?zhí)顚懲耆畔ⅲ?); } } public void back(View v) { this.finish(); } private boolean chackContent(String money, String remark) { if (money.length() > 0 && remark.length() > 0) return true; return false; } private void showDialog() { Dialog dialog = null; Calendar c = Calendar.getInstance(); dialog = new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener() { public void onDateSet(DatePicker dp, int year, int month, int dayOfMonth) { haveDate = true; String mon = String.valueOf(month+1); if(mon.length() == 1){ mon = "0"+mon; } String day = String.valueOf(dayOfMonth); if(day.length() == 1){ day = "0"+day; } et_date.setText(year + "-" + mon + "-" + day); } }, c.get(Calendar.YEAR), // 傳入年份 c.get(Calendar.MONTH), // 傳入月份 c.get(Calendar.DAY_OF_MONTH) // 傳入天數(shù) ); dialog.show(); } }

工作流程:在界面錄入信息后,點(diǎn)擊按鍵保存,檢查所填的信息是不是完全,如果完全則保存信息到本地的sqlite數(shù)據(jù)庫(kù),否則不保存。我想,您看完代碼應(yīng)當(dāng)就懂了。
還有個(gè)是支出的錄入,基本上和這的實(shí)現(xiàn),沒(méi)甚么區(qū)分,主要就是sql語(yǔ)句有所變化,就不在繼續(xù)貼出了。
查詢的實(shí)現(xiàn):
再來(lái)看看查詢吧,這里以收入的查詢?yōu)槔?
或許難度就在于那些勾選查詢,如何才能很好的實(shí)現(xiàn),代碼量少,又靈活的代碼呢?如果有幾10個(gè)勾選的條件,那代碼量想一想便可怕。因此樓主做了1些奇妙的處理:

public class IncomeQueryActivity extends BaseActivity { private EditText et_dateS, et_dateE, et_moneyMin, et_moneyMax; private Spinner sp_source; private CheckBox check_type, check_date, check_money; private DatabaseUtils dbUtils; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.incomequery_layout); dbUtils = new DatabaseUtils(this); init(); } private void init() { check_type = (CheckBox) findViewById(R.id.check_income_source); check_date = (CheckBox) findViewById(R.id.check_income_date); check_money = (CheckBox) findViewById(R.id.check_income_money); sp_source = (Spinner) findViewById(R.id.income_query_source); et_dateS = (EditText) findViewById(R.id.income_query_time1); et_dateE = (EditText) findViewById(R.id.income_query_time2); et_moneyMin = (EditText) findViewById(R.id.income_query_money1); et_moneyMax = (EditText) findViewById(R.id.income_query_money2); et_dateS.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { showDialog(et_dateS); } }); et_dateE.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { showDialog(et_dateE); } }); ArrayAdapter<String> aAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, LifeButlerUtils.incomeType); sp_source.setAdapter(aAdapter); } public void query(View v) { Map<String, Boolean> map = new HashMap<String, Boolean>(); boolean have_type = check_type.isChecked(); boolean have_date = check_date.isChecked(); boolean have_money = check_money.isChecked(); map.put("type", have_type); map.put("date", have_date); map.put("money", have_money); String source = sp_source.getSelectedItem().toString(); String date1 = et_dateS.getText().toString().trim(); String date2 = et_dateE.getText().toString().trim(); String money1 = et_moneyMin.getText().toString().trim(); String money2 = et_moneyMax.getText().toString().trim(); StringBuilder sb = new StringBuilder(); boolean isFirst = true;// 是不是為第1個(gè)where boolean haveWhere = false;// 處理是不是有where 語(yǔ)句 boolean isOk = true;// 處理是不是信息完全性 if (have_type == true) { sb.append("type = '" + source + "'"); isFirst = false; haveWhere = true; } if (have_date == true) { if (date1.length() > 0 && date2.length() > 0) { if (!isFirst) { sb.append(" and "); } sb.append("date >= '" + date1 + "'and date <= '" + date2 + "'"); } else { toast("請(qǐng)選擇日期。"); isOk = false; } haveWhere = true; } if (have_money == true) { if (!isFirst) { sb.append(" and "); } sb.append("money >= '" + money1 + "' and date <= '" + money2 + "'"); haveWhere = true; } // 處理結(jié)果 if (isOk) { String sql = null; if (haveWhere) sql = "select * from income where " + sb.toString().trim(); else sql = "select * from income"; dbUtils.openDatabase(); Cursor c = dbUtils.query(sql); int cCount = c.getColumnCount(); StringBuilder data = new StringBuilder(); while (c.moveToNext()) { for (int i = 0; i < cCount; i++) { data.append(c.getString(i).trim() + " "); } data.append("\n"); } dbUtils.closeDB(); Intent intent = new Intent(IncomeQueryActivity.this, QueryResultActivity.class); intent.putExtra("data", data.toString()); intent.putExtra("operate", "income"); startActivity(intent); System.out.println(sql); } } public void back(View v) { this.finish(); } private void showDialog(final EditText et) { //日期對(duì)話框,和上相同 } }

由因而進(jìn)行sql語(yǔ)句查詢因此,需要生成1條滿足條件的sql語(yǔ)句,有沒(méi)找到那代碼:

if (have_type == true) { sb.append("type = '" + source + "'"); isFirst = false; haveWhere = true; } if (have_date == true) { if (date1.length() > 0 && date2.length() > 0) { if (!isFirst) { sb.append(" and "); } sb.append("date >= '" + date1 + "'and date <= '" + date2 + "'"); } else { toast("請(qǐng)選擇日期。"); isOk = false; } haveWhere = true; } if (have_money == true) { if (!isFirst) { sb.append(" and "); } sb.append("money >= '" + money1 + "' and date <= '" + money2 + "'"); haveWhere = true; }

沒(méi)錯(cuò)就是塊代碼,if語(yǔ)句配合StringBuilder,實(shí)現(xiàn)了sql語(yǔ)句的動(dòng)態(tài)生成。
outlay的查詢與此類似,不在敘述。
因此樓主總結(jié)出了1句話:我們要靈活的應(yīng)對(duì)每件事,這樣能有時(shí)能到達(dá)事半功倍的效果。
再來(lái)看看種別的管理
在對(duì)種別管理的實(shí)現(xiàn)中,樓主用到了ViewPager+ListView和PopMenu

public class CategoryActivity extends BaseActivity implements OnCheckedChangeListener, OnPageChangeListener { private ViewPager viewPager; private ArrayList<View> listView; private DatabaseUtils dbUtils; private ArrayAdapter<String> mAdapter1; private ArrayAdapter<String> mAdapter2; private RadioGroup radioGroup; private RadioButton rb1; private RadioButton rb2; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.category_layout); getActionBar().hide(); dbUtils = new DatabaseUtils(this); init(); } private void init() { dbUtils.openDatabase(); radioGroup = (RadioGroup) findViewById(R.id.novelty_rg); radioGroup.setOnCheckedChangeListener(this); rb1 = (RadioButton) findViewById(R.id.rb_income); rb2 = (RadioButton) findViewById(R.id.rb_outlay);; viewPager = (ViewPager) findViewById(R.id.cate_viewPager); viewPager.setOnPageChangeListener(this); listView = new ArrayList<View>(); View v1 = getLayoutInflater().inflate(R.layout.cate_tab_01, null); View v2 = getLayoutInflater().inflate(R.layout.cate_tab_02, null); initV1(v1); initV2(v2); listView.add(v1); listView.add(v2); viewPager.setCurrentItem(0); viewPager.setAdapter(new MyPagerAdapter()); } private void initV1(View v1) { final String type = "incomeType"; ListView list = (ListView) v1.findViewById(R.id.cate_list1); Button bn = (Button) v1.findViewById(R.id.addOne); final List<String> types = new ArrayList<String>(); Cursor c1 = dbUtils.query("select type from incomeType"); while (c1.moveToNext()) { String t = c1.getString(0); types.add(t); } mAdapter1 = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, types); list.setAdapter(mAdapter1); list.setOnItemLongClickListener(new OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { myPopMenu(view, types, "incomeType", position); return true; } }); bn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { new MyDialog(CategoryActivity.this).showAddDialog(type, types, handler); } }); } private void initV2(View v2) { final String type = "outlayType"; ListView list = (ListView) v2.findViewById(R.id.cate_list2); Button bn = (Button) v2.findViewById(R.id.addOne); final List<String> types = new ArrayList<String>(); Cursor c1 = dbUtils.query("select type from outlayType"); while (c1.moveToNext()) { String t = c1.getString(0); types.add(t); } mAdapter2 = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, types); list.setAdapter(mAdapter2); list.setOnItemLongClickListener(new OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { myPopMenu(view, types, "outlayType", position); return true; } }); bn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { new MyDialog(CategoryActivity.this).showAddDialog(type, types, handler); } }); } public void myPopMenu(View v, final List<String> types, final String tableName, final int position) { PopupMenu p = new PopupMenu(this, v); p.getMenuInflater().inflate(R.menu.menu, p.getMenu()); p.setOnMenuItemClickListener(new OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { int id = item.getItemId(); switch (id) { case R.id.del: dbUtils.openDatabase(); dbUtils.delete("delete from " + tableName + " where type = '" + types.get(position) + "'"); types.remove(position); if (tableName.equals("incomeType")) { handler.sendEmptyMessage(0x1); types.toArray(LifeButlerUtils.incomeType); } else { types.toArray(LifeButlerUtils.outlayType); handler.sendEmptyMessage(0x2); } dbUtils.closeDB(); break; } return true; } }); p.show(); } Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (msg.what == 0x1) { mAdapter1.notifyDataSetChanged(); } else if (msg.what == 0x2) { mAdapter2.notifyDataSetChanged(); } } }; class MyPagerAdapter extends PagerAdapter { @Override public int getCount() { return listView.size(); } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(listView.get(position)); } @Override public boolean isViewFromObject(View view, Object arg1) { return view == arg1; } @Override public Object instantiateItem(ViewGroup container, int position) { // position; container.addView(listView.get(position)); return listView.get(position); } } @Override public void finish() { // TODO Auto-generated method stub super.finish(); dbUtils.closeDB(); } @Override public void onCheckedChanged(RadioGroup group, int checkedId) { switch (checkedId) { case R.id.rb_income:// 選擇校內(nèi) // setTabSelect(0);//顯示校內(nèi)資訊 viewPager.setCurrentItem(0);// 顯示校內(nèi)資訊 break; case R.id.rb_outlay:// 選擇校外 // setTabSelect(1);//顯示校外資訊 viewPager.setCurrentItem(1);// 顯示校外資訊 break; default: break; } } @Override public void onPageScrollStateChanged(int arg0) { } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageSelected(int arg0) { switch (arg0) { case 0:// 第1頁(yè) rb1.setChecked(true); break; case 1:// 第2頁(yè) rb2.setChecked(true); break; default: break; } } }

這塊代碼相對(duì)有點(diǎn)多,是1個(gè)完全的代碼。主要就是自定義的1個(gè)ListView的適配器MyAdapter,將從數(shù)據(jù)庫(kù)中查詢出來(lái)的數(shù)據(jù)展現(xiàn)出來(lái),利用ViewPager分別顯示了輸入的種別管理和支出的種別管理。在每一個(gè)list上可以長(zhǎng)按進(jìn)行刪除,和在最下角可以添加種別操作。

好了這利用大體的主要代碼都給出了,有些功能自己看看源代碼吧,不再給出。謝謝您的圍觀,源碼的下載地址在文章的開頭。

生活不易,碼農(nóng)辛苦
如果您覺(jué)得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 精品99一区二区三区麻豆 | 男人边吃奶边玩下面舒服 | 国产成人高清 | www.日本在线播放 | 校园激情亚洲 | 精品久久免费观看 | 91精品国产美女福到在线不卡 | 一二三四在线观看免费播放视频 | 免费看毛片的网址 | h视频在线免费 | 亚洲欧美四级在线播放 | 日本一区二区在线视频 | 国产成人亚洲精品77 | 欧美色视频免费高清播放 | 国产精品成人扳一级aa毛片 | av蜜桃| 亚洲欧美在线观看首页 | 亚州中文字幕 | xart欧美在线播放精品4k | 三级国产短视频在线观看 | 中文字幕日韩精品中文区 | 一本大道道无香蕉综合在线 | 狂野欧美性猛交xxxx | 亚洲黄色片网站 | 第一福利在线观看永久视频 | 国产不卡高清在线观看视频 | 逼逼综合网 | 一区二区三区视频在线 | 亚洲最大的视频网站 | 免费在线公开视频 | 中国在线观看www视频 | 日本成年一区久久综合 | 欧美一区二区二区 | 欧美综合一区 | 老司机亚洲精品影院在线 | 久操网在线 | 天天做天天爱天天爽综合网 | 国产精品久久毛片 | 在线精品亚洲欧洲第一页 | 黑人性xxxⅹxxbbbbb | 亚洲国产成人久久三区 |