一、項(xiàng)目背景
在校園生活中,圖書館是很多人選擇的學(xué)習(xí)圣地,這里不僅充滿書香氣息,而且還十分靜謐。這樣的學(xué)習(xí)環(huán)境,必然會(huì)很搶手,導(dǎo)致很多學(xué)生早早就來(lái)圖書館占座,漸漸地因?yàn)橐恢闭疾坏阶耐瑢W(xué)就失去了學(xué)習(xí)的動(dòng)力。
針對(duì)這樣的實(shí)際問(wèn)題,我們?cè)O(shè)計(jì)了一款圖書館訂座系統(tǒng)。主要有四大功能模塊,包括預(yù)訂座位、查看座位、個(gè)人信息和我的步數(shù)。預(yù)訂座位可以選3層樓,每層樓座位表不同,每位學(xué)生同一時(shí)間只能預(yù)訂一個(gè)座位;查看座位的樓層和座位號(hào),如果離開(kāi)圖書館了,可以退訂座位;在個(gè)人信息中可以點(diǎn)擊編輯進(jìn)入編輯模式,保存進(jìn)入查看模式;最后我的步數(shù)可以進(jìn)行計(jì)步,還有每日名言警句。整體功能很完善,界面設(shè)計(jì)美觀。
二、需求分析
訂座系統(tǒng)滿足以下所有的要求:
- 項(xiàng)目主題中要體現(xiàn)解決現(xiàn)實(shí)中的某種實(shí)際問(wèn)題
- 項(xiàng)目app不能是單機(jī)版
- UI設(shè)計(jì)要求簡(jiǎn)單美觀、實(shí)用性強(qiáng)
- 項(xiàng)目至少包含4個(gè)功能模塊,功能模塊必須與題目相關(guān)
- 使用技術(shù)的要求:
a.網(wǎng)絡(luò)通信(socket或http) | b.數(shù)據(jù)庫(kù) | c.傳感器 | d.多線程 |
---|
三、開(kāi)發(fā)環(huán)境
打開(kāi)Android Studio,Help——>About,只要你的AS是從官網(wǎng)下載的都可以運(yùn)行。比如小蜜蜂版本就是2021.1.1,這種日期形式的都完全OK。
四、詳細(xì)設(shè)計(jì)
1、主界面
這里最上面是一個(gè)ViewPager,用來(lái)顯示輪播圖,下面就是四個(gè)設(shè)置了bg的按鈕,在預(yù)定座位下面是一個(gè)RadioGroup,包含3個(gè)單選按鈕。
這里實(shí)現(xiàn)輪播圖的主函數(shù)initPager(),聲明了圖片和小點(diǎn)列表并初始化。對(duì)于綁定的ImageView,我們依次設(shè)置圖片數(shù)組中的圖片,設(shè)置它的ScaleType為FIT_XY,進(jìn)行平鋪圖片。接著設(shè)置圖片view的寬高,然后將這張圖片放入ivList,小圓點(diǎn)也是同樣的方式, pointLayout.addView(piv);將小圓點(diǎn)添加到布局當(dāng)中。這樣的數(shù)據(jù)源就添加好了,實(shí)例化個(gè)適配器,然后ViewPager加載適配器即可。和列表顯示的原理很像。
private void initPager() {
ivList = new ArrayList<>();
pointList = new ArrayList<>();
for (int i = 0; i < imgIds.length; i++) {
ImageView iv = new ImageView(this);
iv.setImageResource(imgIds[i]);
iv.setScaleType(ImageView.ScaleType.FIT_XY);
// 設(shè)置圖片view的寬高
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
iv.setLayoutParams(lp);
// 將圖片view加載到集合中
ivList.add(iv);
// 創(chuàng)建圖片對(duì)應(yīng)的指示器小圓點(diǎn)
ImageView piv = new ImageView(this);
piv.setImageResource(R.drawable.point_normal);
LinearLayout.LayoutParams plp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
plp.setMargins(20, 0, 0, 0);
piv.setLayoutParams(plp);
// 將小圓點(diǎn)添加到布局當(dāng)中
pointLayout.addView(piv);
// 為了方便操作,將小圓點(diǎn)加入統(tǒng)一管理的集合
pointList.add(piv);
}
pointList.get(0).setImageResource(R.drawable.point_focus);
pagerAdapter = new PagerAdapter(this, ivList);
libraryVp.setAdapter(pagerAdapter);
}
2、 預(yù)定座位
在座位表設(shè)置這里,我構(gòu)思了很長(zhǎng)時(shí)間,到底使用什么控件來(lái)表示座位最好?TextView、Button還是RadioButton,思來(lái)想去最好決定還是RadioButton。那么問(wèn)題又來(lái)了,RadioGroup是繼承LinearLayout布局的,只能水平和垂直,所以導(dǎo)致了每一行都能選擇一個(gè)單選按鈕,這樣就和每位學(xué)生選一個(gè)座位矛盾了,如何解決?
根據(jù)之前在力扣刷題的經(jīng)驗(yàn),這里我們需要對(duì)每一行控件進(jìn)行設(shè)置,當(dāng)選中其中某一行的單選按鈕時(shí),取消其他行的狀態(tài),這樣實(shí)現(xiàn)雖然很繁瑣,但是很有效,主要是由于RadioGroup底層是LinearLayout,其中包含的RadioButton要么全水平要么全垂直,不能自定義排列方式。
根據(jù)數(shù)據(jù)庫(kù)中記錄的狀態(tài),設(shè)置所有單選按鈕的狀態(tài)。
// 遍歷所有單選按鈕
for (int i = 0; i < radioArray.length; i++) {
int id = radioArray[i].getId();
boolean ordered = false;
// 遍歷已選中的單選列表
for (int j = 0; j < seatList.size(); j++) {
if (seatList.get(j).getId() == id) {
radioArray[i].setBackgroundResource(R.drawable.bg_seats_ordered);
radioArray[i].setEnabled(false);
ordered = true;
break;
}
}
// 退訂座位后恢復(fù)可選
if (!ordered && !radioArray[i].isEnabled()) {
radioArray[i].setEnabled(true);
radioArray[i].setBackgroundResource(R.drawable.bg_seats);
}
}
單選按鈕的監(jiān)聽(tīng)器邏輯,夢(mèng)回當(dāng)年的力扣刷題。
// 每一組的監(jiān)聽(tīng)器
radioGroup1.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
// 清除其他組的選擇
for (int k = 0; k < radioGroups.length; k++) {
if (k == 0) continue;
if (radioGroups[k].getCheckedRadioButtonId() != -1) {
radioGroups[k].clearCheck();
}
}
// 獲取seat對(duì)象
seat = new Seat(i, account);
}
});
3、 查看座位
這里可以看到你的座位信息,如果沒(méi)有訂座則默認(rèn)顯示“暫無(wú)信息”。
這里的java文件實(shí)在太簡(jiǎn)單了,沒(méi)必要講了,提一下用到的數(shù)據(jù)庫(kù)方法,退訂的邏輯就是先找到它的樓層,然后在對(duì)應(yīng)的樓層表中刪除這個(gè)座位信息。
// 退訂
public void cancelFloor(Seat seat) {
String table[] = new String[]{"First", "Second", "Third"};
int index = getFloor(seat);
sqLiteDatabase.delete(table[index - 1], "account = ?", new String[] {seat.getAccount()});
}
4、個(gè)人信息
這里圖標(biāo)和TextView的背景的設(shè)置是最花時(shí)間的,布局倒非常簡(jiǎn)單。
定義兩個(gè)方法,進(jìn)行模式切換,就是利用enable這個(gè)屬性。
// 編輯模式,可以編輯
private void enableEditor() {
etName.setEnabled(true);
etAge.setEnabled(true);
etPhone.setEnabled(true);
etCollege.setEnabled(true);
btnSave.setVisibility(View.VISIBLE);
btnUpdate.setVisibility(View.INVISIBLE);
}
5、我的步數(shù)
這里使用了android傳感器技術(shù)和多線程,首先看下布局,雖然簡(jiǎn)單但是設(shè)計(jì)上還是額外花了1個(gè)多小時(shí),反復(fù)調(diào)整樣式。最上面是名言警句,調(diào)用的天行api接口,然后下面是步數(shù)顯示。
這里我們使用的是加速度傳感器,通過(guò)檢測(cè)加速度變化的峰值來(lái)判斷我們移動(dòng),從而記錄步數(shù),我們手機(jī)會(huì)有很多傳感器,比如:溫度傳感器、距離傳感器、角速度傳感器、重力傳感器等。下面是傳感器的使用模板:
sManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mSensorAccelerometer = sManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sManager.registerListener(this, mSensorAccelerometer, SensorManager.SENSOR_DELAY_UI);
我們創(chuàng)建client實(shí)例,然后創(chuàng)建一個(gè)request實(shí)例,封裝了url請(qǐng)求地址,使用newCall讓客戶端向服務(wù)器發(fā)送http請(qǐng)求,并且自動(dòng)放入子進(jìn)程中進(jìn)行請(qǐng)求。這樣,我們?cè)趏nResponse中得到服務(wù)器返回的具體內(nèi)容,然后解析數(shù)據(jù),在UI線程中更新數(shù)據(jù)。
public class HttpUtil {
public static void sendOkHttpRequest(String address, okhttp3.Callback callback) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(address)
.build();
client.newCall(request).enqueue(callback);
}
}
我們對(duì)獲取的數(shù)據(jù)進(jìn)行json解析,就像天氣預(yù)報(bào)、星座配對(duì)一樣,json數(shù)據(jù)其實(shí)就分為數(shù)組和對(duì)象,而且java幫我們封裝的非常好,使用GSON來(lái)處理非常簡(jiǎn)單方便。
// 使用gson解析數(shù)據(jù)
Aphorism aphorism = new Gson().fromJson(result, Aphorism.class);
Aphorism.NewslistDTO newslistDTO = aphorism.getNewslist().get(0);
String saying = newslistDTO.getSaying();
String transl = newslistDTO.getTransl();
String source = newslistDTO.getSource();
6、數(shù)據(jù)庫(kù)
數(shù)據(jù)庫(kù)名稱為library.db,一共有五張表,每張表的屬性主要是根據(jù)Bean實(shí)體類進(jìn)行設(shè)置。
// 創(chuàng)建用戶表User
public static final String CREATE_USER = "create table User ("
+ "account text primary key,"
+ "password text)";
// 創(chuàng)建一樓已預(yù)定座位表
public static final String CREATE_FIRST = "create table First ("
+ "id integer primary key,"
+ "account text)";
// 創(chuàng)建二樓已預(yù)定座位表
public static final String CREATE_SECOND = "create table Second ("
+ "id integer primary key,"
+ "account text)";
// 創(chuàng)建三樓已預(yù)定座位表
public static final String CREATE_THIRD = "create table Third ("
+ "id integer primary key,"
+ "account text)";
// 創(chuàng)建學(xué)生表Student
public static final String CREATE_STUDENT = "create table Student ("
+ "account text primary key,"
+ "name text,"
+ "age text,"
+ "phone text,"
+ "college text)";
五、運(yùn)行演示
1、運(yùn)行項(xiàng)目,進(jìn)入歡迎界面。
2、進(jìn)入登錄界面,我們點(diǎn)擊新用戶注冊(cè),進(jìn)入注冊(cè)界面。
3、進(jìn)入注冊(cè)界面,我們輸入學(xué)號(hào)和密碼之后,點(diǎn)擊注冊(cè),如果注冊(cè)成功則返回登錄界面。
4、注冊(cè)完學(xué)號(hào)和密碼都會(huì)被傳遞過(guò)來(lái),彈出“注冊(cè)成功”的消息,我們直接點(diǎn)擊登錄。
5、進(jìn)入主界面,頂上是輪播圖,一共五張精美圖片在自動(dòng)切換,我們也可以手動(dòng)切換,然后下面的小圓點(diǎn)就對(duì)應(yīng)了圖片的下標(biāo)。下面分別是四個(gè)功能欄。我們選擇1樓,然后點(diǎn)預(yù)訂座位。
6、進(jìn)入一樓座位表,我們可以選擇座位,選中會(huì)有顏色變化,然后點(diǎn)擊懸浮按鈕確定選座。
選擇某個(gè)座位時(shí),座位會(huì)變?yōu)樯钋嗌€有金色花邊。
7、我們預(yù)訂個(gè)6排1座的位置,成功預(yù)定會(huì)有提示信息。
8、因?yàn)槲覀兺粫r(shí)間最多只能預(yù)訂一個(gè)座位,所以再預(yù)約其他座位必須退掉已預(yù)訂的座位才行,否則會(huì)提示“你有預(yù)定的座位未退訂”。
9、返回主界面,點(diǎn)擊查看座位,可以看到我們座位的樓層和座位號(hào)。
10、點(diǎn)擊退訂,然后我們退出該界面,再次點(diǎn)擊查看信息,發(fā)現(xiàn)暫無(wú)信息。
11、點(diǎn)擊個(gè)人信息,進(jìn)入個(gè)人信息界面,點(diǎn)擊修改信息按鈕,進(jìn)入編輯模式,編輯完之后點(diǎn)擊保存按鈕,則進(jìn)入查看模式。
12、我們輸入個(gè)人信息,編輯完之后,點(diǎn)擊保存信息。
13、返回主界面,點(diǎn)擊進(jìn)入我的步數(shù),這里最上面是名人名言、譯文和出處。名人名言會(huì)每次在進(jìn)入該界面時(shí)都更新。下面是計(jì)步顯示。
14、我們點(diǎn)開(kāi)模擬器右側(cè)的省略號(hào),跳出Extended controls,然后點(diǎn)擊Virtual sensors,進(jìn)入虛擬傳感器界面。
15、點(diǎn)擊開(kāi)始計(jì)步,然后我們左側(cè)選擇Move模式,然后不斷左右拖動(dòng)Y的進(jìn)度條,因?yàn)槭謾C(jī)在豎直放置時(shí),Y軸是垂直于地面的,所以會(huì)產(chǎn)生加速度,進(jìn)而記錄步數(shù)。
16、點(diǎn)擊停止會(huì)清零步數(shù),重新計(jì)步。
17、我們點(diǎn)擊退出登錄,然后再注冊(cè)個(gè)用戶111,點(diǎn)擊預(yù)訂座位,進(jìn)入座位表,可以看到6排1座已經(jīng)無(wú)法選中了,因?yàn)楸?23用戶預(yù)訂了。我們選擇3排2座,然后預(yù)訂。
18、再次進(jìn)入選座界面,可以看到這兩個(gè)座位都變?yōu)榛疑珶o(wú)法選中了。
19、三層樓的座位布局都不盡相同,我們可以查看二樓、三樓的座位表,和一樓有很大差別。
六、項(xiàng)目總結(jié)
本次項(xiàng)目使用了ViewPager、Sqlite、FloatingButton、RadioGroup、Http請(qǐng)求、Adapter、Sensor等知識(shí)。相對(duì)來(lái)說(shuō)還是很簡(jiǎn)單的,與之前不同的主要是Sensor傳感器這一項(xiàng),其實(shí)Android知識(shí)非常多,想要深入學(xué)習(xí)學(xué)通還需要花很長(zhǎng)時(shí)間。不過(guò)我個(gè)人來(lái)看,程序開(kāi)發(fā)相對(duì)于深度學(xué)習(xí)搞算法來(lái)說(shuō)還是非常容易的,畢竟創(chuàng)造有突破性的算法比創(chuàng)造新的軟件要難100倍。
七、源碼獲取
關(guān)注公眾號(hào)《萌新加油站》,后臺(tái)回復(fù):訂座
點(diǎn)此直接下載源碼:??Android Studio實(shí)現(xiàn)圖書館訂座系統(tǒng)文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-463259.html
??這有你錯(cuò)過(guò)的精彩內(nèi)容文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-463259.html
??這有你錯(cuò)過(guò)的精彩內(nèi)容?? |
---|
Android Studio實(shí)現(xiàn)五子棋小游戲 |
Android Studio實(shí)現(xiàn)知乎日?qǐng)?bào)App |
Android Studio實(shí)現(xiàn)訂餐系統(tǒng) |
Android Studio實(shí)現(xiàn)倉(cāng)庫(kù)管理系統(tǒng) |
Android Stduio實(shí)現(xiàn)天氣預(yù)報(bào)系統(tǒng) |
到了這里,關(guān)于Android Studio實(shí)現(xiàn)圖書館訂座系統(tǒng)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!