Android学习之网上商城(上)

这篇具有很好参考价值的文章主要介绍了Android学习之网上商城(上)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

又到了课设的时候,这次课设比较难受,因为两周时间中还有3门考试,在课设的时候还要复习,着实耗费了不少的精力,不过也收获多多,接下来总结一下本次课设中学到的东西

Android学习之网上商城(上)
Android学习之网上商城(下)

源码下载:
链接:https://pan.baidu.com/s/1Z17xBHV9iq70LwdgXxwDIQ
提取码:Lin2

Android学习之网上商城源代码

本博客内容原创,创作不易,转载请注明

本文链接

个人博客:https://ronglin.fun/?p=118
PDF链接:见博客网站
CSDN: https://blog.csdn.net/RongLin02/article/details/121876257

开发环境:

  • Android Studio版本:(Android Studio Arctic Fox 2020.3.1 Patch 3)
  • SDK版本:(Android 7.0 API24 Revision 2)
  • Gradle版本:(7.0.2)
  • Android Gradle Plugin版本:(7.0.3)

选题

题目

本次选题为网上商城/外卖小助手。要求如下:
功能要求

  • 要求实现商品展示、商品详细介绍、下订单、购物车。
  • 要求实现用户注册、登录、查看历时订单。
  • 数据:可以采用静态的固定的数据来模拟(如果动手能力较强,可以尝试自己动手搭后台,利用 Android 网络编程)。

目的:

  • 掌握 Android 中的菜单及导航框架。
  • 掌握自定义布局。
  • 掌握 Android 中的数据存储。

分析

1. 商品展示
商品展示准备用一个ListView展示内容,主要包括商品的名称、价格、预览图、加入购物车功能等
2. 商品详细介绍
这个界面准备用一个自定义Dialog实现,主要是布局设计,展示商品的名称、价格、预览图、描述、标签等
3. 购物车
购物车用一个ListView维护,主要是用来显示用户的购物车内容,这个界面的主要功能就是对购物车中的商品删除和下单扣费,因为是静态数据,准备用ArrayList数组维护
4. 下订单
暂定实现用户的扣费和将订单加入历史订单中,用ArrayList维护,主要是内容的增加和删除
5. 注册
用单独的一个Activity实现,主要是用于用户的注册,有三个数据,第一个是用户名,第二个是密码,第三个是确认密码,然后注册成功之后将数据插入本地数据库,用户列表主要用SQLite存储。
6. 登录
登录就是比对用户输入和数据库中的数据是否匹配,匹配则登录成功,失败则提示
7. 历史订单
历史订单用SQLite存储,主要记录的是用户的用户名,商品名称和购物时间
8. 数据
由于时间有限,本次Android设计主要是用静态数据,商品数据由本地写死,用户信息用SQLite数据库维护

效果展示

注册登录

实现账号的注册与登录,当用户注册完成后,会将注册好的账号密码自动填入登录界面中
Android学习之网上商城(上)

商品展示

商品的展示界面,点击每一行展示商品的详细信息,点击+号可以将商品添加到购物车中
Android学习之网上商城(上)

购物车

购物车中需要扣费,在个人中心可以充值,然后购物的时候可以扣费
Android学习之网上商城(上)

用法

这个模块主要用来说明,在本次安卓开发用主要用的部分,一个ListView,一个是viewBinding,一个是Fragment,还有一些其他的用法

ListView

ListView是这其中最常用的控件,包括商品展示,购物车列表展示,个人中心中的历史清单列表,都是用的ListView显示数据。

item

在ListView中,每一行都是一个item,所以说要用ListView首先就是先设计一个item的布局文件,如下图
Android学习之网上商城(上)
部分代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <ImageView
        android:id="@+id/imageViewPreview"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        app:srcCompat="@drawable/default_goods"
        android:background="@color/white"
        android:adjustViewBounds="true"
        android:scaleType="centerInside"/>

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="3"
        android:orientation="vertical">
        ......
    </LinearLayout>
</LinearLayout>

这样新建一个item,并且为其中每一个按钮设置好id

BaseAdapter

