文章目录
- 一、需求分析
- 二、开发环境
- 三、项目结构
- 四、详细设计
- 1、注册登录
- 2、主界面
- 五、运行演示
- 六、源码获取
一、需求分析
为了加强居民的生活垃圾分类意识,提高居民垃圾分类的参与度,促进文明社会的建设,推进低碳城市的进步,设计和开发了这款垃圾分类APP。
用户可以先注册账号,然后进行登录,可以选择记住密码,下次就不需要重新输入了。进入主界面,是三个底部导航栏:首页、分类百科、设置,首页可以进行垃圾类别搜索,输入垃圾名称即可查到类别,还有宣传视频可以观看。分类百科中,有顶部导航栏,可以进行滑动页面,介绍可回收物、干垃圾、湿垃圾和有害垃圾的百科。设置中有六大功能,比如切换地区和用户协议等。
二、开发环境
三、项目结构
先来看下源代码文件,activity包下是主要的活动,比如关于应用、切换地区和搜索垃圾等等;adapter包是地区的适配器和搜索垃圾的适配器;app包是欢迎、注册和登录的活动;fragment包是碎片,用来显示滑动页面的;utils包是DataBaseHelper类和ActivityCollector类等实用工具。剩下的MainPage就是主页面活动,所有的逻辑都在这里面。
再来看下res资源文件,相信大家已经非常熟悉了,drawable是图片,layout是布局,mipmap是图标,raw放的多媒体资源,values是colors颜色、strings字符串和themes主题。
四、详细设计
1、注册登录
这次的登录和注册界面,与以往有很多不同,将所有内容放到一个小的LinearLayout中,然后layout_gravity设置成center即可。xml代码很简单,花时间排版就可以,这里不再赘述了,给出实现代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background"
android:gravity="center">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="60dp"
android:orientation="horizontal">
<TextView
android:layout_width="90dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="用户名:"
android:textColor="@color/white"
android:textSize="20sp" />
<EditText
android:id="@+id/accountEdit"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textColor="@color/white"
android:singleLine="true" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal">
<TextView
android:layout_width="90dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="密 码:"
android:textColor="@color/white"
android:textSize="20sp" />
<EditText
android:id="@+id/passwordEdit"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textColor="@color/white"
android:inputType="textPassword"
android:singleLine="true" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<CheckBox
android:id="@+id/rememberPass"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="记住密码"
android:textColor="@color/white"
android:textSize="18sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="20dp">
<Button
android:id="@+id/login"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"
android:layout_gravity="center_horizontal"
android:text="登录"
android:textSize="20sp"
android:background="@drawable/btn_selector"/>
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.5"/>
<Button
android:id="@+id/register"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="50dp"
android:layout_gravity="center_horizontal"
android:text="注册"
android:textSize="20sp"
android:background="@drawable/btn_selector"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
可以调成Split模式,这样就是Code和Design就可以同步进行了。
下面介绍下注册活动的按钮点击事件,其实就是判断一些情况,是否用户已存在,是否为空,是否密码不一致等等,这些逻辑也很简单。
register.setOnClickListener() {
val name = accountEdit.text.toString().trim()
val password1 = passwordEdit.text.toString().trim()
val password2 = passwordCheckEdit.text.toString().trim()
if (name == "" || password1 == "" || password2 == "") {
passwordEdit.text = null
passwordCheckEdit.text = null
Toast.makeText(this, "用户名或密码不能为空!", Toast.LENGTH_SHORT).show()
} else if (accountList.contains(name)) {
Toast.makeText(this, "该用户已存在!", Toast.LENGTH_SHORT).show()
passwordEdit.text = null
passwordCheckEdit.text = null
accountEdit.text = null
} else if(password1 != password2){
Toast.makeText(this, "两次密码不一致,请重新输入!", Toast.LENGTH_SHORT).show()
passwordEdit.text = null
passwordCheckEdit.text = null
} else{
val output = openFileOutput("account_password.txt", MODE_APPEND)
val writer = BufferedWriter(OutputStreamWriter(output))
writer.use {
it.write(name+'\n')
it.write(password1+'\n')
}
Toast.makeText(this, "注册成功!", Toast.LENGTH_SHORT).show()
finish()
}
}
注册页面,按钮与背景合二为一,大道至简。
2、主界面
这里是自定义底部导航栏,选中某个选项卡时,会放大字体和图标,然后加粗字体,并且其他页面内容Gone,本页面内容Visible,代码如下:
button1.setOnClickListener() {
titleText.text = "垃圾分类"
button3.setImageResource(R.drawable.pic31)
button2.setImageResource(R.drawable.pic21)
button1.setImageResource(R.drawable.pic12)
text1.textSize = 20F
text2.textSize = 15F
text3.textSize = 15F
text1.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
text2.typeface = Typeface.defaultFromStyle(Typeface.NORMAL)
text3.typeface = Typeface.defaultFromStyle(Typeface.NORMAL)
column1.visibility = View.VISIBLE
column2.visibility = View.GONE
column3.visibility = View.GONE
if (videoView.isPlaying) {
videoView.pause()
}
}
这里对设置中的所有按钮设置了点击事件,多数为跳转活动,还有Exit发送广播下线,applyRight进入应用权限管理界面,代码如下:
changePlace.setOnClickListener(){
val intent= Intent(this, PlaceActivity::class.java)
startActivityForResult(intent, 1)
}
givePoint.setOnClickListener(){
launchAppDetail("com.bitmain.btccom", "com.huawei.appmarket")
}
aboutUs.setOnClickListener(){
val intent= Intent(this, AboutUsActivity::class.java)
startActivity(intent)
}
agreement.setOnClickListener(){
val intent= Intent(this, AgreeActivity::class.java)
startActivity(intent)
}
applyRight.setOnClickListener(){
val intent = Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
val uri = Uri.fromParts("package", packageName, null)
intent.data = uri
startActivity(intent)
}
Exit.setOnClickListener(){
val intent = Intent("com.example.experiment3.FORCE_OFFLINE")
intent.setPackage(packageName)
sendBroadcast(intent)
}
search.setOnClickListener(){
val intent= Intent(this, SearchActivity::class.java)
startActivity(intent)
}
对于分类百科选项卡,顶部导航栏以及下面的图片内容控件设置,使用数组存储图片,然后for循环遍历进行设置,代码如下:
//初始化菜单栏显示
for (i in 0 until tabs2.tabCount) {
//寻找到控件
val view: View = LayoutInflater.from(this@MainPage).inflate(R.layout.item_result, null)
val mTabView = view.findViewById<View>(R.id.item_view) as LinearLayout
val mTabText = view.findViewById<View>(R.id.item_text) as TextView
val mTabIcon = view.findViewById<View>(R.id.item_img) as ImageView
mTabText.text = Ltitles[i]
mTabIcon.setImageResource(Limg[i])
//设置不可点击
mTabView.isClickable = false
//更改选中项样式
if (i === ItemWhat) {
mTabIcon.setImageResource(Limg[i])
mTabText.setTextColor(ContextCompat.getColor(this, R.color.purple_200))
}
//设置样式
tabs2.getTabAt(i)?.customView = view
}
五、运行演示
1、打开模拟器,运行app,进入欢迎界面。
2、经过3s后,跳转至登录界面。默认账号为admin,密码为123456。我们也可以注册账号,先点击注册按钮进行注册。
3、注册界面,输入用户名和密码,再确认密码,然后点击注册,如果输入有误会有提示信息。
注册成功后,会跳转回登录界面,然后进行登录即可,这里我选了记住密码。
4、登录成功后进入首页。这里底部导航栏默认显示首页,最上面是标题栏,下面是搜索框和宣传视频。
5、点击搜索框,进入垃圾搜索界面,可以在这里搜索垃圾的类别,搜索结果以列表形式呈现。
6、这里,我们分别输入“卫生纸”和“电池”,然后点击搜索:
7、点击任意搜索结果,会弹出对话框,显示垃圾分类的tips:
8、点击视频进行播放,进度条可以拖动。
9、进入【分类百科】,这里包含四个滑动页面,可回收物、湿垃圾、干垃圾和有害垃圾,既可以滑动切换,也可以手动点击切换。
10、进入【设置】,这里可以切换地区,查看用户协议,退出登录等,点击切换地区:
11、进入城市选择页面,选择成都市,然后点返回键,可以看到变为成都市了。
12、点击【关于我们】,可以看到软件开发的信息,可以进行修改。
13、点击【权限管理】,可以看到App的权限设置界面。
14、最后,点击退出登录,就会重新回到登录界面。