最近作一個登陸的界面,我腦子裏一下就想到QQ的登陸界面,簡單,美觀,因此就找了些資料實現了下,如今整理下android
先來看下效果圖數據庫
1.首先是佈局文件XML文件,不解釋直接上dom
1>主界面ide
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:background="@drawable/back_groud" > 6 7 <LinearLayout 8 android:layout_width="match_parent" 9 android:layout_height="wrap_content" 10 android:layout_above="@+id/login_data_layout" 11 android:layout_marginBottom="30dp" 12 android:gravity="center" 13 android:orientation="horizontal" > 14 15 <ImageView 16 android:layout_width="wrap_content" 17 android:layout_height="wrap_content" 18 android:src="@drawable/logo" /> 19 20 </LinearLayout> 21 22 <LinearLayout 23 android:id="@+id/login_data_layout" 24 android:layout_width="match_parent" 25 android:layout_height="wrap_content" 26 android:layout_centerInParent="true" 27 android:background="@drawable/logindata_back_groud" 28 android:orientation="vertical" > 29 30 <LinearLayout 31 android:id="@+id/username_layout" 32 android:layout_width="match_parent" 33 android:layout_height="match_parent" 34 android:layout_marginLeft="10dp" 35 android:layout_marginRight="10dp" 36 android:layout_weight="1" 37 android:gravity="center_vertical" 38 android:orientation="horizontal" > 39 40 <TextView 41 android:layout_width="wrap_content" 42 android:layout_height="wrap_content" 43 android:layout_gravity="center_vertical" 44 android:layout_marginLeft="15dp" 45 android:text="帳 號" 46 android:textColor="#b3b3b3" 47 android:textSize="16dp" /> 48 49 <EditText 50 android:id="@+id/login_edit_userName" 51 android:layout_width="match_parent" 52 android:layout_height="wrap_content" 53 android:layout_gravity="center_vertical" 54 android:layout_marginLeft="20dp" 55 android:layout_marginRight="20dp" 56 android:layout_weight="1" 57 android:background="@null" 58 android:singleLine="true" /> 59 60 <RelativeLayout 61 android:layout_width="wrap_content" 62 android:layout_height="wrap_content" 63 android:layout_weight="2.5" > 64 65 <Button 66 android:id="@+id/down_but" 67 android:layout_width="24dp" 68 android:layout_height="24dp" 69 android:layout_alignParentRight="true" 70 android:layout_marginRight="8dp" 71 android:background="@drawable/down_img" /> 72 </RelativeLayout> 73 </LinearLayout> 74 75 <LinearLayout 76 android:layout_width="match_parent" 77 android:layout_height="match_parent" 78 android:layout_marginLeft="25dp" 79 android:layout_marginRight="10dp" 80 android:layout_weight="1" 81 android:gravity="center_vertical" 82 android:orientation="horizontal" > 83 84 <TextView 85 android:layout_width="wrap_content" 86 android:layout_height="wrap_content" 87 android:layout_gravity="center_vertical" 88 android:text="密 碼" 89 android:textColor="#b3b3b3" 90 android:textSize="16dp" /> 91 92 <EditText 93 android:id="@+id/login_edit_password" 94 android:layout_width="match_parent" 95 android:layout_height="wrap_content" 96 android:layout_gravity="center_vertical" 97 android:layout_marginLeft="20dp" 98 android:layout_marginRight="20dp" 99 android:background="@null" 100 android:inputType="textPassword" 101 android:singleLine="true" /> 102 </LinearLayout> 103 </LinearLayout> 104 105 <Button 106 android:id="@+id/login_but_landing" 107 android:layout_width="match_parent" 108 android:layout_height="wrap_content" 109 android:layout_below="@+id/login_data_layout" 110 android:layout_marginTop="30dp" 111 android:background="@drawable/login_but_bg" 112 android:text="登 錄" 113 android:textColor="#ffffff" 114 android:textSize="18dp" /> 115 116 </RelativeLayout>
2>浮動窗口界面及其子界面函數
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="wrap_content" 5 android:orientation="vertical" 6 android:gravity="center_horizontal" > 7 8 <ListView 9 android:layout_width="match_parent" 10 android:layout_height="wrap_content" 11 android:id="@+id/list" 12 android:background="@drawable/list_backgroud" 13 ></ListView> 14 15 16 </LinearLayout>
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" > 5 6 <RelativeLayout 7 android:layout_width="wrap_content" 8 android:layout_height="40dp" 9 android:gravity="center_vertical" > 10 11 <Button 12 android:id="@+id/del_but" 13 android:layout_width="25dp" 14 android:layout_height="25dp" 15 android:layout_alignParentRight="true" 16 android:layout_marginRight="15dp" 17 android:background="@drawable/del_but_bg" /> 18 19 <TextView 20 android:id="@+id/tv" 21 android:layout_width="wrap_content" 22 android:layout_height="wrap_content" 23 android:layout_alignParentLeft="true" 24 android:layout_marginLeft="15dp" 25 android:layout_toLeftOf="@+id/del_but" 26 android:textSize="16dp" /> 27 </RelativeLayout> 28 29 </LinearLayout>
2.JAVA代碼佈局
先看下類的結構,代碼中基本都有註釋。我就一次將代碼貼出來。this
1 public class LoginTest_Activity extends Activity implements Callback { 2 3 private PopupWindow mPopupWindow;// 浮動窗口 4 private UOptionsAdapter mOptionsAdapter;//適配器 5 private List<String> mUserNames;// 保存用戶名 6 private List<String> mPassWords;// 保存密碼 7 private List<DBLoginInfoObj> infoObjs;// 保存登錄信息數據對象 8 private LinearLayout parent;//浮動窗口依附佈局 9 private int pwidth;// 浮動寬口的寬度 10 11 private EditText login_edit_userName;// 帳號輸入框 12 private EditText login_edit_password;// 密碼輸入框 13 private Button down_but; 14 private Button login_but; 15 private Handler mHandler;// 處理消息更新UI 16 private boolean init_flag = false;// 浮動窗口顯示標示符 17 private static final String TBL_LOGIN_INFO = "LoginInfo";// 用戶登錄信息 18 19 @Override 20 protected void onCreate(Bundle savedInstanceState) { 21 super.onCreate(savedInstanceState); 22 setContentView(R.layout.activity_logintest); 23 // 初始化 24 this.mUserNames = new ArrayList<String>(); 25 this.mPassWords = new ArrayList<String>(); 26 this.infoObjs = new ArrayList<DBLoginInfoObj>(); 27 this.mHandler = new Handler(this); 28 } 29 30 /** 31 * 在此方法中初始化能夠得到輸入框的寬度,以便於建立一樣寬的浮動窗口 32 */ 33 @Override 34 public void onWindowFocusChanged(boolean hasFocus) { 35 // TODO Auto-generated method stub 36 super.onWindowFocusChanged(hasFocus); 37 while (!init_flag) { 38 // 初始化UI 39 initWedget(); 40 // 初始化浮動窗口 41 initPopuWindow(); 42 init_flag = true; 43 } 44 } 45 46 /** 47 * 初始化UI控件 48 */ 49 private void initWedget() { 50 // 浮動窗口依附的佈局 51 this.parent = (LinearLayout) this.findViewById(R.id.username_layout); 52 this.login_edit_userName = (EditText) this 53 .findViewById(R.id.login_edit_userName); 54 this.login_edit_password = (EditText) this 55 .findViewById(R.id.login_edit_password); 56 this.down_but = (Button) this.findViewById(R.id.down_but); 57 login_but = (Button) this.findViewById(R.id.login_but_landing); 58 // 獲取登錄數據 59 getData(); 60 this.login_edit_userName.setText(this.mUserNames.get(0)); 61 this.login_edit_password.setText(this.mPassWords.get(0)); 62 63 // 獲取地址輸入框的寬度,用於建立浮動窗口的寬度 64 int w = parent.getWidth(); 65 pwidth = w; 66 67 down_but.setOnClickListener(Listener_but); 68 login_but.setOnClickListener(Listener_but); 69 70 } 71 72 /** 73 * 初始化浮動窗口 74 */ 75 public void initPopuWindow() { 76 // 浮動窗口的佈局 77 View loginwindow = (View) this.getLayoutInflater().inflate( 78 R.layout.activity_options, null); 79 ListView listView = (ListView) loginwindow.findViewById(R.id.list); 80 // 初始化適配器 81 this.mOptionsAdapter = new UOptionsAdapter(LoginTest_Activity.this, 82 mUserNames, mHandler); 83 listView.setAdapter(mOptionsAdapter); 84 // 定義一個浮動窗口,並設置 85 this.mPopupWindow = new PopupWindow(loginwindow, pwidth, 86 LayoutParams.WRAP_CONTENT, true); 87 this.mPopupWindow.setOutsideTouchable(true); 88 this.mPopupWindow.setBackgroundDrawable(new BitmapDrawable()); 89 90 } 91 92 /** 93 * 獲取登陸用戶名數據 94 */ 95 private void getData() { 96 //獲取數據對象 97 LoginInfoHandler mHandler = LoginInfoHandler 98 .create(LoginTest_Activity.this); 99 this.infoObjs = mHandler.getLoginInfoObj(); 100 for (int i = 0; i < this.infoObjs.size(); i++) { 101 this.mUserNames.add(this.infoObjs.get(i).getUserName()); 102 this.mPassWords.add(this.infoObjs.get(i).getPassword()); 103 } 104 105 } 106 107 /** 108 * 按鈕點擊事件 109 */ 110 OnClickListener Listener_but = new OnClickListener() { 111 112 @Override 113 public void onClick(View v) { 114 // TODO Auto-generated method stub 115 switch (v.getId()) { 116 case R.id.down_but:// 浮動地址下拉框按鈕事件 117 if (init_flag) { 118 // 顯示浮動窗口 119 mPopupWindow.showAsDropDown(parent, 0, -3); 120 } 121 break; 122 case R.id.login_but_landing:// 登陸按鈕事件 123 // 登陸成功將數據保存到SQLite中 124 ContentValues values = new ContentValues(); 125 String userName = login_edit_userName.getText().toString(); 126 String passWord = login_edit_password.getText().toString(); 127 values.put("UserName", userName); 128 values.put("PassWord", passWord); 129 DBHelper dbHelper = new DBHelper(LoginTest_Activity.this); 130 // 第一次登錄直接保存 131 if (mUserNames.size() == 0) { 132 dbHelper.insert(values, TBL_LOGIN_INFO); 133 } else { 134 // 標示符是否要插入 135 boolean flag = false; 136 // 判斷當前用戶名是否在數據庫存在 137 LoginInfoHandler mHandler = LoginInfoHandler 138 .create(LoginTest_Activity.this); 139 List<DBLoginInfoObj> info = mHandler.getLoginInfoObj(); 140 for (int i = 0; i < info.size(); i++) { 141 String username = info.get(i).getUserName(); 142 if (userName.equals(username)) { 143 flag = true; 144 } 145 } 146 if (!flag) { 147 dbHelper.insert(values, TBL_LOGIN_INFO); 148 } 149 } 150 Toast.makeText(LoginTest_Activity.this, "登錄成功", 1); 151 break; 152 153 } 154 155 } 156 }; 157 158 /** 159 * 處理浮動窗口傳回來的數據 160 * 161 * @param msg 162 * @return 163 */ 164 @Override 165 public boolean handleMessage(Message msg) { 166 // TODO Auto-generated method stub 167 Bundle bundle = msg.getData(); 168 DBHelper dbHelper = new DBHelper(LoginTest_Activity.this); 169 switch (msg.what) { 170 case 1:// 根據返回的id,將數據顯示在輸入框中 171 int sel_id = bundle.getInt("sel_id"); 172 int _id = infoObjs.get(sel_id).getID(); 173 String UserName = infoObjs.get(sel_id).getUserName(); 174 String PassWord = infoObjs.get(sel_id).getPassword(); 175 // 先刪除再插入 176 dbHelper.del(_id, TBL_LOGIN_INFO); 177 login_edit_userName.setText(UserName); 178 login_edit_password.setText(PassWord); 179 mPopupWindow.dismiss(); 180 break; 181 case 2:// 根據返回的ID,刪除數據 182 int del_id = bundle.getInt("del_id"); 183 int id = infoObjs.get(del_id).getID(); 184 dbHelper.del(id, TBL_LOGIN_INFO); 185 mUserNames.remove(del_id); 186 mOptionsAdapter.notifyDataSetChanged(); 187 break; 188 } 189 return false; 190 }
1 public class UOptionsAdapter extends BaseAdapter { 2 3 private Context mContext; 4 private List<String> mDtatList;// 顯示數據 5 private Handler mHandler;// 傳遞消息 6 7 public UOptionsAdapter(Context context, List<String> list, Handler handler) { 8 // TODO Auto-generated constructor stub 9 this.mContext = context; 10 this.mDtatList = list; 11 this.mHandler = handler; 12 } 13 14 @Override 15 public int getCount() { 16 // TODO Auto-generated method stub 17 return mDtatList.size(); 18 } 19 20 @Override 21 public Object getItem(int position) { 22 // TODO Auto-generated method stub 23 return mDtatList.get(position); 24 } 25 26 @Override 27 public long getItemId(int position) { 28 // TODO Auto-generated method stub 29 return position; 30 } 31 32 @Override 33 public View getView(int position, View convertView, ViewGroup parent) { 34 // TODO Auto-generated method stub 35 ViewHolder holder = null; 36 if (convertView == null) { 37 holder = new ViewHolder(); 38 convertView = LayoutInflater.from(mContext).inflate( 39 R.layout.option_item, null); 40 holder.textView = (TextView) convertView.findViewById(R.id.tv); 41 holder.button = (Button) convertView.findViewById(R.id.del_but); 42 43 convertView.setTag(holder); 44 } else { 45 holder = (ViewHolder) convertView.getTag(); 46 } 47 48 // 給textView和button設置惟一標示 49 holder.textView.setTag(position); 50 holder.button.setTag(position); 51 holder.textView.setText(mDtatList.get(position)); 52 holder.textView.setOnClickListener(new View.OnClickListener() { 53 54 @Override 55 public void onClick(View v) { 56 // TODO Auto-generated method stub 57 Message msg = new Message(); 58 Bundle bundle = new Bundle(); 59 int id = Integer.parseInt(v.getTag().toString()); 60 bundle.putInt("sel_id", id); 61 msg.setData(bundle); 62 msg.what = 1; 63 mHandler.sendMessage(msg); 64 } 65 }); 66 67 holder.button.setOnClickListener(new View.OnClickListener() { 68 69 @Override 70 public void onClick(View v) { 71 // TODO Auto-generated method stub 72 Message msg = new Message(); 73 Bundle bundle = new Bundle(); 74 bundle.putInt("del_id", Integer.parseInt(v.getTag().toString())); 75 msg.setData(bundle); 76 msg.what = 2; 77 78 mHandler.sendMessage(msg); 79 80 } 81 }); 82 83 return convertView; 84 } 85 86 public class ViewHolder { 87 TextView textView; 88 Button button; 89 }
1 public class DBLoginInfoObj { 2 private int ID;// 數據庫中的ID 3 private String UserName;// 帳號 4 private String Password;// 密碼 5 6 public int getID() { 7 return ID; 8 } 9 10 public void setID(int iD) { 11 ID = iD; 12 } 13 14 public String getUserName() { 15 return UserName; 16 } 17 18 public void setUserName(String userName) { 19 UserName = userName; 20 } 21 22 public String getPassword() { 23 return Password; 24 } 25 26 public void setPassword(String password) { 27 Password = password; 28 }
1 public class LoginInfoHandler { 2 3 private static LoginInfoHandler mHandler; 4 private Context context; 5 private static final String TBL_LOGIN_INFO = "LoginInfo";// 用戶登錄信息 6 private final String PREFS_NAME = "com.example.logintestdome"; 7 8 /** 9 * 私有構造函數 10 */ 11 private LoginInfoHandler(Context context) { 12 this.context = context; 13 } 14 15 /** 16 * 單例模式——保證對象惟一性 17 * 18 * @return 19 */ 20 public static LoginInfoHandler create(Context context) { 21 if (mHandler == null) { 22 mHandler = new LoginInfoHandler(context); 23 } 24 return mHandler; 25 } 26 27 /** 28 * 獲取用戶登錄信息 29 * 30 * @return 31 */ 32 public List<DBLoginInfoObj> getLoginInfoObj() { 33 List<DBLoginInfoObj> infoObjs = new ArrayList<DBLoginInfoObj>(); 34 DBHelper dbHelper = new DBHelper(context); 35 Cursor c = null; 36 try { 37 c = dbHelper.quertAll(TBL_LOGIN_INFO); 38 for (c.moveToLast(); !c.isBeforeFirst(); c.moveToPrevious()) { 39 DBLoginInfoObj infoObj = new DBLoginInfoObj(); 40 infoObj.setID(c.getInt(c.getColumnIndex("_id"))); 41 infoObj.setUserName(c.getString(c.getColumnIndex("UserName"))); 42 infoObj.setPassword(c.getString(c.getColumnIndex("PassWord"))); 43 infoObjs.add(infoObj); 44 45 } 46 } catch (Exception e) { 47 // TODO: handle exception 48 Log.i("數據庫異常:", e.toString()); 49 } finally { 50 // 關閉遊標 51 c.close(); 52 } 53 return infoObjs; 54 }
1 public class DBHelper extends SQLiteOpenHelper { 2 3 private static final String DB_NAME = "LoginTest.db"; 4 private static final String TBL_LOGIN_INFO = "LoginInfo";// 用戶IP地址 5 6 private static final String CREATE_TBL_LOGININFO = "create table LoginInfo(_id integer primary key autoincrement,UserName text,PassWord text)"; 7 8 9 private SQLiteDatabase db; 10 11 public DBHelper(Context context) { 12 super(context, DB_NAME, null, 2); 13 // TODO Auto-generated constructor stub 14 } 15 16 @Override 17 public void onCreate(SQLiteDatabase arg0) { 18 // TODO Auto-generated method stub 19 // 當數據庫被第一次建立時調用 20 this.db = arg0; 21 db.execSQL(CREATE_TBL_LOGININFO); 22 23 } 24 25 /** 26 * 向指定數據庫中插入一條數據 27 * 28 * @param values 29 * ContentValues 鍵值對, 至關於map 30 * @param tableName 31 */ 32 public void insert(ContentValues values, String tableName) { 33 SQLiteDatabase db = getWritableDatabase(); 34 db.insert(tableName, null, values); 35 db.close(); 36 37 } 38 39 /** 40 * 返回表中全部數據 41 * 42 * @param tableName 43 * @return 44 */ 45 public Cursor quertAll(String tableName) { 46 Cursor c = null; 47 SQLiteDatabase db = getWritableDatabase(); 48 c = db.query(tableName, null, null, null, null, null, null); 49 50 return c; 51 } 52 53 /** 54 * 根據ID刪除一條數據 55 * 56 * @param id 57 * @param tableName 58 */ 59 public void del(int id, String tableName) { 60 61 if (db == null) 62 db = getWritableDatabase(); 63 db.delete(tableName, "_id=?", new String[] { String.valueOf(id) }); 64 65 } 66 67 @Override 68 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 69 // TODO Auto-generated method stub 70 71 }
注:有什麼不對的地方但願有大牛給予指導,共同進步。。。spa