Android實(shí)現(xiàn)志愿者系統(tǒng)詳細(xì)步驟與代碼
一、項(xiàng)目概述
本系統(tǒng)采用MVC架構(gòu)設(shè)計(jì),SQLite數(shù)據(jù)表有用戶(hù)表、成員表和活動(dòng)表,有十多個(gè)Activity頁(yè)面。打開(kāi)應(yīng)用,進(jìn)入歡迎界面,3s后跳轉(zhuǎn)登錄界面,用戶(hù)先注冊(cè)賬號(hào),登錄成功后進(jìn)入主界面。主界面可以查看我的活動(dòng),修改和刪除活動(dòng),還能發(fā)布活動(dòng)。可以添加和刪除成員、還能查看我的成員信息??梢圆榭春托薷膫€(gè)人信息。底部導(dǎo)航欄和頂部菜單欄,菜單欄可以打開(kāi)背景音樂(lè)、查詢(xún)位置和查詢(xún)時(shí)間。應(yīng)用還制作了鐘表顯示的小組件,功能非常豐富。
二、主要技術(shù)
主要應(yīng)用的技術(shù)如下:
Fragment碎片 | Service后臺(tái)服務(wù) | SharedPreferences | MediaPlayer |
---|---|---|---|
Handler | SQLiteDatabase | Bundle | RecyclerView |
Thread多線(xiàn)程 | Menu菜單欄 | 百度地圖 | Widget組件開(kāi)發(fā) |
本項(xiàng)目知識(shí)點(diǎn)還是很多的,涉及到Service后臺(tái)服務(wù),百度地圖定位功能,Widget桌面組件開(kāi)發(fā)等。
三、開(kāi)發(fā)環(huán)境
開(kāi)發(fā)環(huán)境依舊是在Android Studio4.2.1,只要你的AS是近兩年從官網(wǎng)下載的,都是可以滿(mǎn)足的。日期版本是比4.2.1高的。
四、詳細(xì)設(shè)計(jì)
1、基礎(chǔ)Activity
首先,講下歡迎、注冊(cè)和登錄,這三者作為App不可或缺的內(nèi)容,同時(shí)也是邏輯細(xì)節(jié)和UI設(shè)計(jì)最需要注意的地方,做完容易,做好不容易。做過(guò)這么多應(yīng)用了,不同樣式的登錄界面也接觸了20來(lái)種。本次注冊(cè)登錄還是很喜歡的風(fēng)格,很豐富的提示信息,保證賬號(hào)的唯一性。記住密碼,方便用戶(hù),注冊(cè)完也連帶賬號(hào)和密碼一起傳回來(lái)。Layout的Code過(guò)于簡(jiǎn)單,看下Design視圖。
再來(lái)講MainActivity,奠定應(yīng)用基調(diào)的Activity,至關(guān)重要,你要將應(yīng)用的所有功能呈現(xiàn)在這里,底部導(dǎo)航欄采用BottomNavigationView,頂部Menu菜單欄、導(dǎo)航欄以及主體部分都是系統(tǒng)功能。按鈕都設(shè)置了漸變色的background,按下變色。導(dǎo)航欄有圖標(biāo),后面的各個(gè)輸入框都有圖標(biāo)。
MainActivity的代碼很多,因?yàn)樗?fù)責(zé)了后臺(tái)音樂(lè)、位置查詢(xún)、活動(dòng)的查看修改刪除發(fā)布等頁(yè)面跳轉(zhuǎn),查看刪除添加成員的跳轉(zhuǎn),以及個(gè)人信息的修改等。這里就一起看下導(dǎo)航欄的監(jiān)聽(tīng)器吧,和Onclick方法很相似,只能說(shuō)接口方法好像都如此。
// 底部導(dǎo)航欄監(jiān)聽(tīng)器 bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.my_member: Intent intentMember = new Intent(MainActivity.this, ViewMember.class); startActivity(intentMember); return true; case R.id.release_activity: Intent intentActivity = new Intent(MainActivity.this, ReleaseActivity.class); startActivity(intentActivity); return true; case R.id.personal_information: Intent intentPersonal = new Intent(MainActivity.this, PersonalActivity.class); startActivity(intentPersonal); return true; } return false; } });
2、活動(dòng)信息
先看下Activity的Bean類(lèi)的屬性and方法。
// 我的活動(dòng)實(shí)體類(lèi) public class MyActivity { private String name; private String number; private String beginDate; private String endDate; public MyActivity() { } public MyActivity(String name, String number, String beginDate, String endDate) { this.name = name; this.number = number; this.beginDate = beginDate; this.endDate = endDate; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } public String getBeginDate() { return beginDate; } public void setBeginDate() { this.beginDate = beginDate; } public String getEndDate() { return endDate; } public void setEndDate() { this.endDate = endDate; } }
再來(lái)看下數(shù)據(jù)庫(kù)中Activity表,你會(huì)發(fā)現(xiàn)數(shù)據(jù)表的字段名就是Bean的屬性名。
// 活動(dòng)表建表語(yǔ)句 public static final String CREATE_MYACTIVITY = "create table MyActivity (" + "name varchar(20) primary key," + "number varchar(20)," + "beginDate varchar(20)," + "endDate varchar(20))";
建立好表后,在ActivityDao中寫(xiě)好對(duì)活動(dòng)表的增刪改查方法吧,后面只需要?jiǎng)?chuàng)建ActivityDao對(duì)象就可以操作活動(dòng)表了,不需要每次都寫(xiě)一遍。
// 添加我的活動(dòng) public void insertMyActivity(MyActivity myActivity) { // 創(chuàng)建ContentValues對(duì)象 ContentValues values = new ContentValues(); // 向該對(duì)象中插入鍵值對(duì) values.put("name", myActivity.getName()); values.put("number", myActivity.getNumber()); values.put("beginDate", myActivity.getBeginDate()); values.put("endDate", myActivity.getEndDate()); // 通過(guò)insert()方法插入數(shù)據(jù) sqLiteDatabase.insert(MyDBOpenHelper.TABLE_MYACTIVITY, null, values); } // 刪除我的活動(dòng) public void deleteMyActivity(MyActivity myActivity) { sqLiteDatabase.delete(MyDBOpenHelper.TABLE_MYACTIVITY, "name = ?", new String[]{myActivity.getName()}); } // 修改我的活動(dòng) public void updateMyActivity(MyActivity myActivity) { ContentValues values = new ContentValues(); values.put("name", myActivity.getName()); values.put("number", myActivity.getNumber()); values.put("beginDate", myActivity.getBeginDate()); values.put("endDate", myActivity.getEndDate()); sqLiteDatabase.update(MyDBOpenHelper.TABLE_MYACTIVITY, values, "name = ?", new String[]{myActivity.getName()}); } // 查詢(xún)我的活動(dòng) public ArrayList<MyActivity> queryMyActivity() { ArrayList<MyActivity> arrayList = new ArrayList<>(); Cursor cursor = sqLiteDatabase.query(MyDBOpenHelper.TABLE_MYACTIVITY, null, null, null, null, null, null); if (cursor.moveToFirst()) { do { String name = cursor.getString(cursor.getColumnIndex("name")); String number = cursor.getString(cursor.getColumnIndex("number")); String beginDate = cursor.getString(cursor.getColumnIndex("beginDate")); String endDate = cursor.getString(cursor.getColumnIndex("endDate")); MyActivity myActivity = new MyActivity(name, number, beginDate, endDate); arrayList.add(myActivity); } while (cursor.moveToNext()); } cursor.close(); return arrayList; } // 根據(jù)名稱(chēng)查詢(xún)我的活動(dòng) public MyActivity queryByName(String activityName) { Cursor cursor = sqLiteDatabase.query(MyDBOpenHelper.TABLE_MYACTIVITY, null, null, null, null, null, null); if (cursor.moveToFirst()) { do { // 遍歷Cursor對(duì)象,取出數(shù)據(jù)比對(duì) String name = cursor.getString(cursor.getColumnIndex("name")); if (activityName.equals(name)) { String number = cursor.getString(cursor.getColumnIndex("number")); String beginDate = cursor.getString(cursor.getColumnIndex("beginDate")); String endDate = cursor.getString(cursor.getColumnIndex("endDate")); MyActivity myActivity = new MyActivity(name, number, beginDate, endDate); cursor.close(); return myActivity; } } while (cursor.moveToNext()); } cursor.close(); return null; }
3、成員信息
先來(lái)看下成員類(lèi)的屬性和方法:
// 成員實(shí)體類(lèi) public class Member { private String id; private String name; private String age; private String phone; public Member() { } public Member(String id, String name, String age, String phone) { this.id = id; this.name = name; this.age = age; this.phone = phone; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } }
再寫(xiě)建表語(yǔ)句,SQL語(yǔ)法熟練的話(huà),這些都是基操了,沒(méi)什么內(nèi)容。
// 成員表建表語(yǔ)句 public static final String CREATE_MEMBER = "create table Member (" + "id varchar(20) primary key," + "name varchar(20)," + "age varchar(20)," + "phone varchar(20))";
最后,還是寫(xiě)MemberDao,對(duì)用戶(hù)表的增刪改查封裝好。
// 添加我的成員 public void insertMember(Member member) { // 創(chuàng)建ContentValues對(duì)象 ContentValues values = new ContentValues(); // 向該對(duì)象中插入鍵值對(duì) values.put("id", member.getId()); values.put("name", member.getName()); values.put("age", member.getAge()); values.put("phone", member.getPhone()); // 通過(guò)insert()方法插入數(shù)據(jù) sqLiteDatabase.insert(MyDBOpenHelper.TABLE_MEMBER, null, values); } // 刪除我的成員 public void deleteMember(Member member) { sqLiteDatabase.delete(MyDBOpenHelper.TABLE_MEMBER, "id = ?", new String[]{member.getId()}); } // 修改我的成員 public void updateMember(Member member) { ContentValues values = new ContentValues(); values.put("id", member.getId()); values.put("name", member.getName()); values.put("age", member.getAge()); values.put("phone", member.getPhone()); sqLiteDatabase.update(MyDBOpenHelper.TABLE_MEMBER, values, "id = ?", new String[]{member.getId()}); } // 查詢(xún)我的成員 public ArrayList<Member> queryMember() { ArrayList<Member> arrayList = new ArrayList<>(); Cursor cursor = sqLiteDatabase.query(MyDBOpenHelper.TABLE_MEMBER, null, null, null, null, null, null); if (cursor.moveToFirst()) { do { String id = cursor.getString(cursor.getColumnIndex("id")); String name = cursor.getString(cursor.getColumnIndex("name")); String age = cursor.getString(cursor.getColumnIndex("age")); String phone = cursor.getString(cursor.getColumnIndex("phone")); Member member = new Member(id, name, age, phone); arrayList.add(member); } while (cursor.moveToNext()); } cursor.close(); return arrayList; } // 根據(jù)編號(hào)查詢(xún)成員 public Member queryById(String memberId) { Cursor cursor = sqLiteDatabase.query(MyDBOpenHelper.TABLE_MEMBER, null, null, null, null, null, null); if (cursor.moveToFirst()) { do { // 遍歷Cursor對(duì)象,取出數(shù)據(jù)比對(duì) String id = cursor.getString(cursor.getColumnIndex("id")); if (memberId.equals(id)) { String name = cursor.getString(cursor.getColumnIndex("name")); String age = cursor.getString(cursor.getColumnIndex("age")); String phone = cursor.getString(cursor.getColumnIndex("phone")); Member member = new Member(id, name, age, phone); cursor.close(); return member; } } while (cursor.moveToNext()); } cursor.close(); return null; }
4、百度地圖
首先來(lái)看下我引入百度地圖定位功能的過(guò)程。創(chuàng)建libs文件夾,然后拖拽BaiduLBS的jar包進(jìn)去,然后Add as Library即可。
在AndroidManifest.xml中添加上meta-data標(biāo)簽和Service標(biāo)簽,一個(gè)是api_key,還有一個(gè)是location的服務(wù)。
<meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="@string/api_key" /> <service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote" />
在MapActivity中定義并配置地圖的參數(shù)信息,然后初始化當(dāng)前位置并顯示,因?yàn)槟M器的經(jīng)緯度信息是不通過(guò)網(wǎng)絡(luò)或者GPS獲取的,所以絕大多數(shù)時(shí)候是不能用來(lái)使用百度地圖的,我們的坐標(biāo)也都是手動(dòng)輸入顯示即可,想使用還是要用真機(jī),況且大家也不是做什么科研項(xiàng)目,不需要到室外定位。
mapView = findViewById(R.id.map_view); baiduMap = mapView.getMap();// 獲取到地圖 baiduMap.setMyLocationEnabled(true); initMap(); // 設(shè)置地圖放大的倍數(shù) configureMap();// 設(shè)置定位的參數(shù) initLocation();// 初始化位置
5、Widget組件
Widget組件是最近才學(xué)習(xí)的內(nèi)容,發(fā)現(xiàn)平時(shí)手機(jī)應(yīng)用對(duì)Widget用的很少,不過(guò)作為Android開(kāi)發(fā)的知識(shí),有就了解一下不是壞事。為系統(tǒng)制作了一個(gè)日期顯示的Widget桌面組件,可以在活動(dòng)列表中拖到模擬器桌面上。后面運(yùn)行時(shí)候會(huì)演示打開(kāi)組件的方法。
<?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:initialKeyguardLayout="@layout/my_app_widget" android:initialLayout="@layout/my_app_widget" android:minWidth="150dp" android:minHeight="100dp" android:previewImage="@drawable/example_appwidget_preview" android:resizeMode="horizontal|vertical" android:updatePeriodMillis="86400000" android:widgetCategory="home_screen"></appwidget-provider>
長(zhǎng)按桌面,跳出小組件,然后選擇志愿者系統(tǒng)的組件,拖拽到桌面上即可。
五、運(yùn)行演示
Android Studio實(shí)現(xiàn)志愿者系統(tǒng)
到此這篇關(guān)于Android實(shí)現(xiàn)志愿者系統(tǒng)詳細(xì)步驟與代碼的文章就介紹到這了,更多相關(guān)Android志愿者系統(tǒng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android基礎(chǔ)入門(mén)之dataBinding的簡(jiǎn)單使用教程
DataBinding 是谷歌官方發(fā)布的一個(gè)框架,顧名思義即為數(shù)據(jù)綁定,下面這篇文章主要給大家介紹了關(guān)于Android基礎(chǔ)入門(mén)之dataBinding的簡(jiǎn)單使用,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06Android自定義圓形倒計(jì)時(shí)進(jìn)度條
這篇文章主要為大家詳細(xì)介紹了Android自定義圓形倒計(jì)時(shí)進(jìn)度條,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09Android Studio不能獲取遠(yuǎn)程依賴(lài)包的完美解決方法
這篇文章主要介紹了Android Studio不能獲取遠(yuǎn)程依賴(lài)包的解決方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-11-11Android實(shí)現(xiàn)調(diào)用系統(tǒng)相冊(cè)和拍照的Demo示例
這篇文章主要介紹了Android實(shí)現(xiàn)調(diào)用系統(tǒng)相冊(cè)和拍照的Demo示例,實(shí)例分析了Android調(diào)用系統(tǒng)相冊(cè)及拍照的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10Android UI設(shè)計(jì)系列之自定義DrawView組件實(shí)現(xiàn)數(shù)字簽名效果(5)
這篇文章主要介紹了Android UI設(shè)計(jì)系列之自定義DrawView組件實(shí)現(xiàn)數(shù)字簽名效果,具有一定的實(shí)用性和參考價(jià)值,感興趣的小伙伴們可以參考一下2016-06-06Android 仿微信發(fā)動(dòng)態(tài)九宮格拖拽、刪除功能
這篇文章主要介紹了Android 仿微信發(fā)動(dòng)態(tài)九宮格拖拽、刪除功能,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-11-11