设计完每一行的显示之后还不行,还要用代码来设计每一个item是如何显示的,这里就用到了Adapter适配器,因为我的数据显示比较复杂,只能用自定义的适配器,定义一个类,继承自BaseAdapter类,然后实现其中的几个抽象方法,如下

package com.ronglin.linshopping.application;

public class GoodsListAdapter extends BaseAdapter{
    private ArrayList<Goods> list_goods;

    public GoodsListAdapter(ArrayList<Goods> list, Context context){
        this.list_goods = list;
        this.context = context;
    }

    public void setListGoods(ArrayList<Goods> list){this.list_goods = list;}

    @Override
    public int getCount() {return list_goods.size();}

    @Override
    public Object getItem(int i) {return list_goods.get(i);}

    @Override
    public long getItemId(int i) {return i;}

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        View item_view;
        item_view = View.inflate(this.context, R.layout.list_item_goods,null);
        //设置列表的显示形式
        TextView textViewGoodsName = item_view.findViewById(R.id.textViewGoodsName);
        textViewGoodsName.setText(list_goods.get(i).getGoodsName());
        return item_view;
    }
}

这个GoodsListAdapter类就是用来控制每一行如何显示的,为了实现动态数据,用了一个ArrayList实现数据存储,然后显示的数据都从ArrayList中提取这几个方法简单提示一下
getCount()用来获取到底有多少行
getItem(int i)用来获取第i行(从0开始)的数据类
getItemId(int i)用来获取第i行(从0开始)的数据id
getView(int i, View view, ViewGroup viewGroup)用来设置第i行(从0开始)的显示形式

Bottom Navigation Activity

因为要实现多个界面切换,在设计时看到Android Studio中的Activity的时候,看到了Bottom Navigation Activity,是用底边栏按钮切换界面,下面简单介绍一下它的用法

文件分布

bottom_nav_menu.xml
首先是/res/menu下的bottom_nav_menu.xml,这个文件的作用是控制底边栏的样式,比如购物车的图标,名称之类的,基本格式如下:

<item
        android:id="@+id/navigation_person"
        android:icon="@drawable/person"
        android:title="@string/title_person" />

文件中主要就是item,根据所查的资料,item的个数是3–5个,icon就是底边栏的按钮图标,title就是底边栏的名称

mobile_navigation.xml
然后就是在/res/navigation下的mobile_navigation.xml,这个文件就是设置每一个item中面板内容,基本内容如下

<fragment
        android:id="@+id/navigation_goods"
        android:name="com.ronglin.linshopping.ui.goods.GoodsFragment"
        android:label="@string/title_goods"
        tools:layout="@layout/fragment_goods" />

android:name 是用来配置控制界面的类,格式是包名.类名
tools:layout 是用来设置每一个界面的布局文件

简单使用

切换界面
如果想要切换手动的切换界面,要这样使用

binding.imageButtonShopping.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Navigation.findNavController(GoodsFragment.this.getView()).navigate(R.id.navigation_shopping);
            }
        });

这句代码的作用就是切换界面
然后就是Fragment的用法,关于Fragment下面还有用法说明

viewBinding

因为我用的是系统自动生成的Bottom Navigation Activity(底边栏按钮切换界面),在自动生成的代码中,用到了viewBinding,查了一下资料,发现用起来很方便,这里简单的说一下使用

build.gradle

首先要是想使用viewBinding,要在build.gradle(Module:xxx)中开启viewBinding

android {
    compileSdk 30
    ......
    buildFeatures {
        viewBinding true
    }
}

然后就可以用了

使用说明

开启viewBinding后,它会把每一个layout目录下的 xml 文件按照 驼峰命名法 生成了一个类,例如activity_main.xml文件就被生成类ActivityMainBinding然后就可以通过类的实例来访问其中的控件
例如在test_layout.xml中如下定义

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="45dp">
    <EditText
        android:id="@+id/editTextSearch"
        android:gravity="center_vertical"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="4"
        android:layout_gravity="center_vertical"
        android:layout_margin="5dp"/>
</LinearLayout>

然后在Activity中就可以这样使用

public class MainActivity extends AppCompatActivity {

    private TestLayoutBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = TestLayoutBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        binding.editTextSearch.setText("test");
    }
}

通过binding.Id名称就可以访问到特定的控件了,如果没有在Activity中,只有Context对象的话,可以这样初始化

