目录
这是一个使用android studio和java开发的购物商城应用。该应用旨在提供用户一个方便、快捷的购物体验。通过该应用,用户可以浏览不同类别的商品,并将其添加到购物车中。用户可以查看商品的详细信息,包括价格等。购物商城应用还提供了用户注册和登录功能,以便用户可以保存个人信息。该应用还支持商品搜索功能,帮助用户快速找到所需商品。购物商城应用的界面简洁、直观,操作易于上手,为用户提供了一个愉快的购物体验。
项目视频介绍
android studio期末设计大作业~购物商城app
一、项目概述
1、构成以及功能设计
①启动页
②.用户登录/注册功能
③主页面功能
- 顶部轮播图功能
- 搜索功能
- 商品目录
- 商品列表
-点击商品列表进入详情页
④ 购物车功能
- 商品数量的增加减少
- 商品支付购买
⑤ 我的页面
- 修改用户密码
⑥详情页面
- 显示商品详情信息
二、开发环境
我的开发环境如下,大家的as版本不需要和我相同,只要是近两年从官网下载的版本,都是比4.0.0高的,是可以满足运行和开发要求的。
三、准备工具
-
准备商品详情内容
四、详细设计
1、新建工程
-
首先打开android studio,并新建一个工程,file——>new——>new project——>empty project,工程名称叫做newshop,可以根据自己喜好设置名称。
-
包名自己随意设定,这里博主用的是com.example,一般是com.example;工程文件的保存路径要修改一下,不要放在c盘,我这里选择的是放在h盘,养成项目统一放在英文路径下的好习惯。
-
最后选择api 24:android 7.0,因为这样它就拥有了96.3%的跨平台性(兼容性非常好),因为它版本很低,基本上模拟器api版本都是高于20的,所以这个软件可以运行其他各种设备上。点击finish完成创建。
2、搭建启动页面
我们来看一下activity_start布局文件。
启动页面xml完整代码如下:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.constraintlayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ead6b6"
tools:context=".start.startactivity">
<imageview
android:id="@+id/imageview"
android:layout_width="300dp"
android:layout_height="300dp"
app:layout_constraintbottom_tobottomof="parent"
app:layout_constraintend_toendof="parent"
app:layout_constraintstart_tostartof="parent"
app:layout_constrainttop_totopof="parent"
app:srccompat="@drawable/logo" />
</androidx.constraintlayout.widget.constraintlayout>
然后回到我们的activity文件。首先创建一个imageview控件 然后进行页面背景颜色修改。
启动页面代码如下:
package com.android.newshop.start;
import android.content.intent;
import android.os.bundle;
import android.os.countdowntimer;
import android.os.handler;
import android.widget.button;
import android.widget.imageview;
import androidx.appcompat.app.appcompatactivity;
import com.android.newshop.login.loginactivity;
import com.android.newshop.r;
public class startactivity extends appcompatactivity {
private imageview imageview2;
private button button;
private runnable runnable = new runnable() {
@override
public void run() {
tomainactive();
}
};
// 进入主页面
private void tomainactive() {
startactivity(new intent(this, loginactivity.class));
// 跳转完成后注销
finish();
}
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_start);
}
// 计时器
class timecount extends countdowntimer {
public timecount(long millisinfuture, long countdowninterval) {
super(millisinfuture, countdowninterval);
}
@override
public void ontick(long l) {
}
@override
public void onfinish() {
}
}
}
3、搭建注册、登陆界面
主要实现用户数据的存储,实现用户使用注册的账号进行登陆。
注册页面xml代码如下所示:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.constraintlayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ead6b6"
tools:context=".register.registeractivity">
<imageview
android:id="@+id/imageview3"
android:layout_width="200dp"
android:layout_height="150dp"
android:layout_margintop="40dp"
app:layout_constraintend_toendof="parent"
app:layout_constraintstart_tostartof="parent"
app:layout_constrainttop_totopof="parent"
app:srccompat="@drawable/logo" />
<view
android:id="@+id/view2"
android:layout_width="0dp"
android:layout_height="300dp"
android:background="@drawable/login_view"
app:layout_constraintbottom_tobottomof="parent"
app:layout_constraintend_tostartof="@+id/guideline4"
app:layout_constrainthorizontal_bias="0.0"
app:layout_constraintstart_tostartof="@+id/guideline"
app:layout_constrainttop_totopof="@+id/imageview3"
app:layout_constraintvertical_bias="0.501" />
<view
android:id="@+id/view3"
android:layout_width="250dp"
android:layout_height="45dp"
android:layout_margintop="32dp"
android:background="@drawable/login_count"
app:layout_constraintend_tostartof="@+id/guideline4"
app:layout_constraintstart_tostartof="@+id/view2"
app:layout_constrainttop_totopof="@+id/view2" />
<view
android:id="@+id/view4"
android:layout_width="0dp"
android:layout_height="45dp"
android:layout_margintop="32dp"
android:background="@drawable/login_count"
app:layout_constraintend_toendof="@+id/view3"
app:layout_constraintstart_tostartof="@+id/view3"
app:layout_constrainttop_tobottomof="@+id/view3" />
<androidx.constraintlayout.widget.guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintguide_percent="0.1" />
<androidx.constraintlayout.widget.guideline
android:id="@+id/guideline4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintguide_percent="0.9" />
<imageview
android:id="@+id/imageview"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginstart="8dp"
app:layout_constraintbottom_tobottomof="@+id/view3"
app:layout_constraintstart_tostartof="@+id/view3"
app:layout_constrainttop_totopof="@+id/view3"
app:srccompat="@drawable/mima" />
<imageview
android:id="@+id/imageview4"
android:layout_width="20dp"
android:layout_height="20dp"
app:layout_constraintbottom_tobottomof="@+id/view4"
app:layout_constraintstart_tostartof="@+id/imageview"
app:layout_constrainttop_totopof="@+id/view4"
app:srccompat="@drawable/zhanghao" />
<button
android:id="@+id/register_button"
android:layout_width="250dp"
android:layout_height="55dp"
android:layout_marginbottom="32dp"
android:background="@drawable/login"
android:text="立 即 注 册"
app:layout_constraintbottom_tobottomof="@+id/view2"
app:layout_constraintend_toendof="@+id/view2"
app:layout_constrainthorizontal_bias="0.506"
app:layout_constraintstart_tostartof="@+id/view2" />
<edittext
android:id="@+id/username_edittext"
android:layout_width="190dp"
android:layout_height="0dp"
android:layout_marginstart="5dp"
android:background="#eff4f2"
android:ems="10"
android:hint="请输入账号"
android:inputtype="textpersonname"
app:layout_constraintbottom_tobottomof="@+id/view3"
app:layout_constraintstart_toendof="@+id/imageview"
app:layout_constrainttop_totopof="@+id/view3" />
<edittext
android:id="@+id/password_edittext"
android:layout_width="190dp"
android:layout_height="0dp"
android:layout_marginstart="5dp"
android:background="#eff4f2"
android:ems="10"
android:hint="请输入密码"
android:inputtype="textpassword"
app:layout_constraintbottom_tobottomof="@+id/view4"
app:layout_constraintstart_toendof="@+id/imageview4"
app:layout_constrainttop_totopof="@+id/view4" />
<textview
android:id="@+id/tv_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginbottom="8dp"
android:text="已有账号,立即登录"
app:layout_constraintbottom_totopof="@+id/register_button"
app:layout_constraintend_toendof="@+id/view4"
app:layout_constrainttop_tobottomof="@+id/view4" />
</androidx.constraintlayout.widget.constraintlayout>
登陆页面xml代码如下:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.constraintlayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ead6b6"
tools:context=".login.loginactivity">
<imageview
android:id="@+id/imageview3"
android:layout_width="200dp"
android:layout_height="150dp"
android:layout_margintop="24dp"
app:layout_constraintend_toendof="parent"
app:layout_constraintstart_tostartof="parent"
app:layout_constrainttop_totopof="parent"
app:srccompat="@drawable/logo" />
<view
android:id="@+id/view2"
android:layout_width="0dp"
android:layout_height="320dp"
android:layout_margintop="24dp"
android:background="@drawable/login_view"
app:layout_constraintend_tostartof="@+id/guideline2"
app:layout_constraintstart_tostartof="@+id/guideline3"
app:layout_constrainttop_tobottomof="@+id/imageview3" />
<button
android:id="@+id/login_button"
android:layout_width="250dp"
android:layout_height="55dp"
android:layout_marginbottom="32dp"
android:background="@drawable/login"
android:text="立 即 登 录 "
android:textcolor="#fff"
android:textsize="24sp"
app:layout_constraintbottom_tobottomof="@+id/view2"
app:layout_constraintend_tostartof="@+id/guideline2"
app:layout_constraintstart_tostartof="@+id/view2" />
<androidx.constraintlayout.widget.guideline
android:id="@+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintguide_percent="0.9" />
<androidx.constraintlayout.widget.guideline
android:id="@+id/guideline3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintguide_percent="0.1" />
<view
android:id="@+id/view3"
android:layout_width="0dp"
android:layout_height="45dp"
android:layout_margintop="40dp"
android:background="@drawable/login_count"
app:layout_constraintend_toendof="@+id/login_button"
app:layout_constraintstart_tostartof="@+id/login_button"
app:layout_constrainttop_totopof="@+id/view2" />
<view
android:id="@+id/view4"
android:layout_width="0dp"
android:layout_height="45dp"
android:layout_margintop="24dp"
android:background="@drawable/login_count"
app:layout_constraintend_toendof="@+id/login_button"
app:layout_constrainthorizontal_bias="0.0"
app:layout_constraintstart_tostartof="@+id/login_button"
app:layout_constrainttop_tobottomof="@+id/view3" />
<textview
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margintop="24dp"
android:text="忘 记 密 码"
app:layout_constraintstart_tostartof="@+id/view4"
app:layout_constrainttop_tobottomof="@+id/view4" />
<textview
android:id="@+id/login_register"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="立 即 注 册"
app:layout_constraintbottom_tobottomof="@+id/textview"
app:layout_constraintend_toendof="@+id/view4"
app:layout_constrainttop_totopof="@+id/textview" />
<imageview
android:id="@+id/imageview"
android:layout_width="20dp"
android:layout_height="20dp"
app:layout_constraintbottom_tobottomof="@+id/view4"
app:layout_constraintend_toendof="@+id/imageview4"
app:layout_constrainttop_totopof="@+id/view4"
app:srccompat="@drawable/mima" />
<imageview
android:id="@+id/imageview4"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginstart="16dp"
app:layout_constraintbottom_tobottomof="@+id/view3"
app:layout_constraintstart_tostartof="@+id/view3"
app:layout_constrainttop_totopof="@+id/view3"
app:srccompat="@drawable/zhanghao" />
<view
android:id="@+id/view5"
android:layout_width="100dp"
android:layout_height="1dp"
android:layout_margintop="40dp"
android:background="#fff"
app:layout_constraintstart_tostartof="@+id/guideline3"
app:layout_constrainttop_tobottomof="@+id/view2" />
<view
android:id="@+id/view6"
android:layout_width="100dp"
android:layout_height="1dp"
android:background="#fff"
app:layout_constraintend_tostartof="@+id/guideline2"
app:layout_constrainttop_totopof="@+id/view5" />
<textview
android:id="@+id/textview3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="其它方式登陆"
android:textcolor="#fff"
app:layout_constraintbottom_tobottomof="@+id/view5"
app:layout_constraintend_tostartof="@+id/view6"
app:layout_constraintstart_toendof="@+id/view5"
app:layout_constrainttop_totopof="@+id/view5" />
<imageview
android:id="@+id/imageview6"
android:layout_width="30dp"
android:layout_height="30dp"
app:layout_constraintbottom_tobottomof="@+id/imageview5"
app:layout_constraintend_tostartof="@+id/imageview7"
app:layout_constraintstart_toendof="@+id/imageview5"
app:layout_constrainttop_totopof="@+id/imageview5"
app:srccompat="@drawable/qq" />
<imageview
android:id="@+id/imageview5"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginstart="70dp"
android:layout_margintop="24dp"
app:layout_constraintstart_tostartof="@+id/guideline3"
app:layout_constrainttop_tobottomof="@+id/view5"
app:srccompat="@drawable/weixin" />
<imageview
android:id="@+id/imageview7"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginend="70dp"
app:layout_constraintbottom_tobottomof="@+id/imageview6"
app:layout_constraintend_tostartof="@+id/guideline2"
app:layout_constrainttop_totopof="@+id/imageview6"
app:srccompat="@drawable/weibo" />
<edittext
android:id="@+id/user"
android:layout_width="190dp"
android:layout_height="0dp"
android:layout_marginstart="5dp"
android:background="#eff4f2"
android:ems="10"
android:hint="请输入账号"
android:inputtype="textpersonname"
app:layout_constraintbottom_tobottomof="@+id/view3"
app:layout_constraintstart_toendof="@+id/imageview4"
app:layout_constrainttop_totopof="@+id/view3" />
<edittext
android:id="@+id/pass"
android:layout_width="190dp"
android:layout_height="0dp"
android:layout_marginstart="5dp"
android:background="#eff4f2"
android:ems="10"
android:hint="请输入密码"
android:inputtype="textpassword"
app:layout_constraintbottom_tobottomof="@+id/view4"
app:layout_constraintstart_toendof="@+id/imageview"
app:layout_constrainttop_totopof="@+id/view4"
app:layout_constraintvertical_bias="0.0" />
</androidx.constraintlayout.widget.constraintlayout>
注册页面java代码如下所示:
package com.android.newshop.register;
import android.content.intent;
import android.os.bundle;
import android.view.view;
import android.widget.button;
import android.widget.edittext;
import android.widget.textview;
import android.widget.toast;
import androidx.appcompat.app.appcompatactivity;
import com.android.newshop.data.databasehelper;
import com.android.newshop.login.loginactivity;
import com.android.newshop.r;
import org.w3c.dom.text;
public class registeractivity extends appcompatactivity {
private edittext musernameedittext;
private edittext mpasswordedittext;
private textview tvlogin;
private databasehelper mdatabasehelper;
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_register);
mdatabasehelper = new databasehelper(this);
musernameedittext = findviewbyid(r.id.username_edittext);
mpasswordedittext = findviewbyid(r.id.password_edittext);
tvlogin = findviewbyid(r.id.tv_login);
// 返回登陆页面
tvlogin.setonclicklistener(new view.onclicklistener() {
@override
public void onclick(view view) {
finish();
}
});
// 注册
button registerbutton = findviewbyid(r.id.register_button);
registerbutton.setonclicklistener(new view.onclicklistener() {
@override
public void onclick(view v) {
string username = musernameedittext.gettext().tostring().trim();
string password = mpasswordedittext.gettext().tostring().trim();
if (username.isempty() || password.isempty()) {
toast.maketext(getapplicationcontext(), "请输入账号或密码", toast.length_short).show();
return;
}
boolean result = mdatabasehelper.insertdata(username, password);
if (result) {
toast.maketext(getapplicationcontext(), "注册成功", toast.length_short).show();
intent intent = new intent(registeractivity.this, loginactivity.class);
startactivity(intent);
finish();
} else {
toast.maketext(getapplicationcontext(), "注册失败", toast.length_short).show();
}
}
});
}
}
登陆页面xml代码如下所示:
package com.android.newshop.login;
import android.content.intent;
import android.os.bundle;
import android.view.view;
import android.widget.button;
import android.widget.edittext;
import android.widget.textview;
import android.widget.toast;
import androidx.appcompat.app.appcompatactivity;
import com.android.newshop.data.databasehelper;
import com.android.newshop.mainactivity;
import com.android.newshop.r;
import com.android.newshop.register.registeractivity;
public class loginactivity extends appcompatactivity {
private textview loginregister;
private edittext user;
private edittext pass;
private button mloginbutton;
private databasehelper mdatabasehelper;
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_login);
user = findviewbyid(r.id.user);
pass = findviewbyid(r.id.pass);
mloginbutton = findviewbyid(r.id.login_button);
loginregister = findviewbyid(r.id.login_register);
mdatabasehelper = new databasehelper(this);
loginregister.setonclicklistener(new view.onclicklistener() {
@override
public void onclick(view v) {
intent intent = new intent(loginactivity.this, registeractivity.class);
startactivity(intent);
}
});
mloginbutton.setonclicklistener(new view.onclicklistener() {
@override
public void onclick(view v) {
string username = user.gettext().tostring().trim();
string password = pass.gettext().tostring().trim();
if (username.isempty() || password.isempty()) {
toast.maketext(getapplicationcontext(), "请输入账号或密码", toast.length_short).show();
return;
}
boolean result = mdatabasehelper.checkuser(username, password);
if (result) {
toast.maketext(getapplicationcontext(), "登陆成功", toast.length_short).show();
intent intent = new intent(loginactivity.this, mainactivity.class);
startactivity(intent);
finish();
} else {
toast.maketext(getapplicationcontext(), "账号或密码错误", toast.length_short).show();
}
}
});
}
}
4、搭建主页界面
主页面xml如下所示:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.constraintlayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragment.homefragment">
<linearlayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginstart="24dp"
android:layout_margintop="3dp"
android:layout_marginend="24dp"
android:layout_marginbottom="3dp"
android:orientation="vertical"
app:layout_constraintbottom_tobottomof="parent"
app:layout_constraintend_toendof="parent"
app:layout_constraintstart_tostartof="parent"
app:layout_constrainttop_totopof="parent">
<com.youth.banner.banner
android:id="@+id/banner"
android:layout_width="match_parent"
android:layout_height="140dp" />
<androidx.constraintlayout.widget.constraintlayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margintop="10dp">
<view
android:id="@+id/view"
android:layout_width="230dp"
android:layout_height="35dp"
android:background="@drawable/home_sousuo"
app:layout_constraintstart_tostartof="parent"
app:layout_constrainttop_totopof="parent" />
<button
android:id="@+id/btn_search"
android:layout_width="79dp"
android:layout_height="38dp"
android:layout_marginleft="5dp"
android:layout_marginright="5dp"
android:background="@drawable/home_btn"
android:text="搜 索"
android:textcolor="#fff"
app:layout_constraintend_toendof="parent"
app:layout_constraintstart_toendof="@+id/view"
app:layout_constrainttop_totopof="parent"
tools:textsize="15sp" />
<imageview
android:id="@+id/imageview8"
android:layout_width="30dp"
android:layout_height="35dp"
android:layout_marginstart="8dp"
android:src="@drawable/sousuo"
app:layout_constraintbottom_tobottomof="@+id/view"
app:layout_constraintstart_tostartof="@+id/view"
app:layout_constrainttop_totopof="@+id/view" />
<edittext
android:id="@+id/et_search"
android:layout_width="170dp"
android:layout_height="26dp"
android:layout_marginstart="3dp"
android:background="#fff"
android:ems="10"
android:inputtype="textpersonname"
app:layout_constraintbottom_tobottomof="@+id/view"
app:layout_constraintstart_toendof="@+id/imageview8"
app:layout_constrainttop_totopof="@+id/view" />
</androidx.constraintlayout.widget.constraintlayout>
<com.google.android.material.tabs.tablayout
android:id="@+id/tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margintop="10dp"
app:layout_constraintstart_tostartof="@+id/guideline5">
<com.google.android.material.tabs.tabitem
android:id="@+id/tab_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="monday" />
<com.google.android.material.tabs.tabitem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="tuesday" />
<com.google.android.material.tabs.tabitem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="wednesday" />
</com.google.android.material.tabs.tablayout>
<listview
android:id="@+id/lv_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margintop="10dp"
android:scrollbars="none" />
</linearlayout>
</androidx.constraintlayout.widget.constraintlayout>
- 在oncreateview方法中,通过调用initview方法初始化视图控件,包括banner、搜索按钮、搜索框、tablayout和listview等。
- 在sousuo方法中,设置了搜索按钮的点击事件,根据用户输入的关键词搜索相关商品并展示。
- 在initlistview方法中,初始化listview,并加载商品数据。通过读取json数据文件,将商品数据解析为shop对象列表,并将所有商品数据存储在dataall列表中。然后将dataall列表中的商品添加到shoplist列表中,并使用shopadapter作为listview的适配器。同时,根据商品数据中的shoptype字段,动态创建tablayout的tab,并设置tablayout的选择事件监听器,以根据选择的商品类别展示相应的商品列表。
- 在listview的点击事件监听器中,根据点击的商品位置,将对应的shop对象传递给detailsactivity,并启动该活动。
- 通过调用initview方法,将视图控件与布局文件中的对应控件进行绑定。
接下来是对应java文件代码:
package com.android.newshop.fragment;
import android.content.context;
import android.content.intent;
import android.graphics.outline;
import android.os.bundle;
import android.text.textutils;
import android.util.log;
import android.view.layoutinflater;
import android.view.view;
import android.view.viewgroup;
import android.view.viewoutlineprovider;
import android.widget.adapterview;
import android.widget.button;
import android.widget.edittext;
import android.widget.imageview;
import android.widget.listview;
import android.widget.textview;
import android.widget.toast;
import androidx.constraintlayout.widget.guideline;
import androidx.fragment.app.fragment;
import com.android.newshop.adapter.shopadapter;
import com.android.newshop.bean.shop;
import com.android.newshop.details.detailsactivity;
import com.android.newshop.mainactivity;
import com.android.newshop.r;
import com.google.android.material.tabs.tablayout;
import com.google.gson.gson;
import com.google.gson.reflect.typetoken;
import com.youth.banner.banner;
import com.youth.banner.loader.imageloader;
import java.io.ioexception;
import java.io.inputstream;
import java.nio.charset.standardcharsets;
import java.util.arraylist;
import java.util.hashset;
import java.util.list;
import java.util.set;
public class homefragment extends fragment {
// 声明控件成员变量
private edittext etsearch;
private button btnsearch;
private listview listview;
private shopadapter shopadapter;
private list<shop> shoplist = new arraylist<>(); // 存放展示的商品列表
private list<shop> dataall = new arraylist<>(); // 存放所有商品数据
private string selectedtype; // 选择的商品类别
private banner banner;
private tablayout tablayout;
public homefragment() {
}
@override
public void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
if (getarguments() != null) {
}
}
@override
public view oncreateview(layoutinflater inflater, viewgroup container,
bundle savedinstancestate) {
view view = inflater.inflate(r.layout.fragment_home, container, false);
initview(view);
banner();
initlistview();
sousuo();
return view;
}
private void sousuo() {
// 设置点击搜索按钮事件
btnsearch.setonclicklistener(new view.onclicklistener() {
@override
public void onclick(view v) {
string searchtext = etsearch.gettext().tostring().trim(); // 获取搜索框文本
if (textutils.isempty(searchtext)) { // 搜索框为空时展示全部商品
shoplist.clear();
shoplist.addall(dataall);
shopadapter.notifydatasetchanged();
toast.maketext(getactivity(), "请输入搜索内容!", toast.length_short).show();
} else { // 根据关键词搜索相关商品并展示
shoplist.clear();
for (shop shop : dataall) {
if (shop.gettitle().contains(searchtext)) {
shoplist.add(shop);
}
}
shopadapter.notifydatasetchanged();
}
}
});
}
private void initlistview() {
if (!"".equals(loadjsonfromasset())) {
dataall = new gson().fromjson(loadjsonfromasset(), new typetoken<list<shop>>() {
}.gettype());
shoplist.addall(dataall);
}
shopadapter = new shopadapter(getcontext(), shoplist);
listview.setadapter(shopadapter);
listview.setonitemclicklistener(new adapterview.onitemclicklistener() {
@override
public void onitemclick(adapterview<?> parent, view view, int position, long id) {
intent intent = new intent(getactivity(), detailsactivity.class);
intent.putextra("data", shoplist.get(position));
startactivity(intent);
}
});
set<string> tt = new hashset<>();
for (shop newsbean : dataall) {
tt.add(newsbean.getshoptype());
}
tablayout.removealltabs();
for (string s : tt) {
tablayout.tab tab = tablayout.newtab();
tab.settext(s);
tablayout.addtab(tab);
}
// 标题
tablayout.addontabselectedlistener(new tablayout.ontabselectedlistener() {
@override
public void ontabselected(tablayout.tab tab) {
selectedtype = tab.gettext().tostring();
shoplist.clear();
list<shop> filteredlist = new arraylist<>();
for (int i = 0; i < dataall.size(); i++) {
shop newsbean = dataall.get(i);
if (newsbean.getshoptype().equals(selectedtype)) {
shoplist.add(newsbean);
}
}
shopadapter.notifydatasetchanged();
}
@override
public void ontabunselected(tablayout.tab tab) {
}
@override
public void ontabreselected(tablayout.tab tab) {
}
});
}
private void initview(view view) {
banner = (banner) view.findviewbyid(r.id.banner);
btnsearch = (button) view.findviewbyid(r.id.btn_search);
etsearch = (edittext) view.findviewbyid(r.id.et_search);
tablayout = (tablayout) view.findviewbyid(r.id.tablayout);
listview = (listview) view.findviewbyid(r.id.lv_list);
tablayout = view.findviewbyid(r.id.tablayout);
}
}
5、搭建购物车界面
购物车页面xml代码如下所示:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.constraintlayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragment.cartfragment">
<listview
android:id="@+id/lv_cart"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintbottom_totopof="@+id/view10"
app:layout_constraintend_toendof="parent"
app:layout_constrainthorizontal_bias="1.0"
app:layout_constraintstart_tostartof="parent"
app:layout_constrainttop_tobottomof="@+id/view13" />
<view
android:id="@+id/view10"
android:layout_width="0dp"
android:layout_height="50dp"
app:layout_constraintbottom_tobottomof="parent"
app:layout_constraintend_toendof="parent"
app:layout_constraintstart_tostartof="parent" />
<textview
android:id="@+id/tv_total"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginstart="8dp"
android:text="合计:¥00.00"
android:textcolor="#000"
android:textsize="16sp"
android:textstyle="bold"
app:layout_constraintbottom_tobottomof="parent"
app:layout_constraintend_tostartof="@+id/btn_pay"
app:layout_constraintstart_tostartof="parent"
app:layout_constrainttop_tobottomof="@+id/lv_cart" />
<button
android:id="@+id/btn_pay"
android:layout_width="100dp"
android:layout_height="0dp"
android:layout_margintop="5dp"
android:layout_marginend="8dp"
android:layout_marginbottom="5dp"
android:background="@drawable/cart_item"
android:text="去结算"
android:textcolor="#fff"
app:layout_constraintbottom_tobottomof="parent"
app:layout_constraintend_toendof="parent"
app:layout_constrainttop_tobottomof="@+id/lv_cart" />
<view
android:id="@+id/view13"
android:layout_width="wrap_content"
android:layout_height="100dp"
app:layout_constraintend_toendof="parent"
app:layout_constraintstart_tostartof="parent"
app:layout_constrainttop_totopof="parent" />
<textview
android:id="@+id/textview10"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginstart="8dp"
android:layout_margintop="8dp"
android:text="购物车"
android:textcolor="#000"
android:textsize="28sp"
android:textstyle="bold"
app:layout_constraintstart_tostartof="parent"
app:layout_constrainttop_totopof="parent" />
<linearlayout
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="10dp"
android:gravity="center"
android:orientation="vertical"
app:layout_constraintbottom_totopof="@+id/lv_cart"
app:layout_constraintend_toendof="@+id/view13"
app:layout_constraintstart_tostartof="parent"
app:layout_constrainttop_tobottomof="@+id/textview10">
<linearlayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<textview
android:id="@+id/textview15"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="收货地址:"
android:textcolor="#000"
android:textsize="20sp" />
<textview
android:id="@+id/textview16"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="xxx省xxx市xxx区(县)xxx村" />
</linearlayout>
</linearlayout>
</androidx.constraintlayout.widget.constraintlayout>
实现了加载购物车数据、显示购物车列表、支付功能的实现。
在oncreateview方法中,它通过调用loaddatatolistview方法来加载数据并将其设置到listview上。然后,它设置了支付按钮的点击事件,当用户点击支付按钮时,会显示一个支付成功的toast消息。
在loaddatatolistview方法中,它首先对购物车数据进行逆序排序,以便按照添加时间的逆序显示购物车列表。然后,它创建一个cartitemadapter适配器,并将其设置到listview上。
对应的java编程代码:
package com.android.newshop.fragment;
import android.content.context;
import android.content.sharedpreferences;
import android.os.bundle;
import androidx.fragment.app.fragment;
import android.util.log;
import android.view.layoutinflater;
import android.view.view;
import android.view.viewgroup;
import android.widget.button;
import android.widget.listview;
import android.widget.textview;
import android.widget.toast;
import com.android.newshop.adapter.cartitemadapter;
import com.android.newshop.bean.cartitem;
import com.android.newshop.r;
import java.util.arraylist;
import java.util.collections;
import java.util.comparator;
import java.util.list;
import java.util.map;
public class cartfragment extends fragment {
private listview listview;
private cartitemadapter cartadapter;
private button pay;
private textview zj;
public cartfragment() {
}
@override
public void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
}
@override
public view oncreateview(layoutinflater inflater, viewgroup container,
bundle savedinstancestate) {
view view = inflater.inflate(r.layout.fragment_cart, container, false);
listview = view.findviewbyid(r.id.lv_cart);
pay = view.findviewbyid(r.id.btn_pay);
zj = view.findviewbyid(r.id.tv_total);
// 加载并设置数据到listview
loaddatatolistview(listview);
// 设置支付按钮的点击事件
pay.setonclicklistener(new view.onclicklistener() {
@override
public void onclick(view v) {
toast.maketext(getactivity(), "支付成功,购物车已清空!", toast.length_short).show();
}
});
return view;
}
// 对数据集合进行逆序排序
collections.sort(cartlist, new comparator<cartitem>() {
@override
public int compare(cartitem item1, cartitem item2) {
// 逆序比较添加时间
return long.compare(item2.getaddtime(), item1.getaddtime());
}
});
collections.reverse(cartlist); // 将arraylist进行逆序排列
// 创建适配器并设置到listview上
cartitemadapter adapter = new cartitemadapter(getactivity(), cartlist);
log.d("adapter", "adapter set to listview");
}
}
6、搭建我的页面
对应的xml代码如下所示:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.constraintlayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragment.minefragment">
<imageview
android:id="@+id/imageview9"
android:layout_width="0dp"
android:layout_height="260dp"
android:scaletype="centercrop"
android:src="@drawable/bclx"
app:layout_constraintend_toendof="parent"
app:layout_constraintstart_tostartof="parent"
app:layout_constrainttop_totopof="parent" />
<linearlayout
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginstart="16dp"
android:layout_marginend="16dp"
android:orientation="vertical"
app:layout_constraintbottom_tobottomof="parent"
app:layout_constraintend_toendof="parent"
app:layout_constraintstart_tostartof="parent"
app:layout_constrainttop_tobottomof="@+id/imageview9">
<linearlayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<textview
android:id="@+id/textview8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="地址:"
android:textcolor="#000"
android:textsize="18sp" />
<textview
android:id="@+id/textview9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center|left"
android:text="xxx省xxx市xxx区(县)xxx村"
android:textsize="17sp" />
</linearlayout>
<view
android:id="@+id/view11"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_margintop="5dp"
android:background="#ccc" />
<linearlayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margintop="8dp"
android:orientation="horizontal">
<textview
android:id="@+id/tv_modify"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="修改密码"
android:textcolor="#000"
android:textsize="18sp" />
<imageview
android:id="@+id/imageview10"
android:layout_width="15dp"
android:layout_height="match_parent"
android:src="@drawable/right" />
</linearlayout>
<view
android:id="@+id/view15"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_margintop="5dp"
android:background="#ccc" />
</linearlayout>
</androidx.constraintlayout.widget.constraintlayout>
实现java代码如下所示:
package com.android.newshop.fragment;
import android.content.dialoginterface;
import android.content.intent;
import android.os.bundle;
import android.view.layoutinflater;
import android.view.view;
import android.view.viewgroup;
import android.widget.edittext;
import android.widget.imageview;
import android.widget.textview;
import android.widget.toast;
import androidx.appcompat.app.alertdialog;
import androidx.fragment.app.fragment;
import com.android.newshop.data.databasehelper;
import com.android.newshop.login.loginactivity;
import com.android.newshop.r;
/**
* a simple {@link fragment} subclass.
* use the {@link minefragment#newinstance} factory method to
* create an instance of this fragment.
*/
public class minefragment extends fragment {
private imageview imageview9;
private textview textview8;
private textview textview9;
private view view11;
private textview tvmodify;
private view view15;
public static minefragment newinstance(string param1, string param2) {
minefragment fragment = new minefragment();
return fragment;
}
@override
public void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
}
@override
public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) {
view view = inflater.inflate(r.layout.fragment_mine, container, false);
tvmodify = view.findviewbyid(r.id.tv_modify);
modify();
return view;
}
// 设置tvmodify的点击修改密码事件
private void modify() {
tvmodify.setonclicklistener(new view.onclicklistener() {
@override
public void onclick(view v) {
showdialog();
}
});
}
// 创建自定义对话框方法
private void showdialog() {
alertdialog.builder builder = new alertdialog.builder(getactivity());
// 获取布局中的控件
view dialogview = getlayoutinflater().inflate(r.layout.dialog_modify_password, null);
final edittext etusername = dialogview.findviewbyid(r.id.et_username);
final edittext etnewpassword = dialogview.findviewbyid(r.id.et_new_password);
builder.setview(dialogview)
.setpositivebutton("确认", new dialoginterface.onclicklistener() {
@override
public void onclick(dialoginterface dialog, int which) {
string username = etusername.gettext().tostring();
string newpassword = etnewpassword.gettext().tostring();
// 调用修改密码的方法
boolean ispasswordupdated = updatepassword(username, newpassword);
if (ispasswordupdated) {
toast.maketext(getactivity(), "密码修改成功!", toast.length_short).show();
intent intent = new intent(getactivity(), loginactivity.class);
startactivity(intent);
getactivity().finish();//注销页面
} else {
toast.maketext(getactivity(), "密码修改失败!", toast.length_short).show();
}
}
})
.setnegativebutton("取消", null)
.create()
.show();
}
// 修改密码的方法
private boolean updatepassword(string username, string newpassword) {
// 这里调用之前提到的 databasehelper 类的 updatepassword 方法来执行密码修改操作
databasehelper dbhelper = new databasehelper(getactivity());
return dbhelper.updatepassword(username, newpassword);
}
}
至此,完整的购物商城项目创建完成。
五、项目运行
1.图片演示
(1)运行app到模拟器上,显示启动面:
(2)登陆页面:
(3)点击注册跳转到注册页面:
(4)注册账号后进行登陆然乎进入首页:
(5)点击商品进入详情页:
(5)进入购车页面
(6)进入我的页面
运行效果和功能很完整,至此就完成了非常简单的购物车app。大家可以跟着动手做一下,放上自己喜欢的商品,还有头像!
六、项目总结
-
启动页:应用启动时显示的欢迎页面。
-
用户登录/注册功能:用户可以通过输入用户名和密码进行登录或注册新账户。
-
主页面功能:
- 顶部轮播图功能:展示热门商品或促销活动的轮播图。
- 搜索功能:允许用户根据关键字搜索商品。
- 商品目录:按照类别或标签分类展示商品。
- 商品列表:展示符合搜索条件或所选类别的商品列表。
- 点击商品列表进入详情页:用户可以点击商品列表中的商品,查看其详细信息。
-
购物车功能:
- 商品数量的增加减少:允许用户在购物车中增加或减少商品的数量。
- 商品支付购买:用户可以选择购买购物车中的商品,进行支付。
-
我的页面:
- 修改用户密码:允许用户修改已登录账户的密码。
-
详情页面:
- 显示商品详情信息:展示选定商品的详细信息,如价格、描述、评价等。
发表评论