Android 行程APP简单介绍
?
登錄模塊
- ?數據庫設計
? ?
? ? ? ? 如圖所示創建了如上的數據庫由于沒有注冊功能人為添加了兩個用戶:
數據庫創建語句:
public static final String CREATE_task ="create table user ("+ "id integer primary key autoincrement, "+"remenberPassword text,"+"autoLogin text,"+ "username text, "+ "password text"+ ")";public static final String CREATE_task2 ="create table Travel ("+ "id integer primary key autoincrement, "+ "travelName text, "+ "content text,"+ "traveldate date,"+ "userID integer"+ ")"; @Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL(CREATE_task);db.execSQL(CREATE_task2);}與數據庫對應創建了兩個對應于兩張表的數據庫操作DBBean:代碼如下:
????????插入語句:
public long insert(TravelBean travel) {ContentValues newValues =new ContentValues();newValues.put("content", travel.getContent());newValues.put("traveldate",travel.getTraveldate());newValues.put("travelName",travel.getTravelName()); newValues.put("userID",travel.getUserID()); return db.insert(DB_Table, null, newValues); }根據用戶名加載全部行程的語句,此處加載按時間排序進行加載:
public TravelBean[] LoadAllData(String Uername) {Cursor result =db.query( DB_Table, new String[] {"id","travelName","content","traveldate","userID"}, “userID”+” = ”+Uername , null, null, null,"traveldate desc");return ConvertToTravelBean(result);}根據返回的游標,將數據封裝進對象語句:
private TravelBean[] ConvertToTravelBean(Cursor result) {// TODO Auto-generated method stubint resultCounts=result.getCount();if(resultCounts==0||!result.moveToFirst()) {return null;}TravelBean[] travel=new TravelBean[resultCounts]; for(int i=0;i<resultCounts;i++) {travel[i]=new TravelBean();travel[i].setContent(result.getString(result.getColumnIndex("content")));travel[i].setTravelName(result.getString(result.getColumnIndex("travelName")));travel[i].setTraveldate(result.getString(result.getColumnIndex("traveldate")));travel[i].setUserID(result.getString(result.getColumnIndex("userID"))); travel[i].setID(result.getString(result.getColumnIndex("id"))); System.out.println(travel[i].getTravelName());result.moveToNext(); }return travel;}根據travel的ID號修改旅行名稱、內容、時間語句:
public void updateOneData(String travelName,String content,String traveldate,String id) {ContentValues updateValues=new ContentValues();updateValues.put("content", content);updateValues.put("travelName", travelName);updateValues.put("traveldate", traveldate);db.update(DB_Table, updateValues, "id"+" = " +id, null);}根據旅行的ID號刪除一條旅行記錄:
public long deleteOneData(String id) {return db.delete(DB_Table, "id"+" ="+id, null);}Uer對應的UserDBBean
????創建數據庫,并返回一個SQLIteDatabse對象供給TravelDBean使用:
public SQLiteDatabase open() throws SQLiteException{dbOpenhelper=new MyDatabaseHelper(context, DB_NAME, null, DB_VERSION);try {db=dbOpenhelper.getWritableDatabase();return db;}catch(SQLiteException e) {db=dbOpenhelper.getReadableDatabase();return db;}}插入用戶對象,注冊功能為實現,但需要插入兩個用戶進行測試:
public long insert(UserBean user) {ContentValues newValues =new ContentValues();newValues.put("remenberPassword", user.getRemenberPassword());newValues.put("password",user.getPassword());newValues.put("username",user.getUsername()); newValues.put("autoLogin",user.getAutoLogin());return db.insert(DB_Table, null, newValues); }根據用戶名加載用戶:
public UserBean queryByUsername(String username) {UserBean userBean=null;Cursor result =db.query( DB_Table, new String[] {"username","password","remenberPassword","autoLogin"}, "username"+" = '"+username+"'", null, null, null,null);if(result.getCount()!=0) {result.moveToFirst();userBean=new UserBean();userBean.setPassword(result.getString(1));userBean.setAutoLogin(result.getString(3));userBean.setRemenberPassword(result.getString(2));userBean.setUsername(username); }return userBean;}?根據用戶名來更新記住密碼、自動登陸的狀態
public void updateOneData(String username,String remenberPassword,String autoLogin ) {if(username!=null) {ContentValues updateValues=new ContentValues();updateValues.put("autoLogin", autoLogin);updateValues.put("remenberPassword", remenberPassword);db.update(DB_Table, updateValues, "username"+" = " +username, null);}else {return;} }兩個用來封裝數據的實體Bean,代碼如下:
UserBean:
public class UserBean {private String id="";private String username="";private String password="";private String remenberPassword="";private String autoLogin="";public String getRemenberPassword() {return remenberPassword;}public void setRemenberPassword(String remenberPassword) {this.remenberPassword = remenberPassword;}public String getAutoLogin() {return autoLogin;}public void setAutoLogin(String autoLogin) {this.autoLogin = autoLogin;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}}TravelBean:
public class TravelBean {private String ID="";private String travelName="";private String content="";private String traveldate="";private String userID="";public String getID() {return ID;}public void setID(String iD) {ID = iD;}public String getTravelName() {return travelName;}public void setTravelName(String travelName) {this.travelName = travelName;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public String getTraveldate() {return traveldate;}public void setTraveldate(String traveldate) {this.traveldate = traveldate;}public String getUserID() {return userID;}public void setUserID(String userID) {this.userID = userID;}}- 登錄界面設計? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
?登錄界面?源代碼
<TextViewandroid:layout_width="match_parent"android:layout_height="50dp"android:text="登錄界面"android:gravity="center"android:textSize="30sp"/><View android:layout_width="match_parent" android:layout_height="1dp"android:background="@color/orange_main"/> <RelativeLayoutandroid:layout_width="match_parent"android:layout_height="50dp"android:layout_marginLeft="32dp"android:layout_marginRight="32dp"android:layout_marginTop="120dp"><ImageViewandroid:id="@+id/img_account"android:layout_width="19dp"android:layout_height="20dp"android:layout_alignParentBottom="true"android:layout_marginBottom="4dp"android:layout_marginLeft="4dp"android:scaleType="fitXY"android:src="@drawable/icon_login_account"/><EditTextandroid:id="@+id/et_account"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_gravity="center"android:layout_marginBottom="4dp"android:layout_marginLeft="12dp"android:layout_toRightOf="@+id/img_account"android:background="@null"android:hint="@string/account"android:maxLines="1"android:textColor="@android:color/black"android:textColorHint="@color/tv_gray_deep"android:textSize="14dp"/><Viewandroid:layout_width="match_parent"android:layout_height="1dp"android:layout_alignParentBottom="true"android:layout_marginLeft="12dp"android:layout_toRightOf="@+id/img_account"android:background="@color/orange_light"/></RelativeLayout><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="50dp"android:layout_marginLeft="32dp"android:layout_marginRight="32dp"><ImageViewandroid:id="@+id/img_pw"android:layout_width="18dp"android:layout_height="20dp"android:layout_alignParentBottom="true"android:layout_marginBottom="4dp"android:layout_marginLeft="4dp"android:scaleType="fitXY"android:src="@drawable/icon_login_pw"/><EditTextandroid:id="@+id/et_password"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_gravity="center"android:layout_marginBottom="4dp"android:layout_marginLeft="12dp"android:layout_toRightOf="@+id/img_pw"android:background="@null"android:hint="@string/password"android:inputType="textPassword"android:maxLines="1"android:textColor="@android:color/black"android:textColorHint="@color/tv_gray_deep"android:textSize="14dp"/><ImageViewandroid:id="@+id/iv_see_password"android:layout_width="20dp"android:layout_height="20dp"android:src="@drawable/image_password_bg"android:layout_centerVertical="true"android:layout_alignParentRight="true"android:scaleType="fitXY"/><Viewandroid:layout_width="match_parent"android:layout_height="1dp"android:layout_alignParentBottom="true"android:layout_marginLeft="12dp"android:layout_toRightOf="@+id/img_pw"android:background="@color/orange_light"/></RelativeLayout> <CheckBoxandroid:id="@+id/checkBox_password"android:padding="10dp"android:textSize="14dp"android:layout_gravity="center"android:layout_width="wrap_content"android:layout_weight="1"android:layout_height="wrap_content"android:text="@string/check_password"android:textColor="@color/top_bar_normal_bg" android:checked="false"/><CheckBoxandroid:id="@+id/checkBox_login"android:padding="10dp"android:textSize="14dp"android:layout_gravity="center"android:layout_width="wrap_content"android:layout_weight="1"android:layout_height="wrap_content"android:text="@string/check_login"android:textColor="@color/top_bar_normal_bg" android:checked="false"/>??????登錄界面功能
? ? ? ? ? ?登錄界面可隱藏顯示密碼:
? 實現代碼:首先構建一個選擇器,選擇器代碼如下:
<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:drawable="@drawable/icon_see_pass" android:state_selected="false"/><item android:drawable="@drawable/icon_nosee_pass" android:state_selected="true"/></selector>然后在Login.xml文件中調用該選擇器:
<ImageViewandroid:id="@+id/iv_see_password"android:layout_width="20dp"android:layout_height="20dp"android:src="@drawable/image_password_bg"android:layout_centerVertical="true"android:layout_alignParentRight="true"android:scaleType="fitXY" />最后通過設置該選擇器控件的點擊事件,來達到顯示密碼,與不顯示密碼,此時要更換圖片的狀態,以及設置密碼框的?setInputType類型,來使密碼可見。具體代碼如下:
if (iv_see_password.isSelected()) {iv_see_password.setSelected(false);//密碼不可見et_password.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);} else {iv_see_password.setSelected(true);//密碼可見et_password.setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);}? ? ? ? ?登錄界面可記住密碼、自動登陸:
? ?由以上兩張圖片登錄成功后注銷登陸回來仍然顯示當前密碼:
由兩張圖片用戶選擇自動登陸,登錄之后,退出APP,在進去自動登陸。若注銷,則自動登陸狀態自動取消,方便用戶更換賬號。
輸入密碼錯悟提示如上圖所示:
實現代碼思想如下:
我點擊登陸后,會向數據庫更新用戶的記下密碼、自動登陸的狀態,并且將當前用戶的賬號用SharedPreferences類更新在xml配置文件(保存上一次登陸的賬號)中,用戶登陸之前從數據庫中根據根xml配置文件中保存的用戶賬號把用戶所有信息加載出來,并封裝在User對象中,我根據此User的記下密碼、自動登陸的狀態,做出相應的處理;首先將賬號加載到用戶控件,然后若記下密碼我就將密碼顯示到密碼控件上,若是自動登陸,那么直接進行Login()登陸方法。具體代碼如下:
?查找上一次加載的用戶,并從數據庫中將此用戶所有信息獲取。
SharedPreferencesUtils helper = new SharedPreferencesUtils(this, "setting");String lastLoginUserName = helper.getString("name");System.out.println("lastLoginUserName"+lastLoginUserName);user= userBean.queryByUsername(lastLoginUserName);驗證該用戶記住密碼、自動登陸的狀態:
//判斷是否記住密碼if (remenberPassword()) {checkBox_password.setChecked(true);//勾選記住密碼setTextNameAndPassword();//把密碼和賬號輸入到輸入框中} else {setTextName();//把用戶賬號放到輸入賬號的輸入框中}//判斷是否自動登錄if (autoLogin()) {checkBox_login.setChecked(true);login();//去登錄就可以}判斷記住密碼方法代碼如下:
private boolean remenberPassword() {if(user.getRemenberPassword().equals("ture"))return true;elsereturn false;}將密碼以及賬號更新UI界面,代碼如下:
public void setTextNameAndPassword() {UserBean user1=userBean.queryByUsername(user.getUsername());if(user1!=null) {et_name.setText("" +user1.getUsername());et_password.setText("" + user1.getPassword());}}只用賬戶更新UI界面,代碼如下:
public void setTextName() {UserBean user1=userBean.queryByUsername(user.getUsername());if(user1!=null) {et_name.setText("" + user1.getUsername());}}判斷用戶的自動登陸狀態,代碼如下:
private boolean autoLogin() {//獲取SharedPreferences對象,使用自定義類的方法來獲取對象if(user!=null) {if(user.getAutoLogin().equals("true")) {return true;}}return false;}? ? ? ?重寫記住密碼、與自動登陸的狀態改變監聽函數:做到,如選擇自動登陸,那么記住密碼應自動被勾選,如果取消記住密碼,那么自動登陸也將自動取消。重寫OnCheckedChangeListener函數:具體代碼如下:
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {if (buttonView == checkBox_password) { //記住密碼選框發生改變時if (!isChecked) { //如果取消“記住密碼”,那么同樣取消自動登陸checkBox_login.setChecked(false);}} else if (buttonView == checkBox_login) { //自動登陸選框發生改變時if (isChecked) { //如果選擇“自動登錄”,那么同樣選中“記住密碼”checkBox_password.setChecked(true);}}}登錄成功獲取失敗的消息提示,代碼如下:
public void showToast(final String msg) {runOnUiThread(new Runnable() {@Overridepublic void run() {Toast.makeText(LoginActivity.this, msg, Toast.LENGTH_SHORT).show();}});}自動登錄部分,先驗證賬號密碼是不是為空,在進行登陸。若為空消息提示登陸失敗。
若不為空且校驗成功,則將進行頁面跳轉,并將用戶名帶過去。此處因為不涉及更新UI但是要訪問數據庫,就創建了一個子線程處理登錄模塊。具體代碼如下:
private void login() {//先做一些基本的判斷,比如輸入的用戶命為空,密碼為空,若是直接返回提示錯誤if (et_name.getText().toString().trim().isEmpty()){showToast("你輸入的賬號為空!");return;}if (et_password.getText().toString().trim().isEmpty()){showToast("你輸入的密碼為空!");return;}Thread loginRunnable = new Thread() {@Overridepublic void run() {super.run();mLoginBtn.setClickable(false);//點擊登錄后,設置登錄按鈕不可點擊狀態//睡眠2秒try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}user= userBean.queryByUsername(et_name.getText().toString().trim());//判斷賬號和密碼if (et_name.getText().toString().trim().equals(user.getUsername()) &&et_password.getText().toString().trim().equals(user.getPassword())) {showToast("登錄成功");loadCheckBoxState();//記錄下當前用戶記住密碼和自動登錄的狀態;SharedPreferencesUtils helper = new SharedPreferencesUtils(LoginActivity.this, "setting");helper.putValues(new SharedPreferencesUtils.ContentValue("name", et_name.getText().toString().trim()));//將上一次登陸人的賬號存入xml文件Intent intent=new Intent(LoginActivity.this, LoginAfterActivity.class);intent.putExtra("username", et_name.getText().toString().trim());startActivity(intent);finish();//關閉頁面} else {System.out.println("username"+user.getUsername());System.out.println("password"+user.getPassword());showToast("輸入的登錄賬號或密碼不正確");}mLoginBtn.setClickable(true); //這里解放登錄按鈕,設置為可以點擊}};loginRunnable.start();}???????行程界面模塊
- 行程界面就一個自定義標題組件,與一個ListView組件,具體代碼如下:
自定義組件代碼如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="horizontal" ><TextViewandroid:id="@+id/textView1"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="行程安排" android:textColor="@color/black_translucent"android:textSize="30dp" android:gravity="center"android:textAlignment="center"/></LinearLayout>- 行程界面功能實現:截圖
登錄之后,按下”注銷“返回登陸界面。
添加完條記錄,點擊添加出來一跳添加框,填好信息點擊”保存“如下圖按時間最大往低排序顯示,如下圖所示:
選中最后一條信息進行刪除,之后,如上圖顯示:下面進行修改操作:將”baixue“的行程內容更改為”chifan“:
從上圖看到數據庫中數據已經改變。
? ?2. 增加行程的功能代碼主要是增加一行TableRow組件,里面內嵌三個EditText組件和一個保存按鈕組件,保存按鈕實現,點擊保存那么,將數據插入到數據庫,將此組件從TableRowLsit鏈表中刪除,從數據庫重新加載全部數據更新UI界面:
addTravel.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {clear();TableRow tableRow=new TableRow(LoginAfterActivity.this);tableRow.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));final MyEditText et1=new MyEditText(LoginAfterActivity.this,(int)(0.25*ScreenWidth));final MyEditText et2=new MyEditText(LoginAfterActivity.this,(int)(0.25*ScreenWidth));final MyEditText et3=new MyEditText(LoginAfterActivity.this,(int)(0.25*ScreenWidth));tableRow.addView(et1);tableRow.addView(et2);tableRow.addView(et3);final TravelBean travel=new TravelBean();Button save=new Button(LoginAfterActivity.this);save.setText("保存");tableRow.addView(save);tableRowList.add(2,tableRow);save.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {travel.setUserID(username);travel.setTravelName(et1.getText().toString());travel.setContent(et2.getText().toString());travel.setTraveldate(et3.getText().toString());System.out.println("我被觸發了");travelDB.insert(travel);tableRowList.remove(2);queryAll(); }});/*updateButtonList.add(update);*/queryAll(); }});queryAll();System.out.println("列表長度為:"+tableRowList.size());}???????3.?加載所有數據更新UI界面,若有數據那么將數據加載到界面,并且動態創建刪除、修改按鈕,并注冊監聽事件;刪除按鈕:從數據庫中刪除該條記錄,并回調”加載全部函數“更新界面。修改按鈕:根據記錄ID號,對該行程記錄進行更新。具體代碼如下
public void queryAll() {/*lv.removeAllViews();*/if(!firstLogin)clear();//清除ListView原來的組件firstLogin=false;final TravelBean[] sf= travelDB.LoadAllData(username);/*TextView tvNew=new TextView(this);*//*tvNew.setText("沒有數據");*/if(sf!=null) {for( int i=0;i<sf.length;i++) {System.out.println("共有:"+i);/*"ID:"+sf[i].getId()+*/TableRow tr=new TableRow(this);final MyEditText et1=new MyEditText(LoginAfterActivity.this,(int)(0.25*ScreenWidth));et1.setText(" "+sf[i].getTravelName());final MyEditText et2=new MyEditText(LoginAfterActivity.this,(int)(0.25*ScreenWidth));et2.setText(sf[i].getContent());final MyEditText et3=new MyEditText(LoginAfterActivity.this,(int)(0.25*ScreenWidth));et3.setText(sf[i].getTraveldate());Button update=new Button(this);update.setText("修改");final TravelBean sfman=sf[i];final String id=sf[i].getID();update.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {travelDB.updateOneData(et1.getText().toString(),et2.getText().toString(),et3.getText().toString(),id); }});/*updateButtonList.add(update);*/Button delete=new Button(this);delete.setText("刪除");delete.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubtravelDB.deleteOneData(sfman.getID());queryAll();}});tr.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));tr.addView(et1);tr.addView(et2);tr.addView(et3);tr.addView(update);tr.addView(delete);tableRowList.add(tr);}}mAdapter.setTableRowList1(tableRowList);//清空ListView鏈表/*mAdapter.setTableRowList(tableRowList);*/lv.setAdapter(mAdapter);}???????4.?根據屏幕大小調整動態創建的組件的寬度,具體代碼如下:
??獲取當前屏幕寬度:
WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);DisplayMetrics dm = new DisplayMetrics();wm.getDefaultDisplay().getMetrics(dm);ScreenWidth = dm.widthPixels; // 屏幕寬度(dp)ScreenHeight = dm.heightPixels;// 屏幕高度(dp)?對創建的組件寬度進行設置:
text1.setWidth((int)(0.25*ScreenWidth)); Text2.setWidth((int)(0.25*ScreenWidth)); Text3.setWidth((int)(0.25*ScreenWidth)); Text4.setWidth((int)(0.25*ScreenWidth)); final MyEditText et1=new MyEditText(LoginAfterActivity.this,(int)(0.25*ScreenWidth)); final MyEditText et2=new MyEditText(LoginAfterActivity.this,(int)(0.25*ScreenWidth)); final MyEditText et3=new MyEditText(LoginAfterActivity.this,(int)(0.25*ScreenWidth));清除TableRowList中的除注銷登陸、增加行程、和標題欄之外的所有TableRow組件。
public void clear() {if(tableRowList.size()!=0&&tableRowList!=null) {for(int i=0;i<tableRowList.size();i++) {if(tableRowList.get(i).getChildCount()==5) {tableRowList.remove(i);i--;}}}}?
總結
以上是生活随笔為你收集整理的Android 行程APP简单介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue warning如何去掉_详解 v
- 下一篇: textlayout Java_Java