布局:
线性布局+相对布局
日志打印:
利用LogCat和System.out.println打印观察。
Onclick事件是采用过的第四种:
在配置文件中给Button添加点击时间
涉及知识:
通过上线文context获得文件的路径和缓存路径,保存文件
布局代码:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.loginUI.MainActivity" tools:ignore="MergeRootFrame" android:orientation="vertical"> <TextView android:id="@+id/tv_plInputName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/plInputName" /> <EditText android:id="@+id/et_userName" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:inputType="textPersonName" > <requestFocus /> </EditText> <TextView android:id="@+id/tv_plInputPassword" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/plInputPassword" /> <EditText android:id="@+id/et_password" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:inputType="textPassword"/> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content" > <CheckBox android:checked="true" android:id="@+id/cb_rmPassword" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/rmPassword" /> <Button android:onClick="login" android:id="@+id/btn_login" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_marginRight="35dp" android:text="@string/login" /> </RelativeLayout> </LinearLayout>
MainActivity代码:
package com.example.loginUI; import java.util.Map; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.Toast; import com.example.service.LoginService; public class MainActivity extends ActionBarActivity { //日志记录Tag private String TAG = "MainActivity"; /** 用户名 */ private EditText etUserName; /** 密码 */ private EditText etPassword; /** 登陆按钮 */ private Button btnLogin; /** 记住密码按钮 */ private CheckBox cbx; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //获得控件 etUserName = (EditText)findViewById(R.id.et_userName); etPassword = (EditText)findViewById(R.id.et_password); btnLogin = (Button)findViewById(R.id.btn_login); cbx = (CheckBox)findViewById(R.id.cb_rmPassword); Map<String, String> result = (new LoginService().getUserNameAndPassword(this)); if (null != result ) { etUserName.setText(result.get("userName")); etPassword.setText(result.get("password")); } } public void login(View view) { //日志打印 Log.i(TAG, "开始登陆验证"); String userName = etUserName.getText().toString(); String password = etPassword.getText().toString(); //非空判断给出吐司提示 if (TextUtils.equals(userName.trim(), "") || TextUtils.equals(password.trim(), "")) { Toast.makeText(this, "用户名/密码不能为空", Toast.LENGTH_SHORT).show(); return ; } //是否保存密码 if (cbx.isChecked()) { //new LoginService().saveUserNameAndPassword(userName, password); new LoginService().saveUserNameAndPassword(this, userName, password); } if("zz".equals(userName) && "11".equals(password)) { Toast.makeText(this, "登陆成功", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "登陆失败", Toast.LENGTH_SHORT).show(); } Log.i(TAG, "登陆验证完成"); } }
保存数据以及读数据的代码:
package com.example.service; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStreamReader; import java.util.HashMap; import java.util.List; import java.util.Map; import android.content.Context; import android.util.Log; public class LoginService { private String TAG = "loginService"; /** * 保存用户名密码, 这样的方式不灵活, 如果我们改了工程的包名的话, 这里就变成了我们的工程往另一工程写数据了, 这是不允许的 * @param userName * @param password * @return */ public boolean saveUserNameAndPassword(String userName, String password) { Log.i(TAG, "开始保存用户名密码"); File file = new File("/data/data/com.example.loginUI/info.txt"); FileOutputStream outputStream; try { outputStream = new FileOutputStream(file); outputStream.write((userName+"#"+password).getBytes()); outputStream.close(); } catch (Exception e) { Log.e(TAG, "保存用户名密码出现异常"); return false; } return true; } /** * 保存用户名密码, 通过上下文动态的改变文件路径 * @param context * @param userName * @param password * @return */ public boolean saveUserNameAndPassword(Context context, String userName, String password) { Log.i(TAG, "开始保存用户名密码"); File file = new File(context.getFilesDir(), "info.txt"); // == File file = new File("/data/data/com.example.loginUI/files/info.txt"); //File file = new File(context.getCacheDir(), "info.txt"); // /data/data/com.example.loginUI/cache/info.txt 放进缓存,不要放太大的东西 FileOutputStream outputStream; try { outputStream = new FileOutputStream(file); outputStream.write((userName+"#"+password).getBytes()); outputStream.close(); } catch (Exception e) { Log.e(TAG, "保存用户名密码出现异常"); return false; } return true; } public Map<String, String> getUserNameAndPassword(Context context) { Map<String, String> result = new HashMap<String, String>(); File file = new File(context.getFilesDir(), "info.txt"); FileInputStream fis; try { fis = new FileInputStream(file); BufferedReader br = new BufferedReader(new InputStreamReader(fis)); String[] lists = br.readLine().split("#"); Log.i(TAG, "要保存的用户名="+lists[0]+": 密码="+lists[1]); result.put("userName", lists[0]); result.put("password", lists[1]); } catch (Exception e) { e.printStackTrace(); } return result; } }