这是一个使用Android Studio和Java开发的购物商城应用。该应用旨在提供用户一个方便、快捷的购物体验。通过该应用,用户可以浏览不同类别的商品,并将其添加到购物车中。用户可以查看商品的详细信息,包括价格等。购物商城应用还提供了用户注册和登录功能,以便用户可以保存个人信息。该应用还支持商品搜索功能,帮助用户快速找到所需商品。购物商城应用的界面简洁、直观,操作易于上手,为用户提供了一个愉快的购物体验。
目录
一、项目概述
1、构成以及功能设计
二、开发环境
三、准备工具
四、详细设计
1、新建工程
2、搭建启动页面
3、搭建注册、登陆界面
4、搭建主页界面
5、搭建购物车界面
6、搭建我的页面
五、项目运行
1.图片演示
2.视频演示
六、项目总结
七、源码下载
①启动页
②.用户登录/注册功能
③主页面功能
- 顶部轮播图功能
- 搜索功能
- 商品目录
- 商品列表
-点击商品列表进入详情页
④ 购物车功能
- 商品数量的增加减少
- 商品支付购买
⑤ 我的页面
- 修改用户密码
⑥详情页面
- 显示商品详情信息
我的开发环境如下,大家的AS版本不需要和我相同,只要是近两年从官网下载的版本,都是比4.0.0高的,是可以满足运行和开发要求的。
准备商品详情内容
首先打开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完成创建。
我们来看一下activity_start布局文件。
启动页面xml完整代码如下:
然后回到我们的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() {
}
}
}
主要实现用户数据的存储,实现用户使用注册的账号进行登陆。
注册页面xml代码如下所示:
登陆页面xml代码如下:
注册页面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();
}
}
});
}
}
主页面xml如下所示:
接下来是对应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 shopList = new ArrayList<>(); // 存放展示的商品列表
private List 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>() {
}.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 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 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);
}
}
购物车页面xml代码如下所示:
实现了加载购物车数据、显示购物车列表、支付功能的实现。
在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() {
@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");
}
}
对应的xml代码如下所示:
实现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)运行app到模拟器上,显示启动面:
(2)登陆页面:
(3)点击注册跳转到注册页面:
(4)注册账号后进行登陆然乎进入首页:
(5)点击商品进入详情页:
(5)进入购车页面
(6)进入我的页面
基于Android Studio 实现购物商城APP
运行效果和功能很完整,至此就完成了非常简单的购物车App。大家可以跟着动手做一下,放上自己喜欢的商品,还有头像!
启动页:应用启动时显示的欢迎页面。
用户登录/注册功能:用户可以通过输入用户名和密码进行登录或注册新账户。
主页面功能:
购物车功能:
我的页面:
详情页面:
需要源码学习的同学可以关注宫纵号《编程乐学》,回复:购物商城,即可获取源码信息。