因公司近期将开展移动端项目,本人最近学习了安卓开发的基础内容,因此写了一个简单的项目作为练习,本人不才,仅作为自己学习笔录,若有幸帮助到初学安卓的小伙伴笔者更悦,使用工具为Android Atudio。当然了,我会把项目上传上去让大家下载,
下载时可能会需要1积分,这并不是自己的初衷,本想免积分的,但是好像平台不支持,默认弄了一积分。有的时候看到很多人分享学习资料好要很多积分(5左右),重点是狠下心买了点积分下载下来根本不是自己想要的,特别生气,当今是一个共享的社会,知识共享起源最早,所以希望大家一起学习,一起进步。当然后期我会把项目放到github上,到时候也可以下载。
优快云下载地址:https://download.youkuaiyun.com/download/qq_35008624/10572588
GITHUB下载地址:后期更新
项目涵盖的内容:
(1)activity的基础内容包括跳转、生命周期等
(2)如何修改应用的logo
(3)如何设置启用界面
(4)登录界面,包括记住密码和自动登录两大功能。(默认用户密码:lpf/123)
(5)进入主页面有安卓基本样式学习模块:包括shape,selector,layer-list,animation四大模块
(6)断点下载
(7)弹出对话框,包括普通对话框、列表对话框、多选对话框、圆形进度对话框和水平进度条对话框
主要截图:
以上是几个代表性的截图,东西太多不可能都截下来,需要的小伙伴可以去下载https://download.youkuaiyun.com/download/qq_35008624/10572588。
主要代码:
1、清单文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.lwz.login_demo"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="21"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application android:label="@string/app_name" android:icon="@drawable/logo_app"
android:theme="@style/BaseStyle"
>
<activity android:name=".activity.SplashActivity"
android:label="@string/app_name"
android:launchMode="singleTask"
>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".activity.MainActivity"
android:label="@string/app_name"
android:launchMode="singleTask"
>
</activity>
<activity android:name=".activity.LoginActivity"/>
<activity android:name=".activity.LoginAfterActivity"/>
<activity android:name=".activity.basicStyleActivity"/>
<activity android:name=".activity.BreakDownload"/>
<activity android:name=".activity.DialogActivity"/>
<activity
android:name=".activity.RectangleActivity"
android:label="@string/title_activity_rectangle" />
<activity
android:name=".activity.OvalActivity"
android:label="@string/title_activity_oval" />
<activity
android:name=".activity.LineActivity"
android:label="@string/title_activity_line" />
<activity
android:name=".activity.RingActivity"
android:label="@string/title_activity_ring" />
<activity
android:name=".activity.ShapeActivity"
android:label="@string/title_activity_shape" >
</activity>
<activity
android:name=".activity.SelectorActivity"
android:label="@string/title_activity_selector" >
</activity>
<activity
android:name=".activity.LayerListActivity"
android:label="@string/title_activity_layer_list" >
</activity>
<activity android:name=".activity.AnimationActivity" >
</activity>
</application>
</manifest>
2、登录界面和相应的activity
<?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:background="#fff"
android:orientation="vertical">
<TextView
android: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="@dimen/dp_1"
android:background="@color/orange_main"
/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="@dimen/item_height_normal"
android:layout_marginLeft="@dimen/margin_large"
android:layout_marginRight="@dimen/margin_large"
android:layout_marginTop="@dimen/dp_120">
<ImageView
android:id="@+id/img_account"
android:layout_width="@dimen/dp_19"
android:layout_height="@dimen/dp_20"
android:layout_alignParentBottom="true"
android:layout_marginBottom="@dimen/margin_tiny"
android:layout_marginLeft="@dimen/margin_tiny"
android:scaleType="fitXY"
android:src="@drawable/icon_login_account"/>
<EditText
android: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="@dimen/margin_tiny"
android:layout_marginLeft="@dimen/margin_normal"
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="@dimen/text_size_normal"/>
<View
android:layout_width="match_parent"
android:layout_height="@dimen/line_height"
android:layout_alignParentBottom="true"
android:layout_marginLeft="@dimen/margin_normal"
android:layout_toRightOf="@+id/img_account"
android:background="@color/orange_light"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="@dimen/item_height_normal"
android:layout_marginLeft="@dimen/margin_large"
android:layout_marginRight="@dimen/margin_large">
<ImageView
android:id="@+id/img_pw"
android:layout_width="@dimen/dp_18"
android:layout_height="@dimen/dp_20"
android:layout_alignParentBottom="true"
android:layout_marginBottom="@dimen/margin_tiny"
android:layout_marginLeft="@dimen/margin_tiny"
android:scaleType="fitXY"
android:src="@drawable/icon_login_pw"/>
<EditText
android: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="@dimen/margin_tiny"
android:layout_marginLeft="@dimen/margin_normal"
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="@dimen/text_size_normal"/>
<ImageView
android:id="@+id/iv_see_password"
android:layout_width="@dimen/image_height_litter"
android:layout_height="@dimen/image_height_litter"
android:src="@drawable/image_password_bg"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:scaleType="fitXY"
/>
<View
android:layout_width="match_parent"
android:layout_height="@dimen/line_height"
android:layout_alignParentBottom="true"
android:layout_marginLeft="@dimen/margin_normal"
android:layout_toRightOf="@+id/img_pw"
android:background="@color/orange_light"/>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/margin_large"
android:layout_marginRight="@dimen/margin_large"
android:layout_marginTop="@dimen/margin_small"
android:paddingBottom="@dimen/margin_small"
android:paddingTop="@dimen/margin_small"
android:orientation="horizontal"
android:gravity="center"
>
<CheckBox
android:id="@+id/checkBox_password"
android:padding="@dimen/dp_10"
android:textSize="@dimen/text_size_normal"
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"/>
<CheckBox
android:id="@+id/checkBox_login"
android:padding="@dimen/dp_10"
android:textSize="@dimen/text_size_normal"
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"/>
</LinearLayout>
<Button
android:id="@+id/btn_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/margin_large"
android:layout_marginRight="@dimen/margin_large"
android:layout_marginTop="@dimen/margin_huge"
android:paddingBottom="@dimen/margin_small"
android:paddingTop="@dimen/margin_small"
android:text="@string/login"
android:background="@drawable/btn_orange_selector"
android:textColor="@android:color/white"
android:textSize="@dimen/text_size_normal"/>
</LinearLayout>
=================================================================================
package com.lwz.login_demo.activity;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.InputType;
import android.view.View;
import android.widget.*;
import com.lwz.login_demo.R;
import com.lwz.login_demo.util.Base64Utils;
import com.lwz.login_demo.util.SharedPreferencesUtils;
import com.lwz.login_demo.widget.LoadingDialog;
/**
* 登录界面
*/
public class LoginActivity extends Activity
implements View.OnClickListener, CompoundButton.OnCheckedChangeListener {
//布局内的控件
private EditText et_name;
private EditText et_password;
private Button mLoginBtn;
private CheckBox checkBox_password;
private CheckBox checkBox_login;
private ImageView iv_see_password;
private LoadingDialog mLoadingDialog; //显示正在加载的对话框
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
initViews();
setupEvents();
initData();
}
private void initData() {
//判断用户第一次登陆
if (firstLogin()) {
checkBox_password.setChecked(false);//取消记住密码的复选框
checkBox_login.setChecked(false);//取消自动登录的复选框
}
//判断是否记住密码
if (remenberPassword()) {
checkBox_password.setChecked(true);//勾选记住密码
setTextNameAndPassword();//把密码和账号输入到输入框中
} else {
setTextName();//把用户账号放到输入账号的输入框中
}
//判断是否自动登录
if (autoLogin()) {
checkBox_login.setChecked(true);
login();//去登录就可以
}
}
/**
* 把本地保存的数据设置数据到输入框中
*/
public void setTextNameAndPassword() {
et_name.setText("" + getLocalName());
et_password.setText("" + getLocalPassword());
}
/**
* 设置数据到输入框中
*/
public void setTextName() {
et_name.setText("" + getLocalName());
}
/**
* 获得保存在本地的用户名
*/
public String getLocalName() {
//获取SharedPreferences对象,使用自定义类的方法来获取对象
SharedPreferencesUtils helper = new SharedPreferencesUtils(this, "setting");
String name = helper.getString("name");
return name;
}
/**
* 获得保存在本地的密码
*/
public String getLocalPassword() {
//获取SharedPreferences对象,使用自定义类的方法来获取对象
SharedPreferencesUtils helper = new SharedPreferencesUtils(this, "setting");
String password = helper.getString("password");
return Base64Utils.decryptBASE64(password); //解码一下
// return password; //解码一下
}
/**
* 判断是否自动登录
*/
private boolean autoLogin() {
//获取SharedPreferences对象,使用自定义类的方法来获取对象
SharedPreferencesUtils helper = new SharedPreferencesUtils(this, "setting");
boolean autoLogin = helper.getBoolean("autoLogin", false);
return autoLogin;
}
/**
* 判断是否记住密码
*/
private boolean remenberPassword() {
//获取SharedPreferences对象,使用自定义类的方法来获取对象
SharedPreferencesUtils helper = new SharedPreferencesUtils(this, "setting");
boolean remenberPassword = helper.getBoolean("remenberPassword", false);
return remenberPassword;
}
private void initViews() {
mLoginBtn = (Button) findViewById(R.id.btn_login);
et_name = (EditText) findViewById(R.id.et_account);
et_password = (EditText) findViewById(R.id.et_password);
checkBox_password = (CheckBox) findViewById(R.id.checkBox_password);
checkBox_login = (CheckBox) findViewById(R.id.checkBox_login);
iv_see_password = (ImageView) findViewById(R.id.iv_see_password);
}
private void setupEvents() {
mLoginBtn.setOnClickListener(this);
checkBox_password.setOnCheckedChangeListener(this);
checkBox_login.setOnCheckedChangeListener(this);
iv_see_password.setOnClickListener(this);
}
/**
* 判断是否是第一次登陆
*/
private boolean firstLogin() {
//获取SharedPreferences对象,使用自定义类的方法来获取对象
SharedPreferencesUtils helper = new SharedPreferencesUtils(this, "setting");
boolean first = helper.getBoolean("first", true);
if (first) {
//创建一个ContentVa对象(自定义的)设置不是第一次登录,,并创建记住密码和自动登录是默认不选,创建账号和密码为空
helper.putValues(new SharedPreferencesUtils.ContentValue("first", false),
new SharedPreferencesUtils.ContentValue("remenberPassword", false),
new SharedPreferencesUtils.ContentValue("autoLogin", false),
new SharedPreferencesUtils.ContentValue("name", ""),
new SharedPreferencesUtils.ContentValue("password", ""));
return true;
}
return false;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_login:
loadUserName(); //无论如何保存一下用户名
login(); //登陆
break;
case R.id.iv_see_password:
setPasswordVisibility(); //改变图片并设置输入框的文本可见或不可见
break;
}
}
/**
* 模拟登录情况
* 用户名csdn,密码123456,就能登录成功,否则登录失败
*/
private void login() {
//先做一些基本的判断,比如输入的用户命为空,密码为空,网络不可用多大情况,都不需要去链接服务器了,而是直接返回提示错误
if (getAccount().isEmpty()){
showToast("你输入的账号为空!");
return;
}
if (getPassword().isEmpty()){
showToast("你输入的密码为空!");
return;
}
//登录一般都是请求服务器来判断密码是否正确,要请求网络,要子线程
showLoading();//显示加载框
Thread loginRunnable = new Thread() {
@Override
public void run() {
super.run();
setLoginBtnClickable(false);//点击登录后,设置登录按钮不可点击状态
//睡眠3秒
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//判断账号和密码
if (getAccount().equals("lpf") && getPassword().equals("123")) {
showToast("登录成功");
loadCheckBoxState();//记录下当前用户记住密码和自动登录的状态;
startActivity(new Intent(LoginActivity.this, LoginAfterActivity.class));
finish();//关闭页面
} else {
showToast("输入的登录账号或密码不正确");
}
setLoginBtnClickable(true); //这里解放登录按钮,设置为可以点击
hideLoading();//隐藏加载框
}
};
loginRunnable.start();
}
/**
* 保存用户账号
*/
public void loadUserName() {
if (!getAccount().equals("") || !getAccount().equals("请输入登录账号")) {
SharedPreferencesUtils helper = new SharedPreferencesUtils(this, "setting");
helper.putValues(new SharedPreferencesUtils.ContentValue("name", getAccount()));
}
}
/**
* 设置密码可见和不可见的相互转换
*/
private void setPasswordVisibility() {
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);
}
}
/**
* 获取账号
*/
public String getAccount() {
return et_name.getText().toString().trim();//去掉空格
}
/**
* 获取密码
*/
public String getPassword() {
return et_password.getText().toString().trim();//去掉空格
}
/**
* 保存用户选择“记住密码”和“自动登陆”的状态
*/
private void loadCheckBoxState() {
loadCheckBoxState(checkBox_password, checkBox_login);
}
/**
* 保存按钮的状态值
*/
public void loadCheckBoxState(CheckBox checkBox_password, CheckBox checkBox_login) {
//获取SharedPreferences对象,使用自定义类的方法来获取对象
SharedPreferencesUtils helper = new SharedPreferencesUtils(this, "setting");
//如果设置自动登录
if (checkBox_login.isChecked()) {
//创建记住密码和自动登录是都选择,保存密码数据
helper.putValues(
new SharedPreferencesUtils.ContentValue("remenberPassword", true),
new SharedPreferencesUtils.ContentValue("autoLogin", true),
new SharedPreferencesUtils.ContentValue("password", Base64Utils.encryptBASE64(getPassword())));
} else if (!checkBox_password.isChecked()) { //如果没有保存密码,那么自动登录也是不选的
//创建记住密码和自动登录是默认不选,密码为空
helper.putValues(
new SharedPreferencesUtils.ContentValue("remenberPassword", false),
new SharedPreferencesUtils.ContentValue("autoLogin", false),
new SharedPreferencesUtils.ContentValue("password", ""));
} else if (checkBox_password.isChecked()) { //如果保存密码,没有自动登录
//创建记住密码为选中和自动登录是默认不选,保存密码数据
helper.putValues(
new SharedPreferencesUtils.ContentValue("remenberPassword", true),
new SharedPreferencesUtils.ContentValue("autoLogin", false),
new SharedPreferencesUtils.ContentValue("password", Base64Utils.encryptBASE64(getPassword())));
}
}
/**
* 是否可以点击登录按钮
*
* @param clickable
*/
public void setLoginBtnClickable(boolean clickable) {
mLoginBtn.setClickable(clickable);
}
/**
* 显示加载的进度款
*/
public void showLoading() {
if (mLoadingDialog == null) {
mLoadingDialog = new LoadingDialog(this, getString(R.string.loading), false);
}
mLoadingDialog.show();
}
/**
* 隐藏加载的进度框
*/
public void hideLoading() {
if (mLoadingDialog != null) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mLoadingDialog.hide();
}
});
}
}
/**
* CheckBox点击时的回调方法 ,不管是勾选还是取消勾选都会得到回调
*
* @param buttonView 按钮对象
* @param isChecked 按钮的状态
*/
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);
}
}
}
/**
* 监听回退键
*/
@Override
public void onBackPressed() {
if (mLoadingDialog != null) {
if (mLoadingDialog.isShowing()) {
mLoadingDialog.cancel();
} else {
finish();
}
} else {
finish();
}
}
/**
* 页面销毁前回调的方法
*/
protected void onDestroy() {
if (mLoadingDialog != null) {
mLoadingDialog.cancel();
mLoadingDialog = null;
}
super.onDestroy();
}
public void showToast(final String msg) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(LoginActivity.this, msg, Toast.LENGTH_SHORT).show();
}
});
}
}
3、弹出对话框activity
package com.lwz.login_demo.activity;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import com.lwz.login_demo.R;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by think on 2018/6/5.
*/
public class DialogActivity extends Activity {
final String items[] = {"我是Item一", "我是Item二", "我是Item三", "我是Item四"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_main);
}
//普通对话框
public void toGeneralDialog(View view) {
AlertDialog dialog = new AlertDialog.Builder(this)
.setIcon(R.mipmap.logo1)//设置标题的图片
.setTitle("我是对话框")//设置对话框的标题
.setMessage("我是对话框的内容")//设置对话框的内容
//设置对话框的按钮
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(DialogActivity.this, "点击了取消按钮", Toast.LENGTH_SHORT).show();
dialog.dismiss();
}
})
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(DialogActivity.this, "点击了确定的按钮", Toast.LENGTH_SHORT).show();
dialog.dismiss();
}
}).create();
dialog.show();
}
//列表对话框
public void toListDialog(View view) {
AlertDialog dialog = new AlertDialog.Builder(this)
.setIcon(R.mipmap.logo2)//设置标题的图片
.setTitle("列表对话框")//设置对话框的标题
.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(DialogActivity.this, items[which], Toast.LENGTH_SHORT).show();
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).create();
dialog.show();
}
//单选列表对话框
public void toSingleListDialog(View view) {
AlertDialog dialog = new AlertDialog.Builder(this)
.setIcon(R.mipmap.logo3)//设置标题的图片
.setTitle("单选列表对话框")//设置对话框的标题
.setSingleChoiceItems(items, 1, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(DialogActivity.this, items[which], Toast.LENGTH_SHORT).show();
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).create();
dialog.show();
}
//多选列表对话框
public void toMultiChoiceListDialog(View view) {
final boolean checkedItems[] = {true, false, true, false};
AlertDialog dialog = new AlertDialog.Builder(this)
.setIcon(R.mipmap.logo4)//设置标题的图片
.setTitle("多选对话框")//设置对话框的标题
.setMultiChoiceItems(items, checkedItems, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
checkedItems[which] = isChecked;
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
for (int i = 0; i < checkedItems.length; i++) {
if (checkedItems[i]) {
Toast.makeText(DialogActivity.this, "选中了" + i, Toast.LENGTH_SHORT).show();
}
}
dialog.dismiss();
}
}).create();
dialog.show();
}
//圆形进度条对话框
public void toHalfSelfDialog(View view) {
ProgressDialog dialog = new ProgressDialog(this);
dialog.setMessage("正在加载中");
dialog.show();
}
//水平进度条对话框
public void toTotalSelfDialog(View view) {
final ProgressDialog dialog = new ProgressDialog(this);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setMessage("正在加载中");
dialog.setMax(100);
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
int progress = 0;
@Override
public void run() {
dialog.setProgress(progress += 5);
if (progress == 100) {
timer.cancel();
}
}
}, 0, 1000);
dialog.show();
}
}