binding = TestLayoutBinding.inflate(LayoutInflater.from(context));

之后就基本上可以不用findViewById方法了,就可以直接用binding来访问控件了。
注意:
当和ListView中的BaseAdapter一起使用时,不能用binding,还是要用findViewById方法,不知道是不是自己用错了,几次尝试之后都显示失败,无果后只能放弃

Fragment

在使用系统自动生成的Bottom Navigation Activity时,它生成了3个Fragment。
以下部分内容来官方API文档
Fragment 表示应用界面中可重复使用的一部分。Fragment 定义和管理自己的布局,具有自己的生命周期,并且可以处理自己的输入事件。Fragment 不能独立存在,而是必须由 Activity 或另一个 Fragment 托管。Fragment 的视图层次结构会成为宿主的视图层次结构的一部分,或附加到宿主的视图层次结构。

生命周期

Android学习之网上商城(上)
这是它的生命周期图,和Activity很像,简单说明一下,Fragment不能够单独使用,要嵌套在Activity中使用,其生命周期也受到所在Activity的生命周期的影响,需要注意的是,在多个Fragment之中的切换,会调用onDestroyViewonCreateView同时数据会清空,但是对应的类并没有被销毁重构,只是界面View被销毁重构

ViewModel

在使用Bottom Navigation Activity的时候,会发现,每一个界面类还会跟随一个ViewModel类,这个类主要是用来存储数据,用来适配Controller和Model之间的桥梁,同时用ViewModel也可以在多个Fragment中实现数据共享,接下来简单的说明用法

初始化
    private GoodsViewModel goodsViewModel;
    private FragmentGoodsBinding binding;

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        binding = FragmentGoodsBinding.inflate(inflater, container, false);
        View root = binding.getRoot();
        goodsViewModel =
                new ViewModelProvider(this).get(GoodsViewModel.class);
        return root;
    }

可以看到ViewModel的初始化是在onCreateView中,所以说每当点击切换Fragment的时候,ViewMode的数据都会重新初始化,这点要尤为注意

设置数据

先来简单的看一下ViewModel类中的变量和方法

public class GoodsViewModel extends ViewModel {

    private final MutableLiveData<Goods> goods;

    public GoodsViewModel() {
        goods = new MutableLiveData<>();
    }

    public LiveData<Goods> getGoods() {
        return goods;
    }

    public void setGoods(Goods goods){
        this.goods.setValue(goods);
    }
}

主要的变量就是一个MutableLiveData<?>类,这个类可以动态监听值的变化,在对应的Fragment类中可以看到以下方法

goodsViewModel.getGoods().observe(getViewLifecycleOwner(), new Observer<Goods>() {
            @Override
            public void onChanged(Goods goods) {
                Log.i("TAG",Goods.toString());
            }
        });

当类中Goods的值变化的时候就会自动执行onChanged的代码,参数中的goods是变化之后的值
经过我的开发尝试,只有在调用goodsViewModel.setGoods(goods)的时候才会被监听到,所以说当用goodsViewModel.getGoods()方法获取到数据之后,对数据的操作不会引起监听变化,所以说当改变数据之后要调用一下goodsViewModel.setGoods()方法,如下:

goodsViewModel.getGoods().setPrice(1000);
goodsViewModel.setGoods(goodsViewModel.getGoods());

这要变化之后就会调用监听了

然后就是在其他的Fragment获取数据

GoodsViewModel goodsViewModel;
goodsViewModel = new ViewModelProvider(this).get(GoodsViewModel.class);

SQLite

在Android中,数据库是使用SQLite的,关于SQLite用法网上有很多资料,这里简单说一下用法

创建

数据库的创建是需要创建一个类来继承自SQLiteOpenHelper,然后在类中实现它的抽象方法,如下:

public class MySQLiteHelper extends SQLiteOpenHelper {
    public MySQLiteHelper(@Nullable Context context) {
        super(context,"LinShopping.db", null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        sqLiteDatabase.execSQL("create table person(username varchar(30) primary key,password varchar(30))");
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

    }
}

其中构造函数有很多,我这里只是实现了其中一个,主要是需要一个Context类来初始化,然后还要设置一下数据库的名称,这个数据库的创建是在应用刚安装的时候创建的,只会创建一次,然后在onCreate方法用来调用execSQL方法来创建新表

之后有关所有数据库的操作都会用到这个SQLiteOpenHelper

操作

我本人习惯将数据库的操纵封装成一个类来调用,所以说新建一个Database类来实现数据库操作

public class Database {
    private MySQLiteHelper mySQLiteHelper;
    private SQLiteDatabase database;

    public Database(MySQLiteHelper mySQLiteHelper){
        this.mySQLiteHelper = mySQLiteHelper;
    }
}

因为获取数据库需要用到SQLiteOpenHelper类,所以在构造函数中就需要传入一个SQLiteOpenHelper类。
同时可以用execSQL方法直接输入SQL语句操作数据,这里不再说明

增加方法比较简单,如下

public void insertPersonToSQLite(Person person){
        database = mySQLiteHelper.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put("username",person.getUsername());
        values.put("password",person.getPassword());
        long id = database.insert("person",null,values);
        database.close();
    }

需要定义一个ContentValues类来保存Key-Value对,然后通过insert方法插入数据库

删除用法同样比较简单,如法如下:

public int deletePersonToSQLite(Person person){
        database = mySQLiteHelper.getWritableDatabase();
        int number = database.delete("person","username =?",new String[]{person.getUsername()});
        database.close();
        return number;
    }

用法如下

public int updatePersonToSQLite(Person person){
        database = mySQLiteHelper.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put("password",person.getPassword());
        int number = database.update("person",values,"username =?",new String[]{person.getUsername()});
        database.close();
        return number;
    }

查询方法因为需要返回很多数据,所以说用法稍微麻烦一点点,实例如下:

public ArrayList<Person> findPersonFromSQLite(String username){
        database = mySQLiteHelper.getReadableDatabase();
        ArrayList<Person> list = new ArrayList<>();
        Cursor cursor = database.query("person",null,"username=?",new String[]{person.getUsername()},null,null,null);
        if (cursor.getCount() == 0){
            cursor.close();
            database.close();
            return list;
        } else {
            cursor.moveToFirst();
            list.add(new Person(cursor.getString(0),cursor.getString(1)));
            while (cursor.moveToNext()){
                list.add(new Person(cursor.getString(0),cursor.getString(1)));
            }
            cursor.close();
            database.close();
            return list;
        }
    }

简单来说就是需要一个cursor游标来存储返回的数据,然后通过操作游标来实现数据的获取

其他功能

接下来是一些常用的小功能,用法

监听文本框

有时候我们希望,我们的EditText只能输入特定的内容或者当用户输入完毕后立刻处理结果,这样就需要用到TextWatcher类了

binding.editTextSearch.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        String search = s.toString().trim();
        Log.i("TAG",search);
    }

    @Override
    public void afterTextChanged(Editable editable) {
    }
});

简单的说明一下用法
beforeTextChanged(CharSequence s, int start, int count, int after)
s: 修改之前的文字。
start: 字符串中即将发生修改的位置。
count: 字符串中即将被修改的文字的长度。如果是新增的话则为0。
after: 被修改的文字修改之后的长度。如果是删除的话则为0。

onTextChanged(CharSequence s, int start, int before, int count)
s: 改变后的字符串
start: 有变动的字符串的序号
before: 被改变的字符串长度,如果是新增则为0。
count: 添加的字符串长度,如果是删除则为0。
afterTextChanged(Editable s)
s: 修改后的文字

修改机制如下:文字改变->watcher接收到通知->setText->文字改变->watcher接受到通知->…
参考:
Android TextWatcher内容监听死循环
可以实现限制用户输入

@Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        String search = s.toString().trim();
        Log.i("TAG",search);
        editTextSearch.removeTextChangedListener(this);
        editTextSearch.setText(search);
        editTextSearch.addTextChangedListener(this);
    }

定时器

因为Android中的UI界面是一个单线程,所以说如果要实现一个定时器,比如几秒之后干什么,有点小困难,先看实例代码

    @SuppressLint("HandlerLeak") Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
        //这里写到时间之后的操作
        }
    };
    TimerTask task = new TimerTask(){
        public void run() {
            Message message = new Message();
            mHandler.sendMessage(message);
        }
    };
    Timer timer = new Timer();
    timer.schedule(task, 1000);

就是需要定义一个Handler类来处理消息,然后定义一个TimerTask类来发送消息,用一个Timer类来启动

显示图片

图片有很多类型,我这里用的是Bitmap类,从drawable目录下构造Bitmap的方法如下:

    Bitmap bitmap1 = BitmapFactory.decodeResource(context.getResources(), R.drawable.renzituo));

用这个方法在生成release版本的时候,同样会显示,同时操作图片也很方便.

总结

到此,一些本次课设中常用功能实现就总结完毕,接下来就是对单独某些模块的实现总结,未完待续,=w=文章来源地址https://www.toymoban.com/news/detail-500823.html

到了这里,关于Android学习之网上商城(上)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 网上购物商城前后端(安卓课程设计)

    网上购物商城 项目源代码及报告参考地址:点击这里 1.掌握 Android 中的菜单及导航框架。 2.掌握自定义布局。 3.掌握 Android 中的数据存储。 4.掌握Spring boot的快捷开发 1.技术实现 ① 前端-安卓端 ② 后端-服务器端 2.模块介绍 商城安卓前端: 服务器后端: 3.设计步骤 1.需

    2024年02月06日
    浏览(32)
  • 基于微信小程序的网上商城+ssm

    随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,微信小程序被用户普遍使用,为方便用户能够可以随时进行小程序的相应信息内容的管理,特开发了基于微信

    2024年02月21日
    浏览(52)
  • 网上商城系统MySql数据库设计项目实战

    说明:这是一个数据库课程设计实战项目(附带 代码+文档+视频讲解 ),如需 代码+文档+视频讲解 可以直接到文章最后获取。 项目背景         互联网的发展让各个产业突破传统的发展领域,产业功能不断进化,实现同一内容的多领域共生,前所未有地扩大了传统产业链,

    2024年01月25日
    浏览(51)
  • 基于SSM网上商城购物系统的设计与实现

    项目描述 临近学期结束,还是毕业设计,你还在做java程序网络编程,期末作业,老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下,你想解决的问题,今天给在家介绍一篇基于网上商城购物系统的

    2024年02月06日
    浏览(51)
  • 【计算机毕业设计】512网上商城购物系统

    随着科学技术的飞速发展, 社会的方方面面、 各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势, 网上商城购物系统 当然也不能排除在外。 网上商城购物系统 是 以实际运用为开发背景,运用软件工程原理和开发方法,采用 springboot框架 构建的一个

    2024年02月08日
    浏览(41)
  • [附源码]java毕业设计网上手机商城

    项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM + mybatis + Maven + Vue 等等组成,B/S模式 + Maven管理等等。 环境需要 1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以

    2024年02月09日
    浏览(41)
  • 基于ssm+jsp的网上手机商城论文

    随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势;对于网上手机商城当然也不能排除在外,随着网络技术的不断成熟,带动了网上手机商城,它彻底改变了过去传统的管理方式,不仅使服务管理难度变低了,还提升了管理的灵

    2024年02月04日
    浏览(43)
  • 基于JAVA的ssm框架网上手机商城

    博主介绍:java高级开发,从事互联网行业六年,熟悉各种主流语言,精通java、python、爬虫、web开发,已经做了六年的毕业设计程序开发,开发过上千套毕业设计程序,可以定制、也可成品项目,博客中有上百套程序可供参考,欢迎共同交流学习。 🍅文末点击卡片获取联系🍅

    2024年04月17日
    浏览(46)
  • Spring Boot + Vue的网上商城之商品分类

    在网上商城中,商品分类是非常重要的一个功能,它可以帮助用户更方便地浏览和筛选商品。本文将介绍如何使用Spring Boot和Vue来实现商品分类的功能,包括一级分类和二级分类的管理以及前台按分类浏览商品的实现。 数据库设计:设计商品分类表和商品表,商品分类表包含

    2024年02月09日
    浏览(45)
  • 基于Java篮球系列网上商城系统详细设计和实现

    博主介绍 : ✌ 全网粉丝30W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流 ✌ 主要内容: SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、P

    2024年01月17日